Magento 2 ajoute une validation d'attribut de produit personnalisé à partir du script d'installation


17
[
    'type' => 'int',
    'backend' => '',
    'frontend' => '',
    'label' => 'XXXX',
    'input' => 'text',
    'frontend_class' => 'valider-supérieur à zéro',
    'source' => '',
    'global' => \ Magento \ Eav \ Model \ Entity \ Attribute \ ScopedAttributeInterface :: SCOPE_GLOBAL,
    'visible' => vrai,
    'required' => vrai,
    'user_defined' => false,
    'default' => 0,
    'consultable' => false,
    'filtrable' => vrai,
    'comparable' => faux,
    'visible_on_front' => false,
    'used_in_product_listing' => true,
    'unique' => faux
]

J'ajoute un attribut de produit personnalisé qui fonctionne bien, mais je ne peux pas ajouter de validate-greater-than-zerovalidation.

Si nous examinons les propriétés d'attribut dans, Input Validation for Store Owneril y a un nombre limité de validations dans les options sélectionnées.

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

Ce sont les seules validations appliquées dans la section Attribut de produit.


Veuillez voir ma réponse, elle vous aidera à valider la valeur de votre attribut.
— Matthéo Geoffray

Réponses:


13

L'une des solutions consiste à ajouter un backend modelà votre attribut qui est utilisé pour formater / valider la valeur de votre attribut avant l'enregistrement et / ou après le chargement.

Ajoutez une classe backend:

[
    '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
]

Voici un exemple de votre classe personnalisée \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;
    }
}

Si vous voulez un exemple simple de ce type de classe, vous pouvez vérifier

  • \Magento\Customer\Model\Customer\Attribute\Backend\Website
  • toutes les classes qui s'étendent \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
  • les classes en backend_modelcolonne dans le eav_attributetableau


EDIT
Si vous voulez une classe qui fait à peu près la même chose que vous le souhaitez, vous pouvez jeter un œil à la SKUvalidation des attributs \Magento\Catalog\Model\Product\Attribute\Backend\Sku
J'ai également ajouté la méthode dans l'exemple de classe


EDIT
Une autre solution (peut-être pas la meilleure) est de créer un plugin sur la fonction \Magento\Eav\Helper\Data::getFrontendClasseset d'ajouter ici votre classe frontend qui peut être validée en face.


Merci pour votre réponse mais serait-il possible d'appliquer la validation frontale.
— Amit Singh

Si vous jetez un coup d'œil à votre ligne d'attribut dans le eav_attributetableau de la colonne, frontend_classest-ce que c'est la valeur validate-greater-than-zero?
— Matthéo Geoffray

Oui mais ça ne marche pas. Ce sont les seules classes qui fonctionne validate-number, validate-digits, validate-email, validate-url, validate-alpha, validate-alphanum.
— Amit Singh

1
Pouvez-vous essayer ma deuxième édition , pour ajouter vos classes frontales personnalisées?
— Matthéo Geoffray

Je l'ai fait en utilisant un plugin, merci pour l'astuce
— Amit Singh

12

Avec l'aide de Matthéo Geoffray, voici ce que j'ai fait pour appliquer la validation frontale aux attributs personnalisés.

[
    '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
]

Il s'agit de l'attribut personnalisé dans le script d'installation.

J'ai ajouté un plugin dans di.xml

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

Voici le code du plugin.

<?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;
    }
}

Fondamentalement \Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules, la méthode appelée mapRulesne fait correspondre la classe frontale qu'à un nombre limité de règles de validation. Pour appliquer plus de règles de validation, nous devons ajouter des règles à l'aide du plugin.

Pour la validation côté serveur, veuillez vous référer à la Matthéo Geoffrayréponse.


3

Je ne suis pas sûr que cela puisse être possible à partir du script d'installation. Mais je suis sûr que c'est possible si vous créez "avant le plugin d'écoute" avec la fonction beforeSave()et vérifiez la valeur là-bas.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.