code-rhapsodie / ezdataflow-bundle
基于 Code-Rhapsodie Dataflow 的 Ibexa 导入/导出包
Requires
- php: ^7.4||^8.0
- code-rhapsodie/dataflow-bundle: ^3.0||^4.0
- http-interop/http-factory-guzzle: ^1.2
- ibexa/admin-ui: ^4.0
- ibexa/core: ^4.0
Requires (Dev)
- doctrine/dbal: ^2.0|^3.0
- phpunit/phpunit: ^7||^8||^9
README
EzDataflowBundle 是一个将 Code Rhapsodie Dataflow bundle 集成到 Ibexa 4.0+ 中的包。可以从 Ibexa 后台集成界面中启动数据流。EzDataflow bundle 用于管理来自外部数据源的内容导入。
注意:在使用此包之前,请阅读 Code Rhapsodie Dataflow bundle 文档。
命令行注意事项:当您使用数据流命令时,除非是
code-rhapsodie:dataflow:dump-schema
命令,否则请使用--siteaccess
而不是--connection
。
用户界面 (UI)
该 UI 允许您从任何定义的 DataflowTypes
创建工作流程过程,并为每个设置选项。
过程可以设置为
- 仅运行一次,在指定的时间和日期
- 定期运行,通过定义首次运行的时间和日期以及后续运行之间的间隔
安装
步骤 1:通过 composer 安装包
$ composer require code-rhapsodie/ezdataflow-bundle
步骤 2:启用包
注意:数据流包和 Ez Dataflow 包的加载顺序很重要。数据流必须首先加载。
在 config/bundles.php
文件中添加以下两行
<?php return [ // ... CodeRhapsodie\DataflowBundle\CodeRhapsodieDataflowBundle::class => ['all' => true], CodeRhapsodie\EzDataflowBundle\CodeRhapsodieEzDataflowBundle::class => ['all' => true], // ... ];
步骤 3:导入包路由文件
# config/routing/ezdataflow.yaml _cr.dataflow: resource: '@CodeRhapsodieEzDataflowBundle/Resources/config/routing.yaml'
步骤 4:更新数据库模式
请参阅 Code-Rhapsodie Dataflow Bundle 安装指南。
步骤 5:安排作业运行器
请参阅 Code-Rhapsodie Dataflow Bundle 队列部分。
配置
默认情况下,ContentWriter
将使用 admin
用户发布内容。如果您想使用其他用户(具有足够的权限),可以按如下方式进行配置
# 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 admin_login_or_id: webmaster
定义您的数据流
在使用管理 UI 管理数据流之前,您需要定义它们。请参阅 Code-Rhapsodie Dataflow 类型文档。
使用 ContentWriter
要添加或更新 Ibexa 内容,您可以使用 CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter
编写器。
步骤 1:注入依赖项并添加编写器
将 ContentWriter
服务注入到您的 DataflowType 构造函数中,并将内容编写器添加到编写器列表中,如下所示
// In your DataflowType use CodeRhapsodie\EzDataflowBundle\Writer\ContentWriter; use CodeRhapsodie\DataflowBundle\DataflowType\AbstractDataflowType; [...] class MyDataflowType extends AbstractDataflowType { //[...] /** * @var ContentWriter */ private $contentWriter; public function __construct(ContentWriter $contentWriter) { $this->contentWriter = $contentWriter; } //[...] protected function buildDataflow(DataflowBuilder $builder, array $options): void { //[...] $builder->addWriter($this->contentWriter); } }
步骤 2:添加一个步骤来准备内容
要处理 Ibexa 内容并添加到您的数据流中,您需要将数据转换为 ContentCreateStructure
或 ContentUpdateStructure
对象。分别用于创建或更新内容。
但是,为了确定内容是否已经存在,您首先需要查找它。
一种方法是使用远程 id 搜索内容。
在以下示例中,远程 id 模式为 article-<id>
,其中 <id>
由读取器提供的数据 id 替换。为了检查内容是否存在,我使用 Ibexa 提供的 ContentService
服务。
该步骤作为匿名函数添加,有 3 种返回值类型
- 当步骤返回
false
时,数据将被丢弃。 - 当步骤返回一个
ContentCreateStructure
时,数据将被保存到一个新的 Ibexa 内容中。 - 当步骤返回
ContentUpdateStructure
时,现有Ibexa内容将通过覆盖数据中定义的所有字段来更新。
对于新内容,您必须提供一个或多个“父位置ID”,作为ContentCreateStructure
构造函数的第三个参数。
在这个例子中,我添加了一个新的文件夹来存储所有文章。
要获取父Ibexa内容的ID,请转到管理员UI,选择未来的父内容,点击“详细信息”标签,并像这样读取“位置ID”
注意:最佳实践是将此父ID定义在您的
parameters.yml
文件或每个执行环境的.env.local
文件中。
// In your DataflowType use CodeRhapsodie\EzDataflowBundle\Factory\ContentStructureFactory; use CodeRhapsodie\EzDataflowBundle\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; } //[...] protected function buildDataflow(DataflowBuilder $builder, array $options): void { //[...] $builder->addStep(function ($data) { if (!isset($data['id'])) { return false; } $remoteId = sprintf('article-%d', $data['id']); 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 ); }); // If you want the writer log $this->contentWriter->setLogger($this->logger); $builder->addWriter($this->contentWriter); } }
此示例使用ContentStructureFactory
来检查内容是否存在,并返回传递给内容编写器的适当ContentStrucure
。
使用NotModifiedContentFilter
在更新内容时,您可能想忽略更新不会导致字段值实际更改的内容。在这种情况下,您可以将NotModifiedContentFilter
添加为您的步骤之一。
// In your DataflowType public function __construct(NotModifiedContentFilter $notModifiedContentFilter) { $this->notModifiedContentFilter = $notModifiedContentFilter; } //[...] protected function buildDataflow(DataflowBuilder $builder, array $options): void { //[...] // If you want the filter log $this->notModifiedContentFilter->setLogger($this->logger); $builder->addStep($this->notModifiedContentFilter); //[...] }
此过滤器将接收到的ContentUpdateStructure
中的每个字段值与现有内容对象的字段值进行比较。如果所有值都相同,则此过滤器将返回false
,否则将按原样返回ContentUpdateStructure
。
并非所有字段类型都受此过滤器支持。如果字段类型不受支持,则假设值不同。如果您的数据流处理包含不受支持字段类型的内容类型,则最好根本不使用NotModifiedContentFilter
,以防止不必要的开销。
支持的字段类型
- ezstring
- ezauthor
- ezboolean
- ezcountry
- ezdate
- ezdatetime
- ezemail
- ezfloat
- ezisbn
- ezobjectrelation
- ezobjectrelationlist
- ezkeyword
- ezselection
- eztext
- eztime
- eztags
- novaseometas
- ezurl
- ezmatrix
- ezgmaplocation
- ezrichtext
添加自定义字段比较器
如果您想支持某种字段类型,只需创建自己的比较器。
<?php use CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator; use Ibexa\Core\FieldType\Value; //[...] class MyFieldComparator extends AbstractFieldComparator { //[...] protected function compareValues(Value $currentValue, Value $newValue): bool { // Return true if values are identical, false if values are different. } }
# Service declaration App\FieldComparator\MyFieldComparator: parent: 'CodeRhapsodie\EzDataflowBundle\Core\FieldComparator\AbstractFieldComparator' tags: - { name: 'coderhapsodie.ezdataflow.field_comparator', fieldType: 'my_field_type_identifier' }
管理员UI
访问eZ Dataflow UI
您可以从Ibexa管理员后台办公室访问eZ Dataflow管理UI。
- 点击“管理员”
- 点击“eZ Dataflow”
计划的数据流列表
当您访问eZ Dataflow管理UI时,您会在这里
- 计划的数据流列表
- 添加新计划数据流的按钮
- 每个计划数据流可用的工具。从左到右依次为
- 显示此数据流计划的记录
- 编辑此数据流计划
- 启用/禁用此数据流计划
- 删除此数据流计划
注意:您可以为任何给定数据流定义多个计划。
添加新计划
转到eZ Dataflow管理员,并单击橙色加号按钮。
在新弹出窗口中填写字段
- 输入数据流计划名称
- 选择数据流类型。列表会自动从具有
coderhapsodie.dataflow.type
标签的Symfony服务列表中生成。如果您的数据流类型不存在,请检查配置 - 在此处输入数据流选项。基本预期格式:每行一个选项,选项名和值用
:
分隔。对于更复杂选项,支持整个YAML格式。 - 在此处输入频率。值必须与PHP strtotime函数兼容。
- 选择第一个工作的日期和时间。
- 检查是否要运行此数据流。
最后,单击“创建”按钮。
读取历史记录
当您在eZ Dataflow管理UI中单击“历史记录”标签时,将显示所有配置和执行的数据流作业历史记录。
- 历史列表
- 此列显示已处理的对象数量。
- 单击问号可显示作业详情。
一个预定作业的详情
一次性作业
如果您不想定期运行数据流,您可以在您想要的日期和时间添加单次执行。
转到 eZ Dataflow 管理界面并单击“一次性”标签。
- 此按钮允许您定义一次性作业(见下文)。
- 此列显示已处理的对象数量。
- 单击问号可显示作业详情。
一次性作业的详情
这里作业已失败。
添加一次性作业
转到 eZ Dataflow 管理界面并单击“一次性”标签。单击橙色加号按钮打开添加弹出窗口。
- 输入数据流作业名称
- 选择数据流类型。列表会自动从具有
coderhapsodie.dataflow.type
标签的Symfony服务列表中生成。如果您的数据流类型不存在,请检查配置 - 在此处输入数据流选项。基本预期格式:每行一个选项,选项名和值用
:
分隔。对于更复杂选项,支持整个YAML格式。 - 选择第一个工作的日期和时间。
最后,单击“创建”按钮。
权限
如果非管理员用户需要仅对数据流接口的只读访问,请在其角色中添加“设置/管理”和“eZ Dataflow/查看”策略。
问题和功能请求
请在此处报告问题和请求功能:https://github.com/code-rhapsodie/ezdataflow-bundle/issues。
贡献
欢迎贡献。请参阅CONTRIBUTING.md以获取详细信息。感谢所有已贡献者。
许可
此软件包在MIT许可下授权。