Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Rule.php
Go to the documentation of this file.
1 <?php
7 
15 
20 class Rule extends AbstractResource
21 {
27  protected $_associatedEntitiesMap = [];
28 
32  protected $customerGroupIds = [];
33 
37  protected $websiteIds = [];
38 
44  protected $string;
45 
49  protected $_resourceCoupon;
50 
54  protected $entityManager;
55 
59  private $metadataPool;
60 
70  public function __construct(
71  \Magento\Framework\Model\ResourceModel\Db\Context $context,
72  \Magento\Framework\Stdlib\StringUtils $string,
73  \Magento\SalesRule\Model\ResourceModel\Coupon $resourceCoupon,
74  $connectionName = null,
75  \Magento\Framework\DataObject $associatedEntityMapInstance = null,
76  Json $serializer = null,
77  MetadataPool $metadataPool = null
78  ) {
79  $this->string = $string;
80  $this->_resourceCoupon = $resourceCoupon;
81  $associatedEntitiesMapInstance = $associatedEntityMapInstance ?: ObjectManager::getInstance()->get(
82  \Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap::class
83  );
84  $this->_associatedEntitiesMap = $associatedEntitiesMapInstance->getData();
85  $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class);
86  $this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class);
87  parent::__construct($context, $connectionName);
88  }
89 
95  protected function _construct()
96  {
97  $this->_init('salesrule', 'rule_id');
98  }
99 
105  public function loadCustomerGroupIds(AbstractModel $object)
106  {
107  if (!$this->customerGroupIds) {
108  $this->customerGroupIds = (array)$this->getCustomerGroupIds($object->getId());
109  }
110  $object->setData('customer_group_ids', $this->customerGroupIds);
111  }
112 
118  public function loadWebsiteIds(AbstractModel $object)
119  {
120  if (!$this->websiteIds) {
121  $this->websiteIds = (array)$this->getWebsiteIds($object->getId());
122  }
123 
124  $object->setData('website_ids', $this->websiteIds);
125  }
126 
133  public function _beforeSave(AbstractModel $object)
134  {
135  if (!$object->getDiscountQty()) {
136  $object->setDiscountQty(new \Zend_Db_Expr('NULL'));
137  }
138 
139  parent::_beforeSave($object);
140  return $this;
141  }
142 
152  public function load(AbstractModel $object, $value, $field = null)
153  {
154  $this->getEntityManager()->load($object, $value);
155  return $this;
156  }
157 
166  protected function _afterSave(AbstractModel $object)
167  {
168  if ($object->hasStoreLabels()) {
169  $this->saveStoreLabels($object->getId(), $object->getStoreLabels());
170  }
171 
172  // Save product attributes used in rule
173  $ruleProductAttributes = array_merge(
174  $this->getProductAttributes($this->serializer->serialize($object->getConditions()->asArray())),
175  $this->getProductAttributes($this->serializer->serialize($object->getActions()->asArray()))
176  );
177  if (count($ruleProductAttributes)) {
178  $this->setActualProductAttributes($object, $ruleProductAttributes);
179  }
180 
181  // Update auto geterated specific coupons if exists
182  if ($object->getUseAutoGeneration() && $object->hasDataChanges()) {
183  $this->_resourceCoupon->updateSpecificCoupons($object);
184  }
185  return parent::_afterSave($object);
186  }
187 
196  {
197  $connection = $this->getConnection();
198  $select = $connection->select()->from(
199  $this->getTable('salesrule_customer'),
200  ['cnt' => 'count(*)']
201  )->where(
202  'rule_id = :rule_id'
203  )->where(
204  'customer_id = :customer_id'
205  );
206  return $connection->fetchOne($select, [':rule_id' => $rule->getRuleId(), ':customer_id' => $customerId]);
207  }
208 
217  public function saveStoreLabels($ruleId, $labels)
218  {
219  $deleteByStoreIds = [];
220  $table = $this->getTable('salesrule_label');
221  $connection = $this->getConnection();
222 
223  $data = [];
224  foreach ($labels as $storeId => $label) {
225  if ($this->string->strlen($label)) {
226  $data[] = ['rule_id' => $ruleId, 'store_id' => $storeId, 'label' => $label];
227  } else {
228  $deleteByStoreIds[] = $storeId;
229  }
230  }
231 
232  $connection->beginTransaction();
233  try {
234  if (!empty($data)) {
235  $connection->insertOnDuplicate($table, $data, ['label']);
236  }
237 
238  if (!empty($deleteByStoreIds)) {
239  $connection->delete($table, ['rule_id=?' => $ruleId, 'store_id IN (?)' => $deleteByStoreIds]);
240  }
241  } catch (\Exception $e) {
242  $connection->rollBack();
243  throw $e;
244  }
245  $connection->commit();
246 
247  return $this;
248  }
249 
256  public function getStoreLabels($ruleId)
257  {
258  $select = $this->getConnection()->select()->from(
259  $this->getTable('salesrule_label'),
260  ['store_id', 'label']
261  )->where(
262  'rule_id = :rule_id'
263  );
264  return $this->getConnection()->fetchPairs($select, [':rule_id' => $ruleId]);
265  }
266 
274  public function getStoreLabel($ruleId, $storeId)
275  {
276  $select = $this->getConnection()->select()->from(
277  $this->getTable('salesrule_label'),
278  'label'
279  )->where(
280  'rule_id = :rule_id'
281  )->where(
282  'store_id IN(0, :store_id)'
283  )->order(
284  'store_id DESC'
285  );
286  return $this->getConnection()->fetchOne($select, [':rule_id' => $ruleId, ':store_id' => $storeId]);
287  }
288 
294  public function getActiveAttributes()
295  {
296  $connection = $this->getConnection();
297  $select = $connection->select()->from(
298  ['a' => $this->getTable('salesrule_product_attribute')],
299  new \Zend_Db_Expr('DISTINCT ea.attribute_code')
300  )->joinInner(
301  ['ea' => $this->getTable('eav_attribute')],
302  'ea.attribute_id = a.attribute_id',
303  []
304  );
305  return $connection->fetchAll($select);
306  }
307 
316  {
317  $connection = $this->getConnection();
318  $metadata = $this->metadataPool->getMetadata(RuleInterface::class);
319  $connection->delete(
320  $this->getTable('salesrule_product_attribute'),
321  [$metadata->getLinkField() . '=?' => $rule->getData($metadata->getLinkField())]
322  );
323 
324  //Getting attribute IDs for attribute codes
325  $attributeIds = [];
326  $select = $this->getConnection()->select()->from(
327  ['a' => $this->getTable('eav_attribute')],
328  ['a.attribute_id']
329  )->where(
330  'a.attribute_code IN (?)',
331  [$attributes]
332  );
333  $attributesFound = $this->getConnection()->fetchAll($select);
334  if ($attributesFound) {
335  foreach ($attributesFound as $attribute) {
336  $attributeIds[] = $attribute['attribute_id'];
337  }
338 
339  $data = [];
340  foreach ($rule->getCustomerGroupIds() as $customerGroupId) {
341  foreach ($rule->getWebsiteIds() as $websiteId) {
342  foreach ($attributeIds as $attribute) {
343  $data[] = [
344  $metadata->getLinkField() => $rule->getData($metadata->getLinkField()),
345  'website_id' => $websiteId,
346  'customer_group_id' => $customerGroupId,
347  'attribute_id' => $attribute,
348  ];
349  }
350  }
351  }
352  $connection->insertMultiple($this->getTable('salesrule_product_attribute'), $data);
353  }
354 
355  return $this;
356  }
357 
364  public function getProductAttributes($serializedString)
365  {
366  // we need 4 backslashes to match 1 in regexp, see http://www.php.net/manual/en/regexp.reference.escape.php
367  preg_match_all(
368  '~"Magento\\\\\\\\SalesRule\\\\\\\\Model\\\\\\\\Rule\\\\\\\\Condition\\\\\\\\Product","attribute":"(.*?)"~',
369  $serializedString,
370  $matches
371  );
372  // we always have $matches like [[],[]]
373  return array_values($matches[1]);
374  }
375 
380  public function save(\Magento\Framework\Model\AbstractModel $object)
381  {
382  $this->getEntityManager()->save($object);
383  return $this;
384  }
385 
392  public function delete(AbstractModel $object)
393  {
394  $this->getEntityManager()->delete($object);
395  return $this;
396  }
397 
402  private function getEntityManager()
403  {
404  if (null === $this->entityManager) {
406  ->get(\Magento\Framework\EntityManager\EntityManager::class);
407  }
408  return $this->entityManager;
409  }
410 }
loadWebsiteIds(AbstractModel $object)
Definition: Rule.php:118
_beforeSave(AbstractModel $object)
Definition: Rule.php:133
_afterSave(AbstractModel $object)
Definition: Rule.php:166
load(AbstractModel $object, $value, $field=null)
Definition: Rule.php:152
$label
Definition: details.phtml:21
$value
Definition: gender.phtml:16
loadCustomerGroupIds(AbstractModel $object)
Definition: Rule.php:105
setActualProductAttributes($rule, $attributes)
Definition: Rule.php:315
getCustomerUses($rule, $customerId)
Definition: Rule.php:195
$attributes
Definition: matrix.phtml:13
getProductAttributes($serializedString)
Definition: Rule.php:364
__construct(\Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Framework\Stdlib\StringUtils $string, \Magento\SalesRule\Model\ResourceModel\Coupon $resourceCoupon, $connectionName=null, \Magento\Framework\DataObject $associatedEntityMapInstance=null, Json $serializer=null, MetadataPool $metadataPool=null)
Definition: Rule.php:70
$connection
Definition: bulk.php:13
save(\Magento\Framework\Model\AbstractModel $object)
Definition: Rule.php:380
$table
Definition: trigger.php:14