【问题标题】:How to use Catalog rule "Conditions_serialized" to validate product attribute?如何使用目录规则“Conditions_serialized”来验证产品属性?
【发布时间】:2016-05-21 04:37:50
【问题描述】:

我已经在我的表“product_label”上定义了一个条件,即哪个产品作为产品属性“热”等于“是”。

如何使用 \Magento\CatalogRule\Model\Rule\Condition... 来验证 $product 是否符合我的条件?

条件记录如下

 a:7:{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Condition
\Combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_
processed";N;s:10:"aggregator";s:3:"all";s:10:"conditions";a:1:{i:0;a:5:
{s:4:"type";s:48:"Magento\CatalogRule\Model\Rule\Condition
\Product";s:9:"attribute";s:7:"hkt_hot";s:8:"operator";s:2:"==";s:5:"value";
s:1:"1";s:18:"is_value_processed";b:0;}}}

谢谢 诺曼

【问题讨论】:

    标签: magento2 catalog


    【解决方案1】:

    无需编码,您可以使用现有系统进行此检查:

    您的“热门”属性 is_used_for_promo_rules 必须设置为 1。

    此外,函数Mage_Catalog_Model_Resource_Eav_Attribute::isAllowedForRuleCondition() 设置以下先决条件:

    属性必须可见(属性属性 is_visible 必须等于 1)。 frontend_input 属性必须是以下类型之一:'text'、'multiselect'、'textarea'、'date'、'datetime'、'select'、'boolean'、'price'。

    【讨论】:

      【解决方案2】:

      您可以找到满足序列化条件的产品ID列表。

      创建模型Vendor/Module/Model/Rule.php

      <?php 
      namespace Vendor\Module\Model;
      
      class Rule extends \Magento\CatalogRule\Model\Rule
      {
      
          /**
           * Prefix of model events names
           *
           * @var string
           */
          protected $_eventPrefix = 'catalogrule_rule';
      
          /**
           * Parameter name in event
           *
           * In observe method you can use $observer->getEvent()->getRule() in this case
           *
           * @var string
           */
          protected $_eventObject = 'rule';
      
          /**
           * Store matched product Ids
           *
           * @var array
           */
          protected $_productIds;
      
          /**
           * Limitation for products collection
           *
           * @var int|array|null
           */
          protected $_productsFilter = null;
      
          /**
           * Store current date at "Y-m-d H:i:s" format
           *
           * @var string
           */
          protected $_now;
      
          /**
           * Cached data of prices calculated by price rules
           *
           * @var array
           */
          protected static $_priceRulesData = [];
      
          /**
           * Catalog rule data
           *
           * @var \Magento\CatalogRule\Helper\Data
           */
          protected $_catalogRuleData;
      
          /**
           *
           * @var \Magento\Framework\App\Cache\TypeListInterface
           */
          protected $_cacheTypesList;
      
          /**
           *
           * @var array
           */
          protected $_relatedCacheTypes;
      
          /**
           *
           * @var \Magento\Framework\Stdlib\DateTime
           */
          protected $dateTime;
      
          /**
           *
           * @var \Magento\Framework\Model\ResourceModel\Iterator
           */
          protected $_resourceIterator;
      
          /**
           *
           * @var \Magento\Customer\Model\Session
           */
          protected $_customerSession;
      
          /**
           *
           * @var \Magento\CatalogRule\Model\Rule\Condition\CombineFactory
           */
          protected $_combineFactory;
      
          /**
           *
           * @var \Magento\CatalogRule\Model\Rule\Action\CollectionFactory
           */
          protected $_actionCollectionFactory;
      
          /**
           *
           * @var \Magento\Catalog\Model\ProductFactory
           */
          protected $_productFactory;
      
          /**
           *
           * @var \Magento\Store\Model\StoreManagerInterface
           */
          protected $_storeManager;
      
          /**
           *
           * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
           */
          protected $_productCollectionFactory;
      
          /**
           *
           * @var \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor;
           */
          protected $_ruleProductProcessor;
      
          /**
           *
           * @var Data\Condition\Converter
           */
          protected $ruleConditionConverter;
      
          /**
           * Rule constructor.
           *
           * @param \Magento\Framework\Model\Context $context
           * @param \Magento\Framework\Registry $registry
           * @param \Magento\Framework\Data\FormFactory $formFactory
           * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
           * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
           * @param \Magento\Store\Model\StoreManagerInterface $storeManager
           * @param Rule\Condition\CombineFactory $combineFactory
           * @param Rule\Action\CollectionFactory $actionCollectionFactory
           * @param \Magento\Catalog\Model\ProductFactory $productFactory
           * @param \Magento\Framework\Model\ResourceModel\Iterator $resourceIterator
           * @param \Magento\Customer\Model\Session $customerSession
           * @param \Magento\CatalogRule\Helper\Data $catalogRuleData
           * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList
           * @param \Magento\Framework\Stdlib\DateTime $dateTime
           * @param Indexer\Rule\RuleProductProcessor $ruleProductProcessor
           * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
           * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
           * @param array $relatedCacheTypes
           * @param array $data
           *
           * @SuppressWarnings(PHPMD.ExcessiveParameterList)
           */
          public function __construct(\Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Data\FormFactory $formFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\CatalogRule\Model\Rule\Condition\CombineFactory $combineFactory, \Magento\CatalogRule\Model\Rule\Action\CollectionFactory $actionCollectionFactory, \Magento\Catalog\Model\ProductFactory $productFactory, \Magento\Framework\Model\ResourceModel\Iterator $resourceIterator, \Magento\Customer\Model\Session $customerSession, \Magento\CatalogRule\Helper\Data $catalogRuleData, \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList, \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $relatedCacheTypes = [], array $data = [])
          {
              parent::__construct($context, $registry, $formFactory, $localeDate, $productCollectionFactory, $storeManager, $combineFactory, $actionCollectionFactory, $productFactory, $resourceIterator, $customerSession, $catalogRuleData, $cacheTypesList, $dateTime, $ruleProductProcessor, $resource, $resourceCollection, $relatedCacheTypes, $data);
          }
      
          /**
           * Init resource model and id field
           *
           * @return void
           */
          protected function _construct()
          {
              parent::_construct();
              $this->_init('Magento\CatalogRule\Model\ResourceModel\Rule');
              $this->setIdFieldName('rule_id');
          }
      
          /**
           * Getter for rule conditions collection
           *
           * @return \Magento\Rule\Model\Condition\Combine
           */
          public function getConditionsInstance()
          {
              return $this->_combineFactory->create();
          }
      
          /**
           * Getter for rule actions collection
           *
           * @return \Magento\CatalogRule\Model\Rule\Action\Collection
           */
          public function getActionsInstance()
          {
              return $this->_actionCollectionFactory->create();
          }
      
          public function toArray(array $arrAttributes = array())
          {
              return parent::toArray($arrAttributes);
          }
      
          public function getListProductIds()
          {
              $productCollection = \Magento\Framework\App\ObjectManager::getInstance()->create('\Magento\Catalog\Model\ResourceModel\Product\Collection');
              $productFactory = \Magento\Framework\App\ObjectManager::getInstance()->create('\Magento\Catalog\Model\ProductFactory');
              $this->_productIds = [];
              $this->setCollectedAttributes([]);
              $this->getConditions()->collectValidatedAttributes($productCollection);
              \Magento\Framework\App\ObjectManager::getInstance()->create('\Magento\Framework\Model\ResourceModel\Iterator')->walk($productCollection->getSelect(), [
                  [
                      $this,
                      'callbackValidateProduct'
                  ]
              ], [
                  'attributes' => $this->getCollectedAttributes(),
                  'product' => $productFactory->create()
              ]);
              return $this->_productIds;
          }
      
          /**
           * Callback function for product matching
           *
           * @param array $args
           * @return void
           */
          public function callbackValidateProduct($args)
          {
              $product = clone $args['product'];
              $product->setData($args['row']);
              $websites = $this->_getWebsitesMap();
              foreach ($websites as $websiteId => $defaultStoreId) {
                  $product->setStoreId($defaultStoreId);
                  if ($this->getConditions()->validate($product)) {
                      $this->_productIds[] = $product->getId();
                  }
              }
          }
      
          /**
           * Prepare website map
           *
           * @return array
           */
          protected function _getWebsitesMap()
          {
              $map = [];
              $websites = \Magento\Framework\App\ObjectManager::getInstance()->create('\Magento\Store\Model\StoreManagerInterface')->getWebsites();
              foreach ($websites as $website) {
                  // Continue if website has no store to be able to create catalog rule for website without store
                  if ($website->getDefaultStore() === null) {
                      continue;
                  }
                  $map[$website->getId()] = $website->getDefaultStore()->getId();
              }
              return $map;
          }
      }
      

      然后,无论您想在哪里找到产品 ID。使用下面的代码 sn-p。

      ...
          private $ruleModel;
      ...
      
      ...
          private function getRuleModel()
          {
              if($this->ruleModel === null) {
                  $this->ruleModel = $this->objectManager->create('Vendor\Module\Model\Rule');
                  $this->ruleModel->setName('name')
                  ->setDescription('description')
                  ->setWebsiteIds($this->objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId());
              }
              return $this->ruleModel;
          }
      
      ...
      
      ...
      // somewhere in your method
          $matchedProductIds = $this->getRuleModel()
                      ->setData('conditions_serialized', $conditions_serialized)->getListProductIds();
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多