Zum Hauptinhalt springen

Neues Modul registrieren

Das twocream Shopware Connector Bundle bietet zwei Arten an, um ein Importmodul zu implementieren.

Das AbstractModule ist für einfache Entitäten geeignet und wird zum Beispiel für den Attributsimport eingesetzt. Es wird aber auch eingesetzt, wenn man flache Datenstrukturen aus dem MDM-Bereich in eigene Shopware-Entitäten einspielen möchte.

Das AbstractSyncModule ist für komplexere Entitäten, wie die Shopware Produkt-Entität, geeignet. Es bietet an, dass mehrere Entitäten während der Verarbeitung erstellt, aktualisiert oder gelöscht werden können. Zum Beispiel relationale Datensätze wie Shopware Maßeinheiten.

Aufbau eines einfachen Moduls

info

Einfache Module müssen von dieser abstrakten Klasse erben: Twocream\JsonImporter\Core\System\Import\Module\AbstractModule

<?php

namespace MyCustomExtension\Core\System\Import\Module;

use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
use Twocream\JsonImporter\Core\System\Import\Module\AbstractModule;
use Twocream\JsonImporter\Core\System\Import\Validation\Decision;
use Twocream\JsonImporter\Core\System\Import\Validation\Result;
use MyCustomExtension\Core\Content\Pimcore\MasterDataManagement\Video\VideoDefinition;

class VideoModule extends AbstractModule
{
public function getHandledPackage(): string
{
return 'videos';
}

protected function getEntityName(): string
{
return VideoDefinition::ENTITY_NAME;
}

protected function validateEntry(array $entry): array
{
$problems = [];

if (empty($entry['uuid'])) {
$problems[] = 'uuid';
}

if (empty($entry['id'])) {
$problems[] = 'id';
}

return $problems;
}

protected function store(Result $result): ?EntityWrittenContainerEvent
{
$records = [];
$videoRepository = $this->registry->getRepository('app_pimcore_video');

foreach ($result as $entry) {
if ($entry->getDecision() === Decision::DECISION_SKIP_RECORD) {
continue;
}

$translations = $this->service->prepareTranslation($entry['texts']['translations']);
$videoTranslations = $this->service->prepareTranslation($entry['video']['translations'], [
'youtube-link' => 'youtubeLink'
]);
$thumbnailTranslations = $this->service->prepareTranslation($entry['thumbnail']['translations'], [
'image' => 'thumbnailImage',
'title' => 'thumbnailTitle',
'alt-text' => 'thumbnailAltText'
]);

foreach ($translations as $key => $values) {
if (isset($videoTranslations[$key])) {
$translations[$key] = array_merge($values, $videoTranslations[$key]);
} else {
$translations[$key] = array_merge($values, ['youtubeLink' => null]);
}

if (isset($thumbnailTranslations[$key])) {
$translations[$key] = array_merge($translations[$key], $thumbnailTranslations[$key]);
} else {
$translations[$key] = array_merge(
$translations[$key],
['thumbnailImage' => null, 'thumbnailTitle' => null, 'thumbnailAltText' => null]
);
}
}

$records[] = [
'id' => $entry['uuid'],
'pimcoreId' => $entry['id'],
'key' => $entry['key'],
'type' => 'youtube',
'defaultLink' => $entry['video']['default-value'],
'translations' => $translations
];
}

if (!empty($records)) {
return $videoRepository->upsert($records, $this->context);
}

return null;
}
}

Aufbau eines komplexereren Moduls

info

Komplexe Module müssen von dieser abstrakten Klasse erben: Twocream\JsonImporter\Core\System\Import\Module\AbstractSyncModule

namespace MyCustomExtension\Core\System\Import\Module;

use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
use Twocream\JsonImporter\Core\System\Import\Module\AbstractSyncModule;
use Twocream\JsonImporter\Core\System\Import\Validation\Decision;
use Twocream\JsonImporter\Core\System\Import\Validation\Result;

class ExampleModule extends AbstractSyncModule
{
public function getHandledPackage(): string
{
return 'example';
}

protected function getEntityName(): string
{
return ExampleDefinition::ENTITY_NAME;
}

protected function validateEntry(array $entry): array
{
$problems = [];

if (empty($entry['translations']['de_DE']['name'])) {
$problems[] = 'name';
}

return $problems;
}

protected function store(Result $result): ?EntityWrittenContainerEvent
{
foreach ($result as $entry) {
if ($entry->getDecision() === Decision::DECISION_SKIP_RECORD) {
continue;
}

if (!empty($entry['measurement-unit'])) {
$unitId = md5('unit-' . $entry['measurement-unit']);

if (!$this->isIdExist($unitId, UnitDefinition::ENTITY_NAME)) {
$this->syncs[UnitDefinition::ENTITY_NAME][SyncOperation::ACTION_UPSERT][] = [
'id' => $unitId,
'translations' => $this->service->prepareTranslation([
'de' => [
'name' => $entry['measurement-unit'],
'shortCode' => $entry['measurement-unit']
]
])
];
}
}


$translations = $this->service->prepareTranslation(
$entry['texts'],
[
'description' => 'description',
'name' => 'name',
]
);

$this->syncs[ProductDefinition::ENTITY_NAME][SyncOperation::ACTION_UPSERT][] = [
'id' => $entry['uuid'],
'pimcoreId' => $entry['id'],
'unitId' => $unitId,
'translations' => $translations,
'customFields' => [
'position' => $entry['custom-fields']['position'],
],
];
}

return $this->sync();
}
}

Erklärung

Das komplexe Modul baut auf dem einfachen Modul auf, daher ist folgende Definition auf beide Typen anwendbar.

NameBeschreibung
getHandledPackage(): stringEindeutiger Package-Name, z.B. "product"
getEntityName(): stringDer Name der Entity, für die das Modul bestimmt ist, z.B. "product"
store(Result $result): ?EntityWrittenContainerEventHier erfolgt die inhaltsbezogene Verarbeitung der Daten zum importieren
canBeDeleted(): boolHiermit kann optional die Löschung der Daten verhindert werden
isIdExist(string $id, string $entityName): boolHilfsmethode um zu prüfen, ob der Datensatz zu der ID & Entität bereits vorhanden ist
validateEntry(array $entry): arrayHier kann optional eine Validierungslogik für importierte Daten implementiert werden

Das Modul registrieren

Neue Module sind in einer Service-Konfigurationsdatei zu registrieren. Hierbei ist der Service-Tag twocream_json_importer.module zwingend zu verwenden.

Best Practice

Zur strukturierten Konfiguration wird empfohlen, die Datei src/Resources/config/services/import.xml anzulegen. Diese ist anschließend über einen Import in der zentralen services.xml einzubinden.

<service id="MyCustomExtension\Core\System\Import\Module\ProductModule">
<tag name="twocream_json_importer.module"/>
</service>