Zum Hauptinhalt springen

Custom DataField-Typ anlegen

Ein eigener DataField-Typ ist notwendig, wenn DataFields für einen neuen LineItem-Typ (z.B. ein Drittanbieter-Plugin mit eigenen Warenkorbpositionen) erstellt werden sollen, oder wenn eine semantisch neue Kategorie von Feldern eingeführt wird.


Übersicht der Schritte

  1. Eigenes Typ-Enum erstellen
  2. Abstrakte Basis-Klasse für das neue Feld erstellen
  3. Konkretes DataField implementieren
  4. LineItemContextResolver erstellen
  5. Services registrieren

1. Typ-Enum erstellen

Das Enum implementiert DataFieldTypeInterface und definiert den Typnamen.

<?php

declare(strict_types=1);

namespace MyPlugin\Connector\DataField;

use AgiqonConnector\Connector\DataField\DataFieldTypeInterface;

enum MyCustomDataFieldType: string implements DataFieldTypeInterface
{
case MyCustomType = 'my_custom_type';

public function getName(): string
{
return $this->value;
}
}

2. Abstrakte Basis-Klasse erstellen

Die Abstract-Klasse trägt das #[DataFieldTypeAttribute(...)] mit dem neuen Typ und kapselt die null-Prüfung auf das LineItem.

<?php

declare(strict_types=1);

namespace MyPlugin\Connector\DataField\Field;

use AgiqonConnector\Connector\DataField\Attribute\DataFieldTypeAttribute;
use AgiqonConnector\Connector\DataField\DataFieldResolutionContext;
use AgiqonConnector\Connector\DataField\Field\AbstractDataField;
use MyPlugin\Connector\DataField\MyCustomDataFieldType;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;

#[DataFieldTypeAttribute(MyCustomDataFieldType::MyCustomType)]
abstract readonly class AbstractMyCustomField extends AbstractDataField
{
public function resolve(DataFieldResolutionContext $context): ?string
{
$lineItem = $context->getLineItem();

// LineItem prüfen und ggf. auf den richtigen Typ filtern
if ($lineItem === null || $lineItem->getType() !== 'my-custom-line-item-type') {
return null;
}

return $this->getValue($lineItem);
}

abstract public function getValue(LineItem $lineItem): ?string;
}

3. Konkretes DataField implementieren

<?php

declare(strict_types=1);

namespace MyPlugin\Connector\DataField\Field;

use AgiqonConnector\Connector\System\ConnectorSystemType;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;

readonly class MyCustomField extends AbstractMyCustomField
{
public function __construct()
{
parent::__construct(
'myCustomField',
[ConnectorSystemType::OCI, ConnectorSystemType::cXML]
);
}

public function getValue(LineItem $lineItem): ?string
{
// Eigene Logik zum Ermitteln des Werts aus dem LineItem
$payload = $lineItem->getPayload();

return $payload['my_custom_value'] ?? null;
}
}

4. LineItemContextResolver erstellen

Der Resolver entscheidet via supports() ob er für ein LineItem zuständig ist.

<?php

declare(strict_types=1);

namespace MyPlugin\Connector\DataField\LineItemContextResolver;

use AgiqonConnector\Connector\DataField\LineItemContextResolver\AbstractLineItemContextResolver;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;

class MyCustomContextResolver extends AbstractLineItemContextResolver
{
public function supports(LineItem $lineItem): bool
{
return $lineItem->getType() === 'my-custom-line-item-type';
}
}

5. Services registrieren

In services.xml des eigenen Plugins beide Services mit den passenden Tags registrieren:

<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>

<!-- Das neue DataField -->
<service id="MyPlugin\Connector\DataField\Field\MyCustomField">
<tag name="agiqon_connector.data_field"/>
</service>

<!-- Der passende LineItemContextResolver -->
<service id="MyPlugin\Connector\DataField\LineItemContextResolver\MyCustomContextResolver">
<tag name="agiqon_connector.line_item_context_resolver"/>
</service>

</services>
</container>

Ergebnis

Nach der Registrierung:

  • Ist myCustomField in der Connector-Konfiguration unter dem neuen Typ my_custom_type auswählbar.
  • Für Warenkorbpositionen vom Typ my-custom-line-item-type wird automatisch MyCustomContextResolver verwendet.
  • Alle anderen Positionen werden von den eingebauten Resolvern behandelt.