Magento 2 aggiunge la convalida dell'attributo del prodotto personalizzato dallo script di installazione


17
[
    '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,
    'richiesto' => vero,
    'user_defined' => false,
    'default' => 0,
    'searchable' => false,
    'filterable' => true,
    'comparable' => false,
    'visible_on_front' => false,
    'used_in_product_listing' => true,
    'unique' => false
]

Sto aggiungendo l'attributo del prodotto personalizzato che funziona bene, ma non è in grado di aggiungere la validate-greater-than-zeroconvalida.

Se osserviamo le proprietà di un attributo, Input Validation for Store Ownerci sono un numero limitato di convalide nelle opzioni selezionate.

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

Queste sono le uniche validazioni applicate nella sezione degli attributi del prodotto.


Vedi la mia risposta, ti aiuterà a convalidare il valore del tuo attributo.
Matthéo Geoffray,

Risposte:


13

Una delle soluzioni è quella di aggiungere un backend modelal tuo attributo che viene utilizzato per formattare / convalidare il valore del tuo attributo prima del salvataggio e / o dopo il caricamento.

Aggiungi una classe di 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
]

Ecco un esempio della tua classe personalizzata \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;
    }
}

Se vuoi un semplice esempio di quel tipo di classe, puoi controllare

  • \Magento\Customer\Model\Customer\Attribute\Backend\Website
  • tutte le classi che si estendono \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
  • le classi nella backend_modelcolonna nella eav_attributetabella


MODIFICA
Se vuoi una classe che fa quasi la stessa cosa che vuoi puoi dare un'occhiata alla SKUvalidazione dell'attributo \Magento\Catalog\Model\Product\Attribute\Backend\Sku
Ho anche aggiunto il metodo nella classe di esempio


MODIFICA
Un'altra soluzione (forse non la migliore) è quella di creare un plugin per la funzione \Magento\Eav\Helper\Data::getFrontendClassese aggiungere qui la tua classe frontend che può essere validata in anticipo.


Grazie per la tua risposta, ma sarebbe possibile applicare la convalida del frontend.
Amit Singh,

Se dai un'occhiata alla tua linea di attributi nella eav_attributetabella nella colonna frontend_classè il valore validate-greater-than-zero?
Matthéo Geoffray,

Sì ma non funziona. Queste sono le uniche classi che funziona validate-number, validate-digits, validate-email, validate-url, validate-alpha, validate-alphanum.
Amit Singh,

1
Puoi provare la mia seconda modifica per aggiungere le tue classi frontend personalizzate?
Matthéo Geoffray,

L'ho fatto usando il plugin, grazie per il suggerimento
Amit Singh,

12

Con l'aiuto di Matthéo Geoffrayquesto è quello che ho fatto per applicare la convalida del frontend per gli attributi personalizzati.

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

Questo è l'attributo personalizzato nello script di installazione.

Ho aggiunto il plugin in 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>

Ecco il codice del 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;
    }
}

Fondamentalmente \Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules, il metodo chiamato mapRulescorrisponde solo alla classe frontend con un numero limitato di regole di convalida. Per applicare più regole di convalida dobbiamo aggiungere regole usando il plugin.

Per la convalida lato server, fare riferimento alla Matthéo Geoffrayrisposta.


3

Non sono sicuro che potrebbe essere possibile dallo script di installazione. Ma sono sicuro che è possibile creare "prima del plug-in listener" con la funzione beforeSave()e controllare il valore lì.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.