├── .gitignore
├── Resources
├── public
│ ├── less
│ │ ├── index.less
│ │ └── custom.less
│ ├── templates
│ │ └── form
│ │ │ └── common
│ │ │ └── fields
│ │ │ ├── export-mapping.html
│ │ │ ├── import-mapping.html
│ │ │ └── lua-script.html
│ └── js
│ │ └── form
│ │ └── common
│ │ └── fields
│ │ ├── lua-script.js
│ │ ├── import-mapping.js
│ │ └── export-mapping.js
├── translations
│ ├── validators.en.yml
│ ├── validators.fr.yml
│ ├── messages.en.yml
│ ├── messages.fr.yml
│ ├── jsmessages.en.yml
│ └── jsmessages.fr.yml
├── config
│ ├── routing.yml
│ ├── entities.yml
│ ├── controllers.yml
│ ├── validators.yml
│ ├── subscribers.yml
│ ├── custom_entities.yml
│ ├── validation.yml
│ ├── providers.yml
│ ├── normalizers.yml
│ ├── helpers.yml
│ ├── requirejs.yml
│ ├── archiving.yml
│ ├── doctrine
│ │ ├── LuaUpdater.orm.yml
│ │ ├── ExportMapping.orm.yml
│ │ └── ImportMapping.orm.yml
│ ├── form_extensions
│ │ ├── luaUpdater
│ │ │ ├── create.yml
│ │ │ ├── index.yml
│ │ │ └── edit.yml
│ │ ├── exportMapping
│ │ │ ├── create.yml
│ │ │ ├── index.yml
│ │ │ └── edit.yml
│ │ ├── importMapping
│ │ │ ├── create.yml
│ │ │ ├── index.yml
│ │ │ └── edit.yml
│ │ ├── menu.yml
│ │ ├── csv_advanced_product_export_show.yml
│ │ ├── csv_advanced_product_model_export_show.yml
│ │ ├── csv_advanced_product_import_show.yml
│ │ └── csv_advanced_product_model_import_show.yml
│ ├── repositories.yml
│ ├── readers.yml
│ ├── acl.yml
│ ├── job_defaults.yml
│ ├── job_constraints.yml
│ ├── datagrid
│ │ ├── lua_updater.yml
│ │ ├── export_mapping.yml
│ │ └── import_mapping.yml
│ ├── steps.yml
│ ├── jobs.yml
│ └── writers.yml
├── views
│ └── notification.html.twig
└── bin
│ └── split-csv-files.sh
├── Reader
├── MultiFilesReaderInterface.php
└── File
│ └── Csv
│ └── ProductModelAdvancedReader.php
├── Doctrine
└── ORM
│ └── Repository
│ ├── LuaUpdaterRepository.php
│ ├── ExportMappingRepository.php
│ ├── ImportMappingRepository.php
│ └── AttributeOptionRepository.php
├── Writer
└── File
│ ├── Csv
│ └── ProductModelAdvancedWriter.php
│ └── ProductColumnSorterByMapping.php
├── ClickAndMortarAdvancedCsvConnectorBundle.php
├── Validator
├── Constraints
│ └── LuaScriptConstraint.php
└── LuaScriptValidator.php
├── composer.json
├── EventSubscriber
└── LoadClassMetadataSubscriber.php
├── Normalizer
└── Standard
│ ├── LuaUpdaterNormalizer.php
│ ├── ExportMappingNormalizer.php
│ └── ImportMappingNormalizer.php
├── DependencyInjection
└── ClickAndMortarAdvancedCsvConnectorExtension.php
├── Job
└── JobParameters
│ ├── DefaultValuesProvider
│ ├── ProductCsvAdvancedExport.php
│ └── ProductCsvAdvancedImport.php
│ └── ConstraintCollectionProvider
│ ├── ProductCsvAdvancedImport.php
│ └── ProductCsvAdvancedExport.php
├── Controller
└── LuaUpdaterController.php
├── Entity
├── LuaUpdater.php
├── ExportMapping.php
└── ImportMapping.php
├── Archiver
├── AdvancedFileReaderArchiver.php
└── AdvancedCsvInvalidItemWriter.php
├── Helper
└── ExportHelper.php
├── README.md
└── Step
└── MailNotification.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | *~
3 | *.swp
4 | *.swo
--------------------------------------------------------------------------------
/Resources/public/less/index.less:
--------------------------------------------------------------------------------
1 | @import "./public/bundles/clickandmortaradvancedcsvconnector/less/lib/tabulator_bootstrap4.less";
2 | @import "./public/bundles/clickandmortaradvancedcsvconnector/less/custom.less";
--------------------------------------------------------------------------------
/Resources/translations/validators.en.yml:
--------------------------------------------------------------------------------
1 | candm_advanced_csv_connector:
2 | lua_updater:
3 | validation:
4 | lua_script:
5 | empty: LUA script can not be empty
6 | error: Invalid LUA script
--------------------------------------------------------------------------------
/Resources/config/routing.yml:
--------------------------------------------------------------------------------
1 | candm_advanced_csv_connector_api_luaUpdater_test:
2 | path: /lupdateUpdater/test
3 | defaults: { _controller: candm_advanced_csv_connector.controller.lua_updater:testAction, _format: json }
4 | methods: [POST]
--------------------------------------------------------------------------------
/Resources/translations/validators.fr.yml:
--------------------------------------------------------------------------------
1 | candm_advanced_csv_connector:
2 | lua_updater:
3 | validation:
4 | lua_script:
5 | empty: Le script LUA ne doit pas être vide
6 | error: Le script LUA n'est pas correct
--------------------------------------------------------------------------------
/Resources/public/templates/form/common/fields/export-mapping.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Resources/public/templates/form/common/fields/import-mapping.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Resources/config/entities.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | pim_custom_entity.entity.importMapping.class: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ImportMapping
3 | pim_custom_entity.entity.exportMapping.class: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ExportMapping
4 | pim_custom_entity.entity.luaUpdater.class: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\LuaUpdater
--------------------------------------------------------------------------------
/Resources/config/controllers.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.controller.lua_updater.class: ClickAndMortar\AdvancedCsvConnectorBundle\Controller\LuaUpdaterController
3 |
4 | services:
5 | _defaults: { public: true }
6 |
7 | candm_advanced_csv_connector.controller.lua_updater:
8 | class: '%candm_advanced_csv_connector.controller.lua_updater.class%'
9 | arguments:
10 | - '@translator'
--------------------------------------------------------------------------------
/Reader/MultiFilesReaderInterface.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository
12 | */
13 | class LuaUpdaterRepository extends CustomEntityRepository
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/Doctrine/ORM/Repository/ExportMappingRepository.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository
12 | */
13 | class ExportMappingRepository extends CustomEntityRepository
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/Doctrine/ORM/Repository/ImportMappingRepository.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository
12 | */
13 | class ImportMappingRepository extends CustomEntityRepository
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/Resources/config/custom_entities.yml:
--------------------------------------------------------------------------------
1 | custom_entities:
2 | importMapping:
3 | entity_class: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ImportMapping
4 | options:
5 | edit_form_extension: pim-importMapping-edit-form
6 |
7 | exportMapping:
8 | entity_class: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ExportMapping
9 | options:
10 | edit_form_extension: pim-exportMapping-edit-form
11 |
12 | luaUpdater:
13 | entity_class: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\LuaUpdater
14 | options:
15 | edit_form_extension: pim-luaUpdater-edit-form
--------------------------------------------------------------------------------
/Writer/File/Csv/ProductModelAdvancedWriter.php:
--------------------------------------------------------------------------------
1 |
10 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Writer\File\Csv
11 | */
12 | class ProductModelAdvancedWriter extends ProductAdvancedWriter
13 | {
14 | /**
15 | * {@inheritdoc}
16 | */
17 | protected function getItemIdentifier(array $productModel): string
18 | {
19 | return $productModel['code'];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Resources/config/validation.yml:
--------------------------------------------------------------------------------
1 | ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ImportMapping:
2 | properties:
3 | label:
4 | - NotBlank: ~
5 | code:
6 | - NotBlank: ~
7 |
8 | ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ExportMapping:
9 | properties:
10 | label:
11 | - NotBlank: ~
12 | code:
13 | - NotBlank: ~
14 |
15 | ClickAndMortar\AdvancedCsvConnectorBundle\Entity\LuaUpdater:
16 | constraints:
17 | - ClickAndMortar\AdvancedCsvConnectorBundle\Validator\Constraints\LuaScriptConstraint: ~
18 | properties:
19 | label:
20 | - NotBlank: ~
21 | code:
22 | - NotBlank: ~
--------------------------------------------------------------------------------
/Resources/config/providers.yml:
--------------------------------------------------------------------------------
1 | services:
2 | candm_advanced_csv_connector.provider.form.job_instance:
3 | class: 'Akeneo\Platform\Bundle\ImportExportBundle\Provider\Form\JobInstanceFormProvider'
4 | arguments:
5 | -
6 | csv_advanced_product_import: pim-job-instance-csv-advanced-product-import
7 | csv_advanced_product_model_import: pim-job-instance-csv-advanced-product-model-import
8 | csv_advanced_product_export: pim-job-instance-csv-advanced-product-export
9 | csv_advanced_product_model_export: pim-job-instance-csv-advanced-product-model-export
10 | tags:
11 | - { name: pim_enrich.provider.form }
--------------------------------------------------------------------------------
/ClickAndMortarAdvancedCsvConnectorBundle.php:
--------------------------------------------------------------------------------
1 |
12 | * @package ClickAndMortar\AdvancedCsvConnectorBundle
13 | */
14 | class ClickAndMortarAdvancedCsvConnectorBundle extends Bundle
15 | {
16 | /**
17 | * Build.
18 | *
19 | * @param ContainerBuilder $container
20 | */
21 | public function build(ContainerBuilder $container)
22 | {
23 | parent::build($container);
24 | }
25 | }
--------------------------------------------------------------------------------
/Validator/Constraints/LuaScriptConstraint.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Validator\Constraints
12 | */
13 | class LuaScriptConstraint extends Constraint
14 | {
15 | /**
16 | * {@inheritdoc}
17 | */
18 | public function getTargets()
19 | {
20 | return self::CLASS_CONSTRAINT;
21 | }
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function validatedBy()
27 | {
28 | return 'candm_advanced_csv_connector.validator.lua_script';
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Resources/config/normalizers.yml:
--------------------------------------------------------------------------------
1 | # Normalizers
2 | services:
3 | pim_custom_entity.normalizer.standard.importMapping:
4 | public: false
5 | class: ClickAndMortar\AdvancedCsvConnectorBundle\Normalizer\Standard\ImportMappingNormalizer
6 | tags:
7 | - { name: pim_serializer.normalizer, priority: 200 }
8 |
9 | pim_custom_entity.normalizer.standard.exportMapping:
10 | public: false
11 | class: ClickAndMortar\AdvancedCsvConnectorBundle\Normalizer\Standard\ExportMappingNormalizer
12 | tags:
13 | - { name: pim_serializer.normalizer, priority: 200 }
14 |
15 | pim_custom_entity.normalizer.standard.luaUpdater:
16 | public: false
17 | class: ClickAndMortar\AdvancedCsvConnectorBundle\Normalizer\Standard\LuaUpdaterNormalizer
18 | tags:
19 | - { name: pim_serializer.normalizer, priority: 200 }
--------------------------------------------------------------------------------
/Resources/public/templates/form/common/fields/lua-script.html:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | <%- _.__('candm_advanced_csv_connector.luaUpdater.custom.test_action') %>
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Resources/config/helpers.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.helper.import.class: ClickAndMortar\AdvancedCsvConnectorBundle\Helper\ImportHelper
3 | candm_advanced_csv_connector.helper.export.class: ClickAndMortar\AdvancedCsvConnectorBundle\Helper\ExportHelper
4 |
5 | services:
6 | candm_advanced_csv_connector.helper.import:
7 | class: '%candm_advanced_csv_connector.helper.import.class%'
8 | arguments:
9 | - '@logger'
10 | - '@doctrine.orm.entity_manager'
11 | - '%kernel.project_dir%'
12 | - '@pim_catalog.repository.attribute'
13 | - '@translator'
14 |
15 | candm_advanced_csv_connector.helper.export:
16 | class: '%candm_advanced_csv_connector.helper.export.class%'
17 | arguments:
18 | - '@doctrine.orm.entity_manager'
19 | - '@pim_catalog.repository.attribute_option'
--------------------------------------------------------------------------------
/Resources/views/notification.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% for stepName, messagesByType in messagesByStepAndType %}
4 | {{ ('batch_jobs.mail_notification.step_title') | trans }} : {{ stepName }}
5 | {% for messageType, messages in messagesByType %}
6 | {{ ('batch_jobs.mail_notification.types.' ~ messageType) | trans }}
7 |
8 | {% for message in messages %}
9 | {% if messageType == 'default' and message.identifier is not null %}
10 | - {{ message.identifier }} : {{ message.content|raw }}
11 | {% else %}
12 | - {{ message.content|raw }}
13 | {% endif %}
14 | {% endfor %}
15 |
16 | {% endfor %}
17 | {% endfor %}
18 |
19 |
20 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clickandmortar/advanced-csv-connector-bundle",
3 | "description": "Advanced CSV Connector for Akeneo",
4 | "type": "symfony-bundle",
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Simon CARRE",
9 | "email": "simon.carre@clickandmortar.fr"
10 | }
11 | ],
12 | "require": {
13 | "akeneo/pim-community-dev": "^7.0.0",
14 | "akeneo-labs/custom-entity-bundle": "7.0.*"
15 | },
16 | "repositories": [
17 | {
18 | "type": "vcs",
19 | "url": "git@github.com:ClickAndMortar/AdvancedEnrichBundle.git"
20 | },
21 | {
22 | "type": "vcs",
23 | "url": "https://github.com/ClickAndMortar/CustomEntityBundle"
24 | }
25 | ],
26 | "autoload": {
27 | "psr-4": {
28 | "ClickAndMortar\\AdvancedCsvConnectorBundle\\": ""
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Resources/config/requirejs.yml:
--------------------------------------------------------------------------------
1 | config:
2 | paths:
3 | tabulator: clickandmortaradvancedcsvconnector/js/lib/tabulator
4 |
5 | # Mapping fields
6 | pim/form/common/fields/import-mapping: clickandmortaradvancedcsvconnector/js/form/common/fields/import-mapping
7 | pim/template/form/common/fields/import-mapping: clickandmortaradvancedcsvconnector/templates/form/common/fields/import-mapping.html
8 | pim/form/common/fields/export-mapping: clickandmortaradvancedcsvconnector/js/form/common/fields/export-mapping
9 | pim/template/form/common/fields/export-mapping: clickandmortaradvancedcsvconnector/templates/form/common/fields/export-mapping.html
10 |
11 | # LUA script field
12 | pim/form/common/fields/lua-script: clickandmortaradvancedcsvconnector/js/form/common/fields/lua-script
13 | pim/template/form/common/fields/lua-script: clickandmortaradvancedcsvconnector/templates/form/common/fields/lua-script.html
--------------------------------------------------------------------------------
/Resources/config/archiving.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | pim_connector.archiver.file_reader_archiver.class: ClickAndMortar\AdvancedCsvConnectorBundle\Archiver\AdvancedFileReaderArchiver
3 | candm_advanced_csv_connector.archiver.invalid_item_csv_writer.class: ClickAndMortar\AdvancedCsvConnectorBundle\Archiver\AdvancedCsvInvalidItemWriter
4 |
5 | services:
6 | candm_advanced_csv_connector.archiver.invalid_item_csv_writer:
7 | class: '%candm_advanced_csv_connector.archiver.invalid_item_csv_writer.class%'
8 | arguments:
9 | - '@pim_connector.event_listener.invalid_items_collector'
10 | - '@pim_connector.writer.file.invalid_items_csv'
11 | - '@pim_connector.reader.file.csv_iterator_factory'
12 | - '@oneup_flysystem.archivist_filesystem'
13 | - '@pim_connector.job.job_parameters.default_values_provider.product_csv_export'
14 | - 'advanced_csv'
15 | tags:
16 | - { name: pim_connector.archiver }
--------------------------------------------------------------------------------
/Resources/config/doctrine/LuaUpdater.orm.yml:
--------------------------------------------------------------------------------
1 | ClickAndMortar\AdvancedCsvConnectorBundle\Entity\LuaUpdater:
2 | repositoryClass: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\LuaUpdaterRepository
3 | type: entity
4 | table: candm_reference_data_luaupdater
5 | changeTrackingPolicy: DEFERRED_EXPLICIT
6 | fields:
7 | id:
8 | type: integer
9 | id: true
10 | generator:
11 | strategy: AUTO
12 | label:
13 | type: string
14 | length: 255
15 | code:
16 | type: string
17 | length: 255
18 | unique: true
19 | script:
20 | type: text
21 | nullable: true
22 | sortOrder:
23 | type: integer
24 | created:
25 | type: datetime
26 | gedmo:
27 | timestampable:
28 | on: create
29 | updated:
30 | type: datetime
31 | gedmo:
32 | timestampable:
33 | on: update
34 | lifecycleCallbacks: { }
--------------------------------------------------------------------------------
/Reader/File/Csv/ProductModelAdvancedReader.php:
--------------------------------------------------------------------------------
1 |
9 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Reader\File\Csv
10 | */
11 | class ProductModelAdvancedReader extends ProductAdvancedReader
12 | {
13 | /**
14 | * @return array
15 | */
16 | protected function getArrayConverterOptions(): array
17 | {
18 | $jobParameters = $this->stepExecution->getJobParameters();
19 |
20 | return [
21 | // for the array converters
22 | 'mapping' => [
23 | $jobParameters->get('familyVariantColumn') => 'family_variant',
24 | $jobParameters->get('categoriesColumn') => 'categories',
25 | ],
26 | 'with_associations' => false,
27 |
28 | // for the delocalization
29 | 'decimal_separator' => $jobParameters->get('decimalSeparator'),
30 | 'date_format' => $jobParameters->get('dateFormat'),
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/EventSubscriber/LoadClassMetadataSubscriber.php:
--------------------------------------------------------------------------------
1 | getClassMetadata();
33 | if ($classMetadata->getName() !== 'Akeneo\Pim\Structure\Component\Model\AttributeOption') {
34 | return;
35 | }
36 |
37 | $classMetadata->customRepositoryClassName = 'ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\AttributeOptionRepository';
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/ExportMapping.orm.yml:
--------------------------------------------------------------------------------
1 | ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ExportMapping:
2 | repositoryClass: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\ExportMappingRepository
3 | type: entity
4 | table: candm_reference_data_exportmapping
5 | changeTrackingPolicy: DEFERRED_EXPLICIT
6 | fields:
7 | id:
8 | type: integer
9 | id: true
10 | generator:
11 | strategy: AUTO
12 | label:
13 | type: string
14 | length: 255
15 | code:
16 | type: string
17 | length: 255
18 | unique: true
19 | mappingAsJson:
20 | type: text
21 | nullable: true
22 | completeCallback:
23 | type: string
24 | length: 255
25 | nullable: true
26 | sortOrder:
27 | type: integer
28 | created:
29 | type: datetime
30 | gedmo:
31 | timestampable:
32 | on: create
33 | updated:
34 | type: datetime
35 | gedmo:
36 | timestampable:
37 | on: update
38 | lifecycleCallbacks: { }
--------------------------------------------------------------------------------
/Resources/config/form_extensions/luaUpdater/create.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-luaUpdater-create-modal:
3 | module: custom_entity/form/creation/modal
4 | config:
5 | labels:
6 | title: pim_custom_entity.create_popin.title
7 | subTitle: candm_advanced_csv_connector.menu.item.reference_data.luaUpdater
8 | picture: illustrations/User.svg
9 | successMessage: pim_custom_entity.message.created
10 | editRoute: pim_customentity_rest_get
11 | postUrl:
12 | route: pim_customentity_rest_create
13 | parameters:
14 | customEntityName: luaUpdater
15 |
16 | pim-luaUpdater-create-label:
17 | module: pim/form/common/creation/field
18 | parent: pim-luaUpdater-create-modal
19 | targetZone: fields
20 | position: 10
21 | config:
22 | identifier: label
23 | label: pim_custom_entity.form.field.label.label
24 |
25 | pim-luaUpdater-create-code:
26 | module: pim/form/common/creation/field
27 | parent: pim-luaUpdater-create-modal
28 | targetZone: fields
29 | position: 20
30 | config:
31 | identifier: code
32 | label: pim_custom_entity.form.field.label.code
--------------------------------------------------------------------------------
/Resources/config/form_extensions/exportMapping/create.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-exportMapping-create-modal:
3 | module: custom_entity/form/creation/modal
4 | config:
5 | labels:
6 | title: pim_custom_entity.create_popin.title
7 | subTitle: candm_advanced_csv_connector.menu.item.reference_data.exportMapping
8 | picture: illustrations/User.svg
9 | successMessage: pim_custom_entity.message.created
10 | editRoute: pim_customentity_rest_get
11 | postUrl:
12 | route: pim_customentity_rest_create
13 | parameters:
14 | customEntityName: exportMapping
15 |
16 | pim-exportMapping-create-label:
17 | module: pim/form/common/creation/field
18 | parent: pim-exportMapping-create-modal
19 | targetZone: fields
20 | position: 10
21 | config:
22 | identifier: label
23 | label: pim_custom_entity.form.field.label.label
24 |
25 | pim-exportMapping-create-code:
26 | module: pim/form/common/creation/field
27 | parent: pim-exportMapping-create-modal
28 | targetZone: fields
29 | position: 20
30 | config:
31 | identifier: code
32 | label: pim_custom_entity.form.field.label.code
--------------------------------------------------------------------------------
/Resources/config/form_extensions/importMapping/create.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-importMapping-create-modal:
3 | module: custom_entity/form/creation/modal
4 | config:
5 | labels:
6 | title: pim_custom_entity.create_popin.title
7 | subTitle: candm_advanced_csv_connector.menu.item.reference_data.importMapping
8 | picture: illustrations/User.svg
9 | successMessage: pim_custom_entity.message.created
10 | editRoute: pim_customentity_rest_get
11 | postUrl:
12 | route: pim_customentity_rest_create
13 | parameters:
14 | customEntityName: importMapping
15 |
16 | pim-importMapping-create-label:
17 | module: pim/form/common/creation/field
18 | parent: pim-importMapping-create-modal
19 | targetZone: fields
20 | position: 10
21 | config:
22 | identifier: label
23 | label: pim_custom_entity.form.field.label.label
24 |
25 | pim-importMapping-create-code:
26 | module: pim/form/common/creation/field
27 | parent: pim-importMapping-create-modal
28 | targetZone: fields
29 | position: 20
30 | config:
31 | identifier: code
32 | label: pim_custom_entity.form.field.label.code
--------------------------------------------------------------------------------
/Resources/config/form_extensions/menu.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | candm_advanced_csv_connector-menu-reference_data-item-importMapping:
3 | module: pim/menu/item
4 | parent: pim-menu-reference_data-navigation-block
5 | position: 10
6 | config:
7 | title: candm_advanced_csv_connector.menu.item.reference_data.importMapping
8 | to: pim_customentity_index
9 | routeParams:
10 | customEntityName: importMapping
11 |
12 | candm_advanced_csv_connector-menu-reference_data-item-exportMapping:
13 | module: pim/menu/item
14 | parent: pim-menu-reference_data-navigation-block
15 | position: 20
16 | config:
17 | title: candm_advanced_csv_connector.menu.item.reference_data.exportMapping
18 | to: pim_customentity_index
19 | routeParams:
20 | customEntityName: exportMapping
21 |
22 | candm_advanced_csv_connector-menu-reference_data-item-luaUpdater:
23 | module: pim/menu/item
24 | parent: pim-menu-reference_data-navigation-block
25 | position: 30
26 | config:
27 | title: candm_advanced_csv_connector.menu.item.reference_data.luaUpdater
28 | to: pim_customentity_index
29 | routeParams:
30 | customEntityName: luaUpdater
--------------------------------------------------------------------------------
/Normalizer/Standard/LuaUpdaterNormalizer.php:
--------------------------------------------------------------------------------
1 |
12 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Normalizer\Standard
13 | */
14 | class LuaUpdaterNormalizer implements NormalizerInterface
15 | {
16 | /**
17 | * @var string[]
18 | */
19 | protected $supportedFormats = ['standard'];
20 |
21 | /**
22 | * @param LuaUpdater $entity
23 | * @param null $format
24 | * @param array $context
25 | *
26 | * @return array
27 | */
28 | public function normalize($entity, $format = null, array $context = [])
29 | {
30 | $mapping = [
31 | 'id' => $entity->getId(),
32 | 'label' => $entity->getLabel(),
33 | 'code' => $entity->getCode(),
34 | 'script' => $entity->getScript(),
35 | ];
36 |
37 | return $mapping;
38 | }
39 |
40 | /**
41 | * @param mixed $data
42 | * @param null $format
43 | *
44 | * @return bool
45 | */
46 | public function supportsNormalization($data, $format = null)
47 | {
48 | return $data instanceof LuaUpdater && in_array($format, $this->supportedFormats);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/DependencyInjection/ClickAndMortarAdvancedCsvConnectorExtension.php:
--------------------------------------------------------------------------------
1 |
14 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\DependencyInjection
15 | */
16 | class ClickAndMortarAdvancedCsvConnectorExtension extends Extension
17 | {
18 | public function load(array $configs, ContainerBuilder $container)
19 | {
20 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
21 | $loader->load('jobs.yml');
22 | $loader->load('steps.yml');
23 | $loader->load('readers.yml');
24 | $loader->load('writers.yml');
25 | $loader->load('job_constraints.yml');
26 | $loader->load('job_defaults.yml');
27 | $loader->load('providers.yml');
28 | $loader->load('archiving.yml');
29 | $loader->load('helpers.yml');
30 | $loader->load('subscribers.yml');
31 | $loader->load('normalizers.yml');
32 | $loader->load('entities.yml');
33 | $loader->load('repositories.yml');
34 | $loader->load('validators.yml');
35 | $loader->load('controllers.yml');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Writer/File/ProductColumnSorterByMapping.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Writer\File
12 | */
13 | class ProductColumnSorterByMapping extends ProductColumnSorter
14 | {
15 | /**
16 | * Columns order context key
17 | *
18 | * @var string
19 | */
20 | const CONTEXT_KEY_COLUMNS_ORDER = 'columnsOrder';
21 |
22 | /**
23 | * {@inheritdoc}
24 | */
25 | public function sort(array $columns, array $context = [])
26 | {
27 | // Get order from context if possible
28 | if (isset($context[self::CONTEXT_KEY_COLUMNS_ORDER])) {
29 | $sortedColumns = [];
30 | foreach ($context[self::CONTEXT_KEY_COLUMNS_ORDER] as $columnName) {
31 | if (in_array($columnName, $columns)) {
32 | $sortedColumns[] = $columnName;
33 | }
34 | }
35 |
36 | // Add other columns
37 | $otherColumns = array_diff($columns, $sortedColumns);
38 | if (!empty($otherColumns)) {
39 | $sortedColumns = array_merge($sortedColumns, $otherColumns);
40 | }
41 |
42 | return $sortedColumns;
43 | }
44 |
45 | // Else keep classic case
46 | return parent::sort($columns, $context);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Normalizer/Standard/ExportMappingNormalizer.php:
--------------------------------------------------------------------------------
1 |
12 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Normalizer\Standard
13 | */
14 | class ExportMappingNormalizer implements NormalizerInterface
15 | {
16 | /**
17 | * @var string[]
18 | */
19 | protected $supportedFormats = ['standard'];
20 |
21 | /**
22 | * @param ImportMapping $entity
23 | * @param null $format
24 | * @param array $context
25 | *
26 | * @return array
27 | */
28 | public function normalize($entity, $format = null, array $context = [])
29 | {
30 | $mapping = [
31 | 'id' => $entity->getId(),
32 | 'label' => $entity->getLabel(),
33 | 'code' => $entity->getCode(),
34 | 'mappingAsJson' => $entity->getMappingAsJson(),
35 | 'completeCallback' => $entity->getCompleteCallback(),
36 | ];
37 |
38 | return $mapping;
39 | }
40 |
41 | /**
42 | * @param mixed $data
43 | * @param null $format
44 | *
45 | * @return bool
46 | */
47 | public function supportsNormalization($data, $format = null)
48 | {
49 | return $data instanceof ExportMapping && in_array($format, $this->supportedFormats);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Resources/config/doctrine/ImportMapping.orm.yml:
--------------------------------------------------------------------------------
1 | ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ImportMapping:
2 | repositoryClass: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\ImportMappingRepository
3 | type: entity
4 | table: candm_reference_data_importmapping
5 | changeTrackingPolicy: DEFERRED_EXPLICIT
6 | fields:
7 | id:
8 | type: integer
9 | id: true
10 | generator:
11 | strategy: AUTO
12 | label:
13 | type: string
14 | length: 255
15 | code:
16 | type: string
17 | length: 255
18 | unique: true
19 | mappingAsJson:
20 | type: text
21 | nullable: true
22 | completeCallback:
23 | type: string
24 | length: 255
25 | nullable: true
26 | initializeCallback:
27 | type: string
28 | length: 255
29 | nullable: true
30 | flushCallback:
31 | type: string
32 | length: 255
33 | nullable: true
34 | itemsLimit:
35 | type: integer
36 | nullable: true
37 | onlyUpdate:
38 | type: boolean
39 | options:
40 | default: false
41 | sortOrder:
42 | type: integer
43 | created:
44 | type: datetime
45 | gedmo:
46 | timestampable:
47 | on: create
48 | updated:
49 | type: datetime
50 | gedmo:
51 | timestampable:
52 | on: update
53 | lifecycleCallbacks: { }
54 |
--------------------------------------------------------------------------------
/Resources/config/repositories.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.repository.attribute_option.class: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\AttributeOptionRepository
3 | candm_advanced_csv_connector.repository.import_mapping.class: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\ImportMappingRepository
4 | candm_advanced_csv_connector.repository.export_mapping.class: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\ExportMappingRepository
5 | candm_advanced_csv_connector.repository.lua_updater.class: ClickAndMortar\AdvancedCsvConnectorBundle\Doctrine\ORM\Repository\LuaUpdaterRepository
6 |
7 | services:
8 | candm_advanced_csv_connector.repository.import_mapping:
9 | class: '%candm_advanced_csv_connector.repository.import_mapping.class%'
10 | factory: ['@doctrine.orm.entity_manager', 'getRepository']
11 | arguments: ['%pim_custom_entity.entity.importMapping.class%']
12 | tags:
13 | - { name: 'pim_repository' }
14 |
15 | candm_advanced_csv_connector.repository.export_mapping:
16 | class: '%candm_advanced_csv_connector.repository.export_mapping.class%'
17 | factory: ['@doctrine.orm.entity_manager', 'getRepository']
18 | arguments: ['%pim_custom_entity.entity.exportMapping.class%']
19 | tags:
20 | - { name: 'pim_repository' }
21 |
22 | candm_advanced_csv_connector.repository.lua_updater:
23 | class: '%candm_advanced_csv_connector.repository.lua_updater.class%'
24 | factory: ['@doctrine.orm.entity_manager', 'getRepository']
25 | arguments: ['%pim_custom_entity.entity.luaUpdater.class%']
26 | tags:
27 | - { name: 'pim_repository' }
--------------------------------------------------------------------------------
/Doctrine/ORM/Repository/AttributeOptionRepository.php:
--------------------------------------------------------------------------------
1 | createQueryBuilder('o')
21 | ->leftJoin('o.attribute', 'a')
22 | ->where('a.code = :attribute_code')
23 | ->andWhere('o.code IN (:option_codes)')
24 | ->setParameters(array(
25 | 'attribute_code' => $attributeCode,
26 | 'option_codes' => $optionCode
27 | ))
28 | ->getQuery()
29 | ->getResult();
30 | }
31 |
32 | /**
33 | * @param $attributeCode
34 | * @param $attributeValue
35 | *
36 | * @return array
37 | */
38 | public function findOptionByValue($attributeCode, $attributeValue)
39 | {
40 | return $this->createQueryBuilder('o')
41 | ->innerJoin('o.attribute', 'a')
42 | ->innerJoin('o.optionValues', 'v')
43 | ->where('a.code = :attribute_code')
44 | ->andWhere('v.value = :attribute_value')
45 | ->setParameters([
46 | 'attribute_code' => $attributeCode,
47 | 'attribute_value' => $attributeValue
48 | ])
49 | ->getQuery()
50 | ->getResult();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Resources/config/readers.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.reader.file.csv_advanced_product.class: ClickAndMortar\AdvancedCsvConnectorBundle\Reader\File\Csv\ProductAdvancedReader
3 | candm_advanced_csv_connector.reader.file.csv_advanced_product_model.class: ClickAndMortar\AdvancedCsvConnectorBundle\Reader\File\Csv\ProductModelAdvancedReader
4 |
5 | services:
6 | candm_advanced_csv_connector.reader.file.csv_advanced_product:
7 | class: '%candm_advanced_csv_connector.reader.file.csv_advanced_product.class%'
8 | arguments:
9 | - '@pim_connector.reader.file.csv_iterator_factory'
10 | - '@pim_connector.array_converter.flat_to_standard.product_delocalized'
11 | - '@pim_connector.reader.file.media_path_transformer'
12 | - '@candm_advanced_csv_connector.helper.import'
13 | - '@pim_catalog.repository.product'
14 | - '@candm_advanced_csv_connector.repository.import_mapping'
15 | - '@candm_advanced_csv_connector.repository.lua_updater'
16 | - []
17 |
18 | candm_advanced_csv_connector.reader.file.csv_advanced_product_model:
19 | class: '%candm_advanced_csv_connector.reader.file.csv_advanced_product_model.class%'
20 | arguments:
21 | - '@pim_connector.reader.file.csv_iterator_factory'
22 | - '@pim_connector.array_converter.flat_to_standard.product_model_delocalized'
23 | - '@pim_connector.reader.file.media_path_transformer'
24 | - '@candm_advanced_csv_connector.helper.import'
25 | - '@pim_catalog.repository.product_model'
26 | - '@candm_advanced_csv_connector.repository.import_mapping'
27 | - '@candm_advanced_csv_connector.repository.lua_updater'
28 | - []
--------------------------------------------------------------------------------
/Validator/LuaScriptValidator.php:
--------------------------------------------------------------------------------
1 |
14 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Validator
15 | */
16 | class LuaScriptValidator extends ConstraintValidator
17 | {
18 | /**
19 | * Test attribute value
20 | *
21 | * @var string
22 | */
23 | const ATTRIBUTE_VALUE_TEST = '1';
24 |
25 | /**
26 | * @param LuaUpdater $luaUpdater
27 | * @param Constraint $constraint
28 | */
29 | public function validate($luaUpdater, Constraint $constraint)
30 | {
31 | $luaScript = $luaUpdater->getScript();
32 |
33 | // Check if script is empty
34 | if (empty($luaScript)) {
35 | $this->context->addViolation(
36 | 'candm_advanced_csv_connector.lua_updater.validation.lua_script.empty'
37 | );
38 | }
39 |
40 | // Check script validity
41 | $lua = new \Lua();
42 | $lua->assign('attributeValue', self::ATTRIBUTE_VALUE_TEST);
43 | $value = $lua->eval(sprintf(
44 | "%s\n%s",
45 | ProductAdvancedReader::LUA_SCRIPT_PREFIX,
46 | $luaScript
47 | ));
48 | if ($value === false) {
49 | $this->context->addViolation(
50 | 'candm_advanced_csv_connector.lua_updater.validation.lua_script.error'
51 | );
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Job/JobParameters/DefaultValuesProvider/ProductCsvAdvancedExport.php:
--------------------------------------------------------------------------------
1 |
12 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\DefaultValuesProvider
13 | */
14 | class ProductCsvAdvancedExport implements DefaultValuesProviderInterface
15 | {
16 | /**
17 | * @var DefaultValuesProviderInterface
18 | */
19 | protected $baseDefaultValuesProvider;
20 |
21 | /**
22 | * @var array
23 | */
24 | protected $supportedJobNames;
25 |
26 | /**
27 | * @param DefaultValuesProviderInterface $baseDefaultValuesProvider
28 | * @param array $supportedJobNames
29 | */
30 | public function __construct(DefaultValuesProviderInterface $baseDefaultValuesProvider, array $supportedJobNames)
31 | {
32 | $this->baseDefaultValuesProvider = $baseDefaultValuesProvider;
33 | $this->supportedJobNames = $supportedJobNames;
34 | }
35 |
36 | /**
37 | * {@inheritdoc}
38 | */
39 | public function getDefaultValues()
40 | {
41 | return array_merge($this->baseDefaultValuesProvider->getDefaultValues(), [
42 | 'encoding' => null,
43 | 'mapping' => null,
44 | 'forceXlsx' => false
45 | ]);
46 | }
47 |
48 | /**
49 | * {@inheritdoc}
50 | */
51 | public function supports(JobInterface $job)
52 | {
53 | return in_array($job->getName(), $this->supportedJobNames);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Normalizer/Standard/ImportMappingNormalizer.php:
--------------------------------------------------------------------------------
1 |
12 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Normalizer\Standard
13 | */
14 | class ImportMappingNormalizer implements NormalizerInterface
15 | {
16 | /**
17 | * @var string[]
18 | */
19 | protected $supportedFormats = ['standard'];
20 |
21 | /**
22 | * @param ImportMapping $entity
23 | * @param null $format
24 | * @param array $context
25 | *
26 | * @return array
27 | */
28 | public function normalize($entity, $format = null, array $context = [])
29 | {
30 | $mapping = [
31 | 'id' => $entity->getId(),
32 | 'label' => $entity->getLabel(),
33 | 'code' => $entity->getCode(),
34 | 'mappingAsJson' => $entity->getMappingAsJson(),
35 | 'completeCallback' => $entity->getCompleteCallback(),
36 | 'initializeCallback' => $entity->getInitializeCallback(),
37 | 'flushCallback' => $entity->getFlushCallback(),
38 | 'itemsLimit' => $entity->getItemsLimit(),
39 | 'onlyUpdate' => $entity->getOnlyUpdate(),
40 | ];
41 |
42 | return $mapping;
43 | }
44 |
45 | /**
46 | * @param mixed $data
47 | * @param null $format
48 | *
49 | * @return bool
50 | */
51 | public function supportsNormalization($data, $format = null)
52 | {
53 | return $data instanceof ImportMapping && in_array($format, $this->supportedFormats);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Job/JobParameters/DefaultValuesProvider/ProductCsvAdvancedImport.php:
--------------------------------------------------------------------------------
1 |
12 | * @package Solaris\Bundle\RestConnectorBundle\Job\JobParameters\DefaultValuesProvider
13 | */
14 | class ProductCsvAdvancedImport implements DefaultValuesProviderInterface
15 | {
16 | /**
17 | * @var DefaultValuesProviderInterface
18 | */
19 | protected $baseDefaultValuesProvider;
20 |
21 | /**
22 | * @var array
23 | */
24 | protected $supportedJobNames;
25 |
26 | /**
27 | * @param DefaultValuesProviderInterface $baseDefaultValuesProvider
28 | * @param array $supportedJobNames
29 | */
30 | public function __construct(DefaultValuesProviderInterface $baseDefaultValuesProvider, array $supportedJobNames)
31 | {
32 | $this->baseDefaultValuesProvider = $baseDefaultValuesProvider;
33 | $this->supportedJobNames = $supportedJobNames;
34 | }
35 |
36 | /**
37 | * {@inheritdoc}
38 | */
39 | public function getDefaultValues()
40 | {
41 | return array_merge($this->baseDefaultValuesProvider->getDefaultValues(), [
42 | 'mapping' => null,
43 | 'emailRecipients' => '',
44 | 'invalid_items_file_format' => 'advanced_csv',
45 | 'successNotification' => false,
46 | 'fromEncoding' => '',
47 | ]);
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function supports(JobInterface $job)
54 | {
55 | return in_array($job->getName(), $this->supportedJobNames);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Controller/LuaUpdaterController.php:
--------------------------------------------------------------------------------
1 |
14 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Controller
15 | */
16 | class LuaUpdaterController
17 | {
18 | /**
19 | * @var TranslatorInterface
20 | */
21 | protected $translator;
22 |
23 | /**
24 | * LuaUpdaterController constructor.
25 | *
26 | * @param TranslatorInterface $translator
27 | */
28 | public function __construct(TranslatorInterface $translator)
29 | {
30 | $this->translator = $translator;
31 | }
32 |
33 | /**
34 | * Test a given script
35 | *
36 | * @param Request $request
37 | *
38 | * @throws BadRequestHttpException
39 | *
40 | * @return JsonResponse
41 | */
42 | public function testAction(Request $request): JsonResponse
43 | {
44 | // Check if script is not empty
45 | $script = $request->get('script');
46 | if (empty($script)) {
47 | return new JsonResponse([
48 | 'message' => $this->translator->trans('luaUpdater.validation.empty_script'),
49 | ], 400);
50 | }
51 |
52 | // Check if test value is not empty
53 | $testValue = $request->get('testValue');
54 | if (empty($testValue)) {
55 | return new JsonResponse([
56 | 'message' => $this->translator->trans('luaUpdater.validation.empty_test_value'),
57 | ], 400);
58 | }
59 |
60 | $lua = new \Lua();
61 | $lua->assign('attributeValue', $testValue);
62 | $value = $lua->eval(sprintf(
63 | "%s\n%s",
64 | ProductAdvancedReader::LUA_SCRIPT_PREFIX,
65 | $script
66 | ));
67 |
68 | return new JsonResponse(['value' => $value]);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Job/JobParameters/ConstraintCollectionProvider/ProductCsvAdvancedImport.php:
--------------------------------------------------------------------------------
1 |
15 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\ConstraintCollectionProvider
16 | */
17 | class ProductCsvAdvancedImport implements ConstraintCollectionProviderInterface
18 | {
19 | /**
20 | * @var ConstraintCollectionProviderInterface
21 | */
22 | protected $baseConstraintCollectionProvider;
23 |
24 | /**
25 | * @var array
26 | */
27 | protected $supportedJobNames;
28 |
29 | /**
30 | * @param ConstraintCollectionProviderInterface $baseConstraintCollectionProvider
31 | * @param array $supportedJobNames
32 | */
33 | public function __construct(ConstraintCollectionProviderInterface $baseConstraintCollectionProvider, array $supportedJobNames)
34 | {
35 | $this->baseConstraintCollectionProvider = $baseConstraintCollectionProvider;
36 | $this->supportedJobNames = $supportedJobNames;
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function getConstraintCollection()
43 | {
44 | $constraintFields = array_merge($this->baseConstraintCollectionProvider->getConstraintCollection()->fields, [
45 | 'mapping' => [
46 | new NotBlank(),
47 | ],
48 | 'emailRecipients' => [],
49 | 'successNotification' => [],
50 | 'fromEncoding' => []
51 | ]);
52 |
53 | return new Collection(['fields' => $constraintFields]);
54 | }
55 |
56 | /**
57 | * {@inheritdoc}
58 | */
59 | public function supports(JobInterface $job)
60 | {
61 | return in_array($job->getName(), $this->supportedJobNames);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Job/JobParameters/ConstraintCollectionProvider/ProductCsvAdvancedExport.php:
--------------------------------------------------------------------------------
1 |
15 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\ConstraintCollectionProvider
16 | */
17 | class ProductCsvAdvancedExport implements ConstraintCollectionProviderInterface
18 | {
19 | /**
20 | * @var ConstraintCollectionProviderInterface
21 | */
22 | protected $baseConstraintCollectionProvider;
23 |
24 | /**
25 | * @var array
26 | */
27 | protected $supportedJobNames;
28 |
29 | /**
30 | * @param ConstraintCollectionProviderInterface $baseConstraintCollectionProvider
31 | * @param array $supportedJobNames
32 | */
33 | public function __construct(ConstraintCollectionProviderInterface $baseConstraintCollectionProvider, array $supportedJobNames)
34 | {
35 | $this->baseConstraintCollectionProvider = $baseConstraintCollectionProvider;
36 | $this->supportedJobNames = $supportedJobNames;
37 | }
38 |
39 | /**
40 | * {@inheritdoc}
41 | */
42 | public function getConstraintCollection()
43 | {
44 | $constraintFields = array_merge($this->baseConstraintCollectionProvider->getConstraintCollection()->fields, [
45 | 'encoding' => [
46 | ],
47 | 'mapping' => [
48 | new NotBlank(),
49 | ],
50 | 'forceXlsx' => [
51 | new Type('bool')
52 | ]
53 | ]);
54 |
55 | return new Collection(['fields' => $constraintFields]);
56 | }
57 |
58 | /**
59 | * {@inheritdoc}
60 | */
61 | public function supports(JobInterface $job)
62 | {
63 | return in_array($job->getName(), $this->supportedJobNames);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Entity/LuaUpdater.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Entity
12 | */
13 | class LuaUpdater extends AbstractCustomEntity
14 | {
15 | /**
16 | * Default script value for creation
17 | *
18 | * @return string
19 | */
20 | const DEFAULT_SCRIPT_VALUE = 'return attributeValue;';
21 |
22 | /**
23 | * Label
24 | *
25 | * @var string
26 | */
27 | protected $label;
28 |
29 | /**
30 | * Script to update value
31 | *
32 | * @var string
33 | */
34 | protected $script = self::DEFAULT_SCRIPT_VALUE;
35 |
36 | /**
37 | * Get label
38 | *
39 | * @return string
40 | */
41 | public function getLabel()
42 | {
43 | return $this->label;
44 | }
45 |
46 | /**
47 | * Set label
48 | *
49 | * @param string $label
50 | *
51 | * @return Brand
52 | */
53 | public function setLabel($label)
54 | {
55 | $this->label = $label;
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * @return string
62 | */
63 | public function getScript()
64 | {
65 | return $this->script;
66 | }
67 |
68 | /**
69 | * @param string $script
70 | *
71 | * @return LuaUpdater
72 | */
73 | public function setScript($script)
74 | {
75 | $this->script = $script;
76 |
77 | return $this;
78 | }
79 |
80 | /**
81 | * {@inheritdoc}
82 | */
83 | public static function getLabelProperty(): string
84 | {
85 | return 'label';
86 | }
87 |
88 | /**
89 | * Returns the custom entity name used in the configuration
90 | * Used to map row actions on datagrid
91 | *
92 | * @return string
93 | */
94 | public function getCustomEntityName(): string
95 | {
96 | return 'luaUpdater';
97 | }
98 |
99 | /**
100 | * Get reference value
101 | *
102 | * @return string
103 | */
104 | public function getReference(): string
105 | {
106 | return $this->getCode();
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Resources/translations/messages.en.yml:
--------------------------------------------------------------------------------
1 | # Custom
2 | batch_jobs:
3 | csv_advanced_product_import:
4 | import:
5 | errors:
6 | no_mapping: No mapping found.
7 | mapping_attributes_error: Incorrect mapping. Missing "attributes" key.
8 | mapping_no_attribute_code: Incorrect mapping. Missing "attributeCode" key.
9 | mapping_no_identifier: Incorrect mapping. Missing "identifier" key.
10 | warnings:
11 | new_product: Product "%identifier%" does not exist. It cannot be updated.
12 | csv_advanced_product_export:
13 | export:
14 | errors:
15 | no_mapping: No mapping found.
16 | mail_notification:
17 | subject: "Import report '%importLabel%' (%date%)"
18 | step_title: "Step name"
19 | types:
20 | default: "Warnings:"
21 | statistics: "Summary:"
22 | statistics:
23 | read: "Lines read : %readCount%"
24 | write: "Processed : %writeCount%"
25 | warning: "Warnings : %warningCount%"
26 |
27 | # Custom entity
28 | importMapping:
29 | this:
30 | edit: Edit import mapping
31 | show: Show import mapping
32 | delete: Delete import mapping
33 |
34 | exportMapping:
35 | this:
36 | edit: Edit export mapping
37 | show: Show export mapping
38 | delete: Delete export mapping
39 |
40 | luaUpdater:
41 | this:
42 | edit: Edit LUA script
43 | show: Show LUA script
44 | delete: Delete LUA script
45 | validation:
46 | empty_script: Your script is empty.
47 | empty_test_value: Your test value is empty.
48 |
49 | pim_custom_entity:
50 | form:
51 | field:
52 | label:
53 | label: Label
54 | code: Code
55 |
56 | candm_advanced_csv_connector:
57 | acl:
58 | importMapping:
59 | index: List import mappings
60 | create: Create an import mapping
61 | edit: Edit an import mapping
62 | delete: Delete an import mapping
63 | exportMapping:
64 | index: List export mappings
65 | create: Create an export mapping
66 | edit: Edit an export mapping
67 | delete: Delete an export mapping
68 | luaUpdater:
69 | index: List LUA scripts
70 | create: Create a LUA script
71 | edit: Edit a LUA script
72 | delete: Delete a LUA script
73 |
--------------------------------------------------------------------------------
/Resources/config/acl.yml:
--------------------------------------------------------------------------------
1 | # Reference data
2 | ## Import Mapping
3 | candm_advanced_csv_connector_importMapping_index:
4 | type: action
5 | label: candm_advanced_csv_connector.acl.importMapping.index
6 | group_name: pim_custom_entity.acl_group.reference_data
7 |
8 | candm_advanced_csv_connector_importMapping_create:
9 | type: action
10 | label: candm_advanced_csv_connector.acl.importMapping.create
11 | group_name: pim_custom_entity.acl_group.reference_data
12 |
13 | candm_advanced_csv_connector_importMapping_edit:
14 | type: action
15 | label: candm_advanced_csv_connector.acl.importMapping.edit
16 | group_name: pim_custom_entity.acl_group.reference_data
17 |
18 | candm_advanced_csv_connector_importMapping_delete:
19 | type: action
20 | label: candm_advanced_csv_connector.acl.importMapping.delete
21 | group_name: pim_custom_entity.acl_group.reference_data
22 |
23 | ## Export Mapping
24 | candm_advanced_csv_connector_exportMapping_index:
25 | type: action
26 | label: candm_advanced_csv_connector.acl.exportMapping.index
27 | group_name: pim_custom_entity.acl_group.reference_data
28 |
29 | candm_advanced_csv_connector_exportMapping_create:
30 | type: action
31 | label: candm_advanced_csv_connector.acl.exportMapping.create
32 | group_name: pim_custom_entity.acl_group.reference_data
33 |
34 | candm_advanced_csv_connector_exportMapping_edit:
35 | type: action
36 | label: candm_advanced_csv_connector.acl.exportMapping.edit
37 | group_name: pim_custom_entity.acl_group.reference_data
38 |
39 | candm_advanced_csv_connector_exportMapping_delete:
40 | type: action
41 | label: candm_advanced_csv_connector.acl.exportMapping.delete
42 | group_name: pim_custom_entity.acl_group.reference_data
43 |
44 | ## Lua Updater
45 | candm_advanced_csv_connector_luaUpdater_index:
46 | type: action
47 | label: candm_advanced_csv_connector.acl.luaUpdater.index
48 | group_name: pim_custom_entity.acl_group.reference_data
49 |
50 | candm_advanced_csv_connector_luaUpdater_create:
51 | type: action
52 | label: candm_advanced_csv_connector.acl.luaUpdater.create
53 | group_name: pim_custom_entity.acl_group.reference_data
54 |
55 | candm_advanced_csv_connector_luaUpdater_edit:
56 | type: action
57 | label: candm_advanced_csv_connector.acl.luaUpdater.edit
58 | group_name: pim_custom_entity.acl_group.reference_data
59 |
60 | candm_advanced_csv_connector_luaUpdater_delete:
61 | type: action
62 | label: candm_advanced_csv_connector.acl.luaUpdater.delete
63 | group_name: pim_custom_entity.acl_group.reference_data
--------------------------------------------------------------------------------
/Resources/config/form_extensions/csv_advanced_product_export_show.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-job-instance-csv-advanced-product-export-show:
3 | module: pim/form/common/edit-form
4 |
5 | pim-job-instance-csv-advanced-product-export-show-main-image:
6 | module: pim/form/common/main-image
7 | parent: pim-job-instance-csv-advanced-product-export-show
8 | targetZone: main-image
9 | config:
10 | path: bundles/pimui/images/illustrations/ExportCSV.svg
11 |
12 | pim-job-instance-csv-advanced-product-export-show-user-navigation:
13 | module: pim/menu/user-navigation
14 | parent: pim-job-instance-csv-advanced-product-export-show
15 | targetZone: user-menu
16 | config:
17 | userAccount: pim_menu.user.user_account
18 | logout: pim_menu.user.logout
19 |
20 | pim-job-instance-csv-advanced-product-export-show-breadcrumbs:
21 | module: pim/job/common/breadcrumb/breadcrumb
22 | parent: pim-job-instance-csv-advanced-product-export-show
23 | targetZone: breadcrumbs
24 |
25 | pim-job-instance-csv-advanced-product-export-show-launch:
26 | module: pim/job/common/edit/launch
27 | parent: pim-job-instance-csv-advanced-product-export-show
28 | targetZone: meta
29 | position: 110
30 | config:
31 | label: pim_import_export.form.job_instance.button.export.title
32 | route: pim_enrich_job_instance_rest_export_launch
33 | identifier:
34 | path: code
35 | name: code
36 |
37 | pim-job-instance-csv-advanced-product-export-show-label:
38 | module: pim/job/common/edit/label
39 | parent: pim-job-instance-csv-advanced-product-export-show
40 | targetZone: title
41 | position: 100
42 |
43 | pim-job-instance-csv-advanced-product-export-show-edit:
44 | module: pim/job/common/edit-button
45 | parent: pim-job-instance-csv-advanced-product-export-show
46 | targetZone: buttons
47 | position: 100
48 | aclResourceId: pim_importexport_export_profile_edit
49 | config:
50 | label: pim_common.edit
51 | route: pim_importexport_export_profile_edit
52 | buttonClass: AknButton AknButton--action
53 | identifier:
54 | path: code
55 | name: code
56 |
57 | pim-job-instance-csv-advanced-product-export-show-last-executions:
58 | module: akeneojob/controller/job-instance
59 | parent: pim-job-instance-csv-advanced-product-export-show
60 | position: 100
61 | targetZone: content
62 |
--------------------------------------------------------------------------------
/Resources/public/js/form/common/fields/lua-script.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | define([
4 | 'jquery',
5 | 'underscore',
6 | 'routing',
7 | 'pim/form/common/fields/field',
8 | 'pim/template/form/common/fields/lua-script'
9 | ],
10 | function (
11 | $,
12 | _,
13 | Routing,
14 | BaseField,
15 | template
16 | ) {
17 | return BaseField.extend({
18 | template: _.template(template),
19 | events: {
20 | 'keyup textarea': function (event) {
21 | this.errors = [];
22 | this.updateModel(this.getFieldValue(event.target));
23 | },
24 | 'click .AknButton--apply': function (event) {
25 | var $messageContainer = $('.lua-message-container');
26 | var data = {
27 | 'script': this.getModelValue(),
28 | 'testValue': $('.AknTextField--testValue').val()
29 | };
30 |
31 | $.ajax({
32 | method: 'POST',
33 | url: Routing.generate('candm_advanced_csv_connector_api_luaUpdater_test'),
34 | contentType: 'application/json',
35 | data: JSON.stringify(data),
36 | success: function (response) {
37 | $messageContainer.empty();
38 | if (_.has(response, 'value')) {
39 | $messageContainer.append('' + response.value + '
');
40 | }
41 | },
42 | error: function (response) {
43 | $messageContainer.empty();
44 | if (_.has(response.responseJSON, 'message')) {
45 | $messageContainer.append('' + response.responseJSON.message + '
');
46 | }
47 | }
48 | });
49 | }
50 | },
51 |
52 | /**
53 | * {@inheritdoc}
54 | */
55 | renderInput: function (templateContext) {
56 | return this.template(_.extend(templateContext, {
57 | value: this.getModelValue()
58 | }));
59 | },
60 |
61 | /**
62 | * {@inheritdoc}
63 | */
64 | getFieldValue: function (field) {
65 | return $(field).val();
66 | },
67 | });
68 | });
69 |
--------------------------------------------------------------------------------
/Resources/config/form_extensions/csv_advanced_product_model_export_show.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-job-instance-csv-advanced-product-model-export-show:
3 | module: pim/form/common/edit-form
4 |
5 | pim-job-instance-csv-advanced-product-model-export-show-main-image:
6 | module: pim/form/common/main-image
7 | parent: pim-job-instance-csv-advanced-product-model-export-show
8 | targetZone: main-image
9 | config:
10 | path: bundles/pimui/images/illustrations/ExportCSV.svg
11 |
12 | pim-job-instance-csv-advanced-product-model-export-show-user-navigation:
13 | module: pim/menu/user-navigation
14 | parent: pim-job-instance-csv-advanced-product-model-export-show
15 | targetZone: user-menu
16 | config:
17 | userAccount: pim_menu.user.user_account
18 | logout: pim_menu.user.logout
19 |
20 | pim-job-instance-csv-advanced-product-model-export-show-breadcrumbs:
21 | module: pim/job/common/breadcrumb/breadcrumb
22 | parent: pim-job-instance-csv-advanced-product-model-export-show
23 | targetZone: breadcrumbs
24 |
25 | pim-job-instance-csv-advanced-product-model-export-show-launch:
26 | module: pim/job/common/edit/launch
27 | parent: pim-job-instance-csv-advanced-product-model-export-show
28 | targetZone: meta
29 | position: 110
30 | config:
31 | label: pim_import_export.form.job_instance.button.export.title
32 | route: pim_enrich_job_instance_rest_export_launch
33 | identifier:
34 | path: code
35 | name: code
36 |
37 | pim-job-instance-csv-advanced-product-model-export-show-label:
38 | module: pim/job/common/edit/label
39 | parent: pim-job-instance-csv-advanced-product-model-export-show
40 | targetZone: title
41 | position: 100
42 |
43 | pim-job-instance-csv-advanced-product-model-export-show-edit:
44 | module: pim/job/common/edit-button
45 | parent: pim-job-instance-csv-advanced-product-model-export-show
46 | targetZone: buttons
47 | position: 100
48 | aclResourceId: pim_importexport_export_profile_edit
49 | config:
50 | label: pim_common.edit
51 | route: pim_importexport_export_profile_edit
52 | buttonClass: AknButton AknButton--action
53 | identifier:
54 | path: code
55 | name: code
56 |
57 | pim-job-instance-csv-advanced-product-model-export-show-last-executions:
58 | module: akeneojob/controller/job-instance
59 | parent: pim-job-instance-csv-advanced-product-model-export-show
60 | position: 100
61 | targetZone: content
--------------------------------------------------------------------------------
/Resources/config/job_defaults.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_import.class: ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\DefaultValuesProvider\ProductCsvAdvancedImport
3 | candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_export.class: ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\DefaultValuesProvider\ProductCsvAdvancedExport
4 |
5 | services:
6 | candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_import:
7 | class: '%candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_import.class%'
8 | arguments:
9 | - '@pim_connector.job.job_parameters.default_values_provider.product_csv_import'
10 | -
11 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_import%'
12 | tags:
13 | - { name: akeneo_batch.job.job_parameters.default_values_provider }
14 |
15 | candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_model_csv_import:
16 | class: '%candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_import.class%'
17 | arguments:
18 | - '@pim_connector.job.job_parameters.default_values_provider.product_model_csv_import'
19 | -
20 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_model_import%'
21 | tags:
22 | - { name: akeneo_batch.job.job_parameters.default_values_provider }
23 |
24 | candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_export:
25 | class: '%candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_export.class%'
26 | arguments:
27 | - '@pim_connector.job.job_parameters.default_values_provider.product_csv_export'
28 | -
29 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_export%'
30 | tags:
31 | - { name: akeneo_batch.job.job_parameters.default_values_provider }
32 |
33 | candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_model_csv_advanced_export:
34 | class: '%candm_advanced_csv_connector.job.job_parameters.default_values_provider.product_csv_advanced_export.class%'
35 | arguments:
36 | - '@pim_connector.job.job_parameters.default_values_provider.product_model_csv_export'
37 | -
38 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_model_export%'
39 | tags:
40 | - { name: akeneo_batch.job.job_parameters.default_values_provider }
41 |
--------------------------------------------------------------------------------
/Resources/translations/messages.fr.yml:
--------------------------------------------------------------------------------
1 | # Custom
2 | batch_jobs:
3 | csv_advanced_product_import:
4 | import:
5 | errors:
6 | no_mapping: Aucun mapping trouvé. Merci de réessayer.
7 | mapping_attributes_error: Le mapping est incorrect. La clé "attributes" est manquante.
8 | mapping_no_attribute_code: Le mapping est incorrect. La clé "attributeCode" est manquante pour un attribut.
9 | mapping_no_identifier: Le mapping est incorrect. la clé "identifier" est manquante sur au moins un attribut.
10 | warnings:
11 | new_product: Le produit "%identifier%" n'existe pas, il ne peut pas être mis à jour.
12 | csv_advanced_product_export:
13 | export:
14 | errors:
15 | no_mapping: Aucun mapping trouvé. Merci de réessayer.
16 | mail_notification:
17 | subject: "Rapport de l'import '%importLabel%' (%date%)"
18 | step_title: "Nom de l'étape"
19 | types:
20 | default: "Liste des avertissements :"
21 | statistics: "Résumé :"
22 | statistics:
23 | read: "Lignes lues : %readCount%"
24 | write: "Traité(s) : %writeCount%"
25 | warning: "Avertissements : %warningCount%"
26 |
27 | # Custom entity
28 | importMapping:
29 | this:
30 | edit: Éditer le mapping d'import
31 | show: Afficher le mapping d'import
32 | delete: Supprimer le mapping d'import
33 |
34 | exportMapping:
35 | this:
36 | edit: Éditer le mapping d'export
37 | show: Afficher le mapping d'export
38 | delete: Supprimer le mapping d'export
39 |
40 | luaUpdater:
41 | this:
42 | edit: Éditer le script LUA
43 | show: Afficher le script LUA
44 | delete: Supprimer le script LUA
45 | validation:
46 | empty_script: Votre script est vide.
47 | empty_test_value: Votre valeur de test est vide.
48 |
49 | pim_custom_entity:
50 | form:
51 | field:
52 | label:
53 | label: Libellé
54 | code: Code
55 |
56 | candm_advanced_csv_connector:
57 | acl:
58 | importMapping:
59 | index: Lister les mappings d'import
60 | create: Créer un mapping d'import
61 | edit: Éditer un mapping d'import
62 | delete: Supprimer un mapping d'import
63 | exportMapping:
64 | index: Lister les mappings d'export
65 | create: Créer un mapping d'export
66 | edit: Éditer un mapping d'export
67 | delete: Supprimer un mapping d'export
68 | luaUpdater:
69 | index: Lister les scripts LUA
70 | create: Créer un script LUA
71 | edit: Éditer un script LUA
72 | delete: Supprimer un script LUA
73 |
--------------------------------------------------------------------------------
/Resources/config/job_constraints.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_advanced_import.class: ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\ConstraintCollectionProvider\ProductCsvAdvancedImport
3 | candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_advanced_export.class: ClickAndMortar\AdvancedCsvConnectorBundle\Job\JobParameters\ConstraintCollectionProvider\ProductCsvAdvancedExport
4 |
5 | services:
6 | candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_import:
7 | class: '%candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_advanced_import.class%'
8 | arguments:
9 | - '@pim_connector.job.job_parameters.constraint_collection_provider.product_csv_import'
10 | -
11 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_import%'
12 | tags:
13 | - { name: akeneo_batch.job.job_parameters.constraint_collection_provider }
14 |
15 | candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_model_csv_import:
16 | class: '%candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_advanced_import.class%'
17 | arguments:
18 | - '@pim_connector.job.job_parameters.constraint_collection_provider.product_model_csv_import'
19 | -
20 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_model_import%'
21 | tags:
22 | - { name: akeneo_batch.job.job_parameters.constraint_collection_provider }
23 |
24 | candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_export:
25 | class: '%candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_advanced_export.class%'
26 | arguments:
27 | - '@pim_connector.job.job_parameters.constraint_collection_provider.product_csv_export'
28 | -
29 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_export%'
30 | tags:
31 | - { name: akeneo_batch.job.job_parameters.constraint_collection_provider }
32 |
33 | candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_model_csv_export:
34 | class: '%candm_advanced_csv_connector.job.job_parameters.constraint_collection_provider.product_csv_advanced_export.class%'
35 | arguments:
36 | - '@pim_connector.job.job_parameters.constraint_collection_provider.product_model_csv_export'
37 | -
38 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_model_export%'
39 | tags:
40 | - { name: akeneo_batch.job.job_parameters.constraint_collection_provider }
--------------------------------------------------------------------------------
/Archiver/AdvancedFileReaderArchiver.php:
--------------------------------------------------------------------------------
1 |
14 | * @package Pim\Component\Connector\Archiver
15 | */
16 | class AdvancedFileReaderArchiver extends FileReaderArchiver
17 | {
18 | /**
19 | * Archive files used by job execution (input / output)
20 | *
21 | * @param JobExecution $jobExecution
22 | */
23 | public function archive(JobExecution $jobExecution): void
24 | {
25 | $job = $this->jobRegistry->get($jobExecution->getJobInstance()->getJobName());
26 | foreach ($job->getSteps() as $step) {
27 | if (
28 | method_exists($step, 'getReader')
29 | && $step->getReader() instanceof MultiFilesReaderInterface
30 | ) {
31 | $reader = $step->getReader();
32 | $filePaths = $reader->getFilePaths();
33 | foreach ($filePaths as $filePath) {
34 | if (file_exists($filePath)) {
35 | $archivePath = strtr(
36 | $this->getRelativeArchivePath($jobExecution),
37 | [
38 | '%filename%' => basename($filePath),
39 | ]
40 | );
41 |
42 | if (is_readable($filePath)) {
43 | $fileResource = fopen($filePath, 'r');
44 | $this->filesystem->writeStream($archivePath, $fileResource);
45 |
46 | if (is_resource($fileResource)) {
47 | fclose($fileResource);
48 | }
49 | }
50 | unlink($filePath);
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
57 | /**
58 | * Check if the job execution is supported
59 | *
60 | * @param JobExecution $jobExecution
61 | *
62 | * @return bool
63 | */
64 | public function supports(JobExecution $jobExecution): bool
65 | {
66 | $job = $this->jobRegistry->get($jobExecution->getJobInstance()->getJobName());
67 | foreach ($job->getSteps() as $step) {
68 | if (
69 | method_exists($step, 'getReader')
70 | && $step->getReader() instanceof MultiFilesReaderInterface
71 | ) {
72 | return true;
73 | }
74 | }
75 |
76 | return false;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Resources/config/form_extensions/luaUpdater/index.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-luaUpdater-index:
3 | module: pim/common/simple-view
4 | config:
5 | template: pim/template/common/default-template
6 | forwarded-events:
7 | grid_load:start: grid_load:start
8 | grid_load:complete: grid_load:complete
9 |
10 | pim-luaUpdater-index-grid-container:
11 | module: pim/common/simple-view
12 | parent: pim-luaUpdater-index
13 | targetZone: content
14 | config:
15 | template: pim/template/form/index/index
16 |
17 | pim-luaUpdater-index-user-navigation:
18 | module: pim/menu/user-navigation
19 | parent: pim-luaUpdater-index
20 | targetZone: user-menu
21 | config:
22 | userAccount: pim_menu.user.user_account
23 | logout: pim_menu.user.logout
24 |
25 | pim-luaUpdater-index-grid-title:
26 | module: pim/common/grid-title
27 | parent: pim-luaUpdater-index
28 | targetZone: title
29 | config:
30 | title: candm_advanced_csv_connector.luaUpdater.index_title
31 |
32 | pim-luaUpdater-index-breadcrumbs:
33 | module: pim/common/breadcrumbs
34 | parent: pim-luaUpdater-index
35 | targetZone: breadcrumbs
36 | config:
37 | tab: pim-menu-reference_data
38 | item: candm_advanced_csv_connector-menu-reference_data-item-luaUpdater
39 |
40 | pim-luaUpdater-index-grid-filters-list:
41 | module: oro/datafilter/filters-list
42 | parent: pim-luaUpdater-index-grid-container
43 | targetZone: filters
44 |
45 | pim-luaUpdater-index-grid-filters-manage:
46 | module: oro/datafilter/filters-button
47 | parent: pim-luaUpdater-index-grid-container
48 | targetZone: filters
49 |
50 | pim-luaUpdater-index-mass-actions:
51 | module: pim/grid/mass-actions
52 | parent: pim-luaUpdater-index
53 | targetZone: bottom-panel
54 | config:
55 | label: candm_advanced_csv_connector.luaUpdater.selected
56 |
57 | pim-luaUpdater-index-actions-panel:
58 | module: oro/datagrid/actions-panel
59 | parent: pim-luaUpdater-index-mass-actions
60 | targetZone: actions-panel
61 |
62 | pim-luaUpdater-index-pagination:
63 | module: oro/datagrid/pagination-input
64 | parent: pim-luaUpdater-index-grid-container
65 | targetZone: toolbar
66 | config:
67 | gridName: luaUpdater
68 |
69 | pim-luaUpdater-index-grid:
70 | module: pim/form/common/index/grid
71 | parent: pim-luaUpdater-index
72 | targetZone: content
73 | position: 1000
74 | config:
75 | alias: luaUpdater
76 |
77 | pim-luaUpdater-index-create-button:
78 | module: pim/form/common/index/create-button
79 | parent: pim-luaUpdater-index
80 | targetZone: buttons
81 | aclResourceId: pim_enrich_product_create
82 | config:
83 | title: pim_custom_entity.button.create
84 | modalForm: pim-luaUpdater-create-modal
--------------------------------------------------------------------------------
/Resources/config/datagrid/lua_updater.yml:
--------------------------------------------------------------------------------
1 | datagrid:
2 | luaUpdater:
3 | options:
4 | entityHint: luaUpdater
5 | manageFilters: false
6 | source:
7 | type: pim_datasource_default
8 | entity: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\LuaUpdater
9 | repository_method: createDatagridQueryBuilder
10 | columns:
11 | label:
12 | label: pim_custom_entity.form.field.label.label
13 | code:
14 | label: pim_custom_entity.form.field.label.code
15 | properties:
16 | id: ~
17 | edit_link:
18 | type: url
19 | route: pim_customentity_rest_get
20 | params:
21 | - id
22 | - customEntityName
23 | delete_link:
24 | type: url
25 | route: pim_customentity_rest_delete
26 | params:
27 | - id
28 | - customEntityName
29 | actions:
30 | edit:
31 | type: navigate
32 | acl_resource: candm_advanced_csv_connector_luaUpdater_edit
33 | label: luaUpdater.this.edit
34 | icon: edit
35 | link: edit_link
36 | rowAction: true
37 | delete:
38 | type: delete
39 | acl_resource: candm_advanced_csv_connector_luaUpdater_delete
40 | label: luaUpdater.this.delete
41 | icon: trash
42 | link: delete_link
43 | filters:
44 | columns:
45 | label:
46 | type: string
47 | label: pim_custom_entity.form.field.label.label
48 | data_name: rd.label
49 | code:
50 | type: string
51 | label: pim_custom_entity.form.field.label.code
52 | data_name: rd.code
53 | sorters:
54 | columns:
55 | label:
56 | data_name: rd.label
57 | code:
58 | data_name: rd.code
59 | default:
60 | code: '%oro_datagrid.extension.orm_sorter.class%::DIRECTION_ASC'
61 |
62 | mass_actions:
63 | delete:
64 | type: delete
65 | label: pim.grid.mass_action.delete
66 | entity_name: brand
67 | acl_resource: ~
68 | handler: mass_delete
69 | className: 'AknButton AknButton--important AknButtonList-item'
70 | messages:
71 | confirm_title: pim_datagrid.mass_action.delete.confirm_title
72 | confirm_content: pim_datagrid.mass_action.delete.confirm_content
73 | confirm_ok: OK
74 | success: pim_datagrid.mass_action.delete.success
75 | error: pim_datagrid.mass_action.delete.error
76 | empty_selection: pim_datagrid.mass_action.delete.empty_selection
--------------------------------------------------------------------------------
/Resources/config/datagrid/export_mapping.yml:
--------------------------------------------------------------------------------
1 | datagrid:
2 | exportMapping:
3 | options:
4 | entityHint: exportMapping
5 | manageFilters: false
6 | source:
7 | type: pim_datasource_default
8 | entity: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ExportMapping
9 | repository_method: createDatagridQueryBuilder
10 | columns:
11 | label:
12 | label: pim_custom_entity.form.field.label.label
13 | code:
14 | label: pim_custom_entity.form.field.label.code
15 | properties:
16 | id: ~
17 | edit_link:
18 | type: url
19 | route: pim_customentity_rest_get
20 | params:
21 | - id
22 | - customEntityName
23 | delete_link:
24 | type: url
25 | route: pim_customentity_rest_delete
26 | params:
27 | - id
28 | - customEntityName
29 | actions:
30 | edit:
31 | type: navigate
32 | acl_resource: candm_advanced_csv_connector_exportMapping_edit
33 | label: exportMapping.this.edit
34 | icon: edit
35 | link: edit_link
36 | rowAction: true
37 | delete:
38 | type: delete
39 | acl_resource: candm_advanced_csv_connector_exportMapping_delete
40 | label: exportMapping.this.delete
41 | icon: trash
42 | link: delete_link
43 | filters:
44 | columns:
45 | label:
46 | type: string
47 | label: pim_custom_entity.form.field.label.label
48 | data_name: rd.label
49 | code:
50 | type: string
51 | label: pim_custom_entity.form.field.label.code
52 | data_name: rd.code
53 | sorters:
54 | columns:
55 | label:
56 | data_name: rd.label
57 | code:
58 | data_name: rd.code
59 | default:
60 | code: '%oro_datagrid.extension.orm_sorter.class%::DIRECTION_ASC'
61 |
62 | mass_actions:
63 | delete:
64 | type: delete
65 | label: pim.grid.mass_action.delete
66 | entity_name: brand
67 | acl_resource: ~
68 | handler: mass_delete
69 | className: 'AknButton AknButton--important AknButtonList-item'
70 | messages:
71 | confirm_title: pim_datagrid.mass_action.delete.confirm_title
72 | confirm_content: pim_datagrid.mass_action.delete.confirm_content
73 | confirm_ok: OK
74 | success: pim_datagrid.mass_action.delete.success
75 | error: pim_datagrid.mass_action.delete.error
76 | empty_selection: pim_datagrid.mass_action.delete.empty_selection
--------------------------------------------------------------------------------
/Resources/config/datagrid/import_mapping.yml:
--------------------------------------------------------------------------------
1 | datagrid:
2 | importMapping:
3 | options:
4 | entityHint: importMapping
5 | manageFilters: false
6 | source:
7 | type: pim_datasource_default
8 | entity: ClickAndMortar\AdvancedCsvConnectorBundle\Entity\ImportMapping
9 | repository_method: createDatagridQueryBuilder
10 | columns:
11 | label:
12 | label: pim_custom_entity.form.field.label.label
13 | code:
14 | label: pim_custom_entity.form.field.label.code
15 | properties:
16 | id: ~
17 | edit_link:
18 | type: url
19 | route: pim_customentity_rest_get
20 | params:
21 | - id
22 | - customEntityName
23 | delete_link:
24 | type: url
25 | route: pim_customentity_rest_delete
26 | params:
27 | - id
28 | - customEntityName
29 | actions:
30 | edit:
31 | type: navigate
32 | acl_resource: candm_advanced_csv_connector_importMapping_edit
33 | label: importMapping.this.edit
34 | icon: edit
35 | link: edit_link
36 | rowAction: true
37 | delete:
38 | type: delete
39 | acl_resource: candm_advanced_csv_connector_importMapping_delete
40 | label: importMapping.this.delete
41 | icon: trash
42 | link: delete_link
43 | filters:
44 | columns:
45 | label:
46 | type: string
47 | label: pim_custom_entity.form.field.label.label
48 | data_name: rd.label
49 | code:
50 | type: string
51 | label: pim_custom_entity.form.field.label.code
52 | data_name: rd.code
53 | sorters:
54 | columns:
55 | label:
56 | data_name: rd.label
57 | code:
58 | data_name: rd.code
59 | default:
60 | code: '%oro_datagrid.extension.orm_sorter.class%::DIRECTION_ASC'
61 |
62 | mass_actions:
63 | delete:
64 | type: delete
65 | label: pim.grid.mass_action.delete
66 | entity_name: brand
67 | acl_resource: ~
68 | handler: mass_delete
69 | className: 'AknButton AknButton--important AknButtonList-item'
70 | messages:
71 | confirm_title: pim_datagrid.mass_action.delete.confirm_title
72 | confirm_content: pim_datagrid.mass_action.delete.confirm_content
73 | confirm_ok: OK
74 | success: pim_datagrid.mass_action.delete.success
75 | error: pim_datagrid.mass_action.delete.error
76 | empty_selection: pim_datagrid.mass_action.delete.empty_selection
--------------------------------------------------------------------------------
/Resources/config/form_extensions/exportMapping/index.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-exportMapping-index:
3 | module: pim/common/simple-view
4 | config:
5 | template: pim/template/common/default-template
6 | forwarded-events:
7 | grid_load:start: grid_load:start
8 | grid_load:complete: grid_load:complete
9 |
10 | pim-exportMapping-index-grid-container:
11 | module: pim/common/simple-view
12 | parent: pim-exportMapping-index
13 | targetZone: content
14 | config:
15 | template: pim/template/form/index/index
16 |
17 | pim-exportMapping-index-user-navigation:
18 | module: pim/menu/user-navigation
19 | parent: pim-exportMapping-index
20 | targetZone: user-menu
21 | config:
22 | userAccount: pim_menu.user.user_account
23 | logout: pim_menu.user.logout
24 |
25 | pim-exportMapping-index-grid-title:
26 | module: pim/common/grid-title
27 | parent: pim-exportMapping-index
28 | targetZone: title
29 | config:
30 | title: candm_advanced_csv_connector.exportMapping.index_title
31 |
32 | pim-exportMapping-index-breadcrumbs:
33 | module: pim/common/breadcrumbs
34 | parent: pim-exportMapping-index
35 | targetZone: breadcrumbs
36 | config:
37 | tab: pim-menu-reference_data
38 | item: candm_advanced_csv_connector-menu-reference_data-item-exportMapping
39 |
40 | pim-exportMapping-index-grid-filters-list:
41 | module: oro/datafilter/filters-list
42 | parent: pim-exportMapping-index-grid-container
43 | targetZone: filters
44 |
45 | pim-exportMapping-index-grid-filters-manage:
46 | module: oro/datafilter/filters-button
47 | parent: pim-exportMapping-index-grid-container
48 | targetZone: filters
49 |
50 | pim-exportMapping-index-mass-actions:
51 | module: pim/grid/mass-actions
52 | parent: pim-exportMapping-index
53 | targetZone: bottom-panel
54 | config:
55 | label: candm_advanced_csv_connector.exportMapping.selected
56 |
57 | pim-exportMapping-index-actions-panel:
58 | module: oro/datagrid/actions-panel
59 | parent: pim-exportMapping-index-mass-actions
60 | targetZone: actions-panel
61 |
62 | pim-exportMapping-index-pagination:
63 | module: oro/datagrid/pagination-input
64 | parent: pim-exportMapping-index-grid-container
65 | targetZone: toolbar
66 | config:
67 | gridName: exportMapping
68 |
69 | pim-exportMapping-index-grid:
70 | module: pim/form/common/index/grid
71 | parent: pim-exportMapping-index
72 | targetZone: content
73 | position: 1000
74 | config:
75 | alias: exportMapping
76 |
77 | pim-exportMapping-index-create-button:
78 | module: pim/form/common/index/create-button
79 | parent: pim-exportMapping-index
80 | targetZone: buttons
81 | aclResourceId: pim_enrich_product_create
82 | config:
83 | title: pim_custom_entity.button.create
84 | modalForm: pim-exportMapping-create-modal
--------------------------------------------------------------------------------
/Resources/config/form_extensions/importMapping/index.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-importMapping-index:
3 | module: pim/common/simple-view
4 | config:
5 | template: pim/template/common/default-template
6 | forwarded-events:
7 | grid_load:start: grid_load:start
8 | grid_load:complete: grid_load:complete
9 |
10 | pim-importMapping-index-grid-container:
11 | module: pim/common/simple-view
12 | parent: pim-importMapping-index
13 | targetZone: content
14 | config:
15 | template: pim/template/form/index/index
16 |
17 | pim-importMapping-index-user-navigation:
18 | module: pim/menu/user-navigation
19 | parent: pim-importMapping-index
20 | targetZone: user-menu
21 | config:
22 | userAccount: pim_menu.user.user_account
23 | logout: pim_menu.user.logout
24 |
25 | pim-importMapping-index-grid-title:
26 | module: pim/common/grid-title
27 | parent: pim-importMapping-index
28 | targetZone: title
29 | config:
30 | title: candm_advanced_csv_connector.importMapping.index_title
31 |
32 | pim-importMapping-index-breadcrumbs:
33 | module: pim/common/breadcrumbs
34 | parent: pim-importMapping-index
35 | targetZone: breadcrumbs
36 | config:
37 | tab: pim-menu-reference_data
38 | item: candm_advanced_csv_connector-menu-reference_data-item-importMapping
39 |
40 | pim-importMapping-index-grid-filters-list:
41 | module: oro/datafilter/filters-list
42 | parent: pim-importMapping-index-grid-container
43 | targetZone: filters
44 |
45 | pim-importMapping-index-grid-filters-manage:
46 | module: oro/datafilter/filters-button
47 | parent: pim-importMapping-index-grid-container
48 | targetZone: filters
49 |
50 | pim-importMapping-index-mass-actions:
51 | module: pim/grid/mass-actions
52 | parent: pim-importMapping-index
53 | targetZone: bottom-panel
54 | config:
55 | label: candm_advanced_csv_connector.importMapping.selected
56 |
57 | pim-importMapping-index-actions-panel:
58 | module: oro/datagrid/actions-panel
59 | parent: pim-importMapping-index-mass-actions
60 | targetZone: actions-panel
61 |
62 | pim-importMapping-index-pagination:
63 | module: oro/datagrid/pagination-input
64 | parent: pim-importMapping-index-grid-container
65 | targetZone: toolbar
66 | config:
67 | gridName: importMapping
68 |
69 | pim-importMapping-index-grid:
70 | module: pim/form/common/index/grid
71 | parent: pim-importMapping-index
72 | targetZone: content
73 | position: 1000
74 | config:
75 | alias: importMapping
76 |
77 | pim-importMapping-index-create-button:
78 | module: pim/form/common/index/create-button
79 | parent: pim-importMapping-index
80 | targetZone: buttons
81 | aclResourceId: pim_enrich_product_create
82 | config:
83 | title: pim_custom_entity.button.create
84 | modalForm: pim-importMapping-create-modal
--------------------------------------------------------------------------------
/Helper/ExportHelper.php:
--------------------------------------------------------------------------------
1 |
13 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Helper
14 | */
15 | class ExportHelper
16 | {
17 | /**
18 | * Multi select values separator
19 | *
20 | * @var string
21 | */
22 | const MULTI_SELECT_SEPARATOR = ',';
23 |
24 | /**
25 | * Entity manager
26 | *
27 | * @var EntityManager
28 | */
29 | protected $entityManager;
30 |
31 | /**
32 | * Attribute option repository
33 | *
34 | * @var AttributeOptionRepository
35 | */
36 | protected $attributeOptionRepository;
37 |
38 | /**
39 | * ExportHelper constructor.
40 | *
41 | * @param EntityManager $entityManager
42 | */
43 | public function __construct(EntityManager $entityManager, AttributeOptionRepository $attributeOptionRepository)
44 | {
45 | $this->entityManager = $entityManager;
46 | $this->attributeOptionRepository = $attributeOptionRepository;
47 | }
48 |
49 | /**
50 | * Get value from code in a list case
51 | *
52 | * @param string $attributeKey
53 | * @param string $attributeValue
54 | * @param string $locale
55 | *
56 | * @return string
57 | */
58 | public function getValueFromCode($attributeKey, $attributeValue, $locale)
59 | {
60 | // Use loop if we have multi select attribute
61 | $labelAsArray = [];
62 | $attributeValues = explode(self::MULTI_SELECT_SEPARATOR, $attributeValue);
63 | foreach ($attributeValues as $attributeValue) {
64 | $option = $this->attributeOptionRepository->findOptionByCode($attributeKey, array($attributeValue));
65 | if (empty($option) || empty($option[0])) {
66 | continue;
67 | }
68 |
69 | $option[0]->setLocale($locale)->getTranslation();
70 | $labelAsArray[] = $option[0]->getOptionValue()->getLabel();
71 | }
72 |
73 | return implode(self::MULTI_SELECT_SEPARATOR, $labelAsArray);
74 | }
75 |
76 | /**
77 | * Encode given $filePath with $encoding from UTF-8
78 | *
79 | * @param string $filePath
80 | * @param string $encoding
81 | *
82 | * @return void
83 | */
84 | public function encodeFile($filePath, $encoding)
85 | {
86 | $tempFilePath = sprintf('%s.tmp', $filePath);
87 | $encodeFileCommand = sprintf(
88 | 'iconv -f UTF-8 -t %s//TRANSLIT %s > %s',
89 | $encoding,
90 | $filePath,
91 | $tempFilePath
92 | );
93 | $encodeFileProcess = Process::fromShellCommandline($encodeFileCommand);
94 | $encodeFileProcess->mustRun();
95 |
96 | if (file_exists($tempFilePath)) {
97 | unlink($filePath);
98 | rename($tempFilePath, $filePath);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/Resources/config/steps.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | pim_connector.step.product.import.bulk_size: 100
3 | candm_advanced_csv_connector.step.mail_notification.class: 'ClickAndMortar\AdvancedCsvConnectorBundle\Step\MailNotification'
4 |
5 | services:
6 | candm_advanced_csv_connector.step.csv_advanced_product.import:
7 | class: '%pim_connector.step.item_step.class%'
8 | arguments:
9 | - 'import'
10 | - '@event_dispatcher'
11 | - '@akeneo_batch.job_repository'
12 | - '@candm_advanced_csv_connector.reader.file.csv_advanced_product'
13 | - '@pim_connector.processor.denormalization.product'
14 | - '@pim_connector.writer.database.product'
15 | - '%pim_connector.step.product.import.bulk_size%'
16 |
17 | candm_advanced_csv_connector.step.csv_advanced_root_product_model.import:
18 | class: '%pim_connector.step.item_step.class%'
19 | arguments:
20 | - 'import_root_product_model'
21 | - '@event_dispatcher'
22 | - '@akeneo_batch.job_repository'
23 | - '@candm_advanced_csv_connector.reader.file.csv_advanced_product_model'
24 | - '@pim_connector.processor.denormalization.root_product_model'
25 | - '@pim_connector.writer.database.product_model'
26 | - '%pim_job_product_batch_size%'
27 |
28 | candm_advanced_csv_connector.step.csv_advanced_sub_product_model.import:
29 | class: '%pim_connector.step.item_step.class%'
30 | arguments:
31 | - 'import_sub_product_model'
32 | - '@event_dispatcher'
33 | - '@akeneo_batch.job_repository'
34 | - '@candm_advanced_csv_connector.reader.file.csv_advanced_product_model'
35 | - '@pim_connector.processor.denormalization.sub_product_model'
36 | - '@pim_connector.writer.database.product_model'
37 | - '%pim_job_product_batch_size%'
38 |
39 | candm_advanced_csv_connector.step.csv_advanced_product.export:
40 | class: '%pim_connector.step.item_step.class%'
41 | arguments:
42 | - 'export'
43 | - '@event_dispatcher'
44 | - '@akeneo_batch.job_repository'
45 | - '@pim_connector.reader.database.product'
46 | - '@pim_connector.processor.normalization.product'
47 | - '@candm_advanced_csv_connector.writer.file.csv_advanced_product'
48 | - '%pim_job_product_batch_size%'
49 |
50 | candm_advanced_csv_connector.step.csv_advanced_product_model.export:
51 | class: '%pim_connector.step.item_step.class%'
52 | arguments:
53 | - 'export'
54 | - '@event_dispatcher'
55 | - '@akeneo_batch.job_repository'
56 | - '@pim_connector.reader.database.product_model'
57 | - '@pim_connector.processor.normalization.product_model'
58 | - '@candm_advanced_csv_connector.writer.file.csv_advanced_product_model'
59 | - '%pim_job_product_batch_size%'
60 |
61 | candm_advanced_csv_connector.step.mail_notification:
62 | class: '%candm_advanced_csv_connector.step.mail_notification.class%'
63 | arguments:
64 | - 'notification'
65 | - '@event_dispatcher'
66 | - '@akeneo_batch.job_repository'
67 | - '@pim_notification.email.email_notifier'
68 | - '@twig'
69 | - '@translator'
70 |
--------------------------------------------------------------------------------
/Resources/config/jobs.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.connector_name.csv: 'Click And Mortar Advanced CSV Connector'
3 | candm_advanced_csv_connector.job_name.csv_advanced_product_import: 'csv_advanced_product_import'
4 | candm_advanced_csv_connector.job_name.csv_advanced_product_model_import: 'csv_advanced_product_model_import'
5 | candm_advanced_csv_connector.job_name.csv_advanced_product_export: 'csv_advanced_product_export'
6 | candm_advanced_csv_connector.job_name.csv_advanced_product_model_export: 'csv_advanced_product_model_export'
7 |
8 | services:
9 | candm_advanced_csv_connector.job.csv_advanced_product_import:
10 | class: '%pim_connector.job.simple_job.class%'
11 | arguments:
12 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_import%'
13 | - '@event_dispatcher'
14 | - '@akeneo_batch.job_repository'
15 | -
16 | - '@akeneo.job_automation.connector.step.download'
17 | - '@candm_advanced_csv_connector.step.csv_advanced_product.import'
18 | - '@candm_advanced_csv_connector.step.mail_notification'
19 | tags:
20 | - { name: akeneo_batch.job, connector: '%candm_advanced_csv_connector.connector_name.csv%', type: '%pim_connector.job.import_type%' }
21 |
22 | candm_advanced_csv_connector.job.csv_advanced_product_model_import:
23 | class: '%pim_connector.job.simple_job.class%'
24 | arguments:
25 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_model_import%'
26 | - '@event_dispatcher'
27 | - '@akeneo_batch.job_repository'
28 | -
29 | - '@akeneo.job_automation.connector.step.download'
30 | - '@candm_advanced_csv_connector.step.csv_advanced_root_product_model.import'
31 | - '@candm_advanced_csv_connector.step.csv_advanced_sub_product_model.import'
32 | - '@candm_advanced_csv_connector.step.mail_notification'
33 | tags:
34 | - { name: akeneo_batch.job, connector: '%candm_advanced_csv_connector.connector_name.csv%', type: '%pim_connector.job.import_type%' }
35 |
36 | candm_advanced_csv_connector.job.csv_advanced_product_export:
37 | class: '%pim_connector.job.simple_job.class%'
38 | arguments:
39 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_export%'
40 | - '@event_dispatcher'
41 | - '@akeneo_batch.job_repository'
42 | -
43 | - '@candm_advanced_csv_connector.step.csv_advanced_product.export'
44 | - '@akeneo.job_automation.connector.step.upload'
45 | tags:
46 | - { name: akeneo_batch.job, connector: '%candm_advanced_csv_connector.connector_name.csv%', type: '%pim_connector.job.export_type%' }
47 |
48 | candm_advanced_csv_connector.job.csv_advanced_product_model_export:
49 | class: '%pim_connector.job.simple_job.class%'
50 | arguments:
51 | - '%candm_advanced_csv_connector.job_name.csv_advanced_product_model_export%'
52 | - '@event_dispatcher'
53 | - '@akeneo_batch.job_repository'
54 | -
55 | - '@candm_advanced_csv_connector.step.csv_advanced_product_model.export'
56 | - '@akeneo.job_automation.connector.step.upload'
57 | tags:
58 | - { name: akeneo_batch.job, connector: '%candm_advanced_csv_connector.connector_name.csv%', type: '%pim_connector.job.export_type%' }
59 |
--------------------------------------------------------------------------------
/Entity/ExportMapping.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Entity
12 | */
13 | class ExportMapping extends AbstractCustomEntity
14 | {
15 | /**
16 | * Label
17 | *
18 | * @var string
19 | */
20 | protected $label;
21 |
22 | /**
23 | * Mapping as JSON
24 | *
25 | * @var string
26 | */
27 | protected $mappingAsJson;
28 |
29 | /**
30 | * Complete callback
31 | *
32 | * @var string
33 | */
34 | protected $completeCallback;
35 |
36 | /**
37 | * Get label
38 | *
39 | * @return string
40 | */
41 | public function getLabel()
42 | {
43 | return $this->label;
44 | }
45 |
46 | /**
47 | * Set label
48 | *
49 | * @param string $label
50 | *
51 | * @return Brand
52 | */
53 | public function setLabel($label)
54 | {
55 | $this->label = $label;
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * @return string
62 | */
63 | public function getMappingAsJson()
64 | {
65 | return $this->mappingAsJson;
66 | }
67 |
68 | /**
69 | * @param string $mappingAsJson
70 | *
71 | * @return Mapping
72 | */
73 | public function setMappingAsJson($mappingAsJson)
74 | {
75 | $this->mappingAsJson = $mappingAsJson;
76 |
77 | return $this;
78 | }
79 |
80 | /**
81 | * @return string
82 | */
83 | public function getCompleteCallback()
84 | {
85 | return $this->completeCallback;
86 | }
87 |
88 | /**
89 | * @param string $completeCallback
90 | *
91 | * @return ImportMapping
92 | */
93 | public function setCompleteCallback($completeCallback)
94 | {
95 | $this->completeCallback = $completeCallback;
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * {@inheritdoc}
102 | */
103 | public static function getLabelProperty(): string
104 | {
105 | return 'label';
106 | }
107 |
108 | /**
109 | * Returns the custom entity name used in the configuration
110 | * Used to map row actions on datagrid
111 | *
112 | * @return string
113 | */
114 | public function getCustomEntityName(): string
115 | {
116 | return 'exportMapping';
117 | }
118 |
119 | /**
120 | * Get reference value
121 | *
122 | * @return string
123 | */
124 | public function getReference()
125 | {
126 | return $this->getCode();
127 | }
128 |
129 | /**
130 | * Get complete mapping
131 | *
132 | * @return string
133 | */
134 | public function getMappingAsArray()
135 | {
136 | // Get columns mapping
137 | $columnsMapping = !empty($this->getMappingAsJson()) ? $this->getMappingAsJson() : '[]';
138 |
139 | $mapping = [
140 | 'columns' => json_decode($columnsMapping, true),
141 | ];
142 |
143 | // And complete callback if necessary
144 | if (!empty($this->getCompleteCallback())) {
145 | $mapping['completeCallback'] = $this->getCompleteCallback();
146 | }
147 |
148 | return $mapping;
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/Resources/config/writers.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | candm_advanced_csv_connector.writer.file.product.flat_item_buffer_flusher.class: Akeneo\Tool\Component\Connector\Writer\File\FlatItemBufferFlusher
3 | candm_advanced_csv_connector.writer.file.product.column_sorter_by_mapping.class: ClickAndMortar\AdvancedCsvConnectorBundle\Writer\File\ProductColumnSorterByMapping
4 | candm_advanced_csv_connector.writer.file.csv_advanced_product.class: ClickAndMortar\AdvancedCsvConnectorBundle\Writer\File\Csv\ProductAdvancedWriter
5 | candm_advanced_csv_connector.writer.file.csv_advanced_product_model.class: ClickAndMortar\AdvancedCsvConnectorBundle\Writer\File\Csv\ProductModelAdvancedWriter
6 |
7 | services:
8 | candm_advanced_csv_connector.writer.file.product.flat_item_buffer_flusher:
9 | class: '%candm_advanced_csv_connector.writer.file.product.flat_item_buffer_flusher.class%'
10 | arguments:
11 | - '@pim_connector.writer.file.product.column_presenter'
12 | - '@candm_advanced_csv_connector.writer.file.product.column_sorter_by_mapping'
13 |
14 | candm_advanced_csv_connector.writer.file.product.column_sorter_by_mapping:
15 | class: '%candm_advanced_csv_connector.writer.file.product.column_sorter_by_mapping.class%'
16 | arguments:
17 | - '@pim_connector.array_converter.flat_to_standard.product.field_splitter'
18 | - '@pim_catalog.repository.attribute'
19 | - '@pim_catalog.repository.association_type'
20 | - ['categories', 'enabled', 'family', 'parent', 'groups']
21 |
22 | candm_advanced_csv_connector.writer.file.csv_advanced_product:
23 | class: '%candm_advanced_csv_connector.writer.file.csv_advanced_product.class%'
24 | arguments:
25 | - '@pim_connector.array_converter.standard_to_flat.product_localized'
26 | - '@pim_connector.factory.flat_item_buffer'
27 | - '@candm_advanced_csv_connector.writer.file.product.flat_item_buffer_flusher'
28 | - '@pim_catalog.repository.attribute'
29 | - '@pim_connector.writer.file.media_exporter_path_generator'
30 | - '@pim_enrich.connector.flat_translators.product_translator'
31 | - '@akeneo_file_storage.repository.file_info'
32 | - '@akeneo_file_storage.file_storage.filesystem_provider'
33 | - ['pim_catalog_file', 'pim_catalog_image']
34 | - '@candm_advanced_csv_connector.helper.export'
35 | - '@doctrine.orm.entity_manager'
36 | - '@candm_advanced_csv_connector.repository.export_mapping'
37 | - '@service_container'
38 | - '@candm_advanced_csv_connector.repository.lua_updater'
39 | - 'fr_FR'
40 | - 'file_path'
41 |
42 | candm_advanced_csv_connector.writer.file.csv_advanced_product_model:
43 | class: '%candm_advanced_csv_connector.writer.file.csv_advanced_product_model.class%'
44 | arguments:
45 | - '@pim_connector.array_converter.standard_to_flat.product_model_localized'
46 | - '@pim_connector.factory.flat_item_buffer'
47 | - '@candm_advanced_csv_connector.writer.file.product.flat_item_buffer_flusher'
48 | - '@pim_catalog.repository.attribute'
49 | - '@pim_connector.writer.file.media_exporter_path_generator'
50 | - '@pim_enrich.connector.flat_translators.product_translator'
51 | - '@akeneo_file_storage.repository.file_info'
52 | - '@akeneo_file_storage.file_storage.filesystem_provider'
53 | - ['pim_catalog_file', 'pim_catalog_image']
54 | - '@candm_advanced_csv_connector.helper.export'
55 | - '@doctrine.orm.entity_manager'
56 | - '@candm_advanced_csv_connector.repository.export_mapping'
57 | - '@service_container'
58 | - '@candm_advanced_csv_connector.repository.lua_updater'
59 | - 'fr_FR'
60 | - 'file_path'
--------------------------------------------------------------------------------
/Archiver/AdvancedCsvInvalidItemWriter.php:
--------------------------------------------------------------------------------
1 |
16 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Archiver
17 | */
18 | class AdvancedCsvInvalidItemWriter extends AbstractInvalidItemWriter
19 | {
20 | /**
21 | * {@inheritdoc}
22 | */
23 | public function getName(): string
24 | {
25 | return 'invalid_advanced_csv';
26 | }
27 |
28 | /**
29 | * {@inheritdoc}
30 | *
31 | * Re-parse imported files and write into a new one the invalid lines.
32 | */
33 | public function archive(JobExecution $jobExecution): void
34 | {
35 | if (empty($this->collector->getInvalidItems())) {
36 | return;
37 | }
38 |
39 | $invalidItemPositions = new ArrayCollection();
40 | foreach ($this->collector->getInvalidItems() as $invalidItem) {
41 | if ($invalidItem instanceof InvalidItemInterface) {
42 | $invalidItemPositions->add($invalidItem->getItemPosition());
43 | }
44 | }
45 |
46 | $readJobParameters = $jobExecution->getJobParameters();
47 | if ($readJobParameters->has('mapping')) {
48 | return;
49 | }
50 | $currentItemPosition = 0;
51 | $itemsToWrite = [];
52 |
53 | $fileIterator = $this->getInputFileIterator($readJobParameters);
54 | $this->setupWriter($jobExecution);
55 |
56 | while ($fileIterator->valid()) {
57 | $readItem = $fileIterator->current();
58 |
59 | $currentItemPosition++;
60 |
61 | if ($invalidItemPositions->contains($currentItemPosition)) {
62 | $headers = $fileIterator->getHeaders();
63 | $invalidItem = array_combine($headers, array_slice($readItem, 0, count($headers)));
64 | if (false !== $invalidItem) {
65 | $itemsToWrite[] = $invalidItem;
66 | }
67 |
68 | $invalidItemPositions->removeElement($currentItemPosition);
69 | }
70 |
71 | if (count($itemsToWrite) > 0 && 0 === count($itemsToWrite) % $this->batchSize) {
72 | $this->writer->write($itemsToWrite);
73 | $itemsToWrite = [];
74 | }
75 |
76 | if ($invalidItemPositions->isEmpty()) {
77 | break;
78 | }
79 |
80 | $fileIterator->next();
81 | }
82 |
83 | if (count($itemsToWrite) > 0) {
84 | $this->writer->write($itemsToWrite);
85 | }
86 |
87 | $this->writer->flush();
88 | }
89 |
90 | /**
91 | * {@inheritdoc}
92 | */
93 | protected function getFilename(): string
94 | {
95 | return 'invalid_items.csv';
96 | }
97 |
98 | /**
99 | * {@inheritdoc}
100 | */
101 | protected function getInputFileIterator(JobParameters $jobParameters): FileIteratorInterface
102 | {
103 | $filePath = $jobParameters->get('storage')['file_path'];
104 | $delimiter = $jobParameters->get('delimiter');
105 | $enclosure = $jobParameters->get('enclosure');
106 | $fileIterator = $this->fileIteratorFactory->create($filePath, [
107 | 'reader_options' => [
108 | 'fieldDelimiter' => $delimiter,
109 | 'fieldEnclosure' => $enclosure,
110 | ]
111 | ]);
112 | $fileIterator->rewind();
113 | $fileIterator->next();
114 |
115 | return $fileIterator;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/Resources/bin/split-csv-files.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Split large CSV files in chunks
3 |
4 | # Exit on errors
5 | set -e
6 |
7 | FILE_PATH=${1}
8 | LINES_PER_FILE=${2}
9 | TARGET_FOLDER=${3}
10 | PREFIX_FILES=${4}
11 | SEPARATOR=";"
12 |
13 | # Help menu
14 | print_help() {
15 | cat <<-HELP
16 | This script is used to split large CSV files in chunks.
17 | You need to provide the following arguments:
18 | 1) CSV file path.
19 | 2) Lines per each new file.
20 | 3) Target folder for new files.
21 | 4) Prefix for new generated files.
22 | 5) Separator (optional, default: ;).
23 | Usage: bash ${0##*/} --file_path=FILE_PATH --lines_per_file=LINES_PER_FILE --target_folder=TARGET_FOLDER --prefix=PREFIX_FILES [--separator=SEPARATOR]
24 | Example: bash ${0##*/} --file_path=/tmp/frames_csv.csv --lines_per_file=500 --target_folder=/tmp --prefix=products_part_ --separator=;
25 | HELP
26 | exit 0
27 | }
28 |
29 | # Parse Command Line Arguments
30 | while [ $# -gt 0 ]; do
31 | case "$1" in
32 | --file_path=*)
33 | FILE_PATH="${1#*=}"
34 | ;;
35 | --lines_per_file=*)
36 | LINES_PER_FILE="${1#*=}"
37 | ;;
38 | --target_folder=*)
39 | TARGET_FOLDER="${1#*=}"
40 | ;;
41 | --prefix=*)
42 | PREFIX_FILES="${1#*=}"
43 | ;;
44 | --separator=*)
45 | SEPARATOR="${1#*=}"
46 | ;;
47 | --help) print_help;;
48 | *)
49 | printf "Invalid argument, run --help for valid arguments.\n";
50 | exit 1
51 | esac
52 | shift
53 | done
54 |
55 | # Count occurrences of separator in a string
56 | count_separators() {
57 | echo "$1" | awk -F"$SEPARATOR" '{print NF-1}'
58 | }
59 |
60 | if [ -e $FILE_PATH ] ; then
61 | # Get header and count expected separators per record
62 | HEADER=$(head -n 1 "$FILE_PATH")
63 | EXPECTED_SEPARATORS=$(count_separators "$HEADER")
64 |
65 | # Split CSV respecting multiline fields
66 | awk -v lines_per_file="$LINES_PER_FILE" \
67 | -v target_folder="$TARGET_FOLDER" \
68 | -v prefix="$PREFIX_FILES" \
69 | -v sep="$SEPARATOR" \
70 | -v expected_sep="$EXPECTED_SEPARATORS" \
71 | 'BEGIN {
72 | file_num = 0
73 | line_count = 0
74 | current_record = ""
75 | current_sep_count = 0
76 | # Generate suffix like split command (aa, ab, ac...)
77 | split("a b c d e f g h i j k l m n o p q r s t u v w x y z", letters, " ")
78 | }
79 |
80 | function get_suffix(num) {
81 | first = int(num / 26)
82 | second = num % 26
83 | return letters[first + 1] letters[second + 1]
84 | }
85 |
86 | function write_record(record) {
87 | if (line_count % lines_per_file == 0) {
88 | if (file_num > 0) {
89 | close(current_file)
90 | }
91 | current_file = target_folder "/" prefix get_suffix(file_num) ".csv"
92 | file_num++
93 | }
94 | print record > current_file
95 | line_count++
96 | }
97 |
98 | function count_sep(str) {
99 | n = gsub(sep, sep, str)
100 | return n
101 | }
102 |
103 | NR == 1 {
104 | # Store header, do not write yet (will be added later)
105 | header = $0
106 | next
107 | }
108 |
109 | {
110 | if (current_record == "") {
111 | current_record = $0
112 | current_sep_count = count_sep($0)
113 | } else {
114 | current_record = current_record "\n" $0
115 | current_sep_count += count_sep($0)
116 | }
117 |
118 | # Check if we have a complete record
119 | if (current_sep_count >= expected_sep) {
120 | write_record(current_record)
121 | current_record = ""
122 | current_sep_count = 0
123 | }
124 | }
125 |
126 | END {
127 | # Write any remaining record
128 | if (current_record != "") {
129 | write_record(current_record)
130 | }
131 | if (file_num > 0) {
132 | close(current_file)
133 | }
134 | }' "$FILE_PATH"
135 |
136 | # Add header for all files
137 | for CURRENT_FILE in $TARGET_FOLDER/$PREFIX_FILES*
138 | do
139 | head -n 1 "$FILE_PATH" > "$TARGET_FOLDER/tmp_file"
140 | cat "$CURRENT_FILE" >> "$TARGET_FOLDER/tmp_file"
141 | mv -f "$TARGET_FOLDER/tmp_file" "$CURRENT_FILE"
142 | done
143 |
144 | # Delete original file
145 | rm -f "$FILE_PATH"
146 | printf "$FILE_PATH file splitted !\n"
147 | fi
--------------------------------------------------------------------------------
/Resources/config/form_extensions/csv_advanced_product_import_show.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-job-instance-csv-advanced-product-import-show:
3 | module: pim/form/common/edit-form
4 |
5 | pim-job-instance-csv-advanced-product-import-show-main-image:
6 | module: pim/form/common/main-image
7 | parent: pim-job-instance-csv-advanced-product-import-show
8 | targetZone: main-image
9 | config:
10 | path: bundles/pimui/images/illustrations/ImportCSV.svg
11 |
12 | pim-job-instance-csv-advanced-product-import-show-user-navigation:
13 | module: pim/menu/user-navigation
14 | parent: pim-job-instance-csv-advanced-product-import-show
15 | targetZone: user-menu
16 | config:
17 | userAccount: pim_menu.user.user_account
18 | logout: pim_menu.user.logout
19 |
20 | pim-job-instance-csv-advanced-product-import-show-breadcrumbs:
21 | module: pim/job/common/breadcrumb/breadcrumb
22 | parent: pim-job-instance-csv-advanced-product-import-show
23 | targetZone: breadcrumbs
24 |
25 | pim-job-instance-csv-advanced-product-import-show-switcher:
26 | module: pim/job-instance/import/switcher
27 | parent: pim-job-instance-csv-advanced-product-import-show
28 | position: 0
29 | targetZone: meta
30 |
31 | pim-job-instance-csv-advanced-product-import-show-launch-switcher-item:
32 | module: pim/job-instance/import/switcher-item
33 | parent: pim-job-instance-csv-advanced-product-import-show
34 | targetZone: content
35 | aclResourceId: pim_importexport_import_profile_launch
36 | position: 40
37 | config:
38 | label: pim_import_export.form.job_instance.button.import.launch
39 | hideForCloudEdition: true
40 |
41 | pim-job-instance-csv-advanced-product-import-show-file-path:
42 | module: pim/job/common/file-path
43 | parent: pim-job-instance-csv-advanced-product-import-show-launch-switcher-item
44 | config:
45 | label: pim_import_export.form.job_instance.file_path
46 |
47 | pim-job-instance-csv-advanced-product-import-show-import-button:
48 | module: pim/job/common/edit/launch
49 | parent: pim-job-instance-csv-advanced-product-import-show-file-path
50 | targetZone: buttons
51 | config:
52 | label: pim_import_export.form.job_instance.button.import.launch
53 | route: pim_enrich_job_instance_rest_import_launch
54 | identifier:
55 | path: code
56 | name: code
57 |
58 | pim-job-instance-csv-advanced-product-import-show-upload-switcher-item:
59 | module: pim/job-instance/import/switcher-item
60 | parent: pim-job-instance-csv-advanced-product-import-show
61 | targetZone: content
62 | aclResourceId: pim_importexport_import_profile_launch
63 | position: 50
64 | config:
65 | label: pim_import_export.form.job_instance.button.import.upload_file
66 | hideForCloudEdition: false
67 |
68 | pim-job-instance-csv-advanced-product-import-show-upload:
69 | module: pim/job/common/edit/upload
70 | parent: pim-job-instance-csv-advanced-product-import-show-upload-switcher-item
71 | position: 50
72 | config:
73 | type: csv
74 |
75 | pim-job-instance-csv-advanced-product-import-show-upload-button:
76 | module: pim/job/common/edit/upload-launch
77 | parent: pim-job-instance-csv-advanced-product-import-show-upload-switcher-item
78 | position: 60
79 | config:
80 | label: pim_import_export.form.job_instance.button.import.upload
81 | route: pim_enrich_job_instance_rest_import_launch
82 | identifier:
83 | path: code
84 | name: code
85 |
86 | pim-job-instance-csv-advanced-product-import-show-last-executions:
87 | module: akeneojob/controller/job-instance
88 | parent: pim-job-instance-csv-advanced-product-import-show
89 | position: 100
90 | targetZone: content
91 |
92 | pim-job-instance-csv-advanced-product-import-show-label:
93 | module: pim/job/common/edit/label
94 | parent: pim-job-instance-csv-advanced-product-import-show
95 | targetZone: title
96 | position: 100
97 |
98 | pim-job-instance-csv-advanced-product-import-show-edit:
99 | module: pim/job/common/edit-button
100 | parent: pim-job-instance-csv-advanced-product-import-show
101 | targetZone: buttons
102 | position: 100
103 | aclResourceId: pim_importexport_import_profile_edit
104 | config:
105 | label: pim_common.edit
106 | route: pim_importexport_import_profile_edit
107 | buttonClass: AknButton AknButton--action
108 | identifier:
109 | path: code
110 | name: code
111 |
--------------------------------------------------------------------------------
/Resources/config/form_extensions/csv_advanced_product_model_import_show.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-job-instance-csv-advanced-product-model-import-show:
3 | module: pim/form/common/edit-form
4 |
5 | pim-job-instance-csv-advanced-product-model-import-show-mainImage:
6 | module: pim/form/common/main-image
7 | parent: pim-job-instance-csv-advanced-product-model-import-show
8 | targetZone: main-image
9 | config:
10 | path: bundles/pimui/images/illustrations/ImportCSV.svg
11 |
12 | pim-job-instance-csv-advanced-product-model-import-show-user-navigation:
13 | module: pim/menu/user-navigation
14 | parent: pim-job-instance-csv-advanced-product-model-import-show
15 | targetZone: user-menu
16 | config:
17 | userAccount: pim_menu.user.user_account
18 | logout: pim_menu.user.logout
19 |
20 | pim-job-instance-csv-advanced-product-model-import-show-breadcrumbs:
21 | module: pim/job/common/breadcrumb/breadcrumb
22 | parent: pim-job-instance-csv-advanced-product-model-import-show
23 | targetZone: breadcrumbs
24 |
25 | pim-job-instance-csv-advanced-product-model-import-show-switcher:
26 | module: pim/job-instance/import/switcher
27 | parent: pim-job-instance-csv-advanced-product-model-import-show
28 | position: 0
29 | targetZone: meta
30 |
31 | pim-job-instance-csv-advanced-product-model-import-show-launch-switcher-item:
32 | module: pim/job-instance/import/switcher-item
33 | parent: pim-job-instance-csv-advanced-product-model-import-show
34 | targetZone: content
35 | aclResourceId: pim_importexport_import_profile_launch
36 | position: 40
37 | config:
38 | label: pim_import_export.form.job_instance.button.import.launch
39 | hideForCloudEdition: true
40 |
41 | pim-job-instance-csv-advanced-product-model-import-show-file-path:
42 | module: pim/job/common/file-path
43 | parent: pim-job-instance-csv-advanced-product-model-import-show-launch-switcher-item
44 | config:
45 | label: pim_import_export.form.job_instance.file_path
46 |
47 | pim-job-instance-csv-advanced-product-model-import-show-import-button:
48 | module: pim/job/common/edit/launch
49 | parent: pim-job-instance-csv-advanced-product-model-import-show-file-path
50 | targetZone: buttons
51 | config:
52 | label: pim_import_export.form.job_instance.button.import.launch
53 | route: pim_enrich_job_instance_rest_import_launch
54 | identifier:
55 | path: code
56 | name: code
57 |
58 | pim-job-instance-csv-advanced-product-model-import-show-upload-switcher-item:
59 | module: pim/job-instance/import/switcher-item
60 | parent: pim-job-instance-csv-advanced-product-model-import-show
61 | targetZone: content
62 | aclResourceId: pim_importexport_import_profile_launch
63 | position: 50
64 | config:
65 | allowedKey: uploadAllowed
66 | label: pim_import_export.form.job_instance.button.import.upload_file
67 | hideForCloudEdition: false
68 |
69 | pim-job-instance-csv-advanced-product-model-import-show-upload:
70 | module: pim/job/common/edit/upload
71 | parent: pim-job-instance-csv-advanced-product-model-import-show-upload-switcher-item
72 | position: 50
73 | config:
74 | type: csv
75 |
76 | pim-job-instance-csv-advanced-product-model-import-show-upload-button:
77 | module: pim/job/common/edit/upload-launch
78 | parent: pim-job-instance-csv-advanced-product-model-import-show-upload-switcher-item
79 | position: 60
80 | config:
81 | label: pim_import_export.form.job_instance.button.import.upload
82 | route: pim_enrich_job_instance_rest_import_launch
83 | identifier:
84 | path: code
85 | name: code
86 |
87 | pim-job-instance-csv-advanced-product-model-import-show-last-executions:
88 | module: akeneojob/controller/job-instance
89 | parent: pim-job-instance-csv-advanced-product-model-import-show
90 | position: 100
91 | targetZone: content
92 |
93 | pim-job-instance-csv-advanced-product-model-import-show-label:
94 | module: pim/job/common/edit/label
95 | parent: pim-job-instance-csv-advanced-product-model-import-show
96 | targetZone: title
97 | position: 100
98 |
99 | pim-job-instance-csv-advanced-product-model-import-show-edit:
100 | module: pim/job/common/edit-button
101 | parent: pim-job-instance-csv-advanced-product-model-import-show
102 | targetZone: buttons
103 | position: 100
104 | aclResourceId: pim_importexport_import_profile_edit
105 | config:
106 | label: pim_common.edit
107 | route: pim_importexport_import_profile_edit
108 | buttonClass: AknButton AknButton--action
109 | identifier:
110 | path: code
111 | name: code
112 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Advanced CSV Connector - C&M
2 |
3 | Advanced CSV Connector is an extension of classic Akeneo CSV Connector. It allows to customize columns mapping on import or export.
4 |
5 | Made with :blue_heart: by C&M
6 |
7 | ## Versions
8 |
9 | | **Bundle version** | **Akeneo version** |
10 | |--------------------|-------------------|
11 | | v7.0.* | v7.0.* |
12 | | v6.0.* | v6.0.* |
13 | | v5.0.* | v5.0.* |
14 | | v1.8.* | v4.0.* |
15 | | v1.7.* | v3.2.* (EE) |
16 | | v1.6.* | v3.1.* / v3.2.* |
17 | | v1.5.* | v3.1.* / v3.2.* |
18 | | v1.4.* | v2.3.* |
19 | | v1.3.* | v2.1.* |
20 |
21 | ## Optional
22 |
23 | You can use `php-lua` package to update your values dynamically during import or export.
24 | For LUA scripts available functions and libraries have been limited for security reasons. You can use:
25 |
26 | * string
27 | * math
28 | * ipairs
29 | * load
30 | * next
31 | * pairs
32 | * rawequal
33 | * rawgetwget
34 | * rawlen
35 | * rawset
36 | * select
37 | * tonumber
38 | * tostring
39 | * type
40 |
41 | This package is not a requirement. A classic PHP method can also be used.
42 |
43 | ## Installation
44 |
45 | ### Download the Bundle
46 |
47 | Update your `composer.json` file to use our fork of **Custom entity bundle** in `repositories` node:
48 |
49 | ```console
50 | "repositories": [
51 | ...
52 | {
53 | "type": "vcs",
54 | "url": "https://github.com/ClickAndMortar/CustomEntityBundle"
55 | }
56 | ...
57 | ],
58 | ```
59 |
60 | And add our bundle:
61 |
62 | ```console
63 | $ composer require "clickandmortar/advanced-csv-connector-bundle":".*"
64 | ```
65 |
66 | Example for last version:
67 |
68 | ```console
69 | $ composer require "clickandmortar/advanced-csv-connector-bundle":"7.0.*"
70 | ```
71 |
72 |
73 | ### Enable the Bundle
74 |
75 | Enable the bundle by adding it to the list of registered bundles
76 | in the `config/bundles.php` file of your project:
77 |
78 | ```php
79 | ['all' => true],
84 | ClickAndMortar\AdvancedCsvConnectorBundle\ClickAndMortarAdvancedCsvConnectorBundle::class => ['all' => true]
85 | ];
86 | ```
87 |
88 | Update your `config/routes/routes.yml` file:
89 |
90 | ```
91 | pim_customentity:
92 | prefix: /reference-data
93 | resource: "@PimCustomEntityBundle/Resources/config/routing.yml"
94 |
95 | candm_advanced_csv_connector:
96 | prefix: /candm-advanced-csv-connector
97 | resource: "@ClickAndMortarAdvancedCsvConnectorBundle/Resources/config/routing.yml"
98 | ```
99 |
100 | And finally clear cache and update database:
101 |
102 | ```
103 | rm -rf var/cache/*
104 | php bin/console --env=prod pim:installer:assets --symlink --clean
105 | yarn run webpack
106 | php bin/console doctrine:schema:update --force
107 | ```
108 |
109 | ## Usage
110 |
111 | ### Import
112 |
113 | To create a new import mapping, go to `Référenciel / Mappings d'import` and click on `Create` top right button.
114 | You can add as many mapping lines as you want by clicking on `Ajouter une ligne`.
115 |
116 | Some explanations for table columns:
117 |
118 | * `Attribut` (mandatory): Attribute code in your Akeneo project (you can use suffixes like `-fr_FR` or `-EUR` for locales, channels, currencies, ...)
119 | * `Nom de la colonne` (mandatory): Column name in your file to import
120 | * `Transformation`: LUA script name or PHP method name to update value after mapping. Example: Uppercase, lowercase, ... (you can create a new LUA script under `Référenciel / Scripts LUA`).
121 | * `Valeur par défaut`: Default value for attribute if empty data in file
122 | * `Identifiant` (mandatory): Used to defined main identifier attribute of product
123 | * `Uniquement à la création`: Set attribute value only if product is new (checked with `identifier` attribute)
124 | * `Effacer si null`: Remove key from item mapping if value is null
125 | * `Supprimer`: Click on this cell to delete mapping line
126 |
127 | Once mapping is saved, go to `Imports` part and create a new job with type `Import des produits avancé (CSV)`.
128 | After job creation, go to edition mode and update `Mapping` parameter in global parameters tab.
129 |
130 | ### Export
131 |
132 | To create a new export mapping, go to `Référenciel / Mappings d'export` and click on `Create` top right button.
133 | You can add as many mapping lines as you want by clicking on `Ajouter une ligne`.
134 |
135 | Some explanations for table columns:
136 |
137 | * `Attribut` (mandatory): Attribute code in your Akeneo project (you can use suffixes like `-fr_FR` or `-EUR` for locales, channels, currencies, ...)
138 | * `Nom de la colonne` (mandatory): Column name in your file to export
139 | * `Valeur forcée`: Force a value (erase given attribute value from Akeneo)
140 | * `Transformation`: LUA script name or PHP method name to update value after mapping. Example: Uppercase, lowercase, ... (you can create a new LUA script under `Référenciel / Scripts LUA`)
141 | * `Utiliser le libellé`: Boolean to get the label associated to the code given (for attribute options or custom entities)
142 | * `Langue`: Select a specific locale for the label to export (linked to `Utiliser le libellé` column)
143 | * `Longueur max.`: Integer use to shorten attribute value if necessary
144 | * `Valeur par défaut`: Default value for column if empty attribute value
145 | * `Supprimer`: Click on this cell to delete mapping line
146 |
147 | Once mapping is saved, go to `Exports` part and create a new job with type `Export des produits avancé (CSV)`.
148 | After job creation, go to edition mode and update `Mapping` parameter in global parameters tab.
--------------------------------------------------------------------------------
/Resources/config/form_extensions/luaUpdater/edit.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-luaUpdater-edit-form:
3 | module: pim/form/common/edit-form
4 |
5 | pim-luaUpdater-edit-form-breadcrumbs:
6 | module: pim/common/breadcrumbs
7 | parent: pim-luaUpdater-edit-form
8 | targetZone: breadcrumbs
9 | config:
10 | tab: pim-menu-reference_data
11 | item: candm_advanced_csv_connector-menu-reference_data-item-luaUpdater
12 |
13 | pim-luaUpdater-edit-form-cache-invalidator:
14 | module: pim/cache-invalidator
15 | parent: pim-luaUpdater-edit-form
16 | position: 1000
17 |
18 | pim-color-edit-form-label:
19 | module: custom_entity/form/common/label
20 | parent: pim-color-edit-form
21 | targetZone: title
22 | position: 90
23 |
24 | pim-luaUpdater-edit-form-form-tabs:
25 | module: pim/form/common/form-tabs
26 | parent: pim-luaUpdater-edit-form
27 | targetZone: content
28 | position: 100
29 |
30 | pim-luaUpdater-edit-form-secondary-actions:
31 | module: pim/form/common/secondary-actions
32 | parent: pim-luaUpdater-edit-form
33 | targetZone: buttons
34 | position: 50
35 |
36 | pim-luaUpdater-edit-form-delete:
37 | module: custom_entity/form/common/delete
38 | parent: pim-luaUpdater-edit-form-secondary-actions
39 | targetZone: secondary-actions
40 | aclResourceId: pim_enrich_group_remove
41 | position: 100
42 | config:
43 | route: pim_customentity_rest_delete
44 | routeParams:
45 | customEntityName: luaUpdater
46 | trans:
47 | title: candm_advanced_csv_connector.luaUpdater.message.delete
48 | container: pim_enrich.confirmation.delete_item
49 | success: pim_custom_entity.message.removed
50 | fail: pim_custom_entity.error.removing
51 | redirect: pim_customentity_index
52 |
53 | pim-luaUpdater-edit-form-save-buttons:
54 | module: pim/form/common/save-buttons
55 | parent: pim-luaUpdater-edit-form
56 | targetZone: buttons
57 | position: 120
58 |
59 | pim-luaUpdater-edit-form-state:
60 | module: pim/form/common/state
61 | parent: pim-luaUpdater-edit-form
62 | targetZone: state
63 | position: 900
64 | config:
65 | entity: pim_enrich.entity.group.title
66 |
67 | pim-luaUpdater-edit-form-save:
68 | module: custom_entity/form/common/save-form
69 | parent: pim-luaUpdater-edit-form
70 | targetZone: buttons
71 | position: 0
72 | config:
73 | updateSuccessMessage: pim_enrich.entity.generic.flash.update.success
74 | updateFailureMessage: pim_enrich.entity.generic.flash.update.fail
75 | notReadyMessage: pim_enrich.entity.generic.flash.info.field_not_ready
76 | url: pim_customentity_rest_edit
77 | route_params:
78 | customEntityName: luaUpdater
79 | redirectAfter: pim_customentity_rest_get
80 | excludedProperties: ['data']
81 |
82 | pim-luaUpdater-edit-form-properties-tab:
83 | module: pim/common/tab
84 | parent: pim-luaUpdater-edit-form-form-tabs
85 | targetZone: container
86 | position: 100
87 | config:
88 | label: pim_custom_entity.form.tab.properties.title
89 |
90 | pim-luaUpdater-edit-form-properties:
91 | module: pim/common/simple-view
92 | parent: pim-luaUpdater-edit-form-properties-tab
93 | targetZone: self
94 | config:
95 | template: pim/template/form/tab/sections
96 |
97 | pim-luaUpdater-edit-form-state:
98 | module: pim/form/common/state
99 | parent: pim-luaUpdater-edit-form
100 | targetZone: state
101 | position: 900
102 | config:
103 | entity: pim_enrich.entity.group.title
104 |
105 | pim-luaUpdater-edit-form-properties:
106 | module: pim/common/simple-view
107 | parent: pim-luaUpdater-edit-form-properties-tab
108 | targetZone: self
109 | config:
110 | template: pim/template/form/tab/sections
111 |
112 | pim-luaUpdater-edit-form-properties-common:
113 | module: pim/common/simple-view
114 | parent: pim-luaUpdater-edit-form-properties
115 | targetZone: accordion
116 | position: 100
117 | config:
118 | template: pim/template/form/tab/section-large
119 | templateParams:
120 | sectionTitle: pim_custom_entity.form.tab.properties.section.common
121 | dropZone: content
122 |
123 | pim-luaUpdater-edit-form-properties-label:
124 | module: pim/form/common/fields/text
125 | parent: pim-luaUpdater-edit-form-properties-common
126 | targetZone: content
127 | position: 90
128 | config:
129 | fieldName: label
130 | label: candm_advanced_csv_connector.luaUpdater.field.label.label
131 | required: true
132 |
133 | pim-luaUpdater-edit-form-properties-code:
134 | module: pim/form/common/fields/text
135 | parent: pim-luaUpdater-edit-form-properties-common
136 | targetZone: content
137 | position: 100
138 | config:
139 | fieldName: code
140 | label: candm_advanced_csv_connector.luaUpdater.field.label.code
141 | required: true
142 |
143 | pim-luaUpdater-edit-form-properties-script:
144 | module: pim/form/common/fields/lua-script
145 | parent: pim-luaUpdater-edit-form-properties-common
146 | targetZone: content
147 | position: 110
148 | config:
149 | fieldName: script
150 | label: candm_advanced_csv_connector.luaUpdater.field.label.script
151 |
--------------------------------------------------------------------------------
/Resources/config/form_extensions/exportMapping/edit.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-exportMapping-edit-form:
3 | module: pim/form/common/edit-form
4 |
5 | pim-exportMapping-edit-form-breadcrumbs:
6 | module: pim/common/breadcrumbs
7 | parent: pim-exportMapping-edit-form
8 | targetZone: breadcrumbs
9 | config:
10 | tab: pim-menu-reference_data
11 | item: candm_advanced_csv_connector-menu-reference_data-item-exportMapping
12 |
13 | pim-exportMapping-edit-form-cache-invalidator:
14 | module: pim/cache-invalidator
15 | parent: pim-exportMapping-edit-form
16 | position: 1000
17 |
18 | pim-color-edit-form-label:
19 | module: custom_entity/form/common/label
20 | parent: pim-color-edit-form
21 | targetZone: title
22 | position: 90
23 |
24 | pim-exportMapping-edit-form-form-tabs:
25 | module: pim/form/common/form-tabs
26 | parent: pim-exportMapping-edit-form
27 | targetZone: content
28 | position: 100
29 |
30 | pim-exportMapping-edit-form-secondary-actions:
31 | module: pim/form/common/secondary-actions
32 | parent: pim-exportMapping-edit-form
33 | targetZone: buttons
34 | position: 50
35 |
36 | pim-exportMapping-edit-form-delete:
37 | module: custom_entity/form/common/delete
38 | parent: pim-exportMapping-edit-form-secondary-actions
39 | targetZone: secondary-actions
40 | aclResourceId: pim_enrich_group_remove
41 | position: 100
42 | config:
43 | route: pim_customentity_rest_delete
44 | routeParams:
45 | customEntityName: exportMapping
46 | trans:
47 | title: candm_advanced_csv_connector.exportMapping.message.delete
48 | container: pim_enrich.confirmation.delete_item
49 | success: pim_custom_entity.message.removed
50 | fail: pim_custom_entity.error.removing
51 | redirect: pim_customentity_index
52 |
53 | pim-exportMapping-edit-form-save-buttons:
54 | module: pim/form/common/save-buttons
55 | parent: pim-exportMapping-edit-form
56 | targetZone: buttons
57 | position: 120
58 |
59 | pim-exportMapping-edit-form-state:
60 | module: pim/form/common/state
61 | parent: pim-exportMapping-edit-form
62 | targetZone: state
63 | position: 900
64 | config:
65 | entity: pim_enrich.entity.group.title
66 |
67 | pim-exportMapping-edit-form-save:
68 | module: custom_entity/form/common/save-form
69 | parent: pim-exportMapping-edit-form
70 | targetZone: buttons
71 | position: 0
72 | config:
73 | updateSuccessMessage: pim_enrich.entity.generic.flash.update.success
74 | updateFailureMessage: pim_enrich.entity.generic.flash.update.fail
75 | notReadyMessage: pim_enrich.entity.generic.flash.info.field_not_ready
76 | url: pim_customentity_rest_edit
77 | route_params:
78 | customEntityName: exportMapping
79 | redirectAfter: pim_customentity_rest_get
80 | excludedProperties: ['data']
81 |
82 | pim-exportMapping-edit-form-properties-tab:
83 | module: pim/common/tab
84 | parent: pim-exportMapping-edit-form-form-tabs
85 | targetZone: container
86 | position: 100
87 | config:
88 | label: pim_custom_entity.form.tab.properties.title
89 |
90 | pim-exportMapping-edit-form-properties:
91 | module: pim/common/simple-view
92 | parent: pim-exportMapping-edit-form-properties-tab
93 | targetZone: self
94 | config:
95 | template: pim/template/form/tab/sections
96 |
97 | pim-exportMapping-edit-form-state:
98 | module: pim/form/common/state
99 | parent: pim-exportMapping-edit-form
100 | targetZone: state
101 | position: 900
102 | config:
103 | entity: pim_enrich.entity.group.title
104 |
105 | pim-exportMapping-edit-form-properties:
106 | module: pim/common/simple-view
107 | parent: pim-exportMapping-edit-form-properties-tab
108 | targetZone: self
109 | config:
110 | template: pim/template/form/tab/sections
111 |
112 | pim-exportMapping-edit-form-properties-common:
113 | module: pim/common/simple-view
114 | parent: pim-exportMapping-edit-form-properties
115 | targetZone: accordion
116 | position: 100
117 | config:
118 | template: pim/template/form/tab/section-large
119 | templateParams:
120 | sectionTitle: pim_custom_entity.form.tab.properties.section.common
121 | dropZone: content
122 |
123 | pim-exportMapping-edit-form-properties-label:
124 | module: pim/form/common/fields/text
125 | parent: pim-exportMapping-edit-form-properties-common
126 | targetZone: content
127 | position: 90
128 | config:
129 | fieldName: label
130 | label: candm_advanced_csv_connector.exportMapping.field.label.label
131 | required: true
132 |
133 | pim-exportMapping-edit-form-properties-code:
134 | module: pim/form/common/fields/text
135 | parent: pim-exportMapping-edit-form-properties-common
136 | targetZone: content
137 | position: 100
138 | config:
139 | fieldName: code
140 | label: candm_advanced_csv_connector.exportMapping.field.label.code
141 | required: true
142 |
143 | pim-exportMapping-edit-form-properties-mapping:
144 | module: pim/form/common/fields/export-mapping
145 | parent: pim-exportMapping-edit-form-properties-common
146 | targetZone: content
147 | position: 110
148 | config:
149 | fieldName: mappingAsJson
150 | label: candm_advanced_csv_connector.exportMapping.field.label.mapping
151 |
152 | pim-exportMapping-edit-form-properties-complete-callback:
153 | module: pim/form/common/fields/text
154 | parent: pim-exportMapping-edit-form-properties-common
155 | targetZone: content
156 | position: 120
157 | config:
158 | fieldName: completeCallback
159 | label: candm_advanced_csv_connector.exportMapping.field.label.complete_callback
160 |
--------------------------------------------------------------------------------
/Entity/ImportMapping.php:
--------------------------------------------------------------------------------
1 |
11 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Entity
12 | */
13 | class ImportMapping extends AbstractCustomEntity
14 | {
15 | /**
16 | * Label
17 | *
18 | * @var string
19 | */
20 | protected $label;
21 |
22 | /**
23 | * Mapping as JSON
24 | *
25 | * @var string
26 | */
27 | protected $mappingAsJson;
28 |
29 | /**
30 | * Complete callback
31 | *
32 | * @var string
33 | */
34 | protected $completeCallback;
35 |
36 | /**
37 | * Initialize callback
38 | *
39 | * @var string
40 | */
41 | protected $initializeCallback;
42 |
43 | /**
44 | * Flush callback
45 | *
46 | * @var string
47 | */
48 | protected $flushCallback;
49 |
50 | /**
51 | * Items limit
52 | *
53 | * @var int
54 | */
55 | protected $itemsLimit;
56 |
57 | /**
58 | * Update product only if already exists
59 | *
60 | * @var boolean
61 | */
62 | protected $onlyUpdate = false;
63 |
64 | /**
65 | * Get label
66 | *
67 | * @return string
68 | */
69 | public function getLabel()
70 | {
71 | return $this->label;
72 | }
73 |
74 | /**
75 | * Set label
76 | *
77 | * @param string $label
78 | *
79 | * @return Brand
80 | */
81 | public function setLabel($label)
82 | {
83 | $this->label = $label;
84 |
85 | return $this;
86 | }
87 |
88 | /**
89 | * @return string
90 | */
91 | public function getMappingAsJson()
92 | {
93 | return $this->mappingAsJson;
94 | }
95 |
96 | /**
97 | * @param string $mappingAsJson
98 | *
99 | * @return Mapping
100 | */
101 | public function setMappingAsJson($mappingAsJson)
102 | {
103 | $this->mappingAsJson = $mappingAsJson;
104 |
105 | return $this;
106 | }
107 |
108 | /**
109 | * @return string
110 | */
111 | public function getCompleteCallback()
112 | {
113 | return $this->completeCallback;
114 | }
115 |
116 | /**
117 | * @param string $completeCallback
118 | *
119 | * @return ImportMapping
120 | */
121 | public function setCompleteCallback($completeCallback)
122 | {
123 | $this->completeCallback = $completeCallback;
124 |
125 | return $this;
126 | }
127 |
128 | /**
129 | * @return string
130 | */
131 | public function getInitializeCallback()
132 | {
133 | return $this->initializeCallback;
134 | }
135 |
136 | /**
137 | * @param string $initializeCallback
138 | *
139 | * @return ImportMapping
140 | */
141 | public function setInitializeCallback($initializeCallback)
142 | {
143 | $this->initializeCallback = $initializeCallback;
144 |
145 | return $this;
146 | }
147 |
148 | /**
149 | * @return string
150 | */
151 | public function getFlushCallback()
152 | {
153 | return $this->flushCallback;
154 | }
155 |
156 | /**
157 | * @param string $flushCallback
158 | *
159 | * @return ImportMapping
160 | */
161 | public function setFlushCallback($flushCallback)
162 | {
163 | $this->flushCallback = $flushCallback;
164 |
165 | return $this;
166 | }
167 |
168 | /**
169 | * @return int
170 | */
171 | public function getItemsLimit()
172 | {
173 | return $this->itemsLimit;
174 | }
175 |
176 | /**
177 | * @param int $itemsLimit
178 | *
179 | * @return ImportMapping
180 | */
181 | public function setItemsLimit($itemsLimit)
182 | {
183 | $this->itemsLimit = $itemsLimit;
184 |
185 | return $this;
186 | }
187 |
188 | /**
189 | * @return bool
190 | */
191 | public function getOnlyUpdate()
192 | {
193 | return $this->onlyUpdate;
194 | }
195 |
196 | /**
197 | * @param bool $onlyUpdate
198 | *
199 | * @return ImportMapping
200 | */
201 | public function setOnlyUpdate($onlyUpdate)
202 | {
203 | $this->onlyUpdate = $onlyUpdate;
204 |
205 | return $this;
206 | }
207 |
208 | /**
209 | * {@inheritdoc}
210 | */
211 | public static function getLabelProperty(): string
212 | {
213 | return 'label';
214 | }
215 |
216 | /**
217 | * Returns the custom entity name used in the configuration
218 | * Used to map row actions on datagrid
219 | *
220 | * @return string
221 | */
222 | public function getCustomEntityName(): string
223 | {
224 | return 'importMapping';
225 | }
226 |
227 | /**
228 | * Get reference value
229 | *
230 | * @return string
231 | */
232 | public function getReference(): string
233 | {
234 | return $this->getCode();
235 | }
236 |
237 | /**
238 | * Get complete mapping
239 | *
240 | * @return string
241 | */
242 | public function getMappingAsArray()
243 | {
244 | // Get attributes mapping
245 | $attributesMapping = !empty($this->getMappingAsJson()) ? $this->getMappingAsJson() : '[]';
246 |
247 | $mapping = [
248 | 'attributes' => json_decode($attributesMapping, true),
249 | ];
250 |
251 | // Add complete callback if necessary
252 | if (!empty($this->getCompleteCallback())) {
253 | $mapping['completeCallback'] = $this->getCompleteCallback();
254 | }
255 |
256 | // Add initialize callback if necessary
257 | if (!empty($this->getInitializeCallback())) {
258 | $mapping['initializeCallback'] = $this->getInitializeCallback();
259 | }
260 |
261 | // Add flush callback if necessary
262 | if (!empty($this->getFlushCallback())) {
263 | $mapping['flushCallback'] = $this->getFlushCallback();
264 | }
265 |
266 | // Add items limit if necessary
267 | if (!empty($this->getItemsLimit())) {
268 | $mapping['itemsLimit'] = $this->getItemsLimit();
269 | }
270 |
271 | // Add only update parameter
272 | $mapping['onlyUpdate'] = $this->getOnlyUpdate();
273 |
274 | return $mapping;
275 | }
276 | }
277 |
--------------------------------------------------------------------------------
/Resources/config/form_extensions/importMapping/edit.yml:
--------------------------------------------------------------------------------
1 | extensions:
2 | pim-importMapping-edit-form:
3 | module: pim/form/common/edit-form
4 |
5 | pim-importMapping-edit-form-breadcrumbs:
6 | module: pim/common/breadcrumbs
7 | parent: pim-importMapping-edit-form
8 | targetZone: breadcrumbs
9 | config:
10 | tab: pim-menu-reference_data
11 | item: candm_advanced_csv_connector-menu-reference_data-item-importMapping
12 |
13 | pim-importMapping-edit-form-cache-invalidator:
14 | module: pim/cache-invalidator
15 | parent: pim-importMapping-edit-form
16 | position: 1000
17 |
18 | pim-color-edit-form-label:
19 | module: custom_entity/form/common/label
20 | parent: pim-color-edit-form
21 | targetZone: title
22 | position: 90
23 |
24 | pim-importMapping-edit-form-form-tabs:
25 | module: pim/form/common/form-tabs
26 | parent: pim-importMapping-edit-form
27 | targetZone: content
28 | position: 100
29 |
30 | pim-importMapping-edit-form-secondary-actions:
31 | module: pim/form/common/secondary-actions
32 | parent: pim-importMapping-edit-form
33 | targetZone: buttons
34 | position: 50
35 |
36 | pim-importMapping-edit-form-delete:
37 | module: custom_entity/form/common/delete
38 | parent: pim-importMapping-edit-form-secondary-actions
39 | targetZone: secondary-actions
40 | aclResourceId: pim_enrich_group_remove
41 | position: 100
42 | config:
43 | route: pim_customentity_rest_delete
44 | routeParams:
45 | customEntityName: importMapping
46 | trans:
47 | title: candm_advanced_csv_connector.importMapping.message.delete
48 | container: pim_enrich.confirmation.delete_item
49 | success: pim_custom_entity.message.removed
50 | fail: pim_custom_entity.error.removing
51 | redirect: pim_customentity_index
52 |
53 | pim-importMapping-edit-form-save-buttons:
54 | module: pim/form/common/save-buttons
55 | parent: pim-importMapping-edit-form
56 | targetZone: buttons
57 | position: 120
58 |
59 | pim-importMapping-edit-form-state:
60 | module: pim/form/common/state
61 | parent: pim-importMapping-edit-form
62 | targetZone: state
63 | position: 900
64 | config:
65 | entity: pim_enrich.entity.group.title
66 |
67 | pim-importMapping-edit-form-save:
68 | module: custom_entity/form/common/save-form
69 | parent: pim-importMapping-edit-form
70 | targetZone: buttons
71 | position: 0
72 | config:
73 | updateSuccessMessage: pim_enrich.entity.generic.flash.update.success
74 | updateFailureMessage: pim_enrich.entity.generic.flash.update.fail
75 | notReadyMessage: pim_enrich.entity.generic.flash.info.field_not_ready
76 | url: pim_customentity_rest_edit
77 | route_params:
78 | customEntityName: importMapping
79 | redirectAfter: pim_customentity_rest_get
80 | excludedProperties: ['data']
81 |
82 | pim-importMapping-edit-form-properties-tab:
83 | module: pim/common/tab
84 | parent: pim-importMapping-edit-form-form-tabs
85 | targetZone: container
86 | position: 100
87 | config:
88 | label: pim_custom_entity.form.tab.properties.title
89 |
90 | pim-importMapping-edit-form-properties:
91 | module: pim/common/simple-view
92 | parent: pim-importMapping-edit-form-properties-tab
93 | targetZone: self
94 | config:
95 | template: pim/template/form/tab/sections
96 |
97 | pim-importMapping-edit-form-state:
98 | module: pim/form/common/state
99 | parent: pim-importMapping-edit-form
100 | targetZone: state
101 | position: 900
102 | config:
103 | entity: pim_enrich.entity.group.title
104 |
105 | pim-importMapping-edit-form-properties:
106 | module: pim/common/simple-view
107 | parent: pim-importMapping-edit-form-properties-tab
108 | targetZone: self
109 | config:
110 | template: pim/template/form/tab/sections
111 |
112 | pim-importMapping-edit-form-properties-common:
113 | module: pim/common/simple-view
114 | parent: pim-importMapping-edit-form-properties
115 | targetZone: accordion
116 | position: 100
117 | config:
118 | template: pim/template/form/tab/section-large
119 | templateParams:
120 | sectionTitle: pim_custom_entity.form.tab.properties.section.common
121 | dropZone: content
122 |
123 | pim-importMapping-edit-form-properties-label:
124 | module: pim/form/common/fields/text
125 | parent: pim-importMapping-edit-form-properties-common
126 | targetZone: content
127 | position: 90
128 | config:
129 | fieldName: label
130 | label: candm_advanced_csv_connector.importMapping.field.label.label
131 | required: true
132 |
133 | pim-importMapping-edit-form-properties-code:
134 | module: pim/form/common/fields/text
135 | parent: pim-importMapping-edit-form-properties-common
136 | targetZone: content
137 | position: 100
138 | config:
139 | fieldName: code
140 | label: candm_advanced_csv_connector.importMapping.field.label.code
141 | required: true
142 |
143 | pim-importMapping-edit-form-properties-mapping:
144 | module: pim/form/common/fields/import-mapping
145 | parent: pim-importMapping-edit-form-properties-common
146 | targetZone: content
147 | position: 110
148 | config:
149 | fieldName: mappingAsJson
150 | label: candm_advanced_csv_connector.importMapping.field.label.mapping
151 |
152 | pim-importMapping-edit-form-properties-complete-callback:
153 | module: pim/form/common/fields/text
154 | parent: pim-importMapping-edit-form-properties-common
155 | targetZone: content
156 | position: 120
157 | config:
158 | fieldName: completeCallback
159 | label: candm_advanced_csv_connector.importMapping.field.label.complete_callback
160 |
161 | pim-importMapping-edit-form-properties-initialize-callback:
162 | module: pim/form/common/fields/text
163 | parent: pim-importMapping-edit-form-properties-common
164 | targetZone: content
165 | position: 130
166 | config:
167 | fieldName: initializeCallback
168 | label: candm_advanced_csv_connector.importMapping.field.label.initialize_callback
169 |
170 | pim-importMapping-edit-form-properties-flush-callback:
171 | module: pim/form/common/fields/text
172 | parent: pim-importMapping-edit-form-properties-common
173 | targetZone: content
174 | position: 140
175 | config:
176 | fieldName: flushCallback
177 | label: candm_advanced_csv_connector.importMapping.field.label.flush_callback
178 |
179 | pim-importMapping-edit-form-properties-items-limit:
180 | module: pim/form/common/fields/text
181 | parent: pim-importMapping-edit-form-properties-common
182 | targetZone: content
183 | position: 150
184 | config:
185 | fieldName: itemsLimit
186 | label: candm_advanced_csv_connector.importMapping.field.label.items_limit
187 |
188 | pim-importMapping-edit-form-properties-only-update:
189 | module: pim/form/common/fields/boolean
190 | parent: pim-importMapping-edit-form-properties-common
191 | targetZone: content
192 | position: 160
193 | config:
194 | fieldName: onlyUpdate
195 | label: candm_advanced_csv_connector.importMapping.field.label.only_update
196 |
--------------------------------------------------------------------------------
/Resources/public/js/form/common/fields/import-mapping.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | define([
4 | 'jquery',
5 | 'underscore',
6 | 'oro/translator',
7 | 'tabulator',
8 | 'pim/fetcher-registry',
9 | 'pim/form/common/fields/field',
10 | 'pim/template/form/common/fields/import-mapping'
11 | ],
12 | function (
13 | $,
14 | _,
15 | __,
16 | Tabulator,
17 | FetcherRegistry,
18 | BaseField,
19 | template
20 | ) {
21 | return BaseField.extend({
22 | template: _.template(template),
23 |
24 | yesNoValues: {
25 | 'true': __('pim_common.yes'),
26 | 'false': __('pim_common.no'),
27 | },
28 |
29 | luaUpdaters: {},
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | renderInput: function (templateContext) {
35 | return this.template(_.extend(templateContext, {
36 | value: this.getModelValue()
37 | }));
38 | },
39 |
40 | /**
41 | * {@inherit}
42 | */
43 | configure() {
44 | return $.when(
45 | this.fetchLuaUpdaters().then(luaUpdaters => {
46 | var self = this;
47 | _.each(luaUpdaters, function (luaUpdater) {
48 | self.luaUpdaters[luaUpdater.code] = luaUpdater.label;
49 | });
50 | }),
51 | );
52 | },
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | postRender: function () {
58 | var self = this;
59 | var modelValueAsString = !_.isUndefined(self.getModelValue()) ? self.getModelValue() : '[]';
60 | var tabledata = JSON.parse(modelValueAsString);
61 | var table = new Tabulator("#mapping-table", {
62 | data: tabledata,
63 | layout: "fitColumns",
64 | responsiveLayout: true,
65 | columnHeaderSortMulti: false,
66 | addRowPos: 'bottom',
67 | cellEdited: function (cell) {
68 | self.updateModelValue(cell._cell.table.getData());
69 | },
70 | rowDeleted: function (row) {
71 | self.updateModelValue(row._row.table.getData());
72 | },
73 | columns: [
74 | {
75 | title: __('candm_advanced_csv_connector.importMapping.columns.attribute_code'),
76 | field: 'attributeCode',
77 | headerSort: false,
78 | editor: 'input'
79 | },
80 | {
81 | title: __('candm_advanced_csv_connector.importMapping.columns.column_name'),
82 | field: 'dataCode',
83 | headerSort: false,
84 | editor: 'input'
85 | },
86 | {
87 | title: __('candm_advanced_csv_connector.importMapping.columns.lua_updater'),
88 | field: 'luaUpdater',
89 | headerSort: false,
90 | editor: 'autocomplete',
91 | editorParams: {
92 | allowEmpty: true,
93 | values: self.luaUpdaters,
94 | freetext: true
95 | }
96 | },
97 | {
98 | title: __('candm_advanced_csv_connector.importMapping.columns.default_value'),
99 | field: 'defaultValue',
100 | headerSort: false,
101 | editor: 'input'
102 | },
103 | {
104 | title: __('candm_advanced_csv_connector.importMapping.columns.identifier'),
105 | field: 'identifier',
106 | headerSort: false,
107 | editor: 'select',
108 | editorParams: {
109 | values: self.yesNoValues
110 | },
111 | accessorData: self.booleanAccessor,
112 | formatter: self.booleanFormatter,
113 | formatterParams: {self: self}
114 | },
115 | {
116 | title: __('candm_advanced_csv_connector.importMapping.columns.only_on_creation'),
117 | field: 'onlyOnCreation',
118 | headerSort: false,
119 | editor: 'select',
120 | editorParams: {
121 | values: self.yesNoValues
122 | },
123 | accessorData: self.booleanAccessor,
124 | formatter: self.booleanFormatter,
125 | formatterParams: {self: self}
126 | },
127 | {
128 | title: __('candm_advanced_csv_connector.importMapping.columns.delete_if_null'),
129 | field: 'deleteIfNull',
130 | headerSort: false,
131 | editor: 'select',
132 | editorParams: {
133 | values: self.yesNoValues
134 | },
135 | accessorData: self.booleanAccessor,
136 | formatter: self.booleanFormatter,
137 | formatterParams: {self: self}
138 | },
139 | {
140 | title: __('candm_advanced_csv_connector.importMapping.actions.delete_row'),
141 | field: 'delete',
142 | formatter: 'tickCross',
143 | headerSort: false,
144 | cellClick: function (e, cell) {
145 | cell._cell.row.delete();
146 | },
147 | }
148 | ]
149 | });
150 |
151 | // Manage clicks
152 | $("#add-row").click(function () {
153 | table.addRow({});
154 | });
155 | },
156 |
157 | /**
158 | * Accessor data used to convert string value to boolean
159 | *
160 | * @param value
161 | * @param data
162 | * @param type
163 | * @param params
164 | * @param column
165 | */
166 | booleanAccessor: function (value, data, type, params, column) {
167 | return value == 'true' || value == true;
168 | },
169 |
170 | /**
171 | * Boolean formatter
172 | *
173 | * @param cell
174 | * @param formaterParams
175 | * @param onRendered
176 | */
177 | booleanFormatter: function (cell, formaterParams, onRendered) {
178 | return _.has(formaterParams.self.yesNoValues, cell.getValue()) ? formaterParams.self.yesNoValues[cell.getValue()] : __('pim_common.no');
179 | },
180 |
181 | /**
182 | * Update model data
183 | *
184 | * @param data
185 | */
186 | updateModelValue: function (data) {
187 | var dataAsString = JSON.stringify(data);
188 | this.updateModel(dataAsString);
189 | },
190 |
191 | /**
192 | * Get LUA scripts
193 | *
194 | * @returns {*|Promise}
195 | */
196 | fetchLuaUpdaters() {
197 | const fetcher = FetcherRegistry.getFetcher('custom_entity');
198 |
199 | return fetcher.fetchAllByType('luaUpdater');
200 | },
201 | });
202 | });
--------------------------------------------------------------------------------
/Resources/public/js/form/common/fields/export-mapping.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | define([
4 | 'jquery',
5 | 'underscore',
6 | 'oro/translator',
7 | 'tabulator',
8 | 'pim/fetcher-registry',
9 | 'pim/form/common/fields/field',
10 | 'pim/template/form/common/fields/export-mapping'
11 | ],
12 | function (
13 | $,
14 | _,
15 | __,
16 | Tabulator,
17 | FetcherRegistry,
18 | BaseField,
19 | template
20 | ) {
21 | return BaseField.extend({
22 | template: _.template(template),
23 |
24 | yesNoValues: {
25 | 'true': __('pim_common.yes'),
26 | 'false': __('pim_common.no'),
27 | },
28 |
29 | localesValues: {},
30 |
31 | luaUpdaters: {},
32 |
33 | /**
34 | * {@inheritdoc}
35 | */
36 | renderInput: function (templateContext) {
37 | return this.template(_.extend(templateContext, {
38 | value: this.getModelValue()
39 | }));
40 | },
41 |
42 | /**
43 | * {@inheritdoc}
44 | */
45 | configure() {
46 | return $.when(
47 | this.fetchLocales().then(locales => {
48 | var self = this;
49 | _.each(locales, function (locale) {
50 | self.localesValues[locale.code] = locale.code;
51 | });
52 | }),
53 | this.fetchLuaUpdaters().then(luaUpdaters => {
54 | var self = this;
55 | _.each(luaUpdaters, function (luaUpdater) {
56 | self.luaUpdaters[luaUpdater.code] = luaUpdater.label;
57 | });
58 | }),
59 | );
60 | },
61 |
62 | /**
63 | * {@inheritdoc}
64 | */
65 | postRender: function () {
66 | var self = this;
67 | var modelValueAsString = !_.isUndefined(self.getModelValue()) ? self.getModelValue() : '[]';
68 | var tabledata = JSON.parse(modelValueAsString);
69 | var table = new Tabulator("#mapping-table", {
70 | data: tabledata,
71 | layout: "fitColumns",
72 | responsiveLayout: true,
73 | columnHeaderSortMulti: false,
74 | addRowPos: 'bottom',
75 | cellEdited: function (cell) {
76 | self.updateModelValue(cell._cell.table.getData());
77 | },
78 | rowDeleted: function (row) {
79 | self.updateModelValue(row._row.table.getData());
80 | },
81 | columns: [
82 | {
83 | title: __('candm_advanced_csv_connector.exportMapping.columns.attribute_code'),
84 | field: 'attributeCode',
85 | headerSort: false,
86 | editor: 'input'
87 | },
88 | {
89 | title: __('candm_advanced_csv_connector.exportMapping.columns.column_name'),
90 | field: 'columnName',
91 | headerSort: false,
92 | editor: 'input'
93 | },
94 | {
95 | title: __('candm_advanced_csv_connector.exportMapping.columns.forced_value'),
96 | field: 'forcedValue',
97 | headerSort: false,
98 | editor: 'input'
99 | },
100 | {
101 | title: __('candm_advanced_csv_connector.exportMapping.columns.lua_updater'),
102 | field: 'luaUpdater',
103 | headerSort: false,
104 | editor: 'autocomplete',
105 | editorParams: {
106 | allowEmpty: true,
107 | values: self.luaUpdaters,
108 | freetext: true
109 | }
110 | },
111 | {
112 | title: __('candm_advanced_csv_connector.exportMapping.columns.use_label'),
113 | field: 'useLabel',
114 | headerSort: false,
115 | editor: 'select',
116 | editorParams: {
117 | values: self.yesNoValues
118 | },
119 | accessorData: self.booleanAccessor,
120 | formatter: self.booleanFormatter,
121 | formatterParams: {self: self}
122 | },
123 | {
124 | title: __('candm_advanced_csv_connector.exportMapping.columns.locale'),
125 | field: 'locale',
126 | headerSort: false,
127 | editor: 'select',
128 | editorParams: {
129 | values: self.localesValues
130 | }
131 | },
132 | {
133 | title: __('candm_advanced_csv_connector.exportMapping.columns.max_length'),
134 | field: 'maxLength',
135 | headerSort: false,
136 | editor: 'input'
137 | },
138 | {
139 | title: __('candm_advanced_csv_connector.exportMapping.columns.default_value'),
140 | field: 'defaultValue',
141 | headerSort: false,
142 | editor: 'input'
143 | },
144 | {
145 | title: __('candm_advanced_csv_connector.importMapping.actions.delete_row'),
146 | field: 'delete',
147 | formatter: 'tickCross',
148 | headerSort: false,
149 | cellClick: function (e, cell) {
150 | cell._cell.row.delete();
151 | },
152 | }
153 | ]
154 | });
155 |
156 | // Manage clicks
157 | $("#add-row").click(function () {
158 | table.addRow({});
159 | });
160 | },
161 |
162 | /**
163 | * Accessor data used to convert string value to boolean
164 | *
165 | * @param value
166 | * @param data
167 | * @param type
168 | * @param params
169 | * @param column
170 | */
171 | booleanAccessor: function (value, data, type, params, column) {
172 | return value == 'true' || value == true;
173 | },
174 |
175 | /**
176 | * Boolean formatter
177 | *
178 | * @param cell
179 | * @param formaterParams
180 | * @param onRendered
181 | */
182 | booleanFormatter: function (cell, formaterParams, onRendered) {
183 | return _.has(formaterParams.self.yesNoValues, cell.getValue()) ? formaterParams.self.yesNoValues[cell.getValue()] : __('pim_common.no');
184 | },
185 |
186 | /**
187 | * Update model data
188 | *
189 | * @param data
190 | */
191 | updateModelValue: function (data) {
192 | var dataAsString = JSON.stringify(data);
193 | this.updateModel(dataAsString);
194 | },
195 |
196 | /**
197 | * Get activated locales
198 | *
199 | * @returns {*|Promise}
200 | */
201 | fetchLocales() {
202 | const localeFetcher = FetcherRegistry.getFetcher('locale');
203 |
204 | return localeFetcher.fetchActivated();
205 | },
206 |
207 | /**
208 | * Get LUA scripts
209 | *
210 | * @returns {*|Promise}
211 | */
212 | fetchLuaUpdaters() {
213 | const fetcher = FetcherRegistry.getFetcher('custom_entity');
214 |
215 | return fetcher.fetchAllByType('luaUpdater');
216 | },
217 | });
218 | });
--------------------------------------------------------------------------------
/Resources/translations/jsmessages.en.yml:
--------------------------------------------------------------------------------
1 | # Custom
2 | batch_jobs:
3 | csv_advanced_product_import:
4 | label: Advanced products import (CSV)
5 | fields:
6 | mapping:
7 | label: Data mapping
8 | email_recipients:
9 | label: Email recipients
10 | help: Email addresses separated by commas
11 | success_notification:
12 | label: Notification on success
13 | help: Allows you to have an email notification in case of success
14 | from_encoding:
15 | label: From encoding
16 | help: Allows you to select the input encoding of the file (it will be re-encoded in UTF-8)
17 | import:
18 | label: Products import
19 |
20 | csv_advanced_product_model_import:
21 | label: Advanced products models import (CSV)
22 | fields:
23 | mapping:
24 | label: Data mapping
25 | email_recipients:
26 | label: Email recipients
27 | help: Email addresses separated by commas
28 | success_notification:
29 | label: Notification on success
30 | help: Allows you to have an email notification in case of success
31 | from_encoding:
32 | label: From encoding
33 | help: Allows you to select the input encoding of the file (it will be re-encoded in UTF-8)
34 | import:
35 | label: Products models import
36 |
37 | csv_advanced_product_export:
38 | label: Advanced products export (CSV)
39 | fields:
40 | mapping:
41 | label: Data mapping
42 | encoding:
43 | label: Encoding
44 | help: Output file encoding (UTF-8 by default)
45 | force_xlsx:
46 | label: Export to Excel format
47 | help: Allows to force the export in .xlsx format
48 | export:
49 | label: Products export
50 |
51 | csv_advanced_product_model_export:
52 | label: Advanced products models export (CSV)
53 | fields:
54 | mapping:
55 | label: Data mapping
56 | encoding:
57 | label: Encoding
58 | help: Output file encoding (UTF-8 by default)
59 | force_xlsx:
60 | label: Export to Excel format
61 | help: Allows to force the export in .xlsx format
62 | export:
63 | label: Products models export
64 | default_steps:
65 | notification: Email notification
66 |
67 | # Custom entity
68 | pim_menu:
69 | tab.reference_data: Referential
70 | item.reference_data: Referential
71 | navigation.reference_data: Referential
72 |
73 | pim_custom_entity:
74 | index_title: Global view
75 | create_popin.title: Create
76 | form:
77 | field.label.label: Label
78 | field.label.code: Code
79 | tab:
80 | history.title: History
81 | properties:
82 | title: Properties
83 | section:
84 | common: General
85 | label_translations: Labels
86 | button:
87 | create: Create
88 | message:
89 | created: Created with success
90 | removed: Deleted with success
91 | delete: Delete element?
92 | error:
93 | removing: This referential data can not be deleted
94 | export.csv.entity_name:
95 | label: Referential name
96 | help: Referential name that you want to export
97 | no_reference_data: No referential available
98 | import.csv.entity_name:
99 | label: Referential name
100 | help: Referential name that you want to import
101 | no_reference_data: No referential available
102 |
103 | pim_title:
104 | pim_customentity_index: 'Referential - Global view'
105 | pim_customentity_rest_create: 'Referential - Global view'
106 | pim_customentity_massedit: 'Referential'
107 | pim_customentity_quickexport: 'Referential'
108 | pim_customentity_rest_delete: 'Referential'
109 | pim_customentity_rest_list: 'Referential'
110 | pim_customentity_rest_get: 'Referential - View'
111 |
112 | # Custom
113 | candm_advanced_csv_connector:
114 | importMapping:
115 | index_title: "] -Inf, 1] {{ count }} import mapping|] 1, Inf [{{ count }} import mappings"
116 | selected: import mapping(s) selected
117 |
118 | field:
119 | label:
120 | label: Label
121 | code: Code
122 | mapping: Mapping attributes / columns
123 | complete_callback: Callback transform after mapping
124 | initialize_callback: Callback before import
125 | flush_callback: Callback after import
126 | items_limit: Items limit
127 | only_update: Products update only
128 |
129 | columns:
130 | attribute_code: Attribute
131 | column_name: Column name
132 | default_value: Default value
133 | identifier: Identifier
134 | only_on_creation: Only on creation
135 | delete_if_null: Erase if null
136 | lua_updater: Transform
137 | actions:
138 | add_row: Add a line
139 | delete_row: Delete
140 |
141 | exportMapping:
142 | index_title: "] -Inf, 1] {{ count }} export mapping|] 1, Inf [{{ count }} export mappings"
143 | selected: export mapping(s) selected
144 |
145 | field:
146 | label:
147 | label: Label
148 | code: Code
149 | mapping: Mapping attributes / columns
150 | complete_callback: Callback transform after mapping
151 |
152 | columns:
153 | attribute_code: Attribute
154 | column_name: Column name
155 | forced_value: Forced value
156 | use_label: Use label
157 | locale: Locale
158 | max_length: Max length
159 | default_value: Default value
160 | lua_updater: Transform
161 | actions:
162 | add_row: Add a line
163 | delete_row: Delete
164 |
165 | luaUpdater:
166 | index_title: "] -Inf, 1] {{ count }} LUA script|] 1, Inf [{{ count }} LUA scripts"
167 | selected: LUA script(s) selected
168 | field:
169 | label:
170 | label: Label
171 | code: Code
172 | script: Script
173 | custom:
174 | test_value: Test value
175 | test_action: Test
176 |
177 | menu.item.reference_data:
178 | importMapping: Import mappings
179 | exportMapping: Export mappings
180 | luaUpdater: LUA scripts
181 |
182 | acl:
183 | importMapping:
184 | index: List import mappings
185 | create: Create an import mapping
186 | edit: Edit an import mapping
187 | delete: Delete an import mapping
188 | exportMapping:
189 | index: List export mappings
190 | create: Create an export mapping
191 | edit: Edit an export mapping
192 | delete: Delete an export mapping
193 | luaUpdater:
194 | index: List LUA scripts
195 | create: Create a LUA script
196 | edit: Edit a LUA script
197 | delete: Delete a LUA script
198 |
199 | pim_enrich:
200 | form.attribute.tab.properties.label:
201 | name: Name
202 | entity:
203 | generic:
204 | flash:
205 | update:
206 | success: Entity updated successfully!
207 | fail: Error during entity update
208 | info:
209 | field_not_ready: Field not ready
210 | importmapping:
211 | flash:
212 | delete:
213 | success: Mapping deleted!
214 | module:
215 | delete:
216 | confirm: Are you sure you want to delete this import mapping?
217 | importMapping:
218 | flash:
219 | delete:
220 | fail: Can not delete this import mapping
221 | exportmapping:
222 | flash:
223 | delete:
224 | success: Mapping deleted!
225 | module:
226 | delete:
227 | confirm: Are you sure you want to delete this export mapping?
228 | exportMapping:
229 | flash:
230 | delete:
231 | fail: Can not delete this export mapping
232 | luaupdater:
233 | flash:
234 | delete:
235 | success: LUA script deleted!
236 | module:
237 | delete:
238 | confirm: Are you sure you want to delete this LUA script?
239 | luaUpdater:
240 | flash:
241 | delete:
242 | fail: Can not delete this LUA script
243 | attribute:
244 | info:
245 | update_failed: Error during entity update
246 |
--------------------------------------------------------------------------------
/Resources/translations/jsmessages.fr.yml:
--------------------------------------------------------------------------------
1 | # Custom
2 | batch_jobs:
3 | csv_advanced_product_import:
4 | label: Import des produits avancé (CSV)
5 | fields:
6 | mapping:
7 | label: Mapping des données
8 | email_recipients:
9 | label: Destinataires pour les rapports
10 | help: Adresses emails séparées par des virgules
11 | success_notification:
12 | label: Notification en cas de succès
13 | help: Permet d'avoir une notification par email en cas de succès
14 | from_encoding:
15 | label: Encodage en entrée
16 | help: Permet de sélectionner l'encodage en entrée du fichier (il sera ré-encodé en UTF-8)
17 | import:
18 | label: Import des produits
19 | default_steps:
20 | notification: Notification par email
21 |
22 | csv_advanced_product_model_import:
23 | label: Import des modèles produits avancé (CSV)
24 | fields:
25 | mapping:
26 | label: Mapping des données
27 | email_recipients:
28 | label: Destinataires pour les rapports
29 | help: Adresses emails séparées par des virgules
30 | success_notification:
31 | label: Notification en cas de succès
32 | help: Permet d'avoir une notification par email en cas de succès
33 | from_encoding:
34 | label: Encodage en entrée
35 | help: Permet de sélectionner l'encodage en entrée du fichier (il sera ré-encodé en UTF-8)
36 | import:
37 | label: Import des modèles produits
38 |
39 | csv_advanced_product_export:
40 | label: Export des produits avancé (CSV)
41 | fields:
42 | mapping:
43 | label: Mapping des données
44 | encoding:
45 | label: Encodage
46 | help: Encodage du fichier de sortie (UTF-8 par défaut)
47 | force_xlsx:
48 | label: Exporter au format Excel
49 | help: Permet de forcer l'export au format .xlsx
50 | export:
51 | label: Export des produits
52 |
53 | csv_advanced_product_model_export:
54 | label: Export des modèles produits avancé (CSV)
55 | fields:
56 | mapping:
57 | label: Mapping des données
58 | encoding:
59 | label: Encodage
60 | help: Encodage du fichier de sortie (UTF-8 par défaut)
61 | force_xlsx:
62 | label: Exporter au format Excel
63 | help: Permet de forcer l'export au format .xlsx
64 | export:
65 | label: Export des modèles produits
66 |
67 | # Custom entity
68 | pim_menu:
69 | tab.reference_data: Référenciel
70 | item.reference_data: Référenciel
71 | navigation.reference_data: Référenciel
72 |
73 | pim_custom_entity:
74 | index_title: Vue générale
75 | create_popin.title: Créer
76 | form:
77 | field.label.label: Libellé
78 | field.label.code: Code
79 | tab:
80 | history.title: Historique
81 | properties:
82 | title: Propriétés
83 | section:
84 | common: Général
85 | label_translations: Libellés
86 | button:
87 | create: Créer
88 | message:
89 | created: Créé avec succès
90 | removed: Supprimé avec succès
91 | delete: Supprimer l'élément ?
92 | error:
93 | removing: Ce référenciel ne peut être supprimé
94 | export.csv.entity_name:
95 | label: Nom du référenciel
96 | help: Le nom du référenciel que vous souhaitez exporter
97 | no_reference_data: Aucun référenciel disponible
98 | import.csv.entity_name:
99 | label: Nom du référenciel
100 | help: Le nom du référenciel que vous souhaitez importer
101 | no_reference_data: Aucun référenciel disponible
102 |
103 | pim_title:
104 | pim_customentity_index: 'Référenciel - Vue générale'
105 | pim_customentity_rest_create: 'Référenciel - Créer'
106 | pim_customentity_massedit: 'Référenciel'
107 | pim_customentity_quickexport: 'Référenciel'
108 | pim_customentity_rest_delete: 'Référenciel'
109 | pim_customentity_rest_list: 'Référenciel'
110 | pim_customentity_rest_get: 'Référenciel - Vue'
111 |
112 | # Custom
113 | candm_advanced_csv_connector:
114 | importMapping:
115 | index_title: "] -Inf, 1] {{ count }} mapping d'import|] 1, Inf [{{ count }} mappings d'import"
116 | selected: mapping(s) d'import sélectionné(s)
117 |
118 | field:
119 | label:
120 | label: Libellé
121 | code: Code
122 | mapping: Mapping attributs / colonnes
123 | complete_callback: Méthode de transformation après mapping
124 | initialize_callback: Méthode avant l'exécution de l'import
125 | flush_callback: Méthode après l'exécution de l'import
126 | items_limit: Nombre de produits max. à importer
127 | only_update: Mise à jour des produits uniquement
128 |
129 | columns:
130 | attribute_code: Attribut
131 | column_name: Nom de la colonne
132 | default_value: Valeur par défaut
133 | identifier: Identifiant
134 | only_on_creation: Uniquement à la création
135 | delete_if_null: Effacer si nul
136 | lua_updater: Transformation
137 | actions:
138 | add_row: Ajouter une ligne
139 | delete_row: Supprimer
140 |
141 | exportMapping:
142 | index_title: "] -Inf, 1] {{ count }} mapping d'export|] 1, Inf [{{ count }} mappings d'export"
143 | selected: mapping(s) d'export sélectionné(s)
144 |
145 | field:
146 | label:
147 | label: Libellé
148 | code: Code
149 | mapping: Mapping attributs / colonnes
150 | complete_callback: Méthode de transformation après mapping
151 |
152 | columns:
153 | attribute_code: Attribut
154 | column_name: Nom de la colonne
155 | forced_value: Valeur forcée
156 | use_label: Utiliser le libellé
157 | locale: Langue
158 | max_length: Longueur max.
159 | default_value: Valeur par défaut
160 | lua_updater: Transformation
161 | actions:
162 | add_row: Ajouter une ligne
163 | delete_row: Supprimer
164 |
165 | luaUpdater:
166 | index_title: "] -Inf, 1] {{ count }} script LUA|] 1, Inf [{{ count }} scripts LUA"
167 | selected: script(s) LUA sélectionné(s)
168 | field:
169 | label:
170 | label: Libellé
171 | code: Code
172 | script: Script
173 | custom:
174 | test_value: Valeur pour le test
175 | test_action: Tester
176 |
177 | menu.item.reference_data:
178 | importMapping: Mappings d'import
179 | exportMapping: Mappings d'export
180 | luaUpdater: Scripts LUA
181 |
182 | acl:
183 | importMapping:
184 | index: Lister les mappings d'import
185 | create: Créer un mapping d'import
186 | edit: Éditer un mapping d'import
187 | delete: Supprimer un mapping d'import
188 | exportMapping:
189 | index: Lister les mappings d'export
190 | create: Créer un mapping d'export
191 | edit: Éditer un mapping d'export
192 | delete: Supprimer un mapping d'export
193 | luaUpdater:
194 | index: Lister les scripts LUA
195 | create: Créer un script LUA
196 | edit: Éditer un script LUA
197 | delete: Supprimer un script LUA
198 |
199 | pim_enrich:
200 | form.attribute.tab.properties.label:
201 | name: Nom
202 | entity:
203 | generic:
204 | flash:
205 | update:
206 | success: Entité mise à jour avec succès !
207 | fail: Erreur pendant la mise à jour
208 | info:
209 | field_not_ready: Ce champ n'est pas prêt
210 | importmapping:
211 | flash:
212 | delete:
213 | success: Mapping supprimé avec succès !
214 | module:
215 | delete:
216 | confirm: Êtes-vous sûr de vouloir supprimer ce mapping d'import ?
217 | importMapping:
218 | flash:
219 | delete:
220 | fail: Impossible de supprimer ce mapping d'import
221 | exportmapping:
222 | flash:
223 | delete:
224 | success: Mapping supprimé avec succès !
225 | module:
226 | delete:
227 | confirm: Êtes-vous sûr de vouloir supprimer ce mapping d'export ?
228 | exportMapping:
229 | flash:
230 | delete:
231 | fail: Impossible de supprimer ce mapping d'export
232 | luaupdater:
233 | flash:
234 | delete:
235 | success: Script LUA supprimé avec succès !
236 | module:
237 | delete:
238 | confirm: Êtes-vous sûr de vouloir supprimer ce script LUA ?
239 | luaUpdater:
240 | flash:
241 | delete:
242 | fail: Impossible de supprimer ce script LUA
243 | attribute:
244 | info:
245 | update_failed: Erreur lors de la mise à jour de l'entité
246 |
--------------------------------------------------------------------------------
/Step/MailNotification.php:
--------------------------------------------------------------------------------
1 |
20 | * @package ClickAndMortar\AdvancedCsvConnectorBundle\Step
21 | */
22 | class MailNotification extends AbstractStep
23 | {
24 | /**
25 | * Email recipients job parameter
26 | *
27 | * @var string
28 | */
29 | const JOB_PARAMETERS_EMAIL_RECIPIENTS = 'emailRecipients';
30 |
31 | /**
32 | * Sucess notification parameter
33 | *
34 | * @var string
35 | */
36 | const JOB_PARAMETERS_SUCCESS_NOTIFICATION = 'successNotification';
37 |
38 | /**
39 | * Import step name
40 | *
41 | * @var string
42 | */
43 | const STEP_NAME_IMPORT = 'import';
44 |
45 | /**
46 | * Recipients separator
47 | *
48 | * @var string
49 | */
50 | const RECIPIENTS_SEPARATOR = ',';
51 |
52 | /**
53 | * Message type reason key
54 | *
55 | * @var string
56 | */
57 | const MESSAGE_TYPE_REASON_KEY = 'messageType';
58 |
59 | /**
60 | * Default message type
61 | *
62 | * @var string
63 | */
64 | const MESSAGE_TYPE_DEFAULT = 'default';
65 |
66 | /**
67 | * Statistics message type
68 | *
69 | * @var string
70 | */
71 | const MESSAGE_TYPE_STATISTICS = 'statistics';
72 |
73 | /**
74 | * @var MailNotifier $notifier
75 | */
76 | protected $notifier;
77 |
78 | /**
79 | * @var Environment $templating
80 | */
81 | protected $templating;
82 |
83 | /**
84 | * @var TranslatorDecorator $translator
85 | */
86 | protected $translator;
87 |
88 | /**
89 | * @var StepExecution $stepExecution
90 | */
91 | protected $stepExecution;
92 |
93 | /**
94 | * Identifier keys for item
95 | *
96 | * @var string[]
97 | */
98 | protected $identifierKeys = [
99 | 'identifier',
100 | 'code',
101 | ];
102 |
103 | /**
104 | * @param string $name
105 | * @param EventDispatcherInterface $eventDispatcher
106 | * @param JobRepositoryInterface $jobRepository
107 | * @param MailNotifier $notifier
108 | * @param Environment $templating
109 | * @param TranslatorDecorator $translator
110 | */
111 | public function __construct(
112 | $name,
113 | EventDispatcherInterface $eventDispatcher,
114 | JobRepositoryInterface $jobRepository,
115 | MailNotifier $notifier,
116 | Environment $templating,
117 | TranslatorDecorator $translator
118 | )
119 | {
120 | parent::__construct($name, $eventDispatcher, $jobRepository);
121 | $this->notifier = $notifier;
122 | $this->templating = $templating;
123 | $this->translator = $translator;
124 | }
125 |
126 | /**
127 | * @param StepExecution $stepExecution
128 | */
129 | protected function doExecute(StepExecution $stepExecution)
130 | {
131 | // Check if we have recipients
132 | $this->stepExecution = $stepExecution;
133 | $jobParameters = $this->stepExecution->getJobParameters();
134 | if (
135 | !$jobParameters->has(self::JOB_PARAMETERS_EMAIL_RECIPIENTS)
136 | || empty($jobParameters->get(self::JOB_PARAMETERS_EMAIL_RECIPIENTS))
137 | ) {
138 | return;
139 | }
140 |
141 | // Check if we want success notification
142 | $successNotification = $jobParameters->has(self::JOB_PARAMETERS_SUCCESS_NOTIFICATION) && $jobParameters->get(self::JOB_PARAMETERS_SUCCESS_NOTIFICATION) === true;
143 |
144 | // Generate and send notifications
145 | $jobExecution = $this->stepExecution->getJobExecution();
146 | $recipients = $jobParameters->get(self::JOB_PARAMETERS_EMAIL_RECIPIENTS);
147 | $recipients = explode(self::RECIPIENTS_SEPARATOR, $recipients);
148 | $mailLabel = $this->translator->trans('batch_jobs.mail_notification.subject', [
149 | '%importLabel%' => $jobExecution->getLabel(),
150 | '%date%' => $jobExecution->getStartTime()->format('d/m/Y, H:i'),
151 | ]);
152 |
153 | // Parse data from steps
154 | $messagesByStepAndType = [];
155 | /** @var StepExecution $stepExecution */
156 | foreach ($jobExecution->getStepExecutions() as $stepExecution) {
157 | // Get statistics data
158 | $statisticsMessages = $this->getStatisticsByStepExecution($stepExecution);
159 |
160 | // Get warnings
161 | $warningMessages = [];
162 | $warnings = $stepExecution->getWarnings();
163 | if (!$warnings->isEmpty()) {
164 | $warningMessages = $this->getMessagesByType($warnings);
165 | }
166 |
167 | // Skip if notification success is not activated
168 | if (!$successNotification && empty($warningMessages)) {
169 | continue;
170 | }
171 |
172 | $messagesForCurrentStep = array_merge($statisticsMessages, $warningMessages);
173 | if (!empty($messagesForCurrentStep)) {
174 | $messagesByStepAndType[$stepExecution->getStepName()] = $messagesForCurrentStep;
175 | }
176 | }
177 |
178 | // Send notification
179 | if (!empty($messagesByStepAndType)) {
180 | $contentAsHtml = $this->templating->render(
181 | '@ClickAndMortarAdvancedCsvConnector/notification.html.twig',
182 | [
183 | 'messagesByStepAndType' => $messagesByStepAndType,
184 | ]
185 | );
186 | $this->notifier->notify($recipients, $mailLabel, '', $contentAsHtml);
187 | }
188 | }
189 |
190 | /**
191 | * Get statistics used by notification template from $stepExecution
192 | *
193 | * @param StepExecution $stepExecution
194 | *
195 | * @return array
196 | */
197 | protected function getStatisticsByStepExecution($stepExecution)
198 | {
199 | $statistics = [];
200 | $trackingData = $stepExecution->getTrackingData();
201 | $readCount = intval($trackingData['totalItems']);
202 | if ($readCount === 0) {
203 | return $statistics;
204 | }
205 |
206 | $warningCount = count($stepExecution->getWarnings());
207 | $writeCount = $readCount - $warningCount;
208 |
209 | // Read lines
210 | $statistics[] = [
211 | 'content' => $this->translator->trans(
212 | 'batch_jobs.mail_notification.statistics.read',
213 | [
214 | '%readCount%' => $readCount,
215 | ]
216 | ),
217 | ];
218 |
219 | // Write lines
220 | $statistics[] = [
221 | 'content' => $this->translator->trans(
222 | 'batch_jobs.mail_notification.statistics.write',
223 | [
224 | '%writeCount%' => $writeCount,
225 | ]
226 | ),
227 | ];
228 |
229 | // Warning lines
230 | $statistics[] = [
231 | 'content' => $this->translator->trans(
232 | 'batch_jobs.mail_notification.statistics.warning',
233 | [
234 | '%warningCount%' => $warningCount,
235 | ]
236 | ),
237 | ];
238 |
239 |
240 | return [
241 | self::MESSAGE_TYPE_STATISTICS => $statistics
242 | ];
243 | }
244 |
245 | /**
246 | * Get messages by type from import step execution $warnings
247 | *
248 | * @param Warning[] $warnings
249 | *
250 | * @return array
251 | */
252 | protected function getMessagesByType($warnings)
253 | {
254 | $messages = [];
255 | foreach ($warnings as $warning) {
256 | // Get product identifier
257 | $identifier = null;
258 | $item = $warning->getItem();
259 | foreach ($this->identifierKeys as $identifierKey) {
260 | if (isset($item[$identifierKey]) && !empty($item[$identifierKey])) {
261 | $identifier = $item[$identifierKey];
262 | break;
263 | }
264 | }
265 |
266 | // Get message type from reason parameters
267 | $reasonParameters = $warning->getReasonParameters();
268 | if (
269 | isset($reasonParameters[self::MESSAGE_TYPE_REASON_KEY])
270 | && !empty($reasonParameters[self::MESSAGE_TYPE_REASON_KEY])
271 | ) {
272 | $messageType = $reasonParameters[self::MESSAGE_TYPE_REASON_KEY];
273 | } else {
274 | $messageType = self::MESSAGE_TYPE_DEFAULT;
275 | }
276 |
277 | // Set message
278 | if (!array_key_exists($messageType, $messages)) {
279 | $messages[$messageType] = [];
280 | }
281 | $messages[$messageType][] = [
282 | 'identifier' => $identifier,
283 | 'content' => $this->translator->trans($warning->getReason(), $warning->getReasonParameters()),
284 | ];
285 | }
286 |
287 | return $messages;
288 | }
289 | }
290 |
--------------------------------------------------------------------------------