Anpassung des Shopware 6 Rule Managers: Eine benutzerdefinierte Regel zum Überprüfen leerer Kunden-CustomFields

Einführung

Shopware 6 bietet mit dem Rulebuilder flexible Möglichkeiten, Abläufe und Berechtigungen zu steuern, aber manche Regeln sind mit dem Standard nicht abzubilden. Im konkreten Fall geht es darum, ein CustomField, das als Textfeld angelegt wurde daraufhin zu testen, ob es leer ist. Diese Möglichkeit wird von Shopware 6 einfach nicht in Betracht gezogen…
In diesem Blogpost beschreiben wir, wie eine benutzerdefinierte Regel erstellt werden kann, die prüft, ob ein kundenspezifisches Zusatzfeld leer ist. Diese Regel kann nützlich sein, um dynamische Preisstrategien, Versandregeln oder andere geschäftsrelevante Entscheidungen zu treffen, die auf kundenspezifischen Feldern basieren.

Voraussetzung ist das Shopware Plugin Grundgerüst. Das wird von Shopware selbst hier behandelt: https://developer.shopware.com/docs/guides/plugins/plugins/plugin-base-guide.html

Schritt 1: Regel-Klasse erstellen

Zuerst erstellen wir eine Regel-Klasse, die die notwendige Logik zur Überprüfung der benutzerdefinierten Felder enthält. Die Regel-Klasse wird im Verzeichnis <plugin root>/src/Core/Rule/ gespeichert und sieht wie folgt aus:

// <plugin root>/src/Core/Rule/CustomerCustomFieldEmptyRule.php
<?php declare(strict_types=1);

namespace YourPluginNamespace\Core\Rule;

use Shopware\Core\Framework\Rule\Rule;
use Shopware\Core\Framework\Rule\RuleScope;
use Symfony\Component\Validator\Constraints\Type;

class CustomerCustomFieldEmptyRule extends Rule
{
protected string $customFieldName;

public function __construct()
{
parent::__construct();
$this->customFieldName = '';
}

public function getName(): string
{
return 'customer_custom_field_empty';
}

public function match(RuleScope $scope): bool
{
if (!$scope instanceof \Shopware\Core\System\SalesChannel\SalesChannelContext) {
return false;
}

$customer = $scope->getCustomer();
if ($customer === null) {
return false;
}

$customFields = $customer->getCustomFields();
return empty($customFields[$this->customFieldName]);
}

public function getConstraints(): array
{
return [
'customFieldName' => [new Type('string')]
];
}
}

Diese Klasse definiert die Regel, die prüft, ob das angegebene benutzerdefinierte Feld eines Kunden leer ist.

Schritt 2: Vue-Komponente für das Admin-Interface

Als nächstes erstellen wir eine Vue-Komponente, die das benutzerdefinierte Feld im Admin-Interface zur Auswahl anbietet. Die Komponente wird im Verzeichnis <plugin root>/src/Resources/app/administration/src/component/sw-condition-customer-custom-field-empty/ gespeichert.

JavaScript-Datei

// <plugin root>/src/Resources/app/administration/src/component/sw-condition-customer-custom-field-empty/index.js
import template from './sw-condition-customer-custom-field-empty.html.twig';

const { Component, Mixin } = Shopware;
const { mapPropertyErrors } = Component.getComponentHelper();
const { Criteria } = Shopware.Data;

Component.extend('sw-condition-customer-custom-field-empty', 'sw-condition-base', {
template,

inject: ['repositoryFactory', 'feature'],

mixins: [
Mixin.getByName('sw-inline-snippet'),
],

data() {
return {
customFieldOptions: []
};
},

computed: {
customFieldCriteria() {
const criteria = new Criteria(1, 25);
criteria.addAssociation('customFieldSet');
criteria.addFilter(Criteria.equals('customFieldSet.relations.entityName', 'customer'));
criteria.addSorting(Criteria.sort('customFieldSet.name', 'ASC'));
return criteria;
},

customFieldName: {
get() {
this.ensureValueExist();
return this.condition.value.customFieldName;
},
set(customFieldName) {
this.ensureValueExist();
this.condition.value = { ...this.condition.value, customFieldName };
}
},

...mapPropertyErrors('condition', [
'value.customFieldName',
]),

currentError() {
return this.conditionValueCustomFieldNameError;
},
},

created() {
this.loadCustomFieldOptions();
},

methods: {
async loadCustomFieldOptions() {
try {
const customFieldRepository = this.repositoryFactory.create('custom_field');
const customFields = await customFieldRepository.search(this.customFieldCriteria);
this.customFieldOptions = customFields.map(field => ({
value: field.name,
label: field.config.label['en-GB'] || field.name
}));
} catch (error) {
console.error('Error loading custom field options:', error);
}
}
}
});

HTML-Template

{# <plugin root>/src/Resources/app/administration/src/component/sw-condition-customer-custom-field-empty/sw-condition-customer-custom-field-empty.html.twig #}
<template>
<sw-single-select v-model="customFieldName" :options="customFieldOptions" label="Select custom field" />
</template>

Diese Komponente lädt die benutzerdefinierten Felder und bietet sie im Admin-Interface zur Auswahl an.

Schritt 3: Registrierung der Regel

Damit Shopware die Regel erkennt, muss sie in der services.xml registriert werden:

<!-- <plugin root>/src/Resources/config/services.xml -->
<services>
<service id="YourPluginNamespace\Core\Rule\CustomerCustomFieldEmptyRule">
<tag name="shopware.rule.condition" />
</service>
</services>

Schritt 4: Cache leeren und Indizes aktualisieren

Nach Änderungen an den Plugin-Konfigurationen und Regel-Klassen ist es wichtig, den Cache zu leeren und die Indizes neu aufzubauen:

bin/console cache:clear
bin/console dal:refresh:index

Fehlerbehebung und Debugging

Um sicherzustellen, dass die Regel in der Storefront korrekt funktioniert, können Debugging-Logs hinzugefügt werden:

public function match(RuleScope $scope): bool
{
if (!$scope instanceof \Shopware\Core\System\SalesChannel\SalesChannelContext) {
return false;
}

$customer = $scope->getCustomer();
if ($customer === null) {
return false;
}

$customFields = $customer->getCustomFields();

// Debugging-Log
file_put_contents('/var/log/shopware_custom_field_rule.log', print_r([
'customFieldName' => $this->customFieldName,
'customFields' => $customFields,
'isEmpty' => empty($customFields[$this->customFieldName])
], true), FILE_APPEND);

return empty($customFields[$this->customFieldName]);
}

Fazit

Die Erstellung einer benutzerdefinierten Regel in Shopware 6 erfordert ein gutes Verständnis der Shopware-Architektur und der Plugin-Entwicklung. Durch die Schritte in diesem Blogpost haben wir eine benutzerdefinierte Regel erstellt, die prüft, ob ein kundenspezifisches Feld leer ist, und diese Regel erfolgreich in das Shopware-Backend integriert.

Tipps zum Testen und Vertiefung

  • Regel in verschiedenen Szenarien testen: Prüfe die Regel mit unterschiedlichen Kundenprofilen und benutzerdefinierten Feldern.
  • Logs überprüfen: Nutze die Debugging-Logs, um sicherzustellen, dass die Regel wie erwartet funktioniert.
  • Weiterführende Dokumentation: Nutze die Shopware-Dokumentation und Community-Ressourcen, um tiefer in die Themen Plugin-Entwicklung und Rule Manager einzutauchen.

Mit diesen Schritten und Tipps solltest du in der Lage sein, benutzerdefinierte Regeln in Shopware 6 zu erstellen und anzupassen, um die Funktionalität deines Shops zu erweitern und zu verbessern.