Magento 2从安装脚本添加自定义产品属性验证


17
[
    'type'=>'int',
    '后端'=>'',
    'frontend'=>'',
    '标签'=>'XXXX',
    '输入'=>'文本',
    'frontend_class'=>'验证大于零的值',
    '源'=>'',
    'global'=> \ Magento \ Eav \ Model \ Entity \ Attribute \ ScopedAttributeInterface :: SCOPE_GLOBAL,
    'visible'=>是,
    'required'=>是,
    'user_defined'=>否,
    '默认'=> 0,
    '可搜索'=>否,
    '可过滤'=> true,
    '可比较'=>否,
    'visible_on_front'=>否,
    'used_in_product_listing'=>是,
    '唯一'=>否
]

我正在添加自定义产品属性,该属性可以正常运行,但无法添加validate-greater-than-zero验证。

如果我们查看其中的任何属性Input Validation for Store Owner,选择选项中的验证次数将有限。

validate-numbervalidate-digitsvalidate-emailvalidate-urlvalidate-alphavalidate-alphanum

这些是“产品属性”部分中应用的唯一验证。


请查看我的答案,它将帮助您验证属性值。
MatthéoGeoffray

Answers:


13

解决方案之一是backend model在属性中添加一个,用于在保存之前和/或加载之后格式化/验证属性值。

添加一个后端类:

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

这是您的自定义类的示例 \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;
    }
}

如果您想要此类的简单示例,可以查看

  • \Magento\Customer\Model\Customer\Attribute\Backend\Website
  • 所有扩展的类 \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
  • 类归入表中的backend_modeleav_attribute


编辑
如果您想要一个与您做几乎相同的事情的类,您可以看一下SKU属性验证,\Magento\Catalog\Model\Product\Attribute\Backend\Sku
我还在示例类中添加了该方法


编辑
另一个解决方案(也许不是最好的解决方案)是在函数上创建一个插件,\Magento\Eav\Helper\Data::getFrontendClasses并在此处添加可以在前面进行验证的前端类。


感谢您的答复,但可以应用前端验证。
阿米特·辛格

如果您看一下eav_attribute表格中该列的属性行,您frontend_class的值是validate-greater-than-zero多少?
MatthéoGeoffray

是的,但是不起作用。这些都是工作的唯一类validate-numbervalidate-digitsvalidate-emailvalidate-urlvalidate-alphavalidate-alphanum
阿米特·辛格

1
您可以尝试第二次编辑来添加自定义前端类吗?
MatthéoGeoffray

我没有用它的插件,感谢您的提示
阿米特·辛格

12

在的帮助下Matthéo Geoffray,这就是我对自定义属性应用前端验证的过程。

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

这是安装脚本中的定制属性。

我在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>

这是插件代码。

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

基本上在中\Magento\Catalog\Ui\DataProvider\CatalogEavValidationRules,所调用的方法mapRules仅将前端类与有限数量的验证规则进行匹配。要应用更多验证规则,我们需要使用插件附加规则。

对于服务器端验证,请参考Matthéo Geoffray答案。


3

我不确定安装脚本是否有可能。但是我敢肯定,是否有可能在函数之前创建“ before listener plugin” beforeSave()并在其中检查值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.