Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions demoentityimporter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Demo: register a custom entity importer

This module shows how a PrestaShop 9.2+ module plugs its own entity importer
into the core import engine (Advanced Parameters > Import) — and actually
imports something: each CSV row becomes a `DemoNote` Doctrine entity.

## How it works

1. The importer class extends
`PrestaShop\PrestaShop\Core\Import\Engine\EntityImporter\AbstractEntityImporter`
([src/Importer/DemoNoteImporter.php](src/Importer/DemoNoteImporter.php)),
which provides the cursor-resumable batch loop, the phase-id guard and
the default unit count (implementing `EntityImporterInterface` directly
also works for full control). It declares two phases — a pausing
`validation` phase (note required, max 255 characters) and a `database`
phase that persists one `DemoNote` per row (create, or update when the
mapped `id` column matches an existing note).
2. The service is registered with `autoconfigure: true`
([config/services.yml](config/services.yml)). The core registers the
`core.import.entity_importer` tag for every autoconfigured service
implementing the interface — no manual tag needed.
3. The core `EntityImporterRegistry` collects every tagged importer: the
import page entity dropdown, the mapping screen field list and the batch
execution all discover the module importer automatically.
4. The importer reuses the core engine services instead of re-implementing
file handling: `ResumableFileReaderInterface` (cursor-resumable reads of
the normalized working file — header/skip rows are already stripped at
normalization) and `RowMapper` (column-to-field mapping).
5. The `DemoNote` entity ([src/Entity/DemoNote.php](src/Entity/DemoNote.php))
lives in `src/Entity`, which the core maps automatically for active
modules — no Doctrine configuration needed. Its table is created at
module install ([demoentityimporter.php](demoentityimporter.php)).

## Verify

After installing the module:

```bash
php bin/console debug:container --tag=core.import.entity_importer
```

should list `DemoNoteImporter` next to the core importers.

A sample import file is provided in [sample/demo_notes.csv](sample/demo_notes.csv):

```csv
id;note
;First imported note
;Second imported note
```

(the empty `id` column means "create"; put an existing note id there to
update it instead).

## Install

```bash
cd modules/demoentityimporter
composer dumpautoload
```

then install the module (BO module manager or `php bin/console prestashop:module install demoentityimporter`).

## Requirements

- PrestaShop 9.2.0 or newer (import engine introduced by [PrestaShop/PrestaShop#41907](https://github.com/PrestaShop/PrestaShop/issues/41907)).
19 changes: 19 additions & 0 deletions demoentityimporter/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "prestashop/demoentityimporter",
"description": "PrestaShop example module: register a custom entity importer into the core import engine",
"license": "AFL-3.0",
"authors": [
{
"name": "PrestaShop Core team"
}
],
"autoload": {
"psr-4": {
"PrestaShop\\Module\\DemoEntityImporter\\": "src/"
}
},
"config": {
"prepend-autoloader": false
},
"type": "prestashop-module"
}
11 changes: 11 additions & 0 deletions demoentityimporter/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<module>
<name>demoentityimporter</name>
<displayName><![CDATA[Demo - register a custom entity importer]]></displayName>
<version><![CDATA[1.0.0]]></version>
<description><![CDATA[Shows how a module registers its own importer into the core import engine and persists a Doctrine entity.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[]]></tab>
<is_configurable>0</is_configurable>
<need_instance>1</need_instance>
</module>
10 changes: 10 additions & 0 deletions demoentityimporter/config/services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
_defaults:
public: true
autowire: true
# autoconfigure is what gets the service automatically tagged as an
# entity importer (the core registers the tag for every autoconfigured
# service implementing EntityImporterInterface)
autoconfigure: true

PrestaShop\Module\DemoEntityImporter\Importer\DemoNoteImporter: ~
72 changes: 72 additions & 0 deletions demoentityimporter/demoentityimporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/

declare(strict_types=1);

if (!defined('_PS_VERSION_')) {
exit;
}

class DemoEntityImporter extends Module
{
public function __construct()
{
$this->name = 'demoentityimporter';
$this->author = 'PrestaShop';
$this->version = '1.0.0';
$this->ps_versions_compliancy = ['min' => '9.2.0', 'max' => '9.99.99'];

parent::__construct();

$this->displayName = $this->trans('Demo - register a custom entity importer', [], 'Modules.Demoentityimporter.Admin');
$this->description = $this->trans('Shows how a module registers its own importer into the core import engine and persists a Doctrine entity.', [], 'Modules.Demoentityimporter.Admin');
}

public function install(): bool
{
return parent::install() && $this->installDatabase();
}

public function uninstall(): bool
{
return parent::uninstall() && $this->uninstallDatabase();
}

/**
* Creates the table backing the DemoNote Doctrine entity
* (src/Entity/DemoNote.php).
*/
private function installDatabase(): bool
{
return Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'demo_note` (
`id_demo_note` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`note` VARCHAR(255) NOT NULL,
`date_add` DATETIME NOT NULL,
PRIMARY KEY (`id_demo_note`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8mb4;
');
}

private function uninstallDatabase(): bool
{
return Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'demo_note`');
}
}
3 changes: 3 additions & 0 deletions demoentityimporter/sample/demo_notes.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id;note
;First imported note
;Second imported note
90 changes: 90 additions & 0 deletions demoentityimporter/src/Entity/DemoNote.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/

declare(strict_types=1);

namespace PrestaShop\Module\DemoEntityImporter\Entity;

use DateTime;
use Doctrine\ORM\Mapping as ORM;

/**
* The entity the demo importer persists. Module entities living in
* src/Entity are mapped automatically by the core (annotation driver,
* active modules only) — no extra Doctrine configuration is needed.
*
* @ORM\Table()
* @ORM\Entity()
*/
class DemoNote
{
/**
* @var int
*
* @ORM\Id
*
* @ORM\Column(name="id_demo_note", type="integer")
*
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var string
*
* @ORM\Column(name="note", type="string", length=255)
*/
private $note;

/**
* @var DateTime
*
* @ORM\Column(name="date_add", type="datetime")
*/
private $dateAdd;

public function __construct(string $note)
{
$this->note = $note;
$this->dateAdd = new DateTime();
}

public function getId(): ?int
{
return $this->id;
}

public function getNote(): string
{
return $this->note;
}

public function setNote(string $note): self
{
$this->note = $note;

return $this;
}

public function getDateAdd(): DateTime
{
return $this->dateAdd;
}
}
Loading