Skip to content

Commit

Permalink
Ibexa 4 support (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremycr authored Jul 21, 2023
1 parent 2274bbf commit d0367d7
Show file tree
Hide file tree
Showing 60 changed files with 813 additions and 762 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-version: [7.3, 7.4, 8.0, 8.1]
php-version: [7.4, 8.0, 8.1, 8.2]

runs-on: ubuntu-latest

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Version 4.0.0

* Add compatibility with Ibexa 4.0+ and drop compatibility for eZPlatform 2 and Ibexa 3

# Version 3.2.0

* Fixed History page pagination is hidden by footer on Ibexa 3.3 #38
Expand Down
47 changes: 13 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Code Rhapsodie eZ Dataflow Bundle

EzDataflowBundle is a bundle integrating [Code Rhapsodie Dataflow bundle](https://github.com/code-rhapsodie/dataflow-bundle) into eZ Platfom 2.0+.
Dataflows can be piloted from an interface integrated in eZ Platform backoffice.
EzDataflowBundle is a bundle integrating [Code Rhapsodie Dataflow bundle](https://github.com/code-rhapsodie/dataflow-bundle) into Ibexa 4.0+.
Dataflows can be piloted from an interface integrated into the Ibexa backoffice.
EzDataflow bundle is intended to manage content imports from external data sources.

> Note: before using this bundle, please read the [Code Rhapsodie Dataflow bundle documentation](https://github.com/code-rhapsodie/dataflow-bundle/blob/master/README.md).
Expand All @@ -28,9 +28,7 @@ $ composer require code-rhapsodie/ezdataflow-bundle

> Note: The loading order between the Dataflow bundle and Ez Dataflow bundle is important. Dataflow must be loaded first.
#### Symfony 4 (new tree)

For Symfony 4, add those two lines in the `config/bundles.php` file:
Add those two lines in the `config/bundles.php` file:

```php
<?php
Expand All @@ -43,29 +41,10 @@ return [
];
```

#### Symfony 3.4 (old tree)

For Symfony 3.4, add those two lines in the `app/AppKernel.php` file:

```php
<?php
// app/AppKernel.php

public function registerBundles()
{
$bundles = [
// ...
new CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle(),
new CodeRhapsodie\EzDataflowBundle\CodeRhapsodieEzDataflowBundle(),
// ...
];
}
```

### Step 3: Import bundle routing file

```yaml
# app/config/routing.yml or config/routing.yaml
# config/routing/ezdataflow.yaml

_cr.dataflow:
resource: '@CodeRhapsodieEzDataflowBundle/Resources/config/routing.yaml'
Expand All @@ -84,7 +63,7 @@ Please refer to the [Code-Rhapsodie Dataflow Bundle Queue section](https://githu
By default, the `ContentWriter` will publish contents using the `admin` user. If you want to use another user (with sufficient permissions), you can configure it like this:

```yaml
# app/config/config.yml or config/packages/code_rhapsodie_ez_dataflow.yaml
# config/packages/code_rhapsodie_ez_dataflow.yaml
code_rhapsodie_ez_dataflow:
# Integer values are assumed to be user ids, non-integer values are assumed to be user logins
Expand All @@ -97,7 +76,7 @@ Before using the admin UI to manage your dataflows, you need to define them. Ple

## Use the ContentWriter

To add or update eZ Platform contents, you can use the `CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter` writer.
To add or update Ibexa contents, you can use the `CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter` writer.

### Step 1: Inject the dependencies and add the writer

Expand Down Expand Up @@ -133,27 +112,27 @@ class MyDataflowType extends AbstractDataflowType

### Step 2: Add a step for prepare the content

To process eZ Platform content into your Dataflow, you need to transform the data into `ContentCreateStructure` or `ContentUpdateStructure` objects.
To process Ibexa contents into your Dataflow, you need to transform the data into `ContentCreateStructure` or `ContentUpdateStructure` objects.
in order to respectively create or update contents.

But, in order to determine if the content already exists or not, you first need to look up for it.

One way is to use the remote id to search for the content.

In the following example, the remote id pattern is `article-<id>` with the `<id>` replaced by the data id provided by the reader.
To check if the content exists or not, I use the service `ContentService` provided by eZ Platform.
To check if the content exists or not, I use the service `ContentService` provided by Ibexa.

The step is added as an anonymous function and has 3 types of return values:

* When the step returns `false`, the data is dropped.
* When the step returns a `ContentCreateStructure`, the data will be saved into a new eZ Platform content.
* When the step returns a `ContentUpdateStructure`, the existing eZ Platform content will be updated by overwriting all defined fields in the data.
* When the step returns a `ContentCreateStructure`, the data will be saved into a new Ibexa content.
* When the step returns a `ContentUpdateStructure`, the existing Ibexa content will be updated by overwriting all defined fields in the data.

For the new content, you must provide one or more "parent location id" as the 3rd argument of the `ContentCreateStructure` constructor.

In this example, I have added a new folder to store all articles.

To get the location id of the parent eZ Platform content, go to the admin UI and select the future parent content, click on the details tabs, and read the "Location id" like this:
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:

![parent folder](src/Resources/doc/dest_folder.jpg)

Expand Down Expand Up @@ -272,7 +251,7 @@ If you want to add support for a field type, simply create your own comparator.
<?php
use CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator;
use eZ\Publish\Core\FieldType\Value;
use Ibexa\Core\FieldType\Value;
//[...]
class MyFieldComparator extends AbstractFieldComparator
Expand All @@ -298,7 +277,7 @@ class MyFieldComparator extends AbstractFieldComparator

## Access to the eZ Dataflow UI

You can access the eZ Dataflow administration UI from your eZ Platform admin back-office.
You can access the eZ Dataflow administration UI from your Ibexa admin back-office.

![Admin menu](src/Resources/doc/ez_dataflow_admin_menu.jpg)

Expand Down
19 changes: 11 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "code-rhapsodie/ezdataflow-bundle",
"description": "Import/export bundle for eZ Platform based on Code-Rhapsodie Dataflow",
"description": "Import/export bundle for Ibexa based on Code-Rhapsodie Dataflow",
"type": "symfony-bundle",
"keywords": ["dataflow", "import", "export", "data processing", "ez publish", "ez platform"],
"keywords": ["dataflow", "import", "export", "data processing", "ibexa"],
"license": "MIT",
"authors": [
{
Expand Down Expand Up @@ -41,14 +41,15 @@
}
},
"require": {
"php": "^7.3||^8.0",
"php": "^7.4||^8.0",
"code-rhapsodie/dataflow-bundle": "^3.0",
"ezsystems/ezplatform-admin-ui": "^2.3",
"ezsystems/ezplatform-kernel": "^1.3"
"http-interop/http-factory-guzzle": "^1.2",
"ibexa/admin-ui": "^4.0",
"ibexa/core": "^4.0"
},
"require-dev": {
"phpunit/phpunit": "^7||^8||^9",
"doctrine/dbal": "^2.0"
"doctrine/dbal": "^2.0|^3.0",
"phpunit/phpunit": "^7||^8||^9"
},
"minimum-stability": "dev",
"prefer-stable": true,
Expand All @@ -60,7 +61,9 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.x-dev",
"dev-master": "4.x-dev",
"dev-v3.x": "3.x-dev",
"dev-v2.x": "2.x-dev",
"dev-v1.x": "1.x-dev"
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/CodeRhapsodieEzDataflowBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use CodeRhapsodie\EzDataflowBundle\DependencyInjection\CodeRhapsodieEzDataflowExtension;
use CodeRhapsodie\EzDataflowBundle\DependencyInjection\Compiler\FieldComparatorCompilerPass;
use CodeRhapsodie\EzDataflowBundle\Security\PolicyProvider;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\EzPublishCoreExtension;
use Ibexa\Bundle\Core\DependencyInjection\IbexaCoreExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

Expand All @@ -26,8 +26,8 @@ public function build(ContainerBuilder $container)

$container->addCompilerPass(new FieldComparatorCompilerPass());

/** @var EzPublishCoreExtension $eZExtension */
$eZExtension = $container->getExtension('ezpublish');
$eZExtension->addPolicyProvider(new PolicyProvider());
/** @var IbexaCoreExtension $ibexaExtension */
$ibexaExtension = $container->getExtension('ibexa');
$ibexaExtension->addPolicyProvider(new PolicyProvider());
}
}
28 changes: 14 additions & 14 deletions src/Controller/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
use CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway;
use CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway;
use Doctrine\DBAL\Query\QueryBuilder;
use eZ\Publish\Core\MVC\Symfony\Security\Authorization\Attribute;
use EzSystems\EzPlatformAdminUiBundle\Controller\Controller;
use Pagerfanta\Adapter\DoctrineDbalAdapter;
use Ibexa\Contracts\AdminUi\Controller\Controller;
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;
Expand All @@ -24,9 +24,9 @@
*/
class DashboardController extends Controller
{
/** @var JobGateway */
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway */
private $jobGateway;
/** @var ScheduledDataflowGateway */
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\ScheduledDataflowGateway */
private $scheduledDataflowGateway;

public function __construct(JobGateway $jobGateway, ScheduledDataflowGateway $scheduledDataflowGateway)
Expand All @@ -42,7 +42,7 @@ public function main(): Response
{
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));

return $this->render('@ezdesign/ezdataflow/Dashboard/main.html.twig');
return $this->render('@ibexadesign/ezdataflow/Dashboard/main.html.twig');
}

public function repeating(Request $request): Response
Expand All @@ -55,7 +55,7 @@ public function repeating(Request $request): Response
'action' => $this->generateUrl('coderhapsodie.ezdataflow.workflow.create'),
]);

return $this->render('@ezdesign/ezdataflow/Dashboard/repeating.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/repeating.html.twig', [
'pager' => $this->getPager($this->scheduledDataflowGateway->getListQueryForAdmin(), $request),
'form' => $form->createView(),
]);
Expand All @@ -68,7 +68,7 @@ public function getRepeatingPage(Request $request): Response
{
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));

return $this->render('@ezdesign/ezdataflow/Dashboard/repeating.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/repeating.html.twig', [
'pager' => $this->getPager($this->scheduledDataflowGateway->getListQueryForAdmin(), $request),
]);
}
Expand All @@ -83,7 +83,7 @@ public function oneshot(Request $request): Response
'action' => $this->generateUrl('coderhapsodie.ezdataflow.job.create'),
]);

return $this->render('@ezdesign/ezdataflow/Dashboard/oneshot.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/oneshot.html.twig', [
'pager' => $this->getPager($this->jobGateway->getOneshotListQueryForAdmin(), $request),
'form' => $form->createView(),
]);
Expand All @@ -96,7 +96,7 @@ public function getOneshotPage(Request $request): Response
{
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));

return $this->render('@ezdesign/ezdataflow/Dashboard/oneshot.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/oneshot.html.twig', [
'pager' => $this->getPager($this->jobGateway->getOneshotListQueryForAdmin(), $request),
]);
}
Expand All @@ -106,7 +106,7 @@ public function history(Request $request): Response
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
$filter = (int) $request->query->get('filter', JobGateway::FILTER_NONE);

return $this->render('@ezdesign/ezdataflow/Dashboard/history.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/history.html.twig', [
'pager' => $this->getPager($this->jobGateway->getListQueryForAdmin($filter), $request),
'filter' => $filter,
]);
Expand All @@ -120,7 +120,7 @@ public function getHistoryPage(Request $request): Response
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));
$filter = (int) $request->query->get('filter', JobGateway::FILTER_NONE);

return $this->render('@ezdesign/ezdataflow/Dashboard/history.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/history.html.twig', [
'pager' => $this->getPager($this->jobGateway->getListQueryForAdmin($filter), $request),
'filter' => $filter,
]);
Expand All @@ -133,15 +133,15 @@ public function getHistoryForScheduled(Request $request, int $id): Response
{
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));

return $this->render('@ezdesign/ezdataflow/Dashboard/schedule_history.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Dashboard/schedule_history.html.twig', [
'id' => $id,
'pager' => $this->getPager($this->jobGateway->getListQueryForScheduleAdmin($id), $request),
]);
}

private function getPager(QueryBuilder $query, Request $request): Pagerfanta
{
$pager = new Pagerfanta(new DoctrineDbalAdapter($query, function ($queryBuilder) {
$pager = new Pagerfanta(new QueryAdapter($query, function ($queryBuilder) {
return $queryBuilder->select('COUNT(DISTINCT id) AS total_results')
->resetQueryPart('orderBy')
->setMaxResults(1);
Expand Down
20 changes: 10 additions & 10 deletions src/Controller/JobController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
use CodeRhapsodie\DataflowBundle\Entity\Job;
use CodeRhapsodie\EzDataflowBundle\Form\CreateOneshotType;
use CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway;
use eZ\Publish\Core\MVC\Symfony\Security\Authorization\Attribute;
use EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface;
use EzSystems\EzPlatformAdminUiBundle\Controller\Controller;
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;
Expand All @@ -22,11 +22,11 @@
*/
class JobController extends Controller
{
/** @var JobGateway */
/** @var \CodeRhapsodie\EzDataflowBundle\Gateway\JobGateway */
private $jobGateway;
/** @var NotificationHandlerInterface */
/** @var \Ibexa\Contracts\AdminUi\Notification\NotificationHandlerInterface */
private $notificationHandler;
/** @var Symfony\Component\Translation\TranslatorInterface|Symfony\Contracts\Translation\TranslatorInterface */
/** @var \Symfony\Contracts\Translation\TranslatorInterface */
private $translator;

public function __construct(
Expand All @@ -46,7 +46,7 @@ public function displayDetails(int $id): Response
{
$this->denyAccessUnlessGranted(new Attribute('ezdataflow', 'view'));

return $this->render('@ezdesign/ezdataflow/Item/details.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Item/details.html.twig', [
'item' => $this->jobGateway->find($id),
]);
}
Expand All @@ -62,7 +62,7 @@ public function displayLog(int $id): Response
return preg_replace('~#\d+~', "\n$0", $line);
}, $item->getExceptions());

return $this->render('@ezdesign/ezdataflow/Item/log.html.twig', [
return $this->render('@ibexadesign/ezdataflow/Item/log.html.twig', [
'log' => $log,
]);
}
Expand All @@ -78,7 +78,7 @@ public function create(Request $request): Response
$form = $this->createForm(CreateOneshotType::class, $newOneshot);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Job $newOneshot */
/** @var \CodeRhapsodie\DataflowBundle\Entity\Job $newOneshot */
$newOneshot = $form->getData();
$newOneshot->setStatus(Job::STATUS_PENDING);

Expand All @@ -97,7 +97,7 @@ public function create(Request $request): Response
}

return new JsonResponse([
'form' => $this->renderView('@ezdesign/ezdataflow/parts/schedule_form.html.twig', [
'form' => $this->renderView('@ibexadesign/ezdataflow/parts/form_modal.html.twig', [
'form' => $form->createView(),
'type_action' => 'new',
'mode' => 'oneshot',
Expand Down
Loading

0 comments on commit d0367d7

Please sign in to comment.