Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
957b270bbe | ||
|
|
cca5bc57b4 | ||
|
|
137d5cbbb8 | ||
|
|
08302a3fd7 | ||
|
|
1dfcd5ef5d | ||
|
|
b3eddc2116 | ||
|
|
f204672681 | ||
|
|
a030a65214 | ||
|
|
b6a1526f56 | ||
|
|
2d3f3df9e8 | ||
|
|
158956117c | ||
|
|
31e9cde92e | ||
|
|
9ed9e84298 | ||
|
|
efe50b7613 | ||
|
|
cae5c3d152 | ||
|
|
a0596374d4 | ||
|
|
3160d0e58e | ||
|
|
bbd1b9f795 | ||
|
|
a968a6c8e3 | ||
|
|
99f1770842 | ||
|
|
ac23baf91f | ||
|
|
a0cb937af6 | ||
|
|
04633d2fd3 | ||
|
|
ffdf24fe0c | ||
|
|
2618ba9463 | ||
|
|
c0c571b058 | ||
|
|
278f2fd114 | ||
|
|
6ece645267 | ||
|
|
5180108598 | ||
|
|
08cd3eccd6 | ||
|
|
9dc90bb001 | ||
|
|
4b8554c64a | ||
|
|
4b8403b2b0 | ||
|
|
198b5922a4 | ||
|
|
eacd4c5e2c | ||
|
|
51132a8a30 | ||
|
|
137f9a46b5 | ||
|
|
2f68d49f4b | ||
|
|
6be0993c98 | ||
|
|
c5ea78f37c | ||
|
|
8bf5805589 |
1
.gitignore
vendored
@@ -4,4 +4,5 @@ composer.lock
|
||||
.php_cs.cache
|
||||
.php_cs
|
||||
.php-cs-fixer.cache
|
||||
.php-version
|
||||
.idea
|
||||
|
||||
22
CHANGELOG.md
@@ -1,3 +1,25 @@
|
||||
# Version 5.2.1
|
||||
* Fixed datepicker in oneshot modal
|
||||
|
||||
# Version 5.2.0
|
||||
* Added Dashboard tab
|
||||
|
||||
# Version 5.1.1
|
||||
* Add branding label
|
||||
|
||||
# Version 5.1.0
|
||||
* Added possibility to create one shot job from scheduled job
|
||||
|
||||
# Version 5.0.0
|
||||
|
||||
* Renamed bundle to IbexaDataflowBundle
|
||||
* Replaced every trace of ezdataflow with ibexa_dataflow or ibexa-dataflow
|
||||
* Added automatic replacement script
|
||||
|
||||
# Version 4.3.0
|
||||
|
||||
* Replaced date field with date picker
|
||||
|
||||
# Version 4.2.0
|
||||
|
||||
* Added error count columns to job tables
|
||||
|
||||
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2019 Code Rhapsodie
|
||||
Copyright (c) 2024 Code Rhapsodie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
157
README.md
@@ -8,12 +8,12 @@ Ibexa Dataflow bundle is intended to manage content imports from external data s
|
||||
> Note: before using this bundle, please read
|
||||
> the [Code Rhapsodie Dataflow bundle documentation](https://github.com/code-rhapsodie/dataflow-bundle/blob/master/README.md).
|
||||
|
||||
> Command line notice: When you use Dataflow commands, **use `--siteaccess` instead of `--connection`** expect
|
||||
> Command line notice: When you use Dataflow commands, **use `--siteaccess` instead of `--connection`** except
|
||||
> for `code-rhapsodie:dataflow:dump-schema` command.
|
||||
|
||||
| Ibexa Dataflow Version | Ibexa Content Version | Status |
|
||||
|------------------------|-----------------------|-------------------------------|
|
||||
| 4.x | 4.x | :white_check_mark: Maintained |
|
||||
| 6.x | 5.x | :white_check_mark: Maintained |
|
||||
|
||||
## User Interface (UI)
|
||||
|
||||
@@ -29,12 +29,12 @@ Processes can be set to run either:
|
||||
### Step 1: Install the bundle via composer
|
||||
|
||||
```shell script
|
||||
$ composer require code-rhapsodie/ezdataflow-bundle
|
||||
$ composer require code-rhapsodie/ibexa-dataflow-bundle
|
||||
```
|
||||
|
||||
### Step 2: Enable the bundle
|
||||
|
||||
> Note: The loading order between the Dataflow bundle and Ez Dataflow bundle is important. Dataflow must be loaded
|
||||
> Note: The loading order between the Dataflow bundle and Ibexa Dataflow bundle is important. Dataflow must be loaded
|
||||
> first.
|
||||
|
||||
Add those two lines in the `config/bundles.php` file:
|
||||
@@ -45,7 +45,7 @@ Add those two lines in the `config/bundles.php` file:
|
||||
return [
|
||||
// ...
|
||||
CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle::class => ['all' => true],
|
||||
CodeRhapsodie\EzDataflowBundle\CodeRhapsodieEzDataflowBundle::class => ['all' => true],
|
||||
CodeRhapsodie\IbexaDataflowBundle\CodeRhapsodieIbexaDataflowBundle::class => ['all' => true],
|
||||
// ...
|
||||
];
|
||||
```
|
||||
@@ -53,10 +53,10 @@ return [
|
||||
### Step 3: Import bundle routing file
|
||||
|
||||
```yaml
|
||||
# config/routing/ezdataflow.yaml
|
||||
# config/routing/ibexa_dataflow.yaml
|
||||
|
||||
_cr.dataflow:
|
||||
resource: '@CodeRhapsodieEzDataflowBundle/Resources/config/routing.yaml'
|
||||
_cr.ibexa_dataflow:
|
||||
resource: '@CodeRhapsodieIbexaDataflowBundle/Resources/config/routing.yaml'
|
||||
```
|
||||
|
||||
### Step 4: Update the database schema
|
||||
@@ -75,9 +75,9 @@ By default, the `ContentWriter` will publish contents using the `admin` user. If
|
||||
sufficient permissions), you can configure it like this:
|
||||
|
||||
```yaml
|
||||
# config/packages/code_rhapsodie_ez_dataflow.yaml
|
||||
# config/packages/code_rhapsodie_ibexa_dataflow.yaml
|
||||
|
||||
code_rhapsodie_ez_dataflow:
|
||||
code_rhapsodie_ibexa_dataflow:
|
||||
# Integer values are assumed to be user ids, non-integer values are assumed to be user logins
|
||||
admin_login_or_id: webmaster
|
||||
```
|
||||
@@ -89,7 +89,7 @@ to [Code-Rhapsodie Dataflow type documentation](https://github.com/code-rhapsodi
|
||||
|
||||
## Use the ContentWriter
|
||||
|
||||
To add or update Ibexa contents, you can use the `CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter` writer.
|
||||
To add or update Ibexa contents, you can use the `CodeRhapsodie\IbexaDataflowBundle\Writer\ContentWriter` writer.
|
||||
|
||||
### Step 1: Inject the dependencies and add the writer
|
||||
|
||||
@@ -99,21 +99,15 @@ list like this:
|
||||
```php
|
||||
// In your DataflowType
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Writer\ContentWriter;
|
||||
use CodeRhapsodie\DataflowBundle\DataflowType\AbstractDataflowType;
|
||||
[...]
|
||||
|
||||
class MyDataflowType extends AbstractDataflowType
|
||||
{
|
||||
//[...]
|
||||
/**
|
||||
* @var ContentWriter
|
||||
*/
|
||||
private $contentWriter;
|
||||
|
||||
public function __construct(ContentWriter $contentWriter)
|
||||
public function __construct(private readonly ContentWriter $contentWriter)
|
||||
{
|
||||
$this->contentWriter = $contentWriter;
|
||||
}
|
||||
//[...]
|
||||
protected function buildDataflow(DataflowBuilder $builder, array $options): void
|
||||
@@ -153,36 +147,26 @@ In this example, I have added a new folder to store all articles.
|
||||
To get the location id of the parent Ibexa content, go to the admin UI and select the future parent content, click on
|
||||
the details tabs, and read the "Location id" like this:
|
||||
|
||||

|
||||

|
||||
|
||||
> Note: the best practice is to define this parent id in your `parameters.yml` file or your `.env.local` file for each
|
||||
> Note: the best practice is to define this parent id in your `parameters.yaml` file or your `.env.local` file for each
|
||||
> execution environment.
|
||||
|
||||
```php
|
||||
// In your DataflowType
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Factory\ContentStructureFactory;
|
||||
use CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Factory\ContentStructureFactory;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Writer\ContentWriter;
|
||||
use CodeRhapsodie\DataflowBundle\DataflowType\AbstractDataflowType;
|
||||
[...]
|
||||
|
||||
class MyDataflowType extends AbstractDataflowType
|
||||
{
|
||||
//[...]
|
||||
/**
|
||||
* @var ContentWriter
|
||||
*/
|
||||
private $contentWriter;
|
||||
|
||||
/**
|
||||
* @var ContentStructureFactory
|
||||
*/
|
||||
private $contentStructureFactory;
|
||||
|
||||
public function __construct(ContentWriter $contentWriter, ContentStructureFactory $contentStructureFactory)
|
||||
{
|
||||
$this->contentWriter = $contentWriter;
|
||||
$this->contentStructureFactory = $contentStructureFactory;
|
||||
public function __construct(
|
||||
private readonly ContentWriter $contentWriter,
|
||||
private readonly ContentStructureFactory $contentStructureFactory
|
||||
) {
|
||||
}
|
||||
//[...]
|
||||
protected function buildDataflow(DataflowBuilder $builder, array $options): void
|
||||
@@ -197,13 +181,13 @@ class MyDataflowType extends AbstractDataflowType
|
||||
unset($data['id']);
|
||||
|
||||
return $this->contentStructureFactory->transform(
|
||||
$data,
|
||||
$remoteId,
|
||||
'eng-GB',
|
||||
'article2',
|
||||
54, //Parent location id
|
||||
ContentStructureFactoryInterface::MODE_INSERT_OR_UPDATE //Optional value. Other choice : ContentStructureFactoryInterface::MODE_INSERT_ONLY or ContentStructureFactoryInterface::MODE_UPDATE_ONLY
|
||||
);
|
||||
$data,
|
||||
$remoteId,
|
||||
'eng-GB',
|
||||
'article2',
|
||||
54, //Parent location id
|
||||
ContentStructureFactoryInterface::MODE_INSERT_OR_UPDATE //Optional value. Other choice : ContentStructureFactoryInterface::MODE_INSERT_ONLY or ContentStructureFactoryInterface::MODE_UPDATE_ONLY
|
||||
);
|
||||
});
|
||||
// If you want the writer log
|
||||
$this->contentWriter->setLogger($this->logger);
|
||||
@@ -248,27 +232,31 @@ the `NotModifiedContentFilter` to prevent unnecessary overhead.
|
||||
|
||||
### Supported field types
|
||||
|
||||
- ezstring
|
||||
- ezauthor
|
||||
- ezboolean
|
||||
- ezcountry
|
||||
- ezdate
|
||||
- ezdatetime
|
||||
- ezemail
|
||||
- ezfloat
|
||||
- ezisbn
|
||||
- ezobjectrelation
|
||||
- ezobjectrelationlist
|
||||
- ezkeyword
|
||||
- ezselection
|
||||
- eztext
|
||||
- eztime
|
||||
- ibexa_author
|
||||
- ibexa_boolean
|
||||
- ibexa_country
|
||||
- ibexa_datetime
|
||||
- ibexa_date
|
||||
- ibexa_email
|
||||
- ibexa_float
|
||||
- ibexa_integer
|
||||
- ibexa_isbn
|
||||
- ibexa_keyword
|
||||
- ibexa_object_relation
|
||||
- ibexa_object_relation_list
|
||||
- ibexa_richtext
|
||||
- ibexa_selection
|
||||
- ibexa_text
|
||||
- ibexa_string
|
||||
- ibexa_time
|
||||
- eztags
|
||||
- ibexa_url
|
||||
- novaseometas
|
||||
- ezurl
|
||||
- ezmatrix
|
||||
- ezgmaplocation
|
||||
- ezrichtext
|
||||
- ibexa_matrix
|
||||
- ibexa_gmap_location
|
||||
- ibexa_taxonomy_entry_assignment
|
||||
- ibexa_address
|
||||
- ibexa_customer_group
|
||||
|
||||
### Add custom field comparator
|
||||
|
||||
@@ -277,7 +265,7 @@ If you want to add support for a field type, simply create your own comparator.
|
||||
```php
|
||||
<?php
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator;
|
||||
use Ibexa\Core\FieldType\Value;
|
||||
//[...]
|
||||
|
||||
@@ -295,9 +283,9 @@ class MyFieldComparator extends AbstractFieldComparator
|
||||
```yaml
|
||||
# Service declaration
|
||||
App\FieldComparator\MyFieldComparator:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'my_field_type_identifier' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'my_field_type_identifier' }
|
||||
```
|
||||
|
||||
# Admin UI
|
||||
@@ -306,16 +294,16 @@ App\FieldComparator\MyFieldComparator:
|
||||
|
||||
You can access the Ibexa Dataflow administration UI from your Ibexa admin back-office.
|
||||
|
||||

|
||||

|
||||
|
||||
1. Click to "Admin"
|
||||
1. Click to "Ibexa Dataflow"
|
||||
|
||||
## Scheduled dataflow list
|
||||
|
||||
When you access to the Ibexa Dataflow administration UI, you going here:
|
||||
When you access to the Ibexa Dataflow administration UI, you arrive on the scheduled dataflow list page:
|
||||
|
||||

|
||||

|
||||
|
||||
1. Scheduled dataflow list
|
||||
1. Button to add a new scheduled dataflow
|
||||
@@ -333,7 +321,7 @@ Go to the Ibexa Dataflow admin, and click on the "+" orange button.
|
||||
|
||||
In the new popin, fill in the fields:
|
||||
|
||||

|
||||

|
||||
|
||||
1. Type the Dataflow schedule name
|
||||
1. Select the Dataflow type. The list is automatically generated from the list of Symfony services with the
|
||||
@@ -353,15 +341,17 @@ Finally, click on the "Create" button.
|
||||
When you click on the "History" tab in the Ibexa Dataflow admin UI, the job history for all Dataflow configured and
|
||||
executed is displayed.
|
||||
|
||||

|
||||

|
||||
|
||||
1. The history list
|
||||
1. This column shows the number of objects that have been processed.
|
||||
1. Click on the question mark to display the job details.
|
||||
1. A summary of each job dates and number of items processed.
|
||||
1. Click on the question mark icon to display the job details.
|
||||
1. Click on the text icon to display the job exception log.
|
||||
1. Switch between displaying all jobs, or only non-empty jobs (at least 1 item was processed)
|
||||
|
||||
Details of one scheduled job:
|
||||
|
||||

|
||||

|
||||
|
||||
## One-shot job
|
||||
|
||||
@@ -369,23 +359,24 @@ If you don't want to run a Dataflow periodically, you can add a single execution
|
||||
|
||||
Go to the Ibexa Dataflow admin UI and click on the "Oneshot" tab.
|
||||
|
||||

|
||||

|
||||
|
||||
1. This button allows you to define the one-shot job (see below).
|
||||
1. This column shows the number of objects that have been processed.
|
||||
1. Click on the question mark to display the job details.
|
||||
1. This button allows you to create a new one-shot job (see below).
|
||||
1. A summary of each job dates and number of items processed.
|
||||
1. Click on the question mark icon to display the job details.
|
||||
1. Click on the text icon to display the job exception log.
|
||||
|
||||
Details of one-shot job:
|
||||
|
||||

|
||||

|
||||
|
||||
Here the job has fail.
|
||||
|
||||
## Add a one-shot job
|
||||
|
||||
Go to the Ibexa Dataflow admin UI and click on the "Oneshot" tab. Click on the "+" orange button to open the adding popin.
|
||||
Go to the Ibexa Dataflow admin UI and click on the "Oneshot" tab. Click on the "+ Create" button to open the add popin.
|
||||
|
||||

|
||||

|
||||
|
||||
1. Type the Dataflow job name
|
||||
1. Select the Dataflow type. The list is automatically generated from the list of Symfony services with the
|
||||
@@ -404,13 +395,13 @@ and `Ibexa Dataflow / View` policies in one of their roles.
|
||||
|
||||
# Issues and feature requests
|
||||
|
||||
Please report issues and request features at https://github.com/code-rhapsodie/ezdataflow-bundle/issues.
|
||||
Please report issues and request features at https://github.com/code-rhapsodie/ibexa-dataflow-bundle/issues.
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions are very welcome. Please see [CONTRIBUTING.md](CONTRIBUTING.md) for
|
||||
details. Thanks
|
||||
to [everyone who has contributed](https://github.com/code-rhapsodie/ezdataflow-bundle/graphs/contributors)
|
||||
to [everyone who has contributed](https://github.com/code-rhapsodie/ibexa-dataflow-bundle/graphs/contributors)
|
||||
already.
|
||||
|
||||
# License
|
||||
|
||||
35
UPGRADE.md
@@ -1,15 +1,28 @@
|
||||
# From v1.0 to v2.0
|
||||
In version 5, all references to ezdataflow were replaced by ibexa-dataflow, in namespaces, class names, tags and config keys.
|
||||
This requires some changes in your application files.
|
||||
|
||||
When you use Dataflow commands, use `--siteaccess` instead of `--connection` except for `code-rhapsodie:dataflow:dump-schema`.
|
||||
## Updating source files
|
||||
|
||||
[BC] The return of `CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway::findForScheduled`
|
||||
and `CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway::findAllOrderedByLabel` has been changed.
|
||||
The iterable contains an associative array instead of an object.
|
||||
A script is provided to do all the replacements in your project files for you. Pass as arguments all directories where
|
||||
replacing is needed.
|
||||
|
||||
[BC] In classes `CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway` and
|
||||
`CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway`, all methods return `Doctrine\ORM\Query` object has
|
||||
changed to return now a `Doctrine\DBAL\Query\QueryBuilder`
|
||||
```shell
|
||||
php vendor/bin/ibexa-dataflow-namespace-changer.phar src/ config/ templates/ translations/
|
||||
```
|
||||
|
||||
[BC] The return type of `CodeRhapsodie\EzDataflowBundle\Factory\ContentStructureFactory::transform` has been changed
|
||||
from `CodeRhapsodie\EzDataflowBundle\Model\ContentStructure` to `mixed`. In fact only `false` or
|
||||
`CodeRhapsodie\EzDataflowBundle\Model\ContentStructure` object will be returned.
|
||||
You should check all changes performed afterward. Here is the list of all the replacement that should be performed:
|
||||
|
||||
- all namespaces starting by `CodeRhapsodie\EzDataflowBundle` should now start by `CodeRhapsodie\IbexaDataflowBundle`, anywhere in PHP sources and services definitions
|
||||
- the class `CodeRhapsodieEzDataflowBundle` should be renamed `CodeRhapsodieIbexaDataflowBundle` in `bundles.php`
|
||||
- the config key `code_rhapsodie_ezdataflow` should be renamed `code_rhapsodie_ibexa_dataflow` in config files
|
||||
- all translation keys starting by `ezdataflow` should now start by `ibexa_dataflow` in translation files
|
||||
- the security policy module `ezdataflow` should be renamed `ibexa_dataflow`
|
||||
- all template paths containing `ezdataflow` should now contain `ibexa_dataflow`
|
||||
|
||||
## Updating database
|
||||
|
||||
Run the following command on your database:
|
||||
|
||||
```sql
|
||||
UPDATE ezpolicy SET module_name = 'ibexa_dataflow' WHERE module_name = 'ezdataflow'
|
||||
```
|
||||
|
||||
BIN
bin/ibexa-dataflow-namespace-changer.phar
Executable file
@@ -3,7 +3,7 @@
|
||||
"replace": {
|
||||
"code-rhapsodie/ezdataflow-bundle": "*"
|
||||
},
|
||||
"description": "Import/export bundle for Ibexa based on Code-Rhapsodie Dataflow",
|
||||
"description": "Import / export bundle for Ibexa Content based on Code Rhapsodie Dataflow framework",
|
||||
"type": "symfony-bundle",
|
||||
"keywords": ["dataflow", "import", "export", "data processing", "ibexa"],
|
||||
"license": "MIT",
|
||||
@@ -29,31 +29,33 @@
|
||||
},
|
||||
{
|
||||
"name": "Other contributors",
|
||||
"homepage": "https://github.com/code-rhapsodie/ezdataflow-bundle/graphs/contributors"
|
||||
"homepage": "https://github.com/code-rhapsodie/ibexa-dataflow-bundle/graphs/contributors"
|
||||
}
|
||||
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"CodeRhapsodie\\EzDataflowBundle\\": "src/"
|
||||
"CodeRhapsodie\\IbexaDataflowBundle\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"CodeRhapsodie\\EzDataflowBundle\\Tests\\": "tests/"
|
||||
"CodeRhapsodie\\IbexaDataflowBundle\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4||^8.0",
|
||||
"php": "^8.3",
|
||||
"ext-json": "*",
|
||||
"code-rhapsodie/dataflow-bundle": "^3.0||^4.0",
|
||||
"code-rhapsodie/dataflow-bundle": "^5.0",
|
||||
"guzzlehttp/promises": "^2.2",
|
||||
"http-interop/http-factory-guzzle": "^1.2",
|
||||
"ibexa/admin-ui": "^4.0",
|
||||
"ibexa/core": "^4.0"
|
||||
"ibexa/admin-ui": "^5.0",
|
||||
"ibexa/core": "^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/dbal": "^2.0|^3.0",
|
||||
"phpunit/phpunit": "^7||^8||^9"
|
||||
"doctrine/dbal": "^3.0",
|
||||
"phpunit/phpunit": "^12.0",
|
||||
"rector/rector": "^2.0"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
@@ -63,9 +65,12 @@
|
||||
"php-http/discovery": true
|
||||
}
|
||||
},
|
||||
"bin": ["bin/ibexa-dataflow-namespace-changer.phar"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-v4.x": "4.x-dev"
|
||||
"dev-v4.x": "4.x-dev",
|
||||
"dev-v5.x": "5.x-dev",
|
||||
"dev-v6.x": "6.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
</php>
|
||||
<testsuites>
|
||||
<testsuite name="EzDataflow tests suite">
|
||||
<testsuite name="Ibexa Dataflow tests suite">
|
||||
<directory suffix="Test.php">./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
19
rector.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\ValueObject\PhpVersion;
|
||||
|
||||
return RectorConfig::configure()
|
||||
->withPaths([
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
])
|
||||
->withPhpVersion(PhpVersion::PHP_83)
|
||||
// uncomment to reach your current PHP version
|
||||
->withPhpSets(php83: true)
|
||||
->withTypeCoverageLevel(0)
|
||||
->withDeadCodeLevel(0)
|
||||
->withCodeQualityLevel(0)
|
||||
->withAttributesSets(symfony: true, doctrine: true);
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\DependencyInjection\CodeRhapsodieEzDataflowExtension;
|
||||
use CodeRhapsodie\EzDataflowBundle\DependencyInjection\Compiler\FieldComparatorCompilerPass;
|
||||
use CodeRhapsodie\EzDataflowBundle\Security\PolicyProvider;
|
||||
use Ibexa\Bundle\Core\DependencyInjection\IbexaCoreExtension;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class CodeRhapsodieEzDataflowBundle extends Bundle
|
||||
{
|
||||
protected $name = 'CodeRhapsodieEzDataflowBundle';
|
||||
|
||||
public function getContainerExtension()
|
||||
{
|
||||
return new CodeRhapsodieEzDataflowExtension();
|
||||
}
|
||||
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
parent::build($container);
|
||||
|
||||
$container->addCompilerPass(new FieldComparatorCompilerPass());
|
||||
|
||||
/** @var IbexaCoreExtension $ibexaExtension */
|
||||
$ibexaExtension = $container->getExtension('ibexa');
|
||||
$ibexaExtension->addPolicyProvider(new PolicyProvider());
|
||||
}
|
||||
}
|
||||
38
src/CodeRhapsodieIbexaDataflowBundle.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle;
|
||||
|
||||
use CodeRhapsodie\IbexaDataflowBundle\DependencyInjection\CodeRhapsodieIbexaDataflowExtension;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\DependencyInjection\Compiler\FieldComparatorCompilerPass;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Security\PolicyProvider;
|
||||
use Ibexa\Bundle\Core\DependencyInjection\IbexaCoreExtension;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class CodeRhapsodieIbexaDataflowBundle extends Bundle
|
||||
{
|
||||
public const string VERSION = '6.0.0';
|
||||
public const string PRODUCT_NAME = 'ibexadataflow';
|
||||
|
||||
protected string $name = 'CodeRhapsodieIbexaDataflowBundle';
|
||||
|
||||
#[\Override]
|
||||
public function getContainerExtension(): ?ExtensionInterface
|
||||
{
|
||||
return new CodeRhapsodieIbexaDataflowExtension();
|
||||
}
|
||||
|
||||
public function build(ContainerBuilder $container): void
|
||||
{
|
||||
parent::build($container);
|
||||
|
||||
$container->addCompilerPass(new FieldComparatorCompilerPass());
|
||||
|
||||
/** @var IbexaCoreExtension $ibexaExtension */
|
||||
$ibexaExtension = $container->getExtension('ibexa');
|
||||
$ibexaExtension->addPolicyProvider(new PolicyProvider());
|
||||
}
|
||||
}
|
||||
@@ -2,158 +2,168 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Controller;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Controller;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\Job;
|
||||
use CodeRhapsodie\DataflowBundle\Entity\ScheduledDataflow;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateOneshotType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateScheduledType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\ExceptionJSONDecoderAdapter;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
use CodeRhapsodie\DataflowBundle\ExceptionsHandler\ExceptionHandlerInterface;
|
||||
use CodeRhapsodie\DataflowBundle\ExceptionsHandler\NullExceptionHandler;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\CodeRhapsodieIbexaDataflowBundle;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Form\CreateOneshotType;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Form\CreateScheduledType;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Form\UpdateScheduledType;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\ExceptionJSONDecoderAdapter;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\JobGateway;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\TransformingAdapter;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use Ibexa\Contracts\AdminUi\Controller\Controller;
|
||||
use Ibexa\Contracts\Core\Ibexa;
|
||||
use Ibexa\Core\MVC\Symfony\Security\Authorization\Attribute;
|
||||
use Pagerfanta\Doctrine\DBAL\QueryAdapter;
|
||||
use Pagerfanta\Pagerfanta;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
/**
|
||||
* @Route("/ezdataflow")
|
||||
*/
|
||||
#[Route(path: '/ibexa_dataflow')]
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway */
|
||||
private $jobGateway;
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway */
|
||||
private $scheduledDataflowGateway;
|
||||
|
||||
public function __construct(JobGateway $jobGateway, ScheduledDataflowGateway $scheduledDataflowGateway)
|
||||
public function __construct(
|
||||
private readonly JobGateway $jobGateway,
|
||||
private readonly ScheduledDataflowGateway $scheduledDataflowGateway,
|
||||
private readonly ExceptionHandlerInterface $exceptionHandler
|
||||
)
|
||||
{
|
||||
$this->jobGateway = $jobGateway;
|
||||
$this->scheduledDataflowGateway = $scheduledDataflowGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/", name="coderhapsodie.ezdataflow.main")
|
||||
*/
|
||||
#[Route(path: '/', name: 'coderhapsodie.ibexa_dataflow.main')]
|
||||
public function main(): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/main.html.twig');
|
||||
$data = [
|
||||
'product' => CodeRhapsodieIbexaDataflowBundle::PRODUCT_NAME,
|
||||
'version' => CodeRhapsodieIbexaDataflowBundle::VERSION,
|
||||
'php' => PHP_VERSION,
|
||||
'ibexa' => Ibexa::VERSION,
|
||||
];
|
||||
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/main.html.twig', [
|
||||
'link' => 'https://www.code-rhapsodie.fr/product/redirect/'.str_replace('=', '',
|
||||
base64_encode(json_encode($data))
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function repeating(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
$newWorkflow = new ScheduledDataflow();
|
||||
$newWorkflow->setNext((new \DateTimeImmutable())->add(new \DateInterval('PT1H')));
|
||||
$form = $this->createForm(CreateScheduledType::class, $newWorkflow, [
|
||||
'action' => $this->generateUrl('coderhapsodie.ezdataflow.workflow.create'),
|
||||
'action' => $this->generateUrl('coderhapsodie.ibexa_dataflow.workflow.create'),
|
||||
]);
|
||||
$updateForm = $this->createForm(UpdateScheduledType::class);
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/repeating.html.twig', [
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/repeating.html.twig', [
|
||||
'pager' => $this->getPager($this->scheduledDataflowGateway->getListQueryForAdmin(), $request),
|
||||
'form' => $form->createView(),
|
||||
'update_form' => $updateForm->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/repeating", name="coderhapsodie.ezdataflow.repeating")
|
||||
*/
|
||||
#[Route(path: '/repeating', name: 'coderhapsodie.ibexa_dataflow.repeating')]
|
||||
public function getRepeatingPage(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/repeating.html.twig', [
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/repeating.html.twig', [
|
||||
'pager' => $this->getPager($this->scheduledDataflowGateway->getListQueryForAdmin(), $request),
|
||||
]);
|
||||
}
|
||||
|
||||
public function oneshot(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
$newOneshotJob = new Job();
|
||||
$newOneshotJob->setRequestedDate((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$form = $this->createForm(CreateOneshotType::class, $newOneshotJob, [
|
||||
'action' => $this->generateUrl('coderhapsodie.ezdataflow.job.create'),
|
||||
'action' => $this->generateUrl('coderhapsodie.ibexa_dataflow.job.create'),
|
||||
]);
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/oneshot.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getOneshotListQueryForAdmin(), $request),
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/oneshot.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getOneshotListQueryForAdmin(), $request, Job::class),
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/oneshot", name="coderhapsodie.ezdataflow.oneshot")
|
||||
*/
|
||||
#[Route(path: '/oneshot', name: 'coderhapsodie.ibexa_dataflow.oneshot')]
|
||||
public function getOneshotPage(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/oneshot.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getOneshotListQueryForAdmin(), $request),
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/oneshot.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getOneshotListQueryForAdmin(), $request, Job::class),
|
||||
]);
|
||||
}
|
||||
|
||||
public function history(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$filter = (int) $request->query->get('filter', JobGateway::FILTER_NONE);
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/history.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getListQueryForAdmin($filter), $request),
|
||||
'filter' => $filter,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/history", name="coderhapsodie.ezdataflow.history")
|
||||
*/
|
||||
#[Route(path: '/history', name: 'coderhapsodie.ibexa_dataflow.history')]
|
||||
public function getHistoryPage(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
$filter = (int) $request->query->get('filter', JobGateway::FILTER_NONE);
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/history.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getListQueryForAdmin($filter), $request),
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/history.html.twig', [
|
||||
'pager' => $this->getPager($this->jobGateway->getListQueryForAdmin($filter), $request, Job::class),
|
||||
'filter' => $filter,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/history/schedule/{id}", name="coderhapsodie.ezdataflow.history.workflow")
|
||||
*/
|
||||
#[Route(path: '/history/schedule/{id}', name: 'coderhapsodie.ibexa_dataflow.history.workflow')]
|
||||
public function getHistoryForScheduled(Request $request, int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Dashboard/schedule_history.html.twig', [
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/schedule_history.html.twig', [
|
||||
'id' => $id,
|
||||
'pager' => $this->getPager($this->jobGateway->getListQueryForScheduleAdmin($id), $request),
|
||||
'pager' => $this->getPager($this->jobGateway->getListQueryForScheduleAdmin($id), $request, Job::class),
|
||||
]);
|
||||
}
|
||||
|
||||
private function getPager(QueryBuilder $query, Request $request): Pagerfanta
|
||||
private function getPager(QueryBuilder $query, Request $request, string $class = null): Pagerfanta
|
||||
{
|
||||
$pager = new Pagerfanta(
|
||||
new ExceptionJSONDecoderAdapter(
|
||||
new QueryAdapter($query, function ($queryBuilder) {
|
||||
return $queryBuilder->select('COUNT(DISTINCT id) AS total_results')
|
||||
->resetQueryPart('orderBy')
|
||||
->setMaxResults(1);
|
||||
})
|
||||
)
|
||||
$adatapter = new ExceptionJSONDecoderAdapter(
|
||||
new QueryAdapter($query, fn($queryBuilder) => $queryBuilder->select('COUNT(DISTINCT id) AS total_results')
|
||||
->resetQueryPart('orderBy')
|
||||
->setMaxResults(1))
|
||||
);
|
||||
|
||||
if ($class === Job::class && !$this->exceptionHandler instanceof NullExceptionHandler) {
|
||||
$adatapter = new TransformingAdapter($adatapter, function (array $value) {
|
||||
$exceptions = $this->exceptionHandler->find((int)$value['id']);
|
||||
$value['exceptions'] = $exceptions;
|
||||
$value['total_results'] = \count($exceptions);
|
||||
|
||||
return $value;
|
||||
});
|
||||
}
|
||||
|
||||
$pager = new Pagerfanta($adatapter);
|
||||
$pager->setMaxPerPage(20);
|
||||
$pager->setCurrentPage($request->query->get('page', 1));
|
||||
$pager->setCurrentPage($request->query->getInt('page', 1));
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
public function dashboard(): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Dashboard/dashboard.html.twig', [
|
||||
'jobs' => $this->jobGateway->getListPendindOrRunning(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,77 +2,56 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Controller;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Controller;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\Job;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateOneshotType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Form\CreateOneshotType;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\JobGateway;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
use Ibexa\Contracts\AdminUi\Controller\Controller;
|
||||
use Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface;
|
||||
use Ibexa\Core\MVC\Symfony\Security\Authorization\Attribute;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* @Route("/ezdataflow/job")
|
||||
*/
|
||||
#[Route(path: '/ibexa_dataflow/job')]
|
||||
class JobController extends Controller
|
||||
{
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway */
|
||||
private $jobGateway;
|
||||
/** @var \Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface */
|
||||
private $notificationHandler;
|
||||
/** @var \Symfony\Contracts\Translation\TranslatorInterface */
|
||||
private $translator;
|
||||
|
||||
public function __construct(
|
||||
JobGateway $jobGateway,
|
||||
NotificationHandlerInterface $notificationHandler,
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
$this->jobGateway = $jobGateway;
|
||||
$this->notificationHandler = $notificationHandler;
|
||||
$this->translator = $translator;
|
||||
public function __construct(private readonly JobGateway $jobGateway, private readonly NotificationHandlerInterface $notificationHandler, private readonly TranslatorInterface $translator, private readonly ScheduledDataflowGateway $scheduledDataflowGateway)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/details/{id}", name="coderhapsodie.ezdataflow.job.details")
|
||||
*/
|
||||
#[Route(path: '/details/{id}', name: 'coderhapsodie.ibexa_dataflow.job.details')]
|
||||
public function displayDetails(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Item/details.html.twig', [
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Item/details.html.twig', [
|
||||
'item' => $this->jobGateway->find($id),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/details/log/{id}", name="coderhapsodie.ezdataflow.job.log")
|
||||
*/
|
||||
#[Route(path: '/details/log/{id}', name: 'coderhapsodie.ibexa_dataflow.job.log')]
|
||||
public function displayLog(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
$item = $this->jobGateway->find($id);
|
||||
$log = array_map(function ($line) {
|
||||
return preg_replace('~#\d+~', "\n$0", $line);
|
||||
}, $item->getExceptions());
|
||||
$log = array_map(fn($line) => preg_replace('~#\d+~', "\n$0", (string) $line), $item->getExceptions());
|
||||
|
||||
return $this->render('@ibexadesign/ezdataflow/Item/log.html.twig', [
|
||||
return $this->render('@ibexadesign/ibexa_dataflow/Item/log.html.twig', [
|
||||
'log' => $log,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/create", name="coderhapsodie.ezdataflow.job.create", methods={"POST"})
|
||||
*/
|
||||
#[Route(path: '/create', name: 'coderhapsodie.ibexa_dataflow.job.create', methods: ['POST'])]
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'edit'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'edit'));
|
||||
|
||||
$newOneshot = new Job();
|
||||
$form = $this->createForm(CreateOneshotType::class, $newOneshot);
|
||||
@@ -84,24 +63,55 @@ class JobController extends Controller
|
||||
|
||||
try {
|
||||
$this->jobGateway->save($newOneshot);
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ezdataflow.job.create.success'));
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ibexa_dataflow.job.create.success'));
|
||||
} catch (\Exception $e) {
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ezdataflow.job.create.error',
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ibexa_dataflow.job.create.error',
|
||||
['message' => $e->getMessage()]));
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'redirect' => $this->generateUrl('coderhapsodie.ezdataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ezdataflow-code-rhapsodie-ezdataflow-oneshot'],
|
||||
'redirect' => $this->generateUrl('coderhapsodie.ibexa_dataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ibexa_dataflow-code-rhapsodie-ibexa_dataflow-oneshot'],
|
||||
UrlGeneratorInterface::ABSOLUTE_URL),
|
||||
]);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'form' => $this->renderView('@ibexadesign/ezdataflow/parts/form_modal.html.twig', [
|
||||
'form' => $this->renderView('@ibexadesign/ibexa_dataflow/parts/form_modal.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'type_action' => 'new',
|
||||
'mode' => 'oneshot',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route(path: '/run-oneshot/{id}', name: 'coderhapsodie.ibexa_dataflow.job.run-oneshot', methods: ['GET'])]
|
||||
public function runOneShot(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'view'));
|
||||
|
||||
$scheduledDataflow = $this->scheduledDataflowGateway->find($id);
|
||||
|
||||
if ($scheduledDataflow === null) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$newOneshotJob = new Job();
|
||||
$newOneshotJob->setOptions($scheduledDataflow->getOptions());
|
||||
$newOneshotJob->setLabel("Manual " . $scheduledDataflow->getLabel());
|
||||
$newOneshotJob->setScheduledDataflowId($scheduledDataflow->getId());
|
||||
$newOneshotJob->setRequestedDate((new \DateTime())->add(new \DateInterval('PT1H')));
|
||||
$newOneshotJob->setDataflowType($scheduledDataflow->getDataflowType());
|
||||
|
||||
$form = $this->createForm(CreateOneshotType::class, $newOneshotJob, [
|
||||
'action' => $this->generateUrl('coderhapsodie.ibexa_dataflow.job.create'),
|
||||
]);
|
||||
|
||||
return new JsonResponse([
|
||||
'form' => $this->renderView('@ibexadesign/ibexa_dataflow/parts/form_modal.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'id' => 'modal-new-oneshot',
|
||||
'mode' => 'oneshot',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,49 +2,32 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Controller;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Controller;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\ScheduledDataflow;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\CreateScheduledType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Form\UpdateScheduledType;
|
||||
use CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Form\CreateScheduledType;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Form\UpdateScheduledType;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway;
|
||||
use Ibexa\Contracts\AdminUi\Controller\Controller;
|
||||
use Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface;
|
||||
use Ibexa\Core\MVC\Symfony\Security\Authorization\Attribute;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* @Route("/ezdataflow/scheduled_workflow")
|
||||
*/
|
||||
#[Route(path: '/ibexa_dataflow/scheduled_workflow')]
|
||||
class ScheduledDataflowController extends Controller
|
||||
{
|
||||
/** @var \Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface */
|
||||
private $notificationHandler;
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway */
|
||||
private $scheduledDataflowGateway;
|
||||
/** @var \Symfony\Contracts\Translation\TranslatorInterface */
|
||||
private $translator;
|
||||
|
||||
public function __construct(
|
||||
NotificationHandlerInterface $notificationHandler,
|
||||
ScheduledDataflowGateway $scheduledDataflowGateway,
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
$this->notificationHandler = $notificationHandler;
|
||||
$this->scheduledDataflowGateway = $scheduledDataflowGateway;
|
||||
$this->translator = $translator;
|
||||
public function __construct(private readonly NotificationHandlerInterface $notificationHandler, private readonly ScheduledDataflowGateway $scheduledDataflowGateway, private readonly TranslatorInterface $translator)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/create", name="coderhapsodie.ezdataflow.workflow.create", methods={"POST"})
|
||||
*/
|
||||
#[Route(path: '/create', name: 'coderhapsodie.ibexa_dataflow.workflow.create', methods: ['POST'])]
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'edit'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'edit'));
|
||||
|
||||
$newWorkflow = new ScheduledDataflow();
|
||||
$form = $this->createForm(CreateScheduledType::class, $newWorkflow);
|
||||
@@ -55,48 +38,44 @@ class ScheduledDataflowController extends Controller
|
||||
$newWorkflow = $form->getData();
|
||||
try {
|
||||
$this->scheduledDataflowGateway->save($newWorkflow);
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ezdataflow.workflow.create.success'));
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ibexa_dataflow.workflow.create.success'));
|
||||
} catch (\Exception $e) {
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ezdataflow.workflow.create.error',
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ibexa_dataflow.workflow.create.error',
|
||||
['message' => $e->getMessage()]));
|
||||
}
|
||||
|
||||
return new JsonResponse(['redirect' => $this->generateUrl('coderhapsodie.ezdataflow.main')]);
|
||||
return new JsonResponse(['redirect' => $this->generateUrl('coderhapsodie.ibexa_dataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ibexa_dataflow-code-rhapsodie-ibexa_dataflow-repeating'])]);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'form' => $this->renderView('@ibexadesign/ezdataflow/parts/form_modal.html.twig', [
|
||||
'form' => $this->renderView('@ibexadesign/ibexa_dataflow/parts/form_modal.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'type_action' => 'new',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/delete", name="coderhapsodie.ezdataflow.workflow.delete", methods={"post"})
|
||||
*/
|
||||
#[Route(path: '/{id}/delete', name: 'coderhapsodie.ibexa_dataflow.workflow.delete', methods: ['post'])]
|
||||
public function delete(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'edit'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'edit'));
|
||||
|
||||
try {
|
||||
$this->scheduledDataflowGateway->delete($id);
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ezdataflow.workflow.delete.success'));
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ibexa_dataflow.workflow.delete.success'));
|
||||
} catch (\Exception $e) {
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ezdataflow.workflow.delete.error',
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ibexa_dataflow.workflow.delete.error',
|
||||
['message' => $e->getMessage()]));
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('coderhapsodie.ezdataflow.main');
|
||||
return $this->redirectToRoute('coderhapsodie.ibexa_dataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ibexa_dataflow-code-rhapsodie-ibexa_dataflow-repeating']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/edit", name="coderhapsodie.ezdataflow.workflow.edit")
|
||||
*/
|
||||
#[Route(path: '/{id}/edit', name: 'coderhapsodie.ibexa_dataflow.workflow.edit')]
|
||||
public function edit(Request $request, int $id): Response
|
||||
{
|
||||
$form = $this->createForm(UpdateScheduledType::class, $this->scheduledDataflowGateway->find($id), [
|
||||
'action' => $this->generateUrl('coderhapsodie.ezdataflow.workflow.edit', ['id' => $id]),
|
||||
'action' => $this->generateUrl('coderhapsodie.ibexa_dataflow.workflow.edit', ['id' => $id]),
|
||||
]);
|
||||
$form->handleRequest($request);
|
||||
|
||||
@@ -106,33 +85,31 @@ class ScheduledDataflowController extends Controller
|
||||
|
||||
try {
|
||||
$this->scheduledDataflowGateway->save($editDataflow);
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ezdataflow.workflow.edit.success'));
|
||||
$this->notificationHandler->success($this->translator->trans('coderhapsodie.ibexa_dataflow.workflow.edit.success'));
|
||||
} catch (\Exception $e) {
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ezdataflow.workflow.edit.error',
|
||||
$this->notificationHandler->error($this->translator->trans('coderhapsodie.ibexa_dataflow.workflow.edit.error',
|
||||
['message' => $e->getMessage()]));
|
||||
}
|
||||
|
||||
return new JsonResponse(['redirect' => $this->generateUrl('coderhapsodie.ezdataflow.main')]);
|
||||
return new JsonResponse(['redirect' => $this->generateUrl('coderhapsodie.ibexa_dataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ibexa_dataflow-code-rhapsodie-ibexa_dataflow-repeating'])]);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'form' => $this->renderView('@ibexadesign/ezdataflow/parts/form_modal.html.twig', [
|
||||
'form' => $this->renderView('@ibexadesign/ibexa_dataflow/parts/form_modal.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'type_action' => 'edit',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/enable", name="coderhapsodie.ezdataflow.workflow.enable")
|
||||
*/
|
||||
#[Route(path: '/{id}/enable', name: 'coderhapsodie.ibexa_dataflow.workflow.enable')]
|
||||
public function enableDataflow(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'edit'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'edit'));
|
||||
|
||||
$this->changeDataflowStatus($id, true);
|
||||
|
||||
return $this->redirectToRoute('coderhapsodie.ezdataflow.main');
|
||||
return $this->redirectToRoute('coderhapsodie.ibexa_dataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ibexa_dataflow-code-rhapsodie-ibexa_dataflow-repeating']);
|
||||
}
|
||||
|
||||
private function changeDataflowStatus(int $id, bool $status)
|
||||
@@ -149,15 +126,13 @@ class ScheduledDataflowController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/{id}/disable", name="coderhapsodie.ezdataflow.workflow.disable")
|
||||
*/
|
||||
#[Route(path: '/{id}/disable', name: 'coderhapsodie.ibexa_dataflow.workflow.disable')]
|
||||
public function disableDataflow(int $id): Response
|
||||
{
|
||||
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'edit'));
|
||||
$this->denyAccessUnlessGranted(new Attribute('ibexa_dataflow', 'edit'));
|
||||
|
||||
$this->changeDataflowStatus($id, false);
|
||||
|
||||
return $this->redirectToRoute('coderhapsodie.ezdataflow.main');
|
||||
return $this->redirectToRoute('coderhapsodie.ibexa_dataflow.main', ['_fragment' => 'ibexa-tab-coderhapsodie-ibexa_dataflow-code-rhapsodie-ibexa_dataflow-repeating']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,36 +2,21 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Content;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Content;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface;
|
||||
use CodeRhapsodie\EzDataflowBundle\Matcher\LocationMatcherInterface;
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentCreateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFillerInterface;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Matcher\LocationMatcherInterface;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentCreateStructure;
|
||||
use Ibexa\Contracts\Core\Repository\ContentService;
|
||||
use Ibexa\Contracts\Core\Repository\ContentTypeService;
|
||||
use Ibexa\Contracts\Core\Repository\Repository;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\LocationCreateStruct;
|
||||
|
||||
class ContentCreator implements ContentCreatorInterface
|
||||
readonly class ContentCreator implements ContentCreatorInterface
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\ContentService */
|
||||
private $contentService;
|
||||
|
||||
/** @var \Ibexa\Contracts\Core\Repository\ContentTypeService */
|
||||
private $contentTypeService;
|
||||
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface */
|
||||
private $filler;
|
||||
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Matcher\LocationMatcherInterface */
|
||||
private $matcher;
|
||||
|
||||
public function __construct(ContentService $contentService, ContentTypeService $contentTypeService, ContentStructFieldFillerInterface $filler, LocationMatcherInterface $matcher)
|
||||
public function __construct(private ContentService $contentService, private ContentTypeService $contentTypeService, private ContentStructFieldFillerInterface $filler, private LocationMatcherInterface $matcher, private Repository $repository)
|
||||
{
|
||||
$this->contentService = $contentService;
|
||||
$this->contentTypeService = $contentTypeService;
|
||||
$this->filler = $filler;
|
||||
$this->matcher = $matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,9 +33,20 @@ class ContentCreator implements ContentCreatorInterface
|
||||
$contentCreateStruct = $this->contentService->newContentCreateStruct($contentType, $structure->getLanguageCode());
|
||||
$contentCreateStruct->remoteId = $structure->getRemoteId();
|
||||
$this->filler->fillFields($contentType, $contentCreateStruct, $structure->getFields());
|
||||
$content = $this->contentService->createContent($contentCreateStruct, $this->getLocationCreateStructs($structure->getLocations()));
|
||||
|
||||
return $this->contentService->publishVersion($content->versionInfo);
|
||||
$this->repository->beginTransaction();
|
||||
try {
|
||||
$content = $this->contentService->createContent($contentCreateStruct, $this->getLocationCreateStructs($structure->getLocations()));
|
||||
|
||||
$content = $this->contentService->publishVersion($content->versionInfo);
|
||||
$this->repository->commit();
|
||||
|
||||
return $content;
|
||||
} catch (\Exception $exception) {
|
||||
$this->repository->rollback();
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Content;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Content;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentCreateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentCreateStructure;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
|
||||
|
||||
interface ContentCreatorInterface
|
||||
|
||||
@@ -2,35 +2,24 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Content;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Content;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface;
|
||||
use CodeRhapsodie\EzDataflowBundle\Exception\NoMatchFoundException;
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentUpdateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFillerInterface;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Exception\NoMatchFoundException;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentUpdateStructure;
|
||||
use Ibexa\Contracts\Core\Repository\ContentService;
|
||||
use Ibexa\Contracts\Core\Repository\ContentTypeService;
|
||||
use Ibexa\Contracts\Core\Repository\Repository;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
|
||||
|
||||
class ContentUpdater implements ContentUpdaterInterface
|
||||
readonly class ContentUpdater implements ContentUpdaterInterface
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\ContentService */
|
||||
private $contentService;
|
||||
|
||||
/** @var \Ibexa\Contracts\Core\Repository\ContentTypeService */
|
||||
private $contentTypeService;
|
||||
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface */
|
||||
private $filler;
|
||||
|
||||
public function __construct(ContentService $contentService, ContentTypeService $contentTypeService, ContentStructFieldFillerInterface $filler)
|
||||
public function __construct(private ContentService $contentService, private ContentTypeService $contentTypeService, private ContentStructFieldFillerInterface $filler, private Repository $repository)
|
||||
{
|
||||
$this->contentService = $contentService;
|
||||
$this->contentTypeService = $contentTypeService;
|
||||
$this->filler = $filler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\NoMatchFoundException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\NoMatchFoundException
|
||||
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException
|
||||
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentFieldValidationException
|
||||
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
|
||||
@@ -56,9 +45,18 @@ class ContentUpdater implements ContentUpdaterInterface
|
||||
$structure->getFields()
|
||||
);
|
||||
|
||||
$draft = $this->contentService->createContentDraft($content->contentInfo);
|
||||
$this->contentService->updateContent($draft->versionInfo, $contentUpdateStruct);
|
||||
$this->repository->beginTransaction();
|
||||
try {
|
||||
$draft = $this->contentService->createContentDraft($content->contentInfo);
|
||||
$this->contentService->updateContent($draft->versionInfo, $contentUpdateStruct);
|
||||
$content = $this->contentService->publishVersion($draft->versionInfo);
|
||||
|
||||
return $this->contentService->publishVersion($draft->versionInfo);
|
||||
$this->repository->commit();
|
||||
|
||||
return $content;
|
||||
} catch (\Exception $e) {
|
||||
$this->repository->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Content;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Content;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentUpdateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentUpdateStructure;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
|
||||
|
||||
interface ContentUpdaterInterface
|
||||
|
||||
@@ -2,32 +2,31 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Field;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Field;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Exception\UnknownFieldException;
|
||||
use CodeRhapsodie\EzDataflowBundle\Exception\UnsupportedFieldTypeException;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Exception\UnknownFieldException;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Exception\UnsupportedFieldTypeException;
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct;
|
||||
use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;
|
||||
|
||||
class ContentStructFieldFiller implements ContentStructFieldFillerInterface
|
||||
{
|
||||
/** @var FieldValueCreatorInterface[] */
|
||||
private $fieldValueCreators;
|
||||
|
||||
/**
|
||||
* ContentStructFieldFiller constructor.
|
||||
*/
|
||||
public function __construct(iterable $fieldValueCreators)
|
||||
public function __construct(
|
||||
/** @var FieldValueCreatorInterface[] */
|
||||
private readonly iterable $fieldValueCreators
|
||||
)
|
||||
{
|
||||
$this->fieldValueCreators = $fieldValueCreators;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\UnknownFieldException
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\UnsupportedFieldTypeException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\UnknownFieldException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\UnsupportedFieldTypeException
|
||||
*/
|
||||
public function fillFields(ContentType $contentType, ContentStruct $contentStruct, array $fieldHashes): void
|
||||
{
|
||||
@@ -47,7 +46,7 @@ class ContentStructFieldFiller implements ContentStructFieldFillerInterface
|
||||
/**
|
||||
* @param mixed $hash
|
||||
*
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\UnsupportedFieldTypeException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\UnsupportedFieldTypeException
|
||||
*/
|
||||
private function createFieldValue(string $fieldTypeIdentifier, $hash): Value
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Field;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Field;
|
||||
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\ContentStruct;
|
||||
use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType;
|
||||
|
||||
@@ -2,19 +2,15 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Field;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Field;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
use Ibexa\Contracts\Core\Repository\FieldTypeService;
|
||||
|
||||
class DefaultFieldValueCreator implements FieldValueCreatorInterface
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\FieldTypeService */
|
||||
private $fieldTypeService;
|
||||
|
||||
public function __construct(FieldTypeService $fieldTypeService)
|
||||
public function __construct(private readonly FieldTypeService $fieldTypeService)
|
||||
{
|
||||
$this->fieldTypeService = $fieldTypeService;
|
||||
}
|
||||
|
||||
public function supports(string $fieldTypeIdentifier): bool
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\Field;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\Field;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
use Ibexa\Contracts\Core\Repository\FieldTypeService;
|
||||
@@ -10,12 +10,8 @@ use Ibexa\Contracts\Core\Repository\Values\Content\Field;
|
||||
|
||||
abstract class AbstractFieldComparator implements FieldComparatorInterface
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\FieldTypeService */
|
||||
private $fieldTypeService;
|
||||
|
||||
public function __construct(FieldTypeService $fieldTypeService)
|
||||
public function __construct(private readonly FieldTypeService $fieldTypeService)
|
||||
{
|
||||
$this->fieldTypeService = $fieldTypeService;
|
||||
}
|
||||
|
||||
public function compare(Field $field, $hash): bool
|
||||
|
||||
18
src/Core/FieldComparator/BillingAddressComparator.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
class BillingAddressComparator extends AbstractFieldComparator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Ibexa\FieldTypeAddress\FieldType\Value $currentValue
|
||||
* @param \Ibexa\FieldTypeAddress\FieldType\Value $newValue
|
||||
*/
|
||||
protected function compareValues(Value $currentValue, Value $newValue): bool
|
||||
{
|
||||
return empty(array_diff_assoc($currentValue->fields, $newValue->fields)) && $currentValue->name === $newValue->name && $currentValue->country === $newValue->country;
|
||||
}
|
||||
}
|
||||
18
src/Core/FieldComparator/CustomerGroupComparator.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
class CustomerGroupComparator extends AbstractFieldComparator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Ibexa\ProductCatalog\FieldType\CustomerGroup\Value $currentValue
|
||||
* @param \Ibexa\ProductCatalog\FieldType\CustomerGroup\Value $newValue
|
||||
*/
|
||||
protected function compareValues(Value $currentValue, Value $newValue): bool
|
||||
{
|
||||
return $currentValue->getCustomerGroup()->getIdentifier() === $newValue->getCustomerGroup()->getIdentifier();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator;
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
use Ibexa\Contracts\Taxonomy\Value\TaxonomyEntry;
|
||||
|
||||
class TaxonomyEntryAssignmentComparator extends AbstractFieldComparator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Ibexa\Taxonomy\FieldType\TaxonomyEntryAssignment\Value $currentValue
|
||||
* @param \Ibexa\Taxonomy\FieldType\TaxonomyEntryAssignment\Value $newValue
|
||||
*/
|
||||
protected function compareValues(Value $currentValue, Value $newValue): bool
|
||||
{
|
||||
return $currentValue->getTaxonomy() === $newValue->getTaxonomy() && $this->compareEntries($currentValue->getTaxonomyEntries(), $newValue->getTaxonomyEntries());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<TaxonomyEntry> $currentEntries
|
||||
* @param array<TaxonomyEntry> $newEntries
|
||||
*/
|
||||
private function compareEntries(array $currentEntries, array $newEntries): bool
|
||||
{
|
||||
$currentEntriesId = array_map(function (TaxonomyEntry $currentEntry) {
|
||||
return $currentEntry->id;
|
||||
}, $currentEntries);
|
||||
|
||||
$newEntriesId = array_map(function (TaxonomyEntry $newEntry) {
|
||||
return $newEntry->id;
|
||||
}, $newEntries);
|
||||
|
||||
if (\count($currentEntriesId) !== \count($newEntriesId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sort($currentEntriesId);
|
||||
sort($newEntriesId);
|
||||
|
||||
return $currentEntriesId === $newEntriesId;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Core\FieldComparator;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator;
|
||||
|
||||
use Ibexa\Contracts\Core\FieldType\Value;
|
||||
|
||||
|
||||
@@ -2,29 +2,29 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\DependencyInjection;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\DependencyInjection;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Core\Field\FieldValueCreatorInterface;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\Field\FieldValueCreatorInterface;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||
|
||||
class CodeRhapsodieEzDataflowExtension extends Extension
|
||||
class CodeRhapsodieIbexaDataflowExtension extends Extension
|
||||
{
|
||||
public function load(array $configs, ContainerBuilder $container)
|
||||
public function load(array $configs, ContainerBuilder $container): void
|
||||
{
|
||||
$configuration = new Configuration();
|
||||
$config = $this->processConfiguration($configuration, $configs);
|
||||
|
||||
$container->setParameter('coderhapsodie.ezdataflow.admin_login_or_id', $config['admin_login_or_id']);
|
||||
$container->setParameter('coderhapsodie.ibexa_dataflow.admin_login_or_id', $config['admin_login_or_id']);
|
||||
|
||||
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
|
||||
$loader->load('services.yaml');
|
||||
|
||||
$container
|
||||
->registerForAutoconfiguration(FieldValueCreatorInterface::class)
|
||||
->addTag('coderhapsodie.ezdataflow.field_value_creator')
|
||||
->addTag('coderhapsodie.ibexa_dataflow.field_value_creator')
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\DependencyInjection\Compiler;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\DependencyInjection\Compiler;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\DelegatorFieldComparator;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\DelegatorFieldComparator;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
class FieldComparatorCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
if (!$container->has(DelegatorFieldComparator::class)) {
|
||||
return;
|
||||
@@ -19,10 +19,10 @@ class FieldComparatorCompilerPass implements CompilerPassInterface
|
||||
|
||||
$delegatorDef = $container->findDefinition(DelegatorFieldComparator::class);
|
||||
|
||||
foreach ($container->findTaggedServiceIds('coderhapsodie.ezdataflow.field_comparator') as $id => $tags) {
|
||||
foreach ($container->findTaggedServiceIds('coderhapsodie.ibexa_dataflow.field_comparator') as $id => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
if (!isset($attributes['fieldType'])) {
|
||||
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "fieldType" attribute on "coderhapsodie.ezdataflow.field_comparator" tags.', $id));
|
||||
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "fieldType" attribute on "coderhapsodie.ibexa_dataflow.field_comparator" tags.', $id));
|
||||
}
|
||||
|
||||
$delegatorDef->addMethodCall(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\DependencyInjection;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
@@ -12,9 +12,9 @@ class Configuration implements ConfigurationInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfigTreeBuilder()
|
||||
public function getConfigTreeBuilder(): TreeBuilder
|
||||
{
|
||||
$treeBuilder = new TreeBuilder('code_rhapsodie_ez_dataflow');
|
||||
$treeBuilder = new TreeBuilder('code_rhapsodie_ibexa_dataflow');
|
||||
|
||||
$rootNode = $treeBuilder->getRootNode();
|
||||
$rootNode
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\EventSubscriber;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\EventSubscriber;
|
||||
|
||||
use Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent;
|
||||
use Ibexa\AdminUi\Menu\MainMenuBuilder;
|
||||
@@ -13,12 +13,12 @@ class MenuSubscriber implements EventSubscriberInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [ConfigureMenuEvent::MAIN_MENU => 'onConfigureMenu'];
|
||||
}
|
||||
|
||||
public function onConfigureMenu(ConfigureMenuEvent $event)
|
||||
public function onConfigureMenu(ConfigureMenuEvent $event): void
|
||||
{
|
||||
/** @var \Knp\Menu\ItemInterface $menu */
|
||||
$menu = $event->getMenu();
|
||||
@@ -27,10 +27,10 @@ class MenuSubscriber implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
$menu[MainMenuBuilder::ITEM_ADMIN]->addChild(
|
||||
'ezdataflow_dashboard',
|
||||
'ibexa_dataflow_dashboard',
|
||||
[
|
||||
'label' => 'coderhapsodie.ezdataflow',
|
||||
'route' => 'coderhapsodie.ezdataflow.main',
|
||||
'label' => 'coderhapsodie.ibexa_dataflow',
|
||||
'route' => 'coderhapsodie.ibexa_dataflow.main',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Exception;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Exception;
|
||||
|
||||
class InvalidArgumentTypeException extends \Exception
|
||||
{
|
||||
@@ -26,7 +26,7 @@ class InvalidArgumentTypeException extends \Exception
|
||||
return new self(sprintf(
|
||||
'Expected argument of type %s, %s received instead',
|
||||
$expectedString,
|
||||
is_object($received) ? get_class($received) : gettype($received)
|
||||
get_debug_type($received)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Exception;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Exception;
|
||||
|
||||
class NoMatchFoundException extends \Exception
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Exception;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Exception;
|
||||
|
||||
class UnknownFieldException extends \Exception
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Exception;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Exception;
|
||||
|
||||
class UnsupportedFieldTypeException extends \Exception
|
||||
{
|
||||
|
||||
@@ -2,35 +2,26 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Factory;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Factory;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentCreateStructure;
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentUpdateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentCreateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentUpdateStructure;
|
||||
use Ibexa\Contracts\Core\Repository\ContentService;
|
||||
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
|
||||
|
||||
final class ContentStructureFactory implements ContentStructureFactoryInterface
|
||||
final readonly class ContentStructureFactory implements ContentStructureFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var \Ibexa\Contracts\Core\Repository\ContentService
|
||||
*/
|
||||
private $contentService;
|
||||
|
||||
/**
|
||||
* ContentStructureFactory constructor.
|
||||
*/
|
||||
public function __construct(ContentService $contentService)
|
||||
public function __construct(private ContentService $contentService)
|
||||
{
|
||||
$this->contentService = $contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $parentLocations
|
||||
* @param int $mode One of the constant ContentStructureFactoryInterface::MODE_*
|
||||
*
|
||||
* @return false|\CodeRhapsodie\EzDataflowBundle\Model\ContentStructure
|
||||
* @return false|\CodeRhapsodie\IbexaDataflowBundle\Model\ContentStructure
|
||||
*
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\InvalidArgumentTypeException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\InvalidArgumentTypeException
|
||||
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
|
||||
*/
|
||||
public function transform(array $data, string $remoteId, string $language, string $contentType, $parentLocations, int $mode = ContentStructureFactoryInterface::MODE_INSERT_OR_UPDATE)
|
||||
@@ -42,7 +33,7 @@ final class ContentStructureFactory implements ContentStructureFactoryInterface
|
||||
}
|
||||
|
||||
return ContentUpdateStructure::createForContentId($content->id, $language, $data);
|
||||
} catch (NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
// The content doesn't exist yet, so it will be created.
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Factory;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Factory;
|
||||
|
||||
interface ContentStructureFactoryInterface
|
||||
{
|
||||
@@ -14,7 +14,7 @@ interface ContentStructureFactoryInterface
|
||||
* @param int|string $parentLocations Int for location id or string for remote location id
|
||||
* @param int $mode ContentStructureFactoryInterface
|
||||
*
|
||||
* @return false|\CodeRhapsodie\EzDataflowBundle\Model\ContentStructure
|
||||
* @return false|\CodeRhapsodie\IbexaDataflowBundle\Model\ContentStructure
|
||||
*/
|
||||
public function transform(array $data, string $remoteId, string $language, string $contentType, $parentLocations, int $mode = ContentStructureFactoryInterface::MODE_INSERT_OR_UPDATE);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Filter;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Filter;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\FieldComparatorInterface;
|
||||
use CodeRhapsodie\EzDataflowBundle\Model\ContentUpdateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\FieldComparatorInterface;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentUpdateStructure;
|
||||
use Ibexa\Contracts\Core\Repository\ContentService;
|
||||
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
@@ -17,16 +17,8 @@ class NotModifiedContentFilter
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/** @var \Ibexa\Contracts\Core\Repository\ContentService */
|
||||
private $contentService;
|
||||
|
||||
/** @var \CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\FieldComparatorInterface */
|
||||
private $comparator;
|
||||
|
||||
public function __construct(ContentService $contentService, FieldComparatorInterface $comparator)
|
||||
public function __construct(private ContentService $contentService, private FieldComparatorInterface $comparator)
|
||||
{
|
||||
$this->contentService = $contentService;
|
||||
$this->comparator = $comparator;
|
||||
}
|
||||
|
||||
public function __invoke($data)
|
||||
@@ -40,7 +32,7 @@ class NotModifiedContentFilter
|
||||
} else {
|
||||
try {
|
||||
$content = $this->contentService->loadContentByRemoteId($data->getRemoteId(), [$data->getLanguageCode()]);
|
||||
} catch (NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
// New translation
|
||||
return $data;
|
||||
}
|
||||
@@ -60,7 +52,7 @@ class NotModifiedContentFilter
|
||||
return false;
|
||||
}
|
||||
|
||||
private function log(string $level, string $message, array $context = [])
|
||||
private function log(string $level, string $message, array $context = []): void
|
||||
{
|
||||
if (null === $this->logger) {
|
||||
return;
|
||||
|
||||
46
src/Filter/NotModifiedProductFilter.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Filter;
|
||||
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ContentUpdateStructure;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Model\ProductUpdateStructure;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
readonly class NotModifiedProductFilter
|
||||
{
|
||||
|
||||
public function __construct(private NotModifiedContentFilter $notModifiedContentFilter, private Connection $connection)
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke(mixed $data)
|
||||
{
|
||||
if (!$data instanceof ProductUpdateStructure) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$contentId = $this->connection->executeQuery('SELECT content_id FROM ibexa_product_specification where code = :code', ['code' => $data->getCode()])
|
||||
->fetchFirstColumn();
|
||||
|
||||
if (empty($contentId)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$result = $this->notModifiedContentFilter->__invoke(ContentUpdateStructure::createForContentId($contentId[0], $data->getLanguageCode(), $data->getFields()));
|
||||
|
||||
if ($result === false) {
|
||||
$data->setUpdateContent(false);
|
||||
}
|
||||
|
||||
$stockData = $this->connection->executeQuery('SELECT stock FROM ibexa_product_specification_availability WHERE product_code = :code', ['code' => $data->getCode()])->fetchFirstColumn();
|
||||
|
||||
if (!empty($stockData) && ($data->getStock() === $stockData[0] || ($data->getStock() === 0 && $stockData[0] === null))) {
|
||||
$data->setUpdateStock(false);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\Job;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@@ -12,7 +12,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class CreateOneshotType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('label', TextType::class, [
|
||||
@@ -31,12 +31,11 @@ class CreateOneshotType extends AbstractType
|
||||
])
|
||||
->add('requestedDate', UserTimezoneAwareDateTimeType::class, [
|
||||
'label' => 'coderhapsodie.dataflow.requestedDate',
|
||||
'years' => range(date('Y'), date('Y') + 5),
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Job::class,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\ScheduledDataflow;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@@ -13,7 +13,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class CreateScheduledType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('label', TextType::class, [
|
||||
@@ -38,7 +38,6 @@ class CreateScheduledType extends AbstractType
|
||||
'label' => 'coderhapsodie.dataflow.frequency',
|
||||
])
|
||||
->add('next', UserTimezoneAwareDateTimeType::class, [
|
||||
'years' => range(date('Y'), date('Y') + 5),
|
||||
'label' => 'coderhapsodie.dataflow.create.next',
|
||||
])
|
||||
->add('enabled', CheckboxType::class, [
|
||||
@@ -48,7 +47,7 @@ class CreateScheduledType extends AbstractType
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => ScheduledDataflow::class,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Registry\DataflowTypeRegistryInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@@ -11,20 +11,17 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class DataflowTypeChoiceType extends AbstractType
|
||||
{
|
||||
/** @var \CodeRhapsodie\DataflowBundle\Registry\DataflowTypeRegistryInterface */
|
||||
private $registry;
|
||||
|
||||
public function __construct(DataflowTypeRegistryInterface $registry)
|
||||
public function __construct(private readonly DataflowTypeRegistryInterface $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
#[\Override]
|
||||
public function getParent(): string
|
||||
{
|
||||
return ChoiceType::class;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$choices = [];
|
||||
foreach ($this->registry->listDataflowTypes() as $fqcn => $dataflowType) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
@@ -12,12 +12,14 @@ use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
*/
|
||||
class FrequencyType extends AbstractType
|
||||
{
|
||||
public function getParent()
|
||||
#[\Override]
|
||||
public function getParent(): string
|
||||
{
|
||||
return TextType::class;
|
||||
}
|
||||
|
||||
public function getBlockPrefix()
|
||||
#[\Override]
|
||||
public function getBlockPrefix(): string
|
||||
{
|
||||
return 'coderhapsodie_port_frequency';
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\ScheduledDataflow;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
@@ -12,7 +12,7 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class UpdateScheduledType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('label', TextType::class, [
|
||||
@@ -32,13 +32,12 @@ class UpdateScheduledType extends AbstractType
|
||||
'label' => 'coderhapsodie.dataflow.frequency',
|
||||
])
|
||||
->add('next', UserTimezoneAwareDateTimeType::class, [
|
||||
'years' => range(date('Y'), date('Y') + 5),
|
||||
'label' => 'coderhapsodie.dataflow.update.next',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => ScheduledDataflow::class,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
|
||||
use Ibexa\Contracts\Core\Repository\UserPreferenceService;
|
||||
@@ -10,15 +10,11 @@ use Symfony\Component\Form\DataTransformerInterface;
|
||||
|
||||
class UserTimezoneAwareDateTimeTransformer implements DataTransformerInterface
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\UserPreferenceService */
|
||||
private $userPreferenceService;
|
||||
|
||||
public function __construct(UserPreferenceService $userPreferenceService)
|
||||
public function __construct(private readonly UserPreferenceService $userPreferenceService)
|
||||
{
|
||||
$this->userPreferenceService = $userPreferenceService;
|
||||
}
|
||||
|
||||
public function transform($value)
|
||||
public function transform($value): mixed
|
||||
{
|
||||
if (!$value instanceof \DateTimeInterface) {
|
||||
return $value;
|
||||
@@ -27,7 +23,7 @@ class UserTimezoneAwareDateTimeTransformer implements DataTransformerInterface
|
||||
return (new \DateTime('now', $this->userTimezone()))->setTimestamp($value->getTimestamp());
|
||||
}
|
||||
|
||||
public function reverseTransform($value)
|
||||
public function reverseTransform($value): mixed
|
||||
{
|
||||
if (!$value instanceof \DateTimeInterface) {
|
||||
return $value;
|
||||
@@ -42,7 +38,7 @@ class UserTimezoneAwareDateTimeTransformer implements DataTransformerInterface
|
||||
{
|
||||
try {
|
||||
$tz = $this->userPreferenceService->getUserPreference('timezone')->value ?? 'UTC';
|
||||
} catch (NotFoundException $e) {
|
||||
} catch (NotFoundException) {
|
||||
$tz = 'UTC';
|
||||
}
|
||||
|
||||
|
||||
@@ -2,29 +2,26 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use Ibexa\AdminUi\Form\Type\DateTimePickerType;
|
||||
use Ibexa\Contracts\Core\Repository\UserPreferenceService;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserTimezoneAwareDateTimeType extends AbstractType
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\UserPreferenceService */
|
||||
private $userPreferenceService;
|
||||
|
||||
public function __construct(UserPreferenceService $userPreferenceService)
|
||||
public function __construct(private readonly UserPreferenceService $userPreferenceService)
|
||||
{
|
||||
$this->userPreferenceService = $userPreferenceService;
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
#[\Override]
|
||||
public function getParent(): string
|
||||
{
|
||||
return DateTimeType::class;
|
||||
return DateTimePickerType::class;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->addModelTransformer(new UserTimezoneAwareDateTimeTransformer($this->userPreferenceService));
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Form;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
@@ -17,12 +17,13 @@ use Symfony\Component\Yaml\Yaml;
|
||||
*/
|
||||
class YamlType extends AbstractType
|
||||
{
|
||||
public function getParent()
|
||||
#[\Override]
|
||||
public function getParent(): string
|
||||
{
|
||||
return TextareaType::class;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder->addModelTransformer(new CallbackTransformer(
|
||||
function ($optionsAsArray) {
|
||||
@@ -51,7 +52,8 @@ class YamlType extends AbstractType
|
||||
));
|
||||
}
|
||||
|
||||
public function getBlockPrefix()
|
||||
#[\Override]
|
||||
public function getBlockPrefix(): string
|
||||
{
|
||||
return 'coderhapsodie_port_yaml';
|
||||
}
|
||||
|
||||
@@ -2,31 +2,27 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Gateway;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Gateway;
|
||||
|
||||
use Pagerfanta\Adapter\AdapterInterface;
|
||||
|
||||
class ExceptionJSONDecoderAdapter implements AdapterInterface
|
||||
{
|
||||
/** @var AdapterInterface */
|
||||
private $adapter;
|
||||
|
||||
public function __construct(AdapterInterface $adapter)
|
||||
public function __construct(private readonly AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
public function getNbResults()
|
||||
public function getNbResults(): int
|
||||
{
|
||||
return $this->adapter->getNbResults();
|
||||
}
|
||||
|
||||
public function getSlice($offset, $length)
|
||||
public function getSlice($offset, $length): iterable
|
||||
{
|
||||
$slice = $this->adapter->getSlice($offset, $length);
|
||||
array_walk($slice, static function (&$value) {
|
||||
array_walk($slice, static function (&$value): void {
|
||||
if (isset($value['exceptions'])) {
|
||||
$value['exceptions'] = json_decode($value['exceptions'], true, 512, JSON_THROW_ON_ERROR);
|
||||
$value['exceptions'] = json_decode((string) $value['exceptions'], true, 512, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,28 +2,25 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Gateway;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Gateway;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\Job;
|
||||
use CodeRhapsodie\DataflowBundle\Gateway\JobGateway as JobGatewayDataflow;
|
||||
use CodeRhapsodie\DataflowBundle\Repository\JobRepository;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
|
||||
final class JobGateway
|
||||
final readonly class JobGateway
|
||||
{
|
||||
public const FILTER_NONE = 0;
|
||||
public const FILTER_NON_EMPTY = 1;
|
||||
public const int FILTER_NONE = 0;
|
||||
public const int FILTER_NON_EMPTY = 1;
|
||||
|
||||
/** @var \CodeRhapsodie\DataflowBundle\Repository\JobRepository */
|
||||
private $jobRepository;
|
||||
|
||||
public function __construct(JobRepository $jobRepository)
|
||||
public function __construct(private JobRepository $jobRepository, private JobGatewayDataflow $jobGateway)
|
||||
{
|
||||
$this->jobRepository = $jobRepository;
|
||||
}
|
||||
|
||||
public function find(int $id): ?Job
|
||||
{
|
||||
return $this->jobRepository->find($id);
|
||||
return $this->jobGateway->find($id);
|
||||
}
|
||||
|
||||
public function getOneshotListQueryForAdmin(): QueryBuilder
|
||||
@@ -56,6 +53,14 @@ final class JobGateway
|
||||
|
||||
public function save(Job $job)
|
||||
{
|
||||
$this->jobRepository->save($job);
|
||||
$this->jobGateway->save($job);
|
||||
}
|
||||
|
||||
public function getListPendindOrRunning(): array
|
||||
{
|
||||
$qb = $this->jobRepository->createQueryBuilder('w');
|
||||
return $qb->andWhere($qb->expr()->in('w.status', [Job::STATUS_RUNNING, Job::STATUS_PENDING, Job::STATUS_QUEUED]))
|
||||
->orderBy('w.requested_date', 'ASC')
|
||||
->fetchAllAssociative();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,16 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Gateway;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Gateway;
|
||||
|
||||
use CodeRhapsodie\DataflowBundle\Entity\ScheduledDataflow;
|
||||
use CodeRhapsodie\DataflowBundle\Repository\ScheduledDataflowRepository;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
|
||||
final class ScheduledDataflowGateway
|
||||
final readonly class ScheduledDataflowGateway
|
||||
{
|
||||
/** @var \CodeRhapsodie\DataflowBundle\Repository\ScheduledDataflowRepository */
|
||||
private $scheduledDataflowRepository;
|
||||
|
||||
public function __construct(ScheduledDataflowRepository $scheduledDataflowRepository)
|
||||
public function __construct(private ScheduledDataflowRepository $scheduledDataflowRepository)
|
||||
{
|
||||
$this->scheduledDataflowRepository = $scheduledDataflowRepository;
|
||||
}
|
||||
|
||||
public function find(int $id): ?ScheduledDataflow
|
||||
|
||||
65
src/Gateway/TransformingAdapter.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Gateway;
|
||||
|
||||
use Pagerfanta\Adapter\AdapterInterface;
|
||||
|
||||
/**
|
||||
* Adapter which transforms the result of other adapter.
|
||||
*
|
||||
* @template T
|
||||
* @template Transformed
|
||||
*
|
||||
* @implements AdapterInterface<Transformed>
|
||||
*/
|
||||
class TransformingAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var AdapterInterface<T>
|
||||
*/
|
||||
private AdapterInterface $adapter;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*
|
||||
* @phpstan-var callable(T, array-key): Transformed
|
||||
*/
|
||||
private $transformer;
|
||||
|
||||
/**
|
||||
* @param AdapterInterface<T> $adapter
|
||||
*
|
||||
* @phpstan-param callable(T, array-key): Transformed $transformer
|
||||
*/
|
||||
public function __construct(AdapterInterface $adapter, callable $transformer)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->transformer = $transformer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return int<0, max>
|
||||
*/
|
||||
public function getNbResults(): int
|
||||
{
|
||||
return $this->adapter->getNbResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param int<0, max> $offset
|
||||
* @phpstan-param int<0, max> $length
|
||||
*
|
||||
* @return iterable<array-key, Transformed>
|
||||
*/
|
||||
public function getSlice(int $offset, int $length): iterable
|
||||
{
|
||||
$transformer = $this->transformer;
|
||||
|
||||
$data = [];
|
||||
foreach ($this->adapter->getSlice($offset, $length) as $key => $item) {
|
||||
$data[] = $transformer($item, $key);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -2,27 +2,23 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Matcher;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Matcher;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Exception\NoMatchFoundException;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Exception\NoMatchFoundException;
|
||||
use Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException;
|
||||
use Ibexa\Contracts\Core\Repository\LocationService;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Location;
|
||||
|
||||
class LocationMatcher implements LocationMatcherInterface
|
||||
{
|
||||
/** @var \Ibexa\Contracts\Core\Repository\LocationService */
|
||||
private $locationService;
|
||||
|
||||
public function __construct(LocationService $locationService)
|
||||
public function __construct(private readonly LocationService $locationService)
|
||||
{
|
||||
$this->locationService = $locationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $valueToMatch
|
||||
*
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\NoMatchFoundException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\NoMatchFoundException
|
||||
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException
|
||||
*/
|
||||
public function matchLocation($valueToMatch): Location
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Matcher;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Matcher;
|
||||
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Location;
|
||||
|
||||
|
||||
@@ -2,19 +2,15 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Model;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Model;
|
||||
|
||||
use CodeRhapsodie\EzDataflowBundle\Exception\InvalidArgumentTypeException;
|
||||
use CodeRhapsodie\IbexaDataflowBundle\Exception\InvalidArgumentTypeException;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\Location;
|
||||
use Ibexa\Contracts\Core\Repository\Values\Content\LocationCreateStruct;
|
||||
|
||||
class ContentCreateStructure extends ContentStructure
|
||||
{
|
||||
/** @var string */
|
||||
protected $contentTypeIdentifier;
|
||||
|
||||
/** @var array */
|
||||
protected $locations;
|
||||
protected array $locations;
|
||||
|
||||
/**
|
||||
* ContentCreateStructure constructor.
|
||||
@@ -28,11 +24,10 @@ class ContentCreateStructure extends ContentStructure
|
||||
* <li>a LocationCreateStruct object</li>
|
||||
* </ul>
|
||||
*
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\InvalidArgumentTypeException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\InvalidArgumentTypeException
|
||||
*/
|
||||
public function __construct(string $contentTypeIdentifier, string $languageCode, array $locations, array $fields, ?string $remoteId = null)
|
||||
public function __construct(protected string $contentTypeIdentifier, string $languageCode, array $locations, array $fields, ?string $remoteId = null)
|
||||
{
|
||||
$this->contentTypeIdentifier = $contentTypeIdentifier;
|
||||
$this->languageCode = $languageCode;
|
||||
$this->setLocations($locations);
|
||||
$this->fields = $fields;
|
||||
@@ -50,9 +45,9 @@ class ContentCreateStructure extends ContentStructure
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \CodeRhapsodie\EzDataflowBundle\Exception\InvalidArgumentTypeException
|
||||
* @throws \CodeRhapsodie\IbexaDataflowBundle\Exception\InvalidArgumentTypeException
|
||||
*/
|
||||
private function setLocations(array $locations)
|
||||
private function setLocations(array $locations): void
|
||||
{
|
||||
foreach ($locations as $locationOrIdOrRemoteIdOrStruct) {
|
||||
if (!is_int($locationOrIdOrRemoteIdOrStruct)
|
||||
|
||||
@@ -2,18 +2,15 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Model;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Model;
|
||||
|
||||
abstract class ContentStructure
|
||||
{
|
||||
/** @var string|null */
|
||||
protected $remoteId;
|
||||
protected ?string $remoteId = null;
|
||||
|
||||
/** @var string */
|
||||
protected $languageCode;
|
||||
protected string $languageCode;
|
||||
|
||||
/** @var array */
|
||||
protected $fields;
|
||||
protected array $fields;
|
||||
|
||||
public function getRemoteId(): ?string
|
||||
{
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\EzDataflowBundle\Model;
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Model;
|
||||
|
||||
class ContentUpdateStructure extends ContentStructure
|
||||
{
|
||||
/** @var int|null */
|
||||
protected $id;
|
||||
protected ?int $id = null;
|
||||
|
||||
private function __construct(string $languageCode, array $fields)
|
||||
{
|
||||
|
||||
15
src/Model/ProductCreateStructure.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Model;
|
||||
|
||||
class ProductCreateStructure extends ProductStructure
|
||||
{
|
||||
public function __construct(string $code, array $fields, string $languageCode)
|
||||
{
|
||||
$this->code = $code;
|
||||
$this->fields = $fields;
|
||||
$this->languageCode = $languageCode;
|
||||
}
|
||||
}
|
||||
35
src/Model/ProductStructure.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Model;
|
||||
|
||||
abstract class ProductStructure
|
||||
{
|
||||
protected string $code;
|
||||
|
||||
protected array $fields;
|
||||
|
||||
protected string $languageCode;
|
||||
|
||||
protected int $stock;
|
||||
|
||||
|
||||
public function getCode(): string
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function getFields(): array
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
public function getLanguageCode(): string
|
||||
{
|
||||
return $this->languageCode;
|
||||
}
|
||||
|
||||
public function getStock(): int
|
||||
{
|
||||
return $this->stock;
|
||||
}
|
||||
}
|
||||
40
src/Model/ProductUpdateStructure.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CodeRhapsodie\IbexaDataflowBundle\Model;
|
||||
|
||||
class ProductUpdateStructure extends ProductStructure
|
||||
{
|
||||
protected bool $updateContent = true;
|
||||
|
||||
protected bool $updateStock = true;
|
||||
|
||||
public function __construct(string $code, array $fields, string $languageCode, int $stock = 0)
|
||||
{
|
||||
$this->code = $code;
|
||||
$this->fields = $fields;
|
||||
$this->languageCode = $languageCode;
|
||||
$this->stock = $stock;
|
||||
}
|
||||
|
||||
public function isUpdateContent(): bool
|
||||
{
|
||||
return $this->updateContent;
|
||||
}
|
||||
|
||||
public function isUpdateStock(): bool
|
||||
{
|
||||
return $this->updateStock;
|
||||
}
|
||||
|
||||
public function setUpdateContent(bool $updateContent): void
|
||||
{
|
||||
$this->updateContent = $updateContent;
|
||||
}
|
||||
|
||||
public function setUpdateStock(bool $updateStock): void
|
||||
{
|
||||
$this->updateStock = $updateStock;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
ezdataflow:
|
||||
ibexa_dataflow:
|
||||
view: ~
|
||||
edit: ~
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
coderhapsodie.ezdataflow.controllers:
|
||||
coderhapsodie.ibexa_dataflow.controllers:
|
||||
resource: '../../Controller/'
|
||||
type: annotation
|
||||
type: attribute
|
||||
|
||||
|
||||
@@ -4,174 +4,178 @@ imports:
|
||||
services:
|
||||
_defaults:
|
||||
public: false
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
coderhapsodie.dataflow.connection: "@ibexa.persistence.connection"
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Controller\DashboardController:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Controller\DashboardController:
|
||||
public: true
|
||||
tags:
|
||||
- { name: controller.service_arguments }
|
||||
arguments:
|
||||
$jobGateway: '@CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway'
|
||||
$scheduledDataflowGateway: '@CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway'
|
||||
calls:
|
||||
- ['setContainer', ['@service_container']]
|
||||
- ['performAccessCheck', []]
|
||||
$jobGateway: '@CodeRhapsodie\IbexaDataflowBundle\Gateway\JobGateway'
|
||||
$scheduledDataflowGateway: '@CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway'
|
||||
$exceptionHandler: '@CodeRhapsodie\DataflowBundle\ExceptionsHandler\ExceptionHandlerInterface'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Controller\ScheduledDataflowController:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Controller\ScheduledDataflowController:
|
||||
public: true
|
||||
tags:
|
||||
- { name: controller.service_arguments }
|
||||
arguments:
|
||||
$notificationHandler: '@Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface'
|
||||
$scheduledDataflowGateway: '@CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway'
|
||||
$scheduledDataflowGateway: '@CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway'
|
||||
$translator: '@translator'
|
||||
calls:
|
||||
- [ 'setContainer', [ '@service_container' ] ]
|
||||
- [ 'performAccessCheck', [ ] ]
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Controller\JobController:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Controller\JobController:
|
||||
public: true
|
||||
tags:
|
||||
- { name: controller.service_arguments }
|
||||
arguments:
|
||||
$jobGateway: '@CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway'
|
||||
$jobGateway: '@CodeRhapsodie\IbexaDataflowBundle\Gateway\JobGateway'
|
||||
$notificationHandler: '@Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface'
|
||||
$translator: '@translator'
|
||||
calls:
|
||||
- [ 'setContainer', [ '@service_container' ] ]
|
||||
- [ 'performAccessCheck', [ ] ]
|
||||
$scheduledDataflowGateway: '@CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Writer\RepositoryWriter:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Writer\RepositoryWriter:
|
||||
abstract: true
|
||||
calls:
|
||||
- ['setUserSwitcher', ['@CodeRhapsodie\EzDataflowBundle\UserSwitcher\UserSwitcherInterface']]
|
||||
- ['setUserSwitcher', ['@CodeRhapsodie\IbexaDataflowBundle\UserSwitcher\UserSwitcherInterface']]
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Writer\RepositoryWriter'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Writer\ContentWriter:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Writer\RepositoryWriter'
|
||||
public: false
|
||||
arguments:
|
||||
$creator: '@CodeRhapsodie\EzDataflowBundle\Core\Content\ContentCreatorInterface'
|
||||
$updater: '@CodeRhapsodie\EzDataflowBundle\Core\Content\ContentUpdaterInterface'
|
||||
$creator: '@CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentCreatorInterface'
|
||||
$updater: '@CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentUpdaterInterface'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\UserSwitcher\UserSwitcherInterface: '@CodeRhapsodie\EzDataflowBundle\UserSwitcher\UserSwitcher'
|
||||
CodeRhapsodie\EzDataflowBundle\UserSwitcher\UserSwitcher:
|
||||
CodeRhapsodie\IbexaDataflowBundle\UserSwitcher\UserSwitcherInterface: '@CodeRhapsodie\IbexaDataflowBundle\UserSwitcher\UserSwitcher'
|
||||
CodeRhapsodie\IbexaDataflowBundle\UserSwitcher\UserSwitcher:
|
||||
arguments:
|
||||
$permissionResolver: '@Ibexa\Contracts\Core\Repository\PermissionResolver'
|
||||
$userService: '@Ibexa\Contracts\Core\Repository\UserService'
|
||||
$adminLoginOrId: '%coderhapsodie.ezdataflow.admin_login_or_id%'
|
||||
$adminLoginOrId: '%coderhapsodie.ibexa_dataflow.admin_login_or_id%'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Content\ContentCreatorInterface: '@CodeRhapsodie\EzDataflowBundle\Core\Content\ContentCreator'
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Content\ContentCreator:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentCreatorInterface: '@CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentCreator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentCreator:
|
||||
arguments:
|
||||
$contentService: '@Ibexa\Contracts\Core\Repository\ContentService'
|
||||
$contentTypeService: '@Ibexa\Contracts\Core\Repository\ContentTypeService'
|
||||
$filler: '@CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface'
|
||||
$matcher: '@CodeRhapsodie\EzDataflowBundle\Matcher\LocationMatcherInterface'
|
||||
$filler: '@CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFillerInterface'
|
||||
$matcher: '@CodeRhapsodie\IbexaDataflowBundle\Matcher\LocationMatcherInterface'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Content\ContentUpdaterInterface: '@CodeRhapsodie\EzDataflowBundle\Core\Content\ContentUpdater'
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Content\ContentUpdater:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentUpdaterInterface: '@CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentUpdater'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Content\ContentUpdater:
|
||||
arguments:
|
||||
$contentService: '@Ibexa\Contracts\Core\Repository\ContentService'
|
||||
$contentTypeService: '@Ibexa\Contracts\Core\Repository\ContentTypeService'
|
||||
$filler: '@CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface'
|
||||
$filler: '@CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFillerInterface'
|
||||
$repository: '@Ibexa\Core\Event\Repository'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFillerInterface: '@CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFiller'
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Field\ContentStructFieldFiller:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFillerInterface: '@CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFiller'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Field\ContentStructFieldFiller:
|
||||
arguments:
|
||||
$fieldValueCreators: !tagged 'coderhapsodie.ezdataflow.field_value_creator'
|
||||
$fieldValueCreators: !tagged_iterator 'coderhapsodie.ibexa_dataflow.field_value_creator'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Matcher\LocationMatcherInterface: '@CodeRhapsodie\EzDataflowBundle\Matcher\LocationMatcher'
|
||||
CodeRhapsodie\EzDataflowBundle\Matcher\LocationMatcher:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Matcher\LocationMatcherInterface: '@CodeRhapsodie\IbexaDataflowBundle\Matcher\LocationMatcher'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Matcher\LocationMatcher:
|
||||
arguments:
|
||||
$locationService: '@Ibexa\Contracts\Core\Repository\LocationService'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\Field\DefaultFieldValueCreator:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\Field\DefaultFieldValueCreator:
|
||||
arguments:
|
||||
$fieldTypeService: '@Ibexa\Contracts\Core\Repository\FieldTypeService'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_value_creator', priority: -1000 }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_value_creator', priority: -1000 }
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\EventSubscriber\MenuSubscriber:
|
||||
CodeRhapsodie\IbexaDataflowBundle\EventSubscriber\MenuSubscriber:
|
||||
tags: ['kernel.event_subscriber']
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Factory\ContentStructureFactoryInterface: '@CodeRhapsodie\EzDataflowBundle\Factory\ContentStructureFactory'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Factory\ContentStructureFactoryInterface: '@CodeRhapsodie\IbexaDataflowBundle\Factory\ContentStructureFactory'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Factory\ContentStructureFactory:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Factory\ContentStructureFactory:
|
||||
arguments:
|
||||
$contentService: '@Ibexa\Contracts\Core\Repository\ContentService'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Form\DataflowTypeChoiceType:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Form\DataflowTypeChoiceType:
|
||||
arguments:
|
||||
$registry: '@CodeRhapsodie\DataflowBundle\Registry\DataflowTypeRegistryInterface'
|
||||
tags: ['form.type']
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Form\CreateScheduledType:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Form\CreateScheduledType:
|
||||
tags: ['form.type']
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Form\UpdateScheduledType:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Form\UpdateScheduledType:
|
||||
tags: ['form.type']
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Form\CreateOneshotType:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Form\CreateOneshotType:
|
||||
tags: ['form.type']
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Form\UserTimezoneAwareDateTimeType:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Form\UserTimezoneAwareDateTimeType:
|
||||
arguments:
|
||||
$userPreferenceService: '@Ibexa\Contracts\Core\Repository\UserPreferenceService'
|
||||
tags: ['form.type']
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Gateway\ScheduledDataflowGateway:
|
||||
arguments:
|
||||
$scheduledDataflowRepository: '@CodeRhapsodie\DataflowBundle\Repository\ScheduledDataflowRepository'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Gateway\JobGateway:
|
||||
arguments:
|
||||
$jobRepository: '@CodeRhapsodie\DataflowBundle\Repository\JobRepository'
|
||||
$jobGateway: '@CodeRhapsodie\DataflowBundle\Gateway\JobGateway'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Tab\RepeatingTab:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Tab\DashboardTab:
|
||||
parent: Ibexa\Contracts\AdminUi\Tab\AbstractTab
|
||||
public: false
|
||||
arguments:
|
||||
$httpKernelRuntime: '@twig.runtime.httpkernel'
|
||||
tags:
|
||||
- {name: ibexa.admin_ui.tab, group: coderhapsodie-ezdataflow}
|
||||
- { name: ibexa.admin_ui.tab, group: coderhapsodie-ibexa_dataflow }
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Tab\OneshotTab:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Tab\RepeatingTab:
|
||||
parent: Ibexa\Contracts\AdminUi\Tab\AbstractTab
|
||||
public: false
|
||||
arguments:
|
||||
$httpKernelRuntime: '@twig.runtime.httpkernel'
|
||||
tags:
|
||||
- {name: ibexa.admin_ui.tab, group: coderhapsodie-ezdataflow}
|
||||
- {name: ibexa.admin_ui.tab, group: coderhapsodie-ibexa_dataflow}
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Tab\HistoryTab:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Tab\OneshotTab:
|
||||
parent: Ibexa\Contracts\AdminUi\Tab\AbstractTab
|
||||
public: false
|
||||
arguments:
|
||||
$httpKernelRuntime: '@twig.runtime.httpkernel'
|
||||
tags:
|
||||
- {name: ibexa.admin_ui.tab, group: coderhapsodie-ezdataflow}
|
||||
- {name: ibexa.admin_ui.tab, group: coderhapsodie-ibexa_dataflow}
|
||||
|
||||
CodeRhapsodie\IbexaDataflowBundle\Tab\HistoryTab:
|
||||
parent: Ibexa\Contracts\AdminUi\Tab\AbstractTab
|
||||
public: false
|
||||
arguments:
|
||||
$httpKernelRuntime: '@twig.runtime.httpkernel'
|
||||
tags:
|
||||
- {name: ibexa.admin_ui.tab, group: coderhapsodie-ibexa_dataflow}
|
||||
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Filter\NotModifiedContentFilter:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Filter\NotModifiedContentFilter:
|
||||
arguments:
|
||||
$contentService: '@Ibexa\Contracts\Core\Repository\ContentService'
|
||||
$comparator: '@CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\FieldComparatorInterface'
|
||||
$comparator: '@CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\FieldComparatorInterface'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\FieldComparatorInterface: '@CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\DelegatorFieldComparator'
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\DelegatorFieldComparator:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Filter\NotModifiedProductFilter:
|
||||
arguments:
|
||||
$notModifiedContentFilter: '@CodeRhapsodie\IbexaDataflowBundle\Filter\NotModifiedContentFilter'
|
||||
$connection: '@ibexa.persistence.connection'
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator:
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\FieldComparatorInterface: '@CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\DelegatorFieldComparator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\DelegatorFieldComparator:
|
||||
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator:
|
||||
arguments:
|
||||
$fieldTypeService: '@Ibexa\Contracts\Core\Repository\FieldTypeService'
|
||||
abstract: true
|
||||
|
||||
_cr.admin_tabs.ezdataflow_group:
|
||||
_cr.admin_tabs.ibexa_dataflow_group:
|
||||
parent: Ibexa\AdminUi\Component\TabsComponent
|
||||
autowire: true
|
||||
autoconfigure: false
|
||||
public: false
|
||||
arguments:
|
||||
$groupIdentifier: 'coderhapsodie-ezdataflow'
|
||||
$groupIdentifier: 'coderhapsodie-ibexa_dataflow'
|
||||
tags:
|
||||
- { name: ibexa.admin_ui.component, group: 'coderhapsodie-ezdataflow' }
|
||||
- { name: ibexa.admin_ui.component, group: 'coderhapsodie-ibexa_dataflow' }
|
||||
|
||||
@@ -1,42 +1,58 @@
|
||||
services:
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\SimpleFieldComparator:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\SimpleFieldComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezauthor' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezboolean' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezcountry' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezdate' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezdatetime' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezemail' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezfloat' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezinteger' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezisbn' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezkeyword' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezobjectrelation' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezobjectrelationlist' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezrichtext' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezselection' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'eztext' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezstring' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'eztime' }
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'eztags' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_author' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_boolean' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_country' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_datetime' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_date' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_email' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_float' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_integer' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_isbn' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_keyword' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_object_relation' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_object_relation_list' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_richtext' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_selection' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_text' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_string' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_time' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'eztags' }
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\UrlFieldComparator:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\UrlFieldComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezurl' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_url' }
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\NovaSEOMetasFieldComparator:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\NovaSEOMetasFieldComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'novaseometas' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'novaseometas' }
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\MatrixFieldComparator:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\MatrixFieldComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezmatrix' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_matrix' }
|
||||
|
||||
CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\MapLocationFieldComparator:
|
||||
parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\MapLocationFieldComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'ezgmaplocation' }
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_gmap_location' }
|
||||
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\TaxonomyEntryAssignmentComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_taxonomy_entry_assignment' }
|
||||
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\BillingAddressComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_address' }
|
||||
|
||||
CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\CustomerGroupComparator:
|
||||
parent: 'CodeRhapsodie\IbexaDataflowBundle\Core\FieldComparator\AbstractFieldComparator'
|
||||
tags:
|
||||
- { name: 'coderhapsodie.ibexa_dataflow.field_comparator', fieldType: 'ibexa_customer_group' }
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 58 KiB |
BIN
src/Resources/doc/add_new_schedule.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
src/Resources/doc/admin_menu.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/Resources/doc/dest_folder.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 78 KiB |
BIN
src/Resources/doc/history_list.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 73 KiB |
BIN
src/Resources/doc/job_failed.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 77 KiB |
BIN
src/Resources/doc/job_successful.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 45 KiB |
BIN
src/Resources/doc/one_shot_job.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 80 KiB |
BIN
src/Resources/doc/oneshot_list.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/Resources/doc/scheduled_list.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
@@ -1,4 +1,4 @@
|
||||
role.policy.ezdataflow: Ibexa Dataflow
|
||||
role.policy.ezdataflow.all_functions: Ibexa Dataflow / All functions
|
||||
role.policy.ezdataflow.view: Ibexa Dataflow / View
|
||||
role.policy.ezdataflow.edit: Ibexa Dataflow / Edit
|
||||
role.policy.ibexa_dataflow: Ibexa Dataflow
|
||||
role.policy.ibexa_dataflow.all_functions: Ibexa Dataflow / All functions
|
||||
role.policy.ibexa_dataflow.view: Ibexa Dataflow / View
|
||||
role.policy.ibexa_dataflow.edit: Ibexa Dataflow / Edit
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
role.policy.ezdataflow: Ibexa Dataflow
|
||||
role.policy.ezdataflow.all_functions: Ibexa Dataflow / Toutes les fonctions
|
||||
role.policy.ezdataflow.view: Ibexa Dataflow / Consultation
|
||||
role.policy.ezdataflow.edit: Ibexa Dataflow / Modification
|
||||
role.policy.ibexa_dataflow: Ibexa Dataflow
|
||||
role.policy.ibexa_dataflow.all_functions: Ibexa Dataflow / Toutes les fonctions
|
||||
role.policy.ibexa_dataflow.view: Ibexa Dataflow / Consultation
|
||||
role.policy.ibexa_dataflow.edit: Ibexa Dataflow / Modification
|
||||
|
||||
@@ -1 +1 @@
|
||||
coderhapsodie.ezdataflow: Ibexa Dataflow
|
||||
coderhapsodie.ibexa_dataflow: Ibexa Dataflow
|
||||
|
||||
@@ -1 +1 @@
|
||||
coderhapsodie.ezdataflow: Ibexa Dataflow
|
||||
coderhapsodie.ibexa_dataflow: Ibexa Dataflow
|
||||
|
||||
@@ -1 +1 @@
|
||||
coderhapsodie.ezdataflow: Ibexa Dataflow
|
||||
coderhapsodie.ibexa_dataflow: Ibexa Dataflow
|
||||
|
||||
@@ -1 +1 @@
|
||||
coderhapsodie.ezdataflow: Ibexa Dataflow
|
||||
coderhapsodie.ibexa_dataflow: Ibexa Dataflow
|
||||
|
||||
@@ -1,67 +1,68 @@
|
||||
coderhapsodie.ezdataflow: Ibexa Dataflow
|
||||
coderhapsodie.ezdataflow.yes: Yes
|
||||
coderhapsodie.ezdataflow.no: No
|
||||
coderhapsodie.ezdataflow.repeating: Repeating
|
||||
coderhapsodie.ezdataflow.repeating.title: Repeating
|
||||
coderhapsodie.ezdataflow.oneshot: Oneshot
|
||||
coderhapsodie.ezdataflow.oneshot.title: Oneshot
|
||||
coderhapsodie.ezdataflow.oneshot.list.title: 'Oneshot dataflow list'
|
||||
coderhapsodie.ezdataflow.workflow.list.title: 'Scheduled dataflow list'
|
||||
coderhapsodie.ezdataflow.history: History
|
||||
coderhapsodie.ezdataflow.workflow.list.name: Name
|
||||
coderhapsodie.ezdataflow.workflow.list.frequency: Frequency
|
||||
coderhapsodie.ezdataflow.workflow.list.next_execution: 'Next execution'
|
||||
coderhapsodie.ezdataflow.workflow.list.enabled: 'Enabled?'
|
||||
coderhapsodie.ezdataflow.workflow.list.history: History
|
||||
coderhapsodie.ezdataflow.workflow.list.edit: Edit
|
||||
coderhapsodie.ezdataflow.workflow.list.disable: Disable
|
||||
coderhapsodie.ezdataflow.workflow.list.enable: Enable
|
||||
coderhapsodie.ezdataflow.history.title: History
|
||||
coderhapsodie.ezdataflow.history.list.title: 'Executions list'
|
||||
coderhapsodie.ezdataflow.history.list.name: Name
|
||||
coderhapsodie.ezdataflow.history.list.request: 'Requested on'
|
||||
coderhapsodie.ezdataflow.history.list.count: 'Number of successes'
|
||||
coderhapsodie.ezdataflow.history.list.errors: 'Number of errors'
|
||||
coderhapsodie.ezdataflow.history.list.start: 'Started on'
|
||||
coderhapsodie.ezdataflow.history.list.end: 'Finished on'
|
||||
coderhapsodie.ezdataflow.history.list.view: 'View details'
|
||||
coderhapsodie.ezdataflow.history.list.status: Status
|
||||
coderhapsodie.ezdataflow.history.filter.label: Filter results
|
||||
coderhapsodie.ezdataflow.history.filter.none: All results
|
||||
coderhapsodie.ezdataflow.history.filter.non_empty_only: Only non empty
|
||||
coderhapsodie.ezdataflow.history.filter.with_error_only: Only with errors
|
||||
coderhapsodie.ezdataflow.job.status.pending: Pending
|
||||
coderhapsodie.ezdataflow.job.status.running: Running
|
||||
coderhapsodie.ezdataflow.job.status.complete: Completed
|
||||
coderhapsodie.ezdataflow.job.status.unknown: Unknown
|
||||
coderhapsodie.ezdataflow.history.job.title: 'Job'
|
||||
coderhapsodie.ezdataflow.history.details.title: 'Job details'
|
||||
coderhapsodie.ezdataflow.history.details.name: Name
|
||||
coderhapsodie.ezdataflow.history.details.request: 'Requested on'
|
||||
coderhapsodie.ezdataflow.history.details.status: Status
|
||||
coderhapsodie.ezdataflow.history.details.start: 'Started on'
|
||||
coderhapsodie.ezdataflow.history.details.end: 'Finished on'
|
||||
coderhapsodie.ezdataflow.history.details.count: 'Items successfully processed'
|
||||
coderhapsodie.ezdataflow.history.details.options: 'Run options'
|
||||
coderhapsodie.ezdataflow.history.details.errors: Errors
|
||||
coderhapsodie.ezdataflow.history.details.type: 'Name of the dataflow executed'
|
||||
coderhapsodie.ezdataflow.history.details.log: 'View log'
|
||||
coderhapsodie.ezdataflow.workflow.repeating.new.title: 'Add a new repeating dataflow'
|
||||
coderhapsodie.ezdataflow.workflow.new.cancel: Cancel
|
||||
coderhapsodie.ezdataflow.workflow.new.submit: Create
|
||||
coderhapsodie.ezdataflow.history.list.empty: 'No execution yet.'
|
||||
coderhapsodie.ezdataflow.workflow.list.empty: 'No repeating workflow configured yet'
|
||||
coderhapsodie.ezdataflow.workflow.history.title: 'Execution history'
|
||||
coderhapsodie.ezdataflow.workflow.log.title: 'Execution log'
|
||||
coderhapsodie.ezdataflow.workflow.list.delete: Delete
|
||||
coderhapsodie.ezdataflow.workflow.delete: 'Are you sure you want to delete this dataflow schedule?'
|
||||
coderhapsodie.ezdataflow.workflow.create.success: 'Dataflow schedule successfully added.'
|
||||
coderhapsodie.ezdataflow.workflow.create.error: 'An error occurred during the dataflow schedule creation: "%message%".'
|
||||
coderhapsodie.ezdataflow.workflow.delete.success: 'Dataflow schedule successfully deleted.'
|
||||
coderhapsodie.ezdataflow.workflow.delete.error: 'An error occurred during the dataflow schedule deletion: "%message%".'
|
||||
coderhapsodie.ezdataflow.workflow.oneshot.new.title: 'New oneshot job'
|
||||
coderhapsodie.ezdataflow.job.create.success: 'Job successfully added.'
|
||||
coderhapsodie.ezdataflow.job.create.error: 'An error occured during the job creation: "%message%".'
|
||||
coderhapsodie.ibexa_dataflow: Ibexa Dataflow
|
||||
coderhapsodie.ibexa_dataflow.yes: Yes
|
||||
coderhapsodie.ibexa_dataflow.no: No
|
||||
coderhapsodie.ibexa_dataflow.repeating: Repeating
|
||||
coderhapsodie.ibexa_dataflow.repeating.title: Repeating
|
||||
coderhapsodie.ibexa_dataflow.oneshot: Oneshot
|
||||
coderhapsodie.ibexa_dataflow.oneshot.title: Oneshot
|
||||
coderhapsodie.ibexa_dataflow.oneshot.list.title: 'Oneshot dataflow list'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.title: 'Scheduled dataflow list'
|
||||
coderhapsodie.ibexa_dataflow.history: History
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.name: Name
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.frequency: Frequency
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.next_execution: 'Next execution'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.enabled: 'Enabled?'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.history: History
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.edit: Edit
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.disable: Disable
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.enable: Enable
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.runonce: Run now
|
||||
coderhapsodie.ibexa_dataflow.history.title: History
|
||||
coderhapsodie.ibexa_dataflow.history.list.title: 'Executions list'
|
||||
coderhapsodie.ibexa_dataflow.history.list.name: Name
|
||||
coderhapsodie.ibexa_dataflow.history.list.request: 'Requested on'
|
||||
coderhapsodie.ibexa_dataflow.history.list.count: 'Number of successes'
|
||||
coderhapsodie.ibexa_dataflow.history.list.errors: 'Number of errors'
|
||||
coderhapsodie.ibexa_dataflow.history.list.start: 'Started on'
|
||||
coderhapsodie.ibexa_dataflow.history.list.end: 'Finished on'
|
||||
coderhapsodie.ibexa_dataflow.history.list.view: 'View details'
|
||||
coderhapsodie.ibexa_dataflow.history.list.status: Status
|
||||
coderhapsodie.ibexa_dataflow.history.filter.label: Filter results
|
||||
coderhapsodie.ibexa_dataflow.history.filter.none: All results
|
||||
coderhapsodie.ibexa_dataflow.history.filter.non_empty_only: Only non empty
|
||||
coderhapsodie.ibexa_dataflow.history.filter.with_error_only: Only with errors
|
||||
coderhapsodie.ibexa_dataflow.job.status.pending: Pending
|
||||
coderhapsodie.ibexa_dataflow.job.status.running: Running
|
||||
coderhapsodie.ibexa_dataflow.job.status.complete: Completed
|
||||
coderhapsodie.ibexa_dataflow.job.status.unknown: Unknown
|
||||
coderhapsodie.ibexa_dataflow.history.job.title: 'Job'
|
||||
coderhapsodie.ibexa_dataflow.history.details.title: 'Job details'
|
||||
coderhapsodie.ibexa_dataflow.history.details.name: Name
|
||||
coderhapsodie.ibexa_dataflow.history.details.request: 'Requested on'
|
||||
coderhapsodie.ibexa_dataflow.history.details.status: Status
|
||||
coderhapsodie.ibexa_dataflow.history.details.start: 'Started on'
|
||||
coderhapsodie.ibexa_dataflow.history.details.end: 'Finished on'
|
||||
coderhapsodie.ibexa_dataflow.history.details.count: 'Items successfully processed'
|
||||
coderhapsodie.ibexa_dataflow.history.details.options: 'Run options'
|
||||
coderhapsodie.ibexa_dataflow.history.details.errors: Errors
|
||||
coderhapsodie.ibexa_dataflow.history.details.type: 'Name of the dataflow executed'
|
||||
coderhapsodie.ibexa_dataflow.history.details.log: 'View log'
|
||||
coderhapsodie.ibexa_dataflow.workflow.repeating.new.title: 'Add a new repeating dataflow'
|
||||
coderhapsodie.ibexa_dataflow.workflow.new.cancel: Cancel
|
||||
coderhapsodie.ibexa_dataflow.workflow.new.submit: Create
|
||||
coderhapsodie.ibexa_dataflow.history.list.empty: 'No execution yet.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.empty: 'No repeating workflow configured yet'
|
||||
coderhapsodie.ibexa_dataflow.workflow.history.title: 'Execution history'
|
||||
coderhapsodie.ibexa_dataflow.workflow.log.title: 'Execution log'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.delete: Delete
|
||||
coderhapsodie.ibexa_dataflow.workflow.delete: 'Are you sure you want to delete this dataflow schedule?'
|
||||
coderhapsodie.ibexa_dataflow.workflow.create.success: 'Dataflow schedule successfully added.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.create.error: 'An error occurred during the dataflow schedule creation: "%message%".'
|
||||
coderhapsodie.ibexa_dataflow.workflow.delete.success: 'Dataflow schedule successfully deleted.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.delete.error: 'An error occurred during the dataflow schedule deletion: "%message%".'
|
||||
coderhapsodie.ibexa_dataflow.workflow.oneshot.new.title: 'New oneshot job'
|
||||
coderhapsodie.ibexa_dataflow.job.create.success: 'Job successfully added.'
|
||||
coderhapsodie.ibexa_dataflow.job.create.error: 'An error occured during the job creation: "%message%".'
|
||||
coderhapsodie.dataflow.label: 'Scheduled dataflow name'
|
||||
coderhapsodie.dataflow.oneshot.label: 'One-shot job name'
|
||||
coderhapsodie.dataflow.dataflowType: 'Select the dataflow to run'
|
||||
@@ -76,9 +77,13 @@ coderhapsodie.dataflow.frequency.title: 'Enter an interval in a format compatibl
|
||||
coderhapsodie.dataflow.frequency.placeholder: 'Example: 1 year 2 months 3 weeks 4 days 5 hours 6 minutes'
|
||||
coderhapsodie.dataflow.create.next: 'First run'
|
||||
coderhapsodie.dataflow.create.enabled: Enabled?
|
||||
coderhapsodie.ezdataflow.workflow.repeating.edit.title: "Dataflow schedule edit"
|
||||
coderhapsodie.ezdataflow.workflow.edit.submit: Save
|
||||
coderhapsodie.ibexa_dataflow.workflow.repeating.edit.title: "Dataflow schedule edit"
|
||||
coderhapsodie.ibexa_dataflow.workflow.edit.submit: Save
|
||||
coderhapsodie.dataflow.update.next: 'Next execution'
|
||||
coderhapsodie.ezdataflow.workflow.edit.success: 'Dataflow schedule successfully updated.'
|
||||
coderhapsodie.ezdataflow.workflow.edit.error: 'An error occurred during the dataflow schedule update: "%message%".'
|
||||
coderhapsodie.ezdataflow.notfound: 'Requested data is not found'
|
||||
coderhapsodie.ibexa_dataflow.workflow.edit.success: 'Dataflow schedule successfully updated.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.edit.error: 'An error occurred during the dataflow schedule update: "%message%".'
|
||||
coderhapsodie.ibexa_dataflow.notfound: 'Requested data is not found'
|
||||
coderhapsodie.ibexa_dataflow.powered_by: 'Powered by'
|
||||
coderhapsodie.ibexa_dataflow.made_by: 'Made by'
|
||||
coderhapsodie.ibexa_dataflow.dashboard: Dashboard
|
||||
coderhapsodie.ibexa_dataflow.dashboard.title: Running or waiting tasks
|
||||
@@ -1,67 +1,68 @@
|
||||
coderhapsodie.ezdataflow: Ibexa Dataflow
|
||||
coderhapsodie.ezdataflow.yes: Oui
|
||||
coderhapsodie.ezdataflow.no: Non
|
||||
coderhapsodie.ezdataflow.repeating: Récurrent
|
||||
coderhapsodie.ezdataflow.repeating.title: Récurrent
|
||||
coderhapsodie.ezdataflow.oneshot: Ponctuel
|
||||
coderhapsodie.ezdataflow.oneshot.title: Ponctuel
|
||||
coderhapsodie.ezdataflow.oneshot.list.title: 'Liste des exécutions ponctuelles de dataflow'
|
||||
coderhapsodie.ezdataflow.workflow.list.title: 'Liste des programmations des dataflow'
|
||||
coderhapsodie.ezdataflow.history: Historique
|
||||
coderhapsodie.ezdataflow.workflow.list.name: Nom
|
||||
coderhapsodie.ezdataflow.workflow.list.frequency: Fréquence
|
||||
coderhapsodie.ezdataflow.workflow.list.next_execution: 'Prochaine exécution'
|
||||
coderhapsodie.ezdataflow.workflow.list.enabled: 'Activé ?'
|
||||
coderhapsodie.ezdataflow.workflow.list.history: Historique
|
||||
coderhapsodie.ezdataflow.workflow.list.edit: Éditer
|
||||
coderhapsodie.ezdataflow.workflow.list.disable: Désactiver
|
||||
coderhapsodie.ezdataflow.workflow.list.enable: Activer
|
||||
coderhapsodie.ezdataflow.history.title: Historique
|
||||
coderhapsodie.ezdataflow.history.list.title: 'Liste des exécutions'
|
||||
coderhapsodie.ezdataflow.history.list.name: Nom
|
||||
coderhapsodie.ezdataflow.history.list.request: 'Demandé le'
|
||||
coderhapsodie.ezdataflow.history.list.count: 'Nombre de succès'
|
||||
coderhapsodie.ezdataflow.history.list.errors: 'Nombre d''erreurs'
|
||||
coderhapsodie.ezdataflow.history.list.start: 'Commencé le'
|
||||
coderhapsodie.ezdataflow.history.list.end: 'Terminé le'
|
||||
coderhapsodie.ezdataflow.history.list.view: 'Voir le détail'
|
||||
coderhapsodie.ezdataflow.history.list.status: État
|
||||
coderhapsodie.ezdataflow.history.filter.label: Filtrer les résultats
|
||||
coderhapsodie.ezdataflow.history.filter.none: Tous les résultats
|
||||
coderhapsodie.ezdataflow.history.filter.non_empty_only: Seulement non vides
|
||||
coderhapsodie.ezdataflow.history.filter.with_error_only: Seulement avec erreurs
|
||||
coderhapsodie.ezdataflow.job.status.pending: 'En attente'
|
||||
coderhapsodie.ezdataflow.job.status.running: 'En cours'
|
||||
coderhapsodie.ezdataflow.job.status.complete: Terminé
|
||||
coderhapsodie.ezdataflow.job.status.unknown: Inconnu
|
||||
coderhapsodie.ezdataflow.history.job.title: 'Exécution'
|
||||
coderhapsodie.ezdataflow.history.details.title: 'Détails de l''exécution'
|
||||
coderhapsodie.ezdataflow.history.details.name: Nom
|
||||
coderhapsodie.ezdataflow.history.details.request: 'Demandé le'
|
||||
coderhapsodie.ezdataflow.history.details.status: État
|
||||
coderhapsodie.ezdataflow.history.details.start: 'Commencé le'
|
||||
coderhapsodie.ezdataflow.history.details.end: 'Terminé le'
|
||||
coderhapsodie.ezdataflow.history.details.count: 'Nombre d''objets mis à jour'
|
||||
coderhapsodie.ezdataflow.history.details.options: 'Options de lancement'
|
||||
coderhapsodie.ezdataflow.history.details.errors: Erreurs
|
||||
coderhapsodie.ezdataflow.history.details.type: 'Nom du dataflow exécuté'
|
||||
coderhapsodie.ezdataflow.history.details.log: 'Voir le log'
|
||||
coderhapsodie.ezdataflow.workflow.repeating.new.title: 'Nouvel programmation d''un dataflow récurrent'
|
||||
coderhapsodie.ezdataflow.workflow.new.cancel: Annuler
|
||||
coderhapsodie.ezdataflow.workflow.new.submit: Créer
|
||||
coderhapsodie.ezdataflow.history.list.empty: 'Aucune exécution pour le moment.'
|
||||
coderhapsodie.ezdataflow.workflow.list.empty: 'Aucun dataflow n''a été programmé.'
|
||||
coderhapsodie.ezdataflow.workflow.history.title: 'Historique des exécutions'
|
||||
coderhapsodie.ezdataflow.workflow.log.title: 'Log de l''exécution'
|
||||
coderhapsodie.ezdataflow.workflow.list.delete: Supprimer
|
||||
coderhapsodie.ezdataflow.workflow.delete: 'Êtes-vous sûr de vouloir supprimer ce dataflow ?'
|
||||
coderhapsodie.ezdataflow.workflow.create.success: 'La programmation du dataflow a bien été ajoutée.'
|
||||
coderhapsodie.ezdataflow.workflow.create.error: 'Une erreur est survenue lors de l''ajout de la programmation du dataflow : "%message%".'
|
||||
coderhapsodie.ezdataflow.workflow.delete.success: 'La programmation du dataflow a bien été supprimée.'
|
||||
coderhapsodie.ezdataflow.workflow.delete.error: 'Une erreur est survenue lors de la suppression de la programmation du dataflow : "%message%".'
|
||||
coderhapsodie.ezdataflow.workflow.oneshot.new.title: 'Nouvelle exécution ponctuelle'
|
||||
coderhapsodie.ezdataflow.job.create.success: 'Votre exécution a bien été ajoutée.'
|
||||
coderhapsodie.ezdataflow.job.create.error: 'Une erreur est survenue lors de l''ajout de l''exécution : "%message%".'
|
||||
coderhapsodie.ibexa_dataflow: Ibexa Dataflow
|
||||
coderhapsodie.ibexa_dataflow.yes: Oui
|
||||
coderhapsodie.ibexa_dataflow.no: Non
|
||||
coderhapsodie.ibexa_dataflow.repeating: Récurrent
|
||||
coderhapsodie.ibexa_dataflow.repeating.title: Récurrent
|
||||
coderhapsodie.ibexa_dataflow.oneshot: Ponctuel
|
||||
coderhapsodie.ibexa_dataflow.oneshot.title: Ponctuel
|
||||
coderhapsodie.ibexa_dataflow.oneshot.list.title: 'Liste des exécutions ponctuelles de dataflow'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.title: 'Liste des programmations des dataflow'
|
||||
coderhapsodie.ibexa_dataflow.history: Historique
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.name: Nom
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.frequency: Fréquence
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.next_execution: 'Prochaine exécution'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.enabled: 'Activé ?'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.history: Historique
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.edit: Éditer
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.disable: Désactiver
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.enable: Activer
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.runonce: Lancer maintenant
|
||||
coderhapsodie.ibexa_dataflow.history.title: Historique
|
||||
coderhapsodie.ibexa_dataflow.history.list.title: 'Liste des exécutions'
|
||||
coderhapsodie.ibexa_dataflow.history.list.name: Nom
|
||||
coderhapsodie.ibexa_dataflow.history.list.request: 'Demandé le'
|
||||
coderhapsodie.ibexa_dataflow.history.list.count: 'Nombre de succès'
|
||||
coderhapsodie.ibexa_dataflow.history.list.errors: 'Nombre d''erreurs'
|
||||
coderhapsodie.ibexa_dataflow.history.list.start: 'Commencé le'
|
||||
coderhapsodie.ibexa_dataflow.history.list.end: 'Terminé le'
|
||||
coderhapsodie.ibexa_dataflow.history.list.view: 'Voir le détail'
|
||||
coderhapsodie.ibexa_dataflow.history.list.status: État
|
||||
coderhapsodie.ibexa_dataflow.history.filter.label: Filtrer les résultats
|
||||
coderhapsodie.ibexa_dataflow.history.filter.none: Tous les résultats
|
||||
coderhapsodie.ibexa_dataflow.history.filter.non_empty_only: Seulement non vides
|
||||
coderhapsodie.ibexa_dataflow.history.filter.with_error_only: Seulement avec erreurs
|
||||
coderhapsodie.ibexa_dataflow.job.status.pending: 'En attente'
|
||||
coderhapsodie.ibexa_dataflow.job.status.running: 'En cours'
|
||||
coderhapsodie.ibexa_dataflow.job.status.complete: Terminé
|
||||
coderhapsodie.ibexa_dataflow.job.status.unknown: Inconnu
|
||||
coderhapsodie.ibexa_dataflow.history.job.title: 'Exécution'
|
||||
coderhapsodie.ibexa_dataflow.history.details.title: 'Détails de l''exécution'
|
||||
coderhapsodie.ibexa_dataflow.history.details.name: Nom
|
||||
coderhapsodie.ibexa_dataflow.history.details.request: 'Demandé le'
|
||||
coderhapsodie.ibexa_dataflow.history.details.status: État
|
||||
coderhapsodie.ibexa_dataflow.history.details.start: 'Commencé le'
|
||||
coderhapsodie.ibexa_dataflow.history.details.end: 'Terminé le'
|
||||
coderhapsodie.ibexa_dataflow.history.details.count: 'Nombre d''objets mis à jour'
|
||||
coderhapsodie.ibexa_dataflow.history.details.options: 'Options de lancement'
|
||||
coderhapsodie.ibexa_dataflow.history.details.errors: Erreurs
|
||||
coderhapsodie.ibexa_dataflow.history.details.type: 'Nom du dataflow exécuté'
|
||||
coderhapsodie.ibexa_dataflow.history.details.log: 'Voir le log'
|
||||
coderhapsodie.ibexa_dataflow.workflow.repeating.new.title: 'Nouvel programmation d''un dataflow récurrent'
|
||||
coderhapsodie.ibexa_dataflow.workflow.new.cancel: Annuler
|
||||
coderhapsodie.ibexa_dataflow.workflow.new.submit: Créer
|
||||
coderhapsodie.ibexa_dataflow.history.list.empty: 'Aucune exécution pour le moment.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.empty: 'Aucun dataflow n''a été programmé.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.history.title: 'Historique des exécutions'
|
||||
coderhapsodie.ibexa_dataflow.workflow.log.title: 'Log de l''exécution'
|
||||
coderhapsodie.ibexa_dataflow.workflow.list.delete: Supprimer
|
||||
coderhapsodie.ibexa_dataflow.workflow.delete: 'Êtes-vous sûr de vouloir supprimer ce dataflow ?'
|
||||
coderhapsodie.ibexa_dataflow.workflow.create.success: 'La programmation du dataflow a bien été ajoutée.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.create.error: 'Une erreur est survenue lors de l''ajout de la programmation du dataflow : "%message%".'
|
||||
coderhapsodie.ibexa_dataflow.workflow.delete.success: 'La programmation du dataflow a bien été supprimée.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.delete.error: 'Une erreur est survenue lors de la suppression de la programmation du dataflow : "%message%".'
|
||||
coderhapsodie.ibexa_dataflow.workflow.oneshot.new.title: 'Nouvelle exécution ponctuelle'
|
||||
coderhapsodie.ibexa_dataflow.job.create.success: 'Votre exécution a bien été ajoutée.'
|
||||
coderhapsodie.ibexa_dataflow.job.create.error: 'Une erreur est survenue lors de l''ajout de l''exécution : "%message%".'
|
||||
coderhapsodie.dataflow.label: 'Nom de la programmation du dataflow'
|
||||
coderhapsodie.dataflow.oneshot.label: 'Nom de l''exécution ponctuelle du dataflow'
|
||||
coderhapsodie.dataflow.dataflowType: 'Dataflow à exécuter'
|
||||
@@ -74,9 +75,13 @@ coderhapsodie.dataflow.frequency.title: 'Entrez un intervalle compatible avec st
|
||||
coderhapsodie.dataflow.frequency.placeholder: 'Exemple: 1 year 2 months 3 weeks 4 days 5 hours 6 minutes'
|
||||
coderhapsodie.dataflow.create.next: 'Première exécution'
|
||||
coderhapsodie.dataflow.create.enabled: 'Activé ?'
|
||||
coderhapsodie.ezdataflow.workflow.repeating.edit.title: "Édition de la programmation d'un dataflow"
|
||||
coderhapsodie.ezdataflow.workflow.edit.submit: Sauvegarder
|
||||
coderhapsodie.ibexa_dataflow.workflow.repeating.edit.title: "Édition de la programmation d'un dataflow"
|
||||
coderhapsodie.ibexa_dataflow.workflow.edit.submit: Sauvegarder
|
||||
coderhapsodie.dataflow.update.next: 'Prochaine exécution'
|
||||
coderhapsodie.ezdataflow.workflow.edit.success: 'La programmation du dataflow a été mise à jour avec succès.'
|
||||
coderhapsodie.ezdataflow.workflow.edit.error: 'Une erreur est survenue lors de la modification de la programmation du dataflow : "%message%".'
|
||||
coderhapsodie.ezdataflow.notfound: 'Les données demandées sont introuvables'
|
||||
coderhapsodie.ibexa_dataflow.workflow.edit.success: 'La programmation du dataflow a été mise à jour avec succès.'
|
||||
coderhapsodie.ibexa_dataflow.workflow.edit.error: 'Une erreur est survenue lors de la modification de la programmation du dataflow : "%message%".'
|
||||
coderhapsodie.ibexa_dataflow.notfound: 'Les données demandées sont introuvables'
|
||||
coderhapsodie.ibexa_dataflow.powered_by: 'Propulsé par'
|
||||
coderhapsodie.ibexa_dataflow.made_by: 'Fabriqué par'
|
||||
coderhapsodie.ibexa_dataflow.dashboard: Dashboard
|
||||
coderhapsodie.ibexa_dataflow.dashboard.title: Tâches en cours ou en attente
|
||||
@@ -1,112 +0,0 @@
|
||||
{% extends "@ibexadesign/ui/layout.html.twig" %}
|
||||
|
||||
{% block body_class %}ibexa-ezdataflow{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{% include '@ibexadesign/ui/breadcrumbs.html.twig' with { items: [
|
||||
{ value: 'breadcrumb.admin'|trans(domain='messages')|desc('Admin') },
|
||||
{ value: 'coderhapsodie.ezdataflow'|trans|desc('EzDataflow') }
|
||||
]} %}
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% include '@ibexadesign/ui/page_title.html.twig' with {
|
||||
title: 'coderhapsodie.ezdataflow'|trans|desc('EzDataflow'),
|
||||
} %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ ibexa_render_component_group('coderhapsodie-ezdataflow', {'filter': app.request.query.get('filter', 0)}) }}
|
||||
|
||||
{% embed '@ibexadesign/ui/component/modal/modal.html.twig' with {
|
||||
id: 'modal-history-details',
|
||||
attr_dialog: {'style': 'max-width: 75vw;'},
|
||||
title: 'coderhapsodie.ezdataflow.history.job.title'|trans,
|
||||
} %}
|
||||
{% block body_content '' %}
|
||||
{% endembed %}
|
||||
|
||||
{% embed '@ibexadesign/ui/component/modal/modal.html.twig' with {
|
||||
id: 'modal-history-log',
|
||||
attr_dialog: {'style': 'max-width: 75vw;'},
|
||||
title: 'coderhapsodie.ezdataflow.workflow.log.title'|trans,
|
||||
} %}
|
||||
{% block body_content '' %}
|
||||
{% endembed %}
|
||||
|
||||
{% embed '@ibexadesign/ui/component/modal/modal.html.twig' with {
|
||||
id: 'modal-history',
|
||||
attr_dialog: {'style': 'max-width: 75vw;'},
|
||||
title: 'coderhapsodie.ezdataflow.workflow.history.title'|trans,
|
||||
} %}
|
||||
{% block body_content '' %}
|
||||
{% endembed %}
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const bindModalLinks = (modalId, linkSelector) => {
|
||||
const modal = document.getElementById(modalId);
|
||||
const modalBody = modal.querySelector('.modal-body');
|
||||
document.addEventListener('click', (e) => {
|
||||
const link = e.target.closest(linkSelector);
|
||||
if (link) {
|
||||
e.preventDefault();
|
||||
modalBody.innerHTML = '';
|
||||
fetch(link.href)
|
||||
.then((r) => r.text())
|
||||
.then((content) => {
|
||||
modalBody.innerHTML = content;
|
||||
})
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
bindModalLinks('modal-history-details', '.modal-history-details');
|
||||
bindModalLinks('modal-history-log', '.modal-history-log');
|
||||
bindModalLinks('modal-history', '.modal-history');
|
||||
|
||||
const labels = document.getElementById('ibexa-tab-label-coderhapsodie-ezdataflow-code-rhapsodie-ezdataflow-repeating')
|
||||
.closest('ul').querySelectorAll('li.ibexa-tabs__tab');
|
||||
const tabs = document.getElementById('ibexa-tab-coderhapsodie-ezdataflow-code-rhapsodie-ezdataflow-repeating')
|
||||
.closest('.tab-content').querySelectorAll('.tab-pane');
|
||||
|
||||
// Manage ajax pagination
|
||||
document.addEventListener('click', (e) => {
|
||||
const link = e.target.closest('.ibexa-pagination a');
|
||||
if (!link) {
|
||||
return;
|
||||
}
|
||||
|
||||
const block = link.closest('.ibexa-pagination').parentNode.parentNode;
|
||||
const display = block.querySelector('.ibexa-table');
|
||||
const pagination = block.querySelector('.pag');
|
||||
const loader = document.querySelector('#' + block.dataset.loader);
|
||||
e.preventDefault();
|
||||
loader.hidden = false;
|
||||
display.innerHTML = '';
|
||||
pagination.innerHTML = '';
|
||||
fetch(link.href)
|
||||
.then((r) => r.text())
|
||||
.then((content) => {
|
||||
const node = document.createElement('div');
|
||||
node.innerHTML = content;
|
||||
display.innerHTML = node.querySelector('#' + block.id).querySelector('.ibexa-table').innerHTML;
|
||||
pagination.innerHTML = node.querySelector('#' + block.id).querySelector('.pag').innerHTML;
|
||||
loader.hidden = true;
|
||||
})
|
||||
;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block stylesheets %}
|
||||
{{ parent() }}
|
||||
<style>
|
||||
.ezdataflow-date .ibexa-dropdown {
|
||||
min-width: 0;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
@@ -1,5 +0,0 @@
|
||||
{% include '@ibexadesign/ezdataflow/parts/tab/job_list.html.twig' with {
|
||||
identifier: 'ezdataflow_schedule_history_results',
|
||||
paginate_route: 'coderhapsodie.ezdataflow.history.workflow',
|
||||
paginate_params: {id: id}
|
||||
} %}
|
||||
@@ -1,59 +0,0 @@
|
||||
{% import '@ibexadesign/ezdataflow/macros.twig' as macros %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container ez-main-container history-details-aware">
|
||||
{% if item is not null %}
|
||||
<h2>{{ 'coderhapsodie.ezdataflow.history.job.title'|trans }} n°{{ item.id }}</h2>
|
||||
|
||||
<table class="table ez-table ez-table--list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
{{ 'coderhapsodie.ezdataflow.history.details.title'|trans }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.name'|trans }}</td>
|
||||
<td>{{ item.label }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.request'|trans }}</td>
|
||||
<td>{{ date(item.requestedDate)|ibexa_short_datetime }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.status'|trans }}</td>
|
||||
<td>{{ macros.translateStatus(item.status) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.start'|trans }}</td>
|
||||
<td>{{ item.startTime ? date(item.startTime)|ibexa_short_datetime : '—' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.end'|trans }}</td>
|
||||
<td>{{ item.endTime ? date(item.endTime)|ibexa_short_datetime : '—' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.count'|trans }}</td>
|
||||
<td>{{ item.count }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.errors'|trans }}</td>
|
||||
<td>{{ item.exceptions|length }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.type'|trans }}</td>
|
||||
<td>{{ item.dataflowType }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'coderhapsodie.ezdataflow.history.details.options'|trans }}</td>
|
||||
<td>{{ item.options|json_encode }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="ez-table-no-content">{{ 'coderhapsodie.ezdataflow.notfound'|trans }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,11 +0,0 @@
|
||||
{% macro translateStatus(status) %}
|
||||
{% if status == 0 %}
|
||||
{{ 'coderhapsodie.ezdataflow.job.status.pending'|trans }}
|
||||
{% elseif status == 1 %}
|
||||
{{ 'coderhapsodie.ezdataflow.job.status.running'|trans }}
|
||||
{% elseif status == 2 %}
|
||||
{{ 'coderhapsodie.ezdataflow.job.status.complete'|trans }}
|
||||
{% else %}
|
||||
{{ 'coderhapsodie.ezdataflow.job.status.unknown'|trans }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{%- block content -%}
|
||||
{% include '@ibexadesign/ibexa_dataflow/parts/tab/dashboard_list.html.twig' with {
|
||||
identifier: 'ibexa_dataflow_schedule_dashboard_results',
|
||||
} %}
|
||||
{%- endblock -%}
|
||||
@@ -2,16 +2,16 @@
|
||||
{% set choices = [
|
||||
{
|
||||
'value': 0,
|
||||
'label': 'coderhapsodie.ezdataflow.history.filter.none'|trans,
|
||||
'label': 'coderhapsodie.ibexa_dataflow.history.filter.none'|trans,
|
||||
},
|
||||
{
|
||||
'value': 1,
|
||||
'label': 'coderhapsodie.ezdataflow.history.filter.non_empty_only'|trans,
|
||||
'label': 'coderhapsodie.ibexa_dataflow.history.filter.non_empty_only'|trans,
|
||||
},
|
||||
] %}
|
||||
|
||||
{% set source %}
|
||||
<select id="ezdataflow_history_filter" class="form-control ibexa-input">
|
||||
<select id="ibexa_dataflow_history_filter" class="form-control ibexa-input">
|
||||
{% for choice in choices %}
|
||||
<option value="{{ choice.value }}">
|
||||
{{ choice.label }}
|
||||
@@ -28,32 +28,32 @@
|
||||
}) }}
|
||||
{% endset %}
|
||||
|
||||
{{ include('@ibexadesign/ezdataflow/parts/tab/job_list.html.twig', {
|
||||
identifier: 'ezdataflow_history_results',
|
||||
paginate_route: 'coderhapsodie.ezdataflow.history',
|
||||
{{ include('@ibexadesign/ibexa_dataflow/parts/tab/job_list.html.twig', {
|
||||
identifier: 'ibexa_dataflow_history_results',
|
||||
paginate_route: 'coderhapsodie.ibexa_dataflow.history',
|
||||
paginate_params: {'filter': filter},
|
||||
headline: 'coderhapsodie.ezdataflow.history.title'|trans,
|
||||
headline: 'coderhapsodie.ibexa_dataflow.history.title'|trans,
|
||||
actions: actions
|
||||
}) }}
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Manage ajax pagination
|
||||
document.getElementById('ezdataflow_history_filter').addEventListener('change', function (e) {
|
||||
document.getElementById('ibexa_dataflow_history_filter').addEventListener('change', function (e) {
|
||||
e.preventDefault();
|
||||
const loading = document.getElementById('loading_ezdataflow_history_results');
|
||||
const results = document.getElementById('ezdataflow_history_results').querySelector('.ibexa-table');
|
||||
const pagination = document.getElementById('ezdataflow_history_results').querySelector('.pag');
|
||||
const loading = document.getElementById('loading_ibexa_dataflow_history_results');
|
||||
const results = document.getElementById('ibexa_dataflow_history_results').querySelector('.ibexa-table');
|
||||
const pagination = document.getElementById('ibexa_dataflow_history_results').querySelector('.pag');
|
||||
loading.hidden = false;
|
||||
results.innerHTML = '';
|
||||
pagination.innerHTML = '';
|
||||
fetch('{{ path('coderhapsodie.ezdataflow.history') }}?filter=' + this.value)
|
||||
fetch('{{ path('coderhapsodie.ibexa_dataflow.history') }}?filter=' + this.value)
|
||||
.then((r) => r.text())
|
||||
.then((content) => {
|
||||
const node = document.createElement('div');
|
||||
node.innerHTML = content;
|
||||
results.innerHTML = node.querySelector('#ezdataflow_history_results .ibexa-table').innerHTML;
|
||||
pagination.innerHTML = node.querySelector('#ezdataflow_history_results .pag').innerHTML;
|
||||
results.innerHTML = node.querySelector('#ibexa_dataflow_history_results .ibexa-table').innerHTML;
|
||||
pagination.innerHTML = node.querySelector('#ibexa_dataflow_history_results .pag').innerHTML;
|
||||
loading.hidden = true;
|
||||
})
|
||||
;
|
||||
@@ -1,29 +1,30 @@
|
||||
{%- block content -%}
|
||||
{% set actions %}
|
||||
<button
|
||||
type="button"
|
||||
class="btn ibexa-btn ibexa-btn--tertiary ibexa-btn--small"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modal-new-oneshot"
|
||||
id="create-oneshot-button"
|
||||
type="button"
|
||||
class="btn ibexa-btn ibexa-btn--tertiary ibexa-btn--small"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#modal-new-oneshot"
|
||||
>
|
||||
<svg class="ibexa-icon ibexa-icon--small ibexa-icon--create">
|
||||
<use xlink:href="{{ ibexa_icon_path('create') }}"></use>
|
||||
</svg>
|
||||
<span class="ibexa-btn__label">
|
||||
{{ 'coderhapsodie.ezdataflow.workflow.new.submit'|trans|desc('Create') }}
|
||||
{{ 'coderhapsodie.ibexa_dataflow.workflow.new.submit'|trans|desc('Create') }}
|
||||
</span>
|
||||
</button>
|
||||
{% endset %}
|
||||
|
||||
{{ include('@ibexadesign/ezdataflow/parts/tab/job_list.html.twig', {
|
||||
identifier: 'ezdataflow_oneshot_history',
|
||||
paginate_route: 'coderhapsodie.ezdataflow.oneshot',
|
||||
headline: 'coderhapsodie.ezdataflow.oneshot.title'|trans,
|
||||
{{ include('@ibexadesign/ibexa_dataflow/parts/tab/job_list.html.twig', {
|
||||
identifier: 'ibexa_dataflow_oneshot_history',
|
||||
paginate_route: 'coderhapsodie.ibexa_dataflow.oneshot',
|
||||
headline: 'coderhapsodie.ibexa_dataflow.oneshot.title'|trans,
|
||||
actions: actions,
|
||||
}) }}
|
||||
|
||||
{% if form is defined %}
|
||||
{{ include('@ibexadesign/ezdataflow/parts/form_modal.html.twig', {
|
||||
{{ include('@ibexadesign/ibexa_dataflow/parts/form_modal.html.twig', {
|
||||
'id': 'modal-new-oneshot',
|
||||
'form': form,
|
||||
'mode': 'oneshot'
|
||||
@@ -53,6 +54,16 @@
|
||||
})
|
||||
;
|
||||
});
|
||||
const createButton = document.getElementById('create-oneshot-button')
|
||||
|
||||
if (createButton) {
|
||||
createButton.addEventListener('click', () => {
|
||||
const oneShotModal = document.getElementById('modal-new-oneshot');
|
||||
oneShotModal.querySelector('#create_oneshot_label').value = '';
|
||||
oneShotModal.querySelector('#create_oneshot_options').value = '';
|
||||
oneShotModal.querySelector('#create_oneshot_requestedDate').closest('.ibexa-picker').querySelector('.ibexa-date-time-picker').ibexaInstance.flatpickrInstance.setDate(new Date(), true);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{%- endblock -%}
|
||||