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.