Magento 2 fügt eine benutzerdefinierte Produktattributüberprüfung aus dem Installationsskript hinzu

17
[
    'type' => 'int',
    'backend' => '',
    'frontend' => '',
    'label' => 'XXXX',
    'input' => 'text',
    'frontend_class' => 'validiere-größer-als-Null',
    'source' => '',
    'global' => \ Magento \ Eav \ Model \ Entity \ Attribute \ ScopedAttributeInterface :: SCOPE_GLOBAL,
    'sichtbar' => wahr,
    'Erforderlich' => wahr,
    'user_defined' => false,
    'default' => 0,
    'durchsuchbar' => falsch,
    'filterable' => true,
    'vergleichbar' => falsch,
    'visible_on_front' => false,
    'used_in_product_listing' => true,
    'unique' => false
]

Ich füge ein benutzerdefiniertes Produktattribut hinzu, das einwandfrei funktioniert, aber keine validate-greater-than-zeroValidierung hinzufügen kann .

Wenn wir Attributeigenschaften in betrachten, Input Validation for Store Ownergibt es eine begrenzte Anzahl von Überprüfungen in ausgewählten Optionen.

validate-number, validate-digits, validate-email, validate-url, validate-alpha,validate-alphanum

Dies sind die einzigen Validierungen, die im Abschnitt Produktattribute angewendet werden.

Amit Singh
quelle
Bitte sehen Sie meine Antwort, es wird Ihnen helfen, Ihren Attributwert zu validieren.
Matthéo Geoffray

Antworten:

13

Eine der Lösungen besteht darin, ein backend modelzu Ihrem Attribut hinzuzufügen , das zum Formatieren / Validieren Ihres Attributwerts vor dem Speichern und / oder nach dem Laden verwendet wird.

Fügen Sie eine Backend-Klasse hinzu:

[
    'type' => 'int',
    'backend' => '\Foo\Bar\Model\Attribute\Backend\YourAttribute',
    'frontend' => '',
    'label' => 'XXXX',
    'input' => 'text',
    'frontend_class' => 'validate-greater-than-zero',
    'source' => '',
    'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
    'visible' => true,
    'required' => true,
    'user_defined' => false,
    'default' => 0,
    'searchable' => false,
    'filterable' => true,
    'comparable' => false,
    'visible_on_front' => false,
    'used_in_product_listing' => true,
    'unique' => false
]

Hier ist ein Beispiel für Ihre benutzerdefinierte Klasse \Foo\Bar\Model\Attribute\Backend\YourAttribute

<?php

namespace Foo\Bar\Model\Attribute\Backend;

/**
 * Class YourAttribute
 */
class YourAttribute extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
{

    /**
     * @var int $minimumValueLength
     */
    protected $minimumValueLength = 0;

    /**
     * @param \Magento\Framework\DataObject $object
     *
     * @return $this
     */
    public function afterLoad($object)
    {
        // your after load logic

        return parent::afterLoad($object);
    }

    /**
     * @param \Magento\Framework\DataObject $object
     *
     * @return $this
     */
    public function beforeSave($object)
    {
        $this->validateLength($object);

        return parent::beforeSave($object);
    }

    /**
     * Validate length
     *
     * @param \Magento\Framework\DataObject $object
     *
     * @return bool
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function validateLength($object)
    {
        /** @var string $attributeCode */
        $attributeCode = $this->getAttribute()->getAttributeCode();
        /** @var int $value */
        $value = (int)$object->getData($attributeCode);
        /** @var int $minimumValueLength */
        $minimumValueLength = $this->getMinimumValueLength();

        if ($this->getAttribute()->getIsRequired() && $value <= $minimumValueLength) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('The value of attribute "%1" must be greater than %2', $attributeCode, $minimumValueLength)
            );
        }

        return true;
    }

    /**
     * Get minimum attribute value length
     * 
     * @return int
     */
    public function getMinimumValueLength()
    {
        return $this->minimumValueLength;
    }
}

Wenn Sie ein einfaches Beispiel für diese Art von Klasse wünschen, können Sie dies überprüfen

  • \Magento\Customer\Model\Customer\Attribute\Backend\Website
  • Alle Klassen, die sich erstrecken \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
  • die Klassen in backend_modelSpalte in der eav_attributeTabelle


BEARBEITEN
Wenn Sie eine Klasse haben möchten, die fast das Gleiche macht wie Sie, können Sie sich die SKUAttributvalidierung ansehen. \Magento\Catalog\Model\Product\Attribute\Backend\Sku
Ich habe die Methode auch in die Beispielklasse eingefügt


BEARBEITEN
Eine andere (möglicherweise nicht die beste) Lösung besteht darin, ein Plugin für die Funktion zu erstellen \Magento\Eav\Helper\Data::getFrontendClassesund hier Ihre Frontend-Klasse hinzuzufügen, die vorab validiert werden kann.

Matthéo Geoffray
quelle
Vielen Dank für Ihre Antwort, aber es wäre möglich, die Frontend-Validierung anzuwenden.
Amit Singh
Wenn Sie sich Ihre Attributzeile in der eav_attributeTabelle in der Spalte ansehen, frontend_classist das der Wert validate-greater-than-zero?
Matthéo Geoffray
Ja, aber es funktioniert nicht. Dies sind die einzigen Klassen , die funktioniert validate-number, validate-digits, validate-email, validate-url, validate-alpha, validate-alphanum.
Amit Singh
1
Können Sie meine zweite Bearbeitung versuchen , um Ihre benutzerdefinierten Frontend-Klassen hinzuzufügen?
Matthéo Geoffray
Ich habe es mit Plugin gemacht, danke für den Hinweis
Amit Singh
12

Mit dieser Hilfe habe Matthéo Geoffrayich die Frontend-Validierung für benutzerdefinierte Attribute angewendet.

[
    'type' => 'int',
    'backend' => '',
    'frontend' => '',
    'label' => 'XXXX',
    'input' => 'text',
    'frontend_class' => 'validate-greater-than-zero',
    'source' => '',
    'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
    'visible' => true,
    'required' => true,
    'user_defined' => false,
    'default' => 0,
    'searchable' => false,
    'filterable' => true,
    'comparable' => false,
    'visible_on_front' => false,
    'used_in_product_listing' => true,
    'unique' => false
]

Dies ist das benutzerdefinierte Attribut im Installationsskript.

Ich habe das Plugin in di.xml hinzugefügt

<type name="Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules">
      <plugin name="namespace_custom_validation_for_product_attribute" type="Namespace\Module\Model\Plugin\Product\ValidationRules"/>
</type>

Hier ist der Plugin-Code.

<?php

namespace Namespace\Module\Model\Plugin\Product;

use Closure;

class ValidationRules
{

    /**
     * @param \Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules $rulesObject
     * @param callable $proceed
     * @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute,
     * @param array $data
     * @return array
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function aroundBuild(
        \Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules $rulesObject,
        Closure $proceed,
        \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute,
        array $data
    ){
        $rules = $proceed($attribute,$data);
        if($attribute->getAttributeCode() == 'xyz'){ //custom filter
            $validationClasses = explode(' ', $attribute->getFrontendClass());
            foreach ($validationClasses as $class) {
                $rules[$class] = true;
            }
        }
        return $rules;
    }
}

Grundsätzlich vergleicht \Magento\Catalog\Ui\DataProvider\CatalogEavValidationRulesdie aufgerufene Methode mapRulesdie Frontend-Klasse nur mit einer begrenzten Anzahl von Validierungsregeln. Um weitere Validierungsregeln anzuwenden, müssen Regeln mithilfe des Plugins angehängt werden.

Informationen zur serverseitigen Überprüfung finden Sie in der Matthéo GeoffrayAntwort.

Amit Singh
quelle
3

Ich bin mir nicht sicher, ob es mit dem Installationsskript möglich sein könnte. Aber ich bin sicher, es ist möglich, wenn Sie "vor dem Listener-Plugin" mit Funktion erstellen beforeSave()und dort den Wert überprüfen.

Fred Orosko Dias
quelle