Magento 2 dodaje niestandardowe sprawdzanie poprawności atrybutów produktu ze skryptu instalacyjnego

17
[
    „type” => „int”,
    „backend” => '',
    „frontend” => '',
    „label” => „XXXX”,
    „input” => „text”,
    „frontend_class” => 'validate-more-than-zero',
    „source” => '',
    'global' => \ Magento \ Eav \ Model \ Entity \ Attribute \ ScopedAttributeInterface :: SCOPE_GLOBAL,
    „widoczne” => prawda,
    „wymagane” => prawda,
    'user_defined' => false,
    „default” => 0,
    „searchable” => false,
    „filterable” => true,
    „porównywalne” => fałsz,
    'visible_on_front' => false,
    'used_in_product_listing' => true,
    „unikalny” => fałsz
]

Dodaję niestandardowy atrybut produktu, który działa dobrze, ale nie można dodać validate-greater-than-zerosprawdzania poprawności.

Jeśli spojrzymy na dowolne właściwości atrybutu, Input Validation for Store Owneristnieje ograniczona liczba walidacji w wybranych opcjach.

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

Są to jedyne walidacje zastosowane w sekcji Atrybut produktu.

Amit Singh
źródło
Zobacz moją odpowiedź, która pomoże ci zweryfikować wartość atrybutu.
Matthéo Geoffray

Odpowiedzi:

13

Jednym z rozwiązań jest dodanie backend modeldo atrybutu atrybutu, który służy do formatowania / sprawdzania wartości atrybutu przed zapisaniem i / lub po załadowaniu.

Dodaj klasę zaplecza:

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

Oto przykład Twojej niestandardowej klasy \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;
    }
}

Jeśli chcesz prosty przykład tego rodzaju zajęć, możesz to sprawdzić

  • \Magento\Customer\Model\Customer\Attribute\Backend\Website
  • wszystkie klasy, które rozszerzają \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
  • klasy do backend_modelkolumny w eav_attributetabeli


EDYCJA
Jeśli chcesz mieć klasę, która robi prawie to samo, co chcesz, możesz rzucić okiem na SKUsprawdzanie poprawności atrybutu. \Magento\Catalog\Model\Product\Attribute\Backend\Sku
Dodałem również metodę do przykładowej klasy


EDYCJA
Innym rozwiązaniem (może nie najlepszym) jest utworzenie wtyczki do funkcji \Magento\Eav\Helper\Data::getFrontendClassesi dodanie tutaj klasy frontendu, którą można zweryfikować z przodu.

Matthéo Geoffray
źródło
Dziękujemy za odpowiedź, ale czy można zastosować weryfikację interfejsu użytkownika.
Amit Singh,
Jeśli spojrzysz na linię atrybutu w eav_attributetabeli w kolumnie, czy frontend_classto ta wartość validate-greater-than-zero?
Matthéo Geoffray
Tak, ale to nie działa. Są jedynymi klasami, który pracuje validate-number, validate-digits, validate-email, validate-url, validate-alpha, validate-alphanum.
Amit Singh
1
Czy możesz wypróbować moją drugą edycję , aby dodać niestandardowe klasy interfejsu użytkownika?
Matthéo Geoffray
Zrobiłem to za pomocą wtyczki, dzięki za podpowiedź
Amit Singh
12

Za pomocą Matthéo Geoffraytego właśnie zrobiłem, aby zastosować walidację interfejsu użytkownika dla niestandardowych atrybutów.

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

Jest to niestandardowy atrybut w skrypcie instalacyjnym.

Dodałem wtyczkę w 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>

Oto kod wtyczki.

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

Zasadniczo \Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules, wywoływana metoda mapRulesdopasowuje tylko klasę frontend do ograniczonej liczby reguł sprawdzania poprawności. Aby zastosować więcej reguł sprawdzania poprawności, musimy dołączyć reguły przy użyciu wtyczki.

Aby sprawdzić poprawność po stronie serwera, zapoznaj się z Matthéo Geoffrayodpowiedzią.

Amit Singh
źródło
3

Nie jestem pewien, czy to możliwe ze skryptu instalacyjnego. Ale jestem pewien, że jest to możliwe, jeśli utworzysz „przed wtyczką nasłuchującą” z funkcją beforeSave()i sprawdzisz tam wartość.

Fred Orosko Dias
źródło