├── doc ├── img │ ├── logging.png │ ├── mapping.png │ ├── datasource.png │ ├── execution.png │ ├── datasource_asset.png │ ├── datasource_sql.png │ ├── execution_cron.png │ ├── execution_manual.png │ ├── import_preview.png │ ├── data_target_direct.png │ ├── resolver_settings.png │ ├── faq_execution_status.png │ ├── transformation_pipeline.png │ ├── data_target_classification_store.png │ ├── data_target_classification_store_batch.png │ ├── data_target_classification_store_batch_date.png │ ├── data_target_classification_store_batch_simple.png │ ├── data_target_classification_store_batch_decoding.png │ └── data_target_classification_store_batch_quantityValue.png ├── 03_Upgrade.md ├── 06_Extending │ ├── README.md │ ├── 03_Events.md │ └── 01_Extend_Custom_Strategies.md ├── 03_Configuration │ ├── README.md │ ├── 03_Import_Preview.md │ ├── 06_Mapping_Configuration │ │ ├── README.md │ │ └── 03_Data_Target │ │ │ └── README.md │ └── 07_Execution_Configuration.md ├── 06_Troubleshooting_FAQ.md └── 05_Import_Progress_and_Logging.md ├── src ├── Resources │ ├── config │ │ ├── doctrine_migrations.yml │ │ └── pimcore │ │ │ ├── routing.yml │ │ │ └── config.yml │ └── public │ │ ├── js │ │ └── pimcore │ │ │ ├── configuration │ │ │ ├── components │ │ │ │ ├── resolver │ │ │ │ │ ├── load │ │ │ │ │ │ ├── path.js │ │ │ │ │ │ ├── notLoad.js │ │ │ │ │ │ └── id.js │ │ │ │ │ ├── location │ │ │ │ │ │ ├── noChange.js │ │ │ │ │ │ ├── doNotCreate.js │ │ │ │ │ │ └── findOrCreateFolder.js │ │ │ │ │ └── publish │ │ │ │ │ │ ├── alwaysPublish.js │ │ │ │ │ │ ├── noChangePublishNew.js │ │ │ │ │ │ ├── noChangeUnpublishNew.js │ │ │ │ │ │ └── attributeBased.js │ │ │ │ ├── cleanup │ │ │ │ │ ├── delete.js │ │ │ │ │ └── unpublish.js │ │ │ │ ├── mapping │ │ │ │ │ └── operator │ │ │ │ │ │ ├── asArray.js │ │ │ │ │ │ ├── flattenArray.js │ │ │ │ │ │ ├── reduceArrayKeyValuePairs.js │ │ │ │ │ │ ├── boolean.js │ │ │ │ │ │ ├── asColor.js │ │ │ │ │ │ ├── gallery.js │ │ │ │ │ │ ├── htmlDecode.js │ │ │ │ │ │ ├── asGeobounds.js │ │ │ │ │ │ ├── asGeopoint.js │ │ │ │ │ │ ├── asGeopolygon.js │ │ │ │ │ │ ├── asCountries.js │ │ │ │ │ │ ├── asGeopolyline.js │ │ │ │ │ │ ├── imageAdvanced.js │ │ │ │ │ │ ├── inputQuantityValue.js │ │ │ │ │ │ ├── quantityValueArray.js │ │ │ │ │ │ ├── inputQuantityValueArray.js │ │ │ │ │ │ ├── combine.js │ │ │ │ │ │ ├── date.js │ │ │ │ │ │ ├── numeric.js │ │ │ │ │ │ ├── trim.js │ │ │ │ │ │ ├── loadAsset.js │ │ │ │ │ │ ├── objectField.js │ │ │ │ │ │ ├── conditionalConversion.js │ │ │ │ │ │ ├── stringReplace.js │ │ │ │ │ │ ├── explode.js │ │ │ │ │ │ └── staticText.js │ │ │ │ ├── interpreter │ │ │ │ │ ├── sql.js │ │ │ │ │ ├── json.js │ │ │ │ │ ├── xlsx.js │ │ │ │ │ └── xml.js │ │ │ │ └── loader │ │ │ │ │ └── http.js │ │ │ └── configEvents.js │ │ │ ├── helper │ │ │ └── abstractOptionType.js │ │ │ └── adapter │ │ │ └── dataImporterDataObject.js │ │ └── css │ │ └── icons.css ├── Exception │ ├── InvalidInputException.php │ ├── ElementNotFoundException.php │ ├── QueueNotEmptyException.php │ └── InvalidConfigurationException.php ├── Settings │ └── SettingsAwareInterface.php ├── DataSource │ ├── Interpreter │ │ └── SqlFileInterpreter.php │ └── Loader │ │ ├── DataLoaderInterface.php │ │ ├── AssetLoader.php │ │ ├── DataLoaderFactory.php │ │ ├── UploadLoader.php │ │ ├── PushLoader.php │ │ └── HttpLoader.php ├── Processing │ └── Scheduler │ │ ├── Exception │ │ └── InvalidScheduleException.php │ │ ├── SchedulerInterface.php │ │ ├── CronScheduler.php │ │ ├── JobScheduler.php │ │ └── SchedulerFactory.php ├── Event │ ├── DataObject │ │ ├── PostSaveEvent.php │ │ ├── PreSaveEvent.php │ │ ├── ProcessElementExceptionEvent.php │ │ └── AbstractDataObjectImportEvent.php │ └── PostPreparationEvent.php ├── Cleanup │ ├── CleanupStrategyInterface.php │ ├── DeleteStrategy.php │ ├── UnpublishStrategy.php │ └── CleanupStrategyFactory.php ├── Resolver │ ├── Location │ │ ├── NoChangeStrategy.php │ │ ├── DoNotCreateStrategy.php │ │ ├── LocationStrategyInterface.php │ │ └── StaticPathStrategy.php │ ├── Factory │ │ ├── FactoryInterface.php │ │ └── DataObjectFactory.php │ ├── Publish │ │ ├── AlwaysPublishStrategy.php │ │ ├── NoChangePublishNewStrategy.php │ │ ├── NoChangeUnpublishNewStrategy.php │ │ ├── PublishStrategyInterface.php │ │ └── AttributeBasedStrategy.php │ └── Load │ │ ├── IdStrategy.php │ │ ├── PathStrategy.php │ │ ├── NotLoadStrategy.php │ │ ├── LoadStrategyInterface.php │ │ └── AttributeStrategy.php ├── Mapping │ ├── DataTarget │ │ └── DataTargetInterface.php │ ├── Operator │ │ ├── Factory │ │ │ ├── AsArray.php │ │ │ ├── AsGeopolygon.php │ │ │ ├── AsGeopolyline.php │ │ │ ├── Boolean.php │ │ │ ├── AsColor.php │ │ │ ├── AsGeopoint.php │ │ │ ├── AsCountries.php │ │ │ ├── AsGeobounds.php │ │ │ ├── ImageAdvanced.php │ │ │ └── InputQuantityValue.php │ │ ├── AbstractOperator.php │ │ ├── OperatorInterface.php │ │ ├── Simple │ │ │ ├── Combine.php │ │ │ ├── FlattenArray.php │ │ │ ├── ReduceArrayKeyValuePairs.php │ │ │ ├── HtmlDecode.php │ │ │ └── StringReplace.php │ │ └── GeopolyAbstractOperator.php │ └── MappingConfiguration.php ├── Messenger │ └── DataImporterMessage.php ├── EventListener │ └── DataImporterListener.php ├── Maintenance │ └── RestartQueueWorkersTask.php ├── Command │ ├── ParallelizationAbstractCommand.php │ ├── PrepareImportCommand.php │ └── ParallelProcessQueueCommand.php ├── Controller │ └── ConnectionController.php ├── Migrations │ ├── Version20210305134111.php │ ├── Version20220304130000.php │ ├── Version20211201173215.php │ ├── Version20251003105903.php │ ├── Version20240715160305.php │ └── Version20211110174732.php ├── DependencyInjection │ └── CompilerPass │ │ ├── LoaderConfigurationFactoryPass.php │ │ ├── CleanupStrategyConfigurationFactoryPass.php │ │ ├── InterpreterConfigurationFactoryPass.php │ │ └── MappingConfigurationFactoryPass.php ├── Installer.php └── Preview │ └── PreviewService.php ├── SECURITY.md ├── composer.json └── README.md /doc/img/logging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/logging.png -------------------------------------------------------------------------------- /doc/img/mapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/mapping.png -------------------------------------------------------------------------------- /doc/img/datasource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/datasource.png -------------------------------------------------------------------------------- /doc/img/execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/execution.png -------------------------------------------------------------------------------- /doc/img/datasource_asset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/datasource_asset.png -------------------------------------------------------------------------------- /doc/img/datasource_sql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/datasource_sql.png -------------------------------------------------------------------------------- /doc/img/execution_cron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/execution_cron.png -------------------------------------------------------------------------------- /doc/img/execution_manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/execution_manual.png -------------------------------------------------------------------------------- /doc/img/import_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/import_preview.png -------------------------------------------------------------------------------- /doc/img/data_target_direct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_direct.png -------------------------------------------------------------------------------- /doc/img/resolver_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/resolver_settings.png -------------------------------------------------------------------------------- /doc/img/faq_execution_status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/faq_execution_status.png -------------------------------------------------------------------------------- /doc/img/transformation_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/transformation_pipeline.png -------------------------------------------------------------------------------- /doc/img/data_target_classification_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_classification_store.png -------------------------------------------------------------------------------- /doc/img/data_target_classification_store_batch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_classification_store_batch.png -------------------------------------------------------------------------------- /doc/img/data_target_classification_store_batch_date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_classification_store_batch_date.png -------------------------------------------------------------------------------- /doc/img/data_target_classification_store_batch_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_classification_store_batch_simple.png -------------------------------------------------------------------------------- /doc/img/data_target_classification_store_batch_decoding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_classification_store_batch_decoding.png -------------------------------------------------------------------------------- /doc/img/data_target_classification_store_batch_quantityValue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pimcore/data-importer/HEAD/doc/img/data_target_classification_store_batch_quantityValue.png -------------------------------------------------------------------------------- /src/Resources/config/doctrine_migrations.yml: -------------------------------------------------------------------------------- 1 | doctrine_migrations: 2 | migrations_paths: 3 | 'Pimcore\Bundle\DataImporterBundle\Migrations': '@PimcoreDataImporterBundle/Migrations' 4 | -------------------------------------------------------------------------------- /doc/03_Upgrade.md: -------------------------------------------------------------------------------- 1 | # Update Notes 2 | 3 | ## Update to Version 1.11 4 | ### General 5 | - Added support of `doctrine/dbal` `v4`, dropped support of `doctrine/dbal` `v2` 6 | 7 | ## Update to Version 1.10 8 | ### General 9 | - Dropped support of Pimcore 10, bumped minimum requirement of `pimcore/pimcore` to `^11.2`. 10 | -------------------------------------------------------------------------------- /doc/06_Extending/README.md: -------------------------------------------------------------------------------- 1 | # Extending 2 | 3 | The bundle architecture provides several extension possibilities for developers to customize the behaviour. 4 | Beside standard symfony extension and customization possibilities, there are two more specific options for extending: 5 | 6 | - [Extend via Custom Strategies](./01_Extend_Custom_Strategies.md) 7 | - [Events](./03_Events.md) 8 | -------------------------------------------------------------------------------- /src/Exception/InvalidInputException.php: -------------------------------------------------------------------------------- 1 | delete(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/resolver/load/path.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.load.path'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.load.path = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.load.id, { 13 | 14 | type: 'path' 15 | 16 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/cleanup/delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.cleanup.delete'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.cleanup.delete = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { 13 | 14 | type: 'delete', 15 | 16 | buildSettingsForm: function() { 17 | return null; 18 | } 19 | 20 | }); -------------------------------------------------------------------------------- /src/Cleanup/UnpublishStrategy.php: -------------------------------------------------------------------------------- 1 | setPublished(false); 23 | $element->save(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/cleanup/unpublish.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.cleanup.unpublish"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.cleanup.unpublish = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { 13 | 14 | type: 'unpublish', 15 | 16 | buildSettingsForm: function() { 17 | return null; 18 | } 19 | 20 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/resolver/load/notLoad.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.load.notLoad'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.load.notLoad = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { 13 | 14 | type: 'notLoad', 15 | 16 | buildSettingsForm: function() { 17 | 18 | return null; 19 | } 20 | 21 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/resolver/location/noChange.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.location.noChange'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.resolver.location.noChange = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { 13 | 14 | type: 'noChange', 15 | 16 | buildSettingsForm: function() { 17 | return null; 18 | } 19 | 20 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/asArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asArray'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asArray = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'asArray', 15 | 16 | getMenuGroup: function() { 17 | return this.menuGroups.dataTypes; 18 | } 19 | }); -------------------------------------------------------------------------------- /src/Resolver/Location/NoChangeStrategy.php: -------------------------------------------------------------------------------- 1 | executionType; 24 | } 25 | 26 | public function getIds(): array 27 | { 28 | return $this->ids; 29 | } 30 | 31 | public function getMessageId(): string 32 | { 33 | return $this->messageId; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/asGeobounds.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeobounds'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeobounds = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'asGeobounds', 15 | getMenuGroup: function() { 16 | return this.menuGroups.dataTypes; 17 | }, 18 | 19 | getIconClass: function() { 20 | return "pimcore_icon_geobounds"; 21 | }, 22 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/asGeopoint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeopoint'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeopoint = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'asGeopoint', 15 | getMenuGroup: function() { 16 | return this.menuGroups.dataTypes; 17 | }, 18 | 19 | getIconClass: function() { 20 | return "pimcore_icon_geopoint"; 21 | }, 22 | 23 | }); -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | If you think that you have found a security issue, 6 | don’t use the bug tracker and don’t publish it publicly. 7 | Instead, all security issues must be reported via a private vulnerability report. 8 | 9 | Please follow the [instructions](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability) to submit a private report. 10 | 11 | 12 | ## Resolving Process 13 | Every submitted security issue is handled with top priority by following these steps: 14 | 15 | 1. Confirm the vulnerability 16 | 2. Determine the severity 17 | 3. Contact reporter 18 | 4. Work on a patch 19 | 5. Get a CVE identification number (may be done by the reporter or a security service provider) 20 | 6. Patch reviewing 21 | 7. Tagging a new release for supported versions 22 | 8. Publish security announcement 23 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/asGeopolygon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeopolygon'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeopolygon = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'asGeopolygon', 15 | getMenuGroup: function() { 16 | return this.menuGroups.dataTypes; 17 | }, 18 | 19 | getIconClass: function() { 20 | return "pimcore_icon_geopolygon"; 21 | }, 22 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/asCountries.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asCountries'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asCountries = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'asCountries', 15 | 16 | getMenuGroup: function() { 17 | return this.menuGroups.dataTypes; 18 | }, 19 | 20 | getIconClass: function() { 21 | return "pimcore_icon_countrymultiselect"; 22 | } 23 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/asGeopolyline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS('pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeopolyline'); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.asGeopolyline = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'asGeopolyline', 15 | getMenuGroup: function() { 16 | return this.menuGroups.dataTypes; 17 | }, 18 | 19 | getIconClass: function() { 20 | return "pimcore_icon_geopolyline"; 21 | }, 22 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/imageAdvanced.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.imageAdvanced"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.imageAdvanced = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'imageAdvanced', 15 | getMenuGroup: function() { 16 | return this.menuGroups.dataTypes; 17 | }, 18 | 19 | getIconClass: function() { 20 | return "pimcore_icon_hotspotimage"; 21 | }, 22 | }); -------------------------------------------------------------------------------- /src/DataSource/Loader/DataLoaderInterface.php: -------------------------------------------------------------------------------- 1 | setPublished(true); 28 | } 29 | 30 | return $element; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/inputQuantityValueArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.inputQuantityValueArray"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.inputQuantityValueArray = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'inputQuantityValueArray', 15 | 16 | getMenuGroup: function() { 17 | return this.menuGroups.dataTypes; 18 | }, 19 | 20 | getIconClass: function() { 21 | return "pimcore_icon_inputQuantityValue"; 22 | }, 23 | }); -------------------------------------------------------------------------------- /src/Resolver/Publish/NoChangePublishNewStrategy.php: -------------------------------------------------------------------------------- 1 | setPublished(true); 28 | } 29 | 30 | return $element; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Resolver/Publish/NoChangeUnpublishNewStrategy.php: -------------------------------------------------------------------------------- 1 | setPublished(false); 28 | } 29 | 30 | return $element; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/helper/abstractOptionType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType = Class.create({ 13 | 14 | type: 'abstract', 15 | data: {}, 16 | dataNamePrefix: '', 17 | configItemRootContainer: null, 18 | initContext: null, 19 | 20 | initialize: function (data, dataNamePrefix, configItemRootContainer, initContext) { 21 | 22 | this.data = data; 23 | this.dataNamePrefix = dataNamePrefix + '.'; 24 | this.configItemRootContainer = configItemRootContainer; 25 | this.initContext = initContext; 26 | } 27 | 28 | }); -------------------------------------------------------------------------------- /src/EventListener/DataImporterListener.php: -------------------------------------------------------------------------------- 1 | messengerQueueActivated) { 29 | return; 30 | } 31 | 32 | $this->dataImporterHandler->dispatchMessages($event->getExecutionType()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Resolver/Publish/PublishStrategyInterface.php: -------------------------------------------------------------------------------- 1 | 10 | 11 |  12 | 13 | ## Logging 14 | 15 | The importer logs overview information into Pimcore application logger and detailed debugging information into standard 16 | Pimcore/symfony loggers. 17 | 18 |
19 | 20 |  21 | 22 | The Import Logs tab of the importer configuration shows a prefiltered list of the application logger containing only 23 | entries belonging to the current import configuration. 24 | 25 | The application logger contains ... 26 | - information about started imports. 27 | - information about each imported element including the original imported data as linked file object. 28 | - archived original import files if activated. 29 | - information about any problems and errors happened. 30 | -------------------------------------------------------------------------------- /doc/03_Configuration/03_Import_Preview.md: -------------------------------------------------------------------------------- 1 | # Import Preview 2 | 3 | The import configuration allows to show a preview of the data which helps 4 | to setup the [mapping configuration](06_Mapping_Configuration/README.md) and 5 | validate the expected results. 6 | 7 | 8 | 9 |  10 | 11 | The preview interprets the file the same way as actual import data sources 12 | will be interpreted when executing the import and shows one record of the preview 13 | file at once. The preview does not import any data though. 14 | 15 | Any changes in file format settings result in a reloading of the uploaded preview 16 | file. Reloading the preview file or paging the records will also update the 17 | processing result preview of the [mapping configuration](06_Mapping_Configuration/README.md). 18 | 19 | There are two options for loading the preview file: 20 | - Upload an extra preview file. 21 | - Copy the preview file from the configured data source (not possible with push data source). 22 | 23 | For both options, preview files are saved per user and import configuration in Pimcores `tmp` directory and 24 | should only be a small extract of the actual import files - due to loading performance and used storage space. 25 | 26 | -------------------------------------------------------------------------------- /src/Event/PostPreparationEvent.php: -------------------------------------------------------------------------------- 1 | configName = $configName; 26 | $this->executionType = $executionType; 27 | $this->fileInterpreted = $fileInterpreted; 28 | } 29 | 30 | public function getConfigName(): string 31 | { 32 | return $this->configName; 33 | } 34 | 35 | public function getExecutionType(): string 36 | { 37 | return $this->executionType; 38 | } 39 | 40 | public function isFileInterpreted(): bool 41 | { 42 | return $this->fileInterpreted; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Processing/Scheduler/CronScheduler.php: -------------------------------------------------------------------------------- 1 | cronDefinition = $cronDefinition; 29 | $this->modifiedAt = $modifiedAt; 30 | } 31 | 32 | public function isExecutable(?DateTime $executedAt): bool 33 | { 34 | $cron = new CronExpression($this->cronDefinition); 35 | $startAt = $executedAt ?: $this->modifiedAt; 36 | 37 | $nextRun = $cron->getNextRunDate($startAt); 38 | $now = new DateTime(); 39 | 40 | return $nextRun < $now; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Maintenance/RestartQueueWorkersTask.php: -------------------------------------------------------------------------------- 1 | messengerQueueActivated === true) { 30 | $this->dataImporterHandler->dispatchMessages(ImportProcessingService::EXECUTION_TYPE_SEQUENTIAL); 31 | $this->dataImporterHandler->dispatchMessages(ImportProcessingService::EXECUTION_TYPE_PARALLEL); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /doc/03_Configuration/06_Mapping_Configuration/README.md: -------------------------------------------------------------------------------- 1 | # Mapping Configuration 2 | 3 | The mapping configuration defines what data fields from the import data should be imported where and how to 4 | the Pimcore data object. 5 | 6 | 7 | 8 |  9 | 10 | The mapping configuration consists of multiple mapping entries. Each mapping entry provides settings for: 11 | - **Label**: Defines a name for the mapping entry. The name is used as title of the mapping entry only and has no further 12 | functionality. 13 | - **Source Attributes**: Define one or multiple fields from the import data as source for the mapping entry. Multiple fields 14 | are passed as an array to transformation pipeline and data target. The field list is based on the preview file uploaded, 15 | but also other fields can be defined by just writing the data index or field name. 16 | - **Transformation Pipeline**: The transformation pipeline transforms the data read from the source attribute(s) with operators. 17 | For details see [Transformation Pipeline](./02_Transformation_Pipeline.md). 18 | - **Data Target**: Data target definition assigns the result of the transformation pipeline to a data object field. 19 | For details see [Data Target](./03_Data_Target/README.md). 20 | -------------------------------------------------------------------------------- /src/Resolver/Load/IdStrategy.php: -------------------------------------------------------------------------------- 1 | dataObjectLoader->loadById($identifier, 30 | $this->getClassName()); 31 | } 32 | 33 | public function loadFullIdentifierList(): array 34 | { 35 | $sql = sprintf( 36 | 'SELECT `id` FROM object_%s', 37 | $this->dataObjectClassId 38 | ); 39 | 40 | return $this->db->fetchFirstColumn($sql); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Resolver/Location/StaticPathStrategy.php: -------------------------------------------------------------------------------- 1 | path = $settings['path']; 33 | } 34 | 35 | public function updateParent(ElementInterface $element, array $inputData): ElementInterface 36 | { 37 | $element->setParent(Service::createFolderByPath($this->path)); 38 | 39 | return $element; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Resolver/Load/PathStrategy.php: -------------------------------------------------------------------------------- 1 | dataObjectLoader->loadByPath($identifier, 30 | $this->getClassName()); 31 | } 32 | 33 | public function loadFullIdentifierList(): array 34 | { 35 | $sql = sprintf( 36 | 'SELECT CONCAT(`path`, `key`) FROM object_%s', 37 | $this->dataObjectClassId 38 | ); 39 | 40 | return $this->db->fetchFirstColumn($sql); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Command/ParallelizationAbstractCommand.php: -------------------------------------------------------------------------------- 1 | doFetchItems($input, $output); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Mapping/Operator/Factory/AsArray.php: -------------------------------------------------------------------------------- 1 | scheduledAt = $scheduledAt; 28 | $this->modifiedAt = $modifiedAt; 29 | } 30 | 31 | public function isExecutable(?DateTime $executedAt): bool 32 | { 33 | $now = new DateTime(); 34 | 35 | $hasExecutedInPast = $executedAt && $this->scheduledAt <= $executedAt; 36 | $isTimeToExecute = $now >= $this->scheduledAt; 37 | $isModifiedBeforeSchedule = $this->modifiedAt <= $this->scheduledAt; 38 | 39 | if ($isTimeToExecute && $isModifiedBeforeSchedule && !$hasExecutedInPast) { 40 | return true; 41 | } 42 | 43 | return false; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/combine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.combine"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.combine = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'combine', 15 | 16 | getMenuGroup: function() { 17 | return this.menuGroups.dataManipulation; 18 | }, 19 | 20 | getFormItems: function() { 21 | return [ 22 | { 23 | xtype: 'textfield', 24 | fieldLabel: t('plugin_pimcore_datahub_data_importer_configpanel_transformation_pipeline_glue'), 25 | value: this.data.settings ? this.data.settings.glue : ' ', 26 | listeners: { 27 | change: this.inputChangePreviewUpdate.bind(this) 28 | }, 29 | name: 'settings.glue' 30 | } 31 | ]; 32 | } 33 | 34 | }); -------------------------------------------------------------------------------- /src/Resolver/Publish/AttributeBasedStrategy.php: -------------------------------------------------------------------------------- 1 | dataSourceIndex = $dsi; 32 | } 33 | 34 | public function updatePublishState(ElementInterface $element, bool $justCreated, array $inputData): ElementInterface 35 | { 36 | if (method_exists($element, 'setPublished')) { 37 | $element->setPublished($inputData[$this->dataSourceIndex] ?? false); 38 | } 39 | 40 | return $element; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Mapping/Operator/Factory/AsGeopolygon.php: -------------------------------------------------------------------------------- 1 | getParameter('doctrine.connections'); 32 | 33 | if (!is_array($connections)) { 34 | throw new Exception('Doctrine connection not returned as array'); 35 | } 36 | 37 | $mappedConnections = array_map(fn ($key, $value): array => [ 38 | 'name' => $key, 39 | 'value' => $value 40 | ], array_keys($connections), $connections); 41 | 42 | return $this->json($mappedConnections); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/date.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.date"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.date = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'date', 15 | 16 | getMenuGroup: function() { 17 | return this.menuGroups.dataTypes; 18 | }, 19 | 20 | getIconClass: function() { 21 | return "pimcore_icon_date"; 22 | }, 23 | 24 | getFormItems: function() { 25 | return [ 26 | { 27 | xtype: 'textfield', 28 | fieldLabel: t('plugin_pimcore_datahub_data_importer_configpanel_transformation_pipeline_format'), 29 | value: this.data.settings ? this.data.settings.format : 'Y-m-d', 30 | listeners: { 31 | change: this.inputChangePreviewUpdate.bind(this) 32 | }, 33 | name: 'settings.format' 34 | } 35 | ]; 36 | } 37 | 38 | }); -------------------------------------------------------------------------------- /src/Cleanup/CleanupStrategyFactory.php: -------------------------------------------------------------------------------- 1 | cleanupStrategies = $cleanupStrategies; 32 | } 33 | 34 | /** 35 | * @param string $type 36 | * 37 | * @return CleanupStrategyInterface 38 | * 39 | * @throws InvalidConfigurationException 40 | */ 41 | public function loadCleanupStrategy(string $type) 42 | { 43 | if (empty($type) || !array_key_exists($type, $this->cleanupStrategies)) { 44 | throw new InvalidConfigurationException('Unknown loader type `' . $type . '`'); 45 | } 46 | 47 | return $this->cleanupStrategies[$type]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /doc/03_Configuration/07_Execution_Configuration.md: -------------------------------------------------------------------------------- 1 | # Execution Configuration 2 | 3 | Depending on the configuration there are different options to start an actual import. 4 | 5 | When data source is `push`, the import process starts every time data is pushed to the corresponding 6 | endpoint. There is no further configuration possible or needed. 7 | 8 | For all the other data sources, Pimcore needs a trigger to start the import process. Following triggers 9 | are available. 10 | 11 | ### Manual Execution 12 | Clicking on the `Manual Execution Start` button in the configuration editor manually starts the import. 13 | 14 |  15 | 16 | ### Cron-based Execution 17 | Besides the `Manual Execution Start` button there is also the possibility to configure a cron definition 18 | based on which the import starts on a regular base, e.g. every 10 Minutes, once a day, etc. 19 | 20 |  21 | 22 | See for example [Crontab Guru](https://crontab.guru/) for possibilities and a generator for generating 23 | cron definitions. 24 | 25 | > Make sure `datahub:data-importer:execute-cron` command is setup properly during installation. 26 | 27 | ### Command-based Execution 28 | It is also possible to imports with executing the `datahub:data-importer:prepare-import` command on the commandline. 29 | 30 | 31 | 32 | For further details on import execution also see [Import Execution Details](../04_Import_Execution_Details.md). 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/adapter/dataImporterDataObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.datahub.adapter.dataImporterDataObject"); 12 | pimcore.plugin.datahub.adapter.dataImporterDataObject = Class.create(pimcore.plugin.datahub.adapter.graphql, { 13 | 14 | createConfigPanel: function(data) { 15 | let fieldPanel = new pimcore.plugin.pimcoreDataImporterBundle.configuration.configItemDataObject(data, this); 16 | }, 17 | 18 | openConfiguration: function (id) { 19 | var existingPanel = Ext.getCmp("plugin_pimcore_datahub_configpanel_panel_" + id); 20 | if (existingPanel) { 21 | this.configPanel.editPanel.setActiveTab(existingPanel); 22 | return; 23 | } 24 | 25 | Ext.Ajax.request({ 26 | url: Routing.generate('pimcore_dataimporter_configdataobject_get'), 27 | params: { 28 | name: id 29 | }, 30 | success: function (response) { 31 | let data = Ext.decode(response.responseText); 32 | this.createConfigPanel(data); 33 | pimcore.layout.refresh(); 34 | }.bind(this) 35 | }); 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/interpreter/json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.interpreter.json"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.interpreter.json = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.abstractOptionType, { 13 | 14 | type: 'json', 15 | 16 | buildSettingsForm: function() { 17 | 18 | if(!this.form) { 19 | this.form = Ext.create('DataHub.DataImporter.StructuredValueForm', { 20 | defaults: { 21 | labelWidth: 200, 22 | width: 600 23 | }, 24 | border: false, 25 | items: [ 26 | { 27 | xtype: 'textfield', 28 | fieldLabel: t('plugin_pimcore_datahub_data_importer_configpanel_json_path'), 29 | name: this.dataNamePrefix + 'path', 30 | value: this.data.path || '', 31 | } 32 | ] 33 | }); 34 | } 35 | 36 | return this.form; 37 | } 38 | 39 | }); -------------------------------------------------------------------------------- /src/Resources/public/js/pimcore/configuration/components/mapping/operator/numeric.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This source file is available under the terms of the 3 | * Pimcore Open Core License (POCL) 4 | * Full copyright and license information is available in 5 | * LICENSE.md which is distributed with this source code. 6 | * 7 | * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.com) 8 | * @license Pimcore Open Core License (POCL) 9 | */ 10 | 11 | pimcore.registerNS("pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.numeric"); 12 | pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.operator.numeric = Class.create(pimcore.plugin.pimcoreDataImporterBundle.configuration.components.mapping.abstractOperator, { 13 | 14 | type: 'numeric', 15 | 16 | getMenuGroup: function() { 17 | return this.menuGroups.dataTypes; 18 | }, 19 | 20 | getIconClass: function() { 21 | return "pimcore_icon_data_group_numeric"; 22 | }, 23 | 24 | getFormItems: function() { 25 | return [ 26 | { 27 | xtype: 'checkbox', 28 | fieldLabel: t('plugin_pimcore_datahub_data_importer_configpanel_transformation_pipeline_numeric_return_null'), 29 | value: this.data.settings ? this.data.settings.returnNullIfEmpty : ' ', 30 | listeners: { 31 | change: this.inputChangePreviewUpdate.bind(this) 32 | }, 33 | name: 'settings.returnNullIfEmpty' 34 | } 35 | ]; 36 | } 37 | 38 | }); -------------------------------------------------------------------------------- /src/Migrations/Version20210305134111.php: -------------------------------------------------------------------------------- 1 | addSql(sprintf("INSERT IGNORE INTO users_permission_definitions (`key`, `category`) VALUES('%s', '%s');", Installer::DATAHUB_ADAPTER_PERMISSION, \Pimcore\Bundle\DataHubBundle\Installer::DATAHUB_PERMISSION_CATEGORY)); 37 | } 38 | 39 | public function down(Schema $schema): void 40 | { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DependencyInjection/CompilerPass/LoaderConfigurationFactoryPass.php: -------------------------------------------------------------------------------- 1 | findTaggedServiceIds(self::loader_tag); 27 | $loader = []; 28 | if (sizeof($taggedServices)) { 29 | foreach ($taggedServices as $id => $tags) { 30 | foreach ($tags as $attributes) { 31 | $loader[$attributes['type']] = new Reference($id); 32 | } 33 | } 34 | } 35 | 36 | $serviceLocator = $container->getDefinition(DataLoaderFactory::class); 37 | $serviceLocator->setArgument('$dataLoaderBluePrints', $loader); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DataSource/Loader/AssetLoader.php: -------------------------------------------------------------------------------- 1 | assetPath); 33 | if (empty($asset)) { 34 | throw new InvalidConfigurationException("Asset {$this->assetPath} not found."); 35 | } 36 | 37 | $this->temporaryFile = $asset->getTemporaryFile(); 38 | 39 | return $this->temporaryFile; 40 | } 41 | 42 | public function setSettings(array $settings): void 43 | { 44 | if (empty($settings['assetPath'])) { 45 | throw new InvalidConfigurationException('Empty asset path.'); 46 | } 47 | 48 | $this->assetPath = $settings['assetPath']; 49 | } 50 | 51 | public function cleanup(): void 52 | { 53 | unlink($this->temporaryFile); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Mapping/Operator/AbstractOperator.php: -------------------------------------------------------------------------------- 1 | applicationLogger = $applicationLogger; 37 | } 38 | 39 | /** 40 | * @param string $configName 41 | * 42 | * @return void 43 | */ 44 | public function setConfigName(string $configName) 45 | { 46 | $this->configName = $configName; 47 | } 48 | 49 | /** 50 | * @param mixed $inputData 51 | * 52 | * @return mixed 53 | */ 54 | public function generateResultPreview($inputData) 55 | { 56 | return $inputData; 57 | } 58 | 59 | public function setSettings(array $settings): void 60 | { 61 | //nothing to do 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Resolver/Load/NotLoadStrategy.php: -------------------------------------------------------------------------------- 1 | findTaggedServiceIds(self::cleanup_tag); 27 | $cleanupStrategies = []; 28 | if (sizeof($taggedServices)) { 29 | foreach ($taggedServices as $id => $tags) { 30 | foreach ($tags as $attributes) { 31 | $cleanupStrategies[$attributes['type']] = new Reference($id); 32 | } 33 | } 34 | } 35 | 36 | $serviceLocator = $container->getDefinition(CleanupStrategyFactory::class); 37 | $serviceLocator->setArgument('$cleanupStrategies', $cleanupStrategies); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DependencyInjection/CompilerPass/InterpreterConfigurationFactoryPass.php: -------------------------------------------------------------------------------- 1 | findTaggedServiceIds(self::interpreter_tag); 27 | $interpreters = []; 28 | if (sizeof($taggedServices)) { 29 | foreach ($taggedServices as $id => $tags) { 30 | foreach ($tags as $attributes) { 31 | $interpreters[$attributes['type']] = new Reference($id); 32 | } 33 | } 34 | } 35 | 36 | $serviceLocator = $container->getDefinition(InterpreterFactory::class); 37 | $serviceLocator->setArgument('$interpreterBluePrints', $interpreters); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Mapping/Operator/OperatorInterface.php: -------------------------------------------------------------------------------- 1 | setTimestamp($config['general']['modificationDate']); 27 | 28 | if ($scheduleType === JobScheduler::NAME) { 29 | if (empty($config['executionConfig']['scheduledAt'])) { 30 | throw new InvalidScheduleException('No scheduled date/time'); 31 | } 32 | 33 | $scheduledAt = DateTime::createFromFormat('d-m-Y H:i', $config['executionConfig']['scheduledAt']); 34 | 35 | return new JobScheduler($scheduledAt, $modifiedAt); 36 | } 37 | 38 | if (empty($config['executionConfig']['cronDefinition'])) { 39 | throw new InvalidScheduleException('No cron definition provided'); 40 | } 41 | 42 | return new CronScheduler($config['executionConfig']['cronDefinition'], $modifiedAt); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Event/DataObject/ProcessElementExceptionEvent.php: -------------------------------------------------------------------------------- 1 | message; 35 | } 36 | 37 | public function getException(): Throwable 38 | { 39 | return $this->exception; 40 | } 41 | 42 | /** 43 | * This is the last mapping configuration that was being processed when the exception was thrown. 44 | * No value will be set if all transformations were completed. 45 | * 46 | * @return null|MappingConfiguration 47 | */ 48 | public function getMappingConfiguration(): ?MappingConfiguration 49 | { 50 | return $this->mappingConfiguration; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /doc/03_Configuration/06_Mapping_Configuration/03_Data_Target/README.md: -------------------------------------------------------------------------------- 1 | # Data Target 2 | 3 | Data target definition assigns the result of the transformation pipeline to a data object field. The available data object 4 | fields for assignment depend on the transformation result of the [transformation pipeline](../02_Transformation_Pipeline.md). 5 | 6 | Three different data target types are available: 7 | 8 | ### Direct 9 | Assign data directly to fields defined directly in the data object class, object bricks or localized fields. The naming 10 | schema for Object brick fields is `