Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Collection.php
Go to the documentation of this file.
1 <?php
8 
12 
21 {
28 
33  protected $dateApplier;
34 
38  protected $_date;
39 
43  private $serializer;
44 
55  public function __construct(
56  \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
57  \Psr\Log\LoggerInterface $logger,
58  \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
59  \Magento\Framework\Event\ManagerInterface $eventManager,
60  \Magento\Framework\Stdlib\DateTime\TimezoneInterface $date,
61  \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
62  \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null,
63  Json $serializer = null
64  ) {
65  parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
66  $this->_date = $date;
67  $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()->get(Json::class);
68  $this->_associatedEntitiesMap = $this->getAssociatedEntitiesMap();
69  }
70 
76  protected function _construct()
77  {
78  $this->_init(\Magento\SalesRule\Model\Rule::class, \Magento\SalesRule\Model\ResourceModel\Rule::class);
79  $this->_map['fields']['rule_id'] = 'main_table.rule_id';
80  }
81 
89  protected function mapAssociatedEntities($entityType, $objectField)
90  {
91  if (!$this->_items) {
92  return;
93  }
94 
95  $entityInfo = $this->_getAssociatedEntityInfo($entityType);
96  $ruleIdField = $entityInfo['rule_id_field'];
97  $entityIds = $this->getColumnValues($ruleIdField);
98 
99  $select = $this->getConnection()->select()->from(
100  $this->getTable($entityInfo['associations_table'])
101  )->where(
102  $ruleIdField . ' IN (?)',
103  $entityIds
104  );
105 
106  $associatedEntities = $this->getConnection()->fetchAll($select);
107 
108  array_map(function ($associatedEntity) use ($entityInfo, $ruleIdField, $objectField) {
109  $item = $this->getItemByColumnValue($ruleIdField, $associatedEntity[$ruleIdField]);
110  $itemAssociatedValue = $item->getData($objectField) === null ? [] : $item->getData($objectField);
111  $itemAssociatedValue[] = $associatedEntity[$entityInfo['entity_id_field']];
112  $item->setData($objectField, $itemAssociatedValue);
113  }, $associatedEntities);
114  }
115 
121  protected function _afterLoad()
122  {
123  $this->mapAssociatedEntities('website', 'website_ids');
124  $this->mapAssociatedEntities('customer_group', 'customer_group_ids');
125 
126  $this->setFlag('add_websites_to_result', false);
127  return parent::_afterLoad();
128  }
129 
144  public function setValidationFilter(
145  $websiteId,
146  $customerGroupId,
147  $couponCode = '',
148  $now = null,
149  Address $address = null
150  ) {
151  if (!$this->getFlag('validation_filter')) {
152  /* We need to overwrite joinLeft if coupon is applied */
153  $this->getSelect()->reset();
154  parent::_initSelect();
155 
156  $this->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now);
157  $select = $this->getSelect();
158 
159  $connection = $this->getConnection();
160  if (strlen($couponCode)) {
161  $select->joinLeft(
162  ['rule_coupons' => $this->getTable('salesrule_coupon')],
163  $connection->quoteInto(
164  'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?',
165  \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
166  ),
167  ['code']
168  );
169 
170  $noCouponWhereCondition = $connection->quoteInto(
171  'main_table.coupon_type = ? ',
172  \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
173  );
174 
175  $autoGeneratedCouponCondition = [
176  $connection->quoteInto(
177  "main_table.coupon_type = ?",
178  \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO
179  ),
180  $connection->quoteInto(
181  "rule_coupons.type = ?",
182  \Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED
183  ),
184  ];
185 
186  $orWhereConditions = [
187  "(" . implode($autoGeneratedCouponCondition, " AND ") . ")",
188  $connection->quoteInto(
189  '(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)',
190  \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
191  ),
192  $connection->quoteInto(
193  '(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)',
194  \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
195  ),
196  ];
197 
198  $andWhereConditions = [
199  $connection->quoteInto(
200  'rule_coupons.code = ?',
202  ),
203  $connection->quoteInto(
204  '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)',
205  $this->_date->date()->format('Y-m-d')
206  ),
207  ];
208 
209  $orWhereCondition = implode(' OR ', $orWhereConditions);
210  $andWhereCondition = implode(' AND ', $andWhereConditions);
211 
212  $select->where(
213  $noCouponWhereCondition . ' OR ((' . $orWhereCondition . ') AND ' . $andWhereCondition . ')',
214  null,
216  );
217  } else {
218  $this->addFieldToFilter(
219  'main_table.coupon_type',
220  \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
221  );
222  }
223  $this->setOrder('sort_order', self::SORT_ORDER_ASC);
224  $this->setFlag('validation_filter', true);
225  }
226 
227  return $this;
228  }
229 
241  public function addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now = null)
242  {
243  if (!$this->getFlag('website_group_date_filter')) {
244  if ($now === null) {
245  $now = $this->_date->date()->format('Y-m-d');
246  }
247 
249 
250  $entityInfo = $this->_getAssociatedEntityInfo('customer_group');
251  $connection = $this->getConnection();
252  $this->getSelect()->joinInner(
253  ['customer_group_ids' => $this->getTable($entityInfo['associations_table'])],
254  $connection->quoteInto(
255  'main_table.' .
256  $entityInfo['rule_id_field'] .
257  ' = customer_group_ids.' .
258  $entityInfo['rule_id_field'] .
259  ' AND customer_group_ids.' .
260  $entityInfo['entity_id_field'] .
261  ' = ?',
262  (int)$customerGroupId
263  ),
264  []
265  );
266 
267  $this->getDateApplier()->applyDate($this->getSelect(), $now);
268 
269  $this->addIsActiveFilter();
270 
271  $this->setFlag('website_group_date_filter', true);
272  }
273 
274  return $this;
275  }
276 
282  public function _initSelect()
283  {
284  parent::_initSelect();
285  $this->getSelect()->joinLeft(
286  ['rule_coupons' => $this->getTable('salesrule_coupon')],
287  'main_table.rule_id = rule_coupons.rule_id AND rule_coupons.is_primary = 1',
288  ['code']
289  );
290  return $this;
291  }
292 
300  {
301  $match = sprintf('%%%s%%', substr($this->serializer->serialize(['attribute' => $attributeCode]), 1, -1));
318  $field = $this->_getMappedField('conditions_serialized');
319  $cCond = $this->_getConditionSql($field, ['like' => $match]);
320  $field = $this->_getMappedField('actions_serialized');
321  $aCond = $this->_getConditionSql($field, ['like' => $match]);
322 
323  $this->getSelect()->where(
324  sprintf('(%s OR %s)', $cCond, $aCond),
325  null,
327  );
328 
329  return $this;
330  }
331 
337  public function addAllowedSalesRulesFilter()
338  {
339  $this->addFieldToFilter('main_table.use_auto_generation', ['neq' => 1]);
340 
341  return $this;
342  }
343 
351  public function addCustomerGroupFilter($customerGroupId)
352  {
353  $entityInfo = $this->_getAssociatedEntityInfo('customer_group');
354  if (!$this->getFlag('is_customer_group_joined')) {
355  $this->setFlag('is_customer_group_joined', true);
356  $this->getSelect()->join(
357  ['customer_group' => $this->getTable($entityInfo['associations_table'])],
358  $this->getConnection()
359  ->quoteInto('customer_group.' . $entityInfo['entity_id_field'] . ' = ?', $customerGroupId)
360  . ' AND main_table.' . $entityInfo['rule_id_field'] . ' = customer_group.'
361  . $entityInfo['rule_id_field'],
362  []
363  );
364  }
365  return $this;
366  }
367 
372  private function getAssociatedEntitiesMap()
373  {
374  if (!$this->_associatedEntitiesMap) {
375  $this->_associatedEntitiesMap = \Magento\Framework\App\ObjectManager::getInstance()
376  ->get(\Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap::class)
377  ->getData();
378  }
380  }
381 
386  private function getDateApplier()
387  {
388  if (null === $this->dateApplier) {
390  ->get(\Magento\SalesRule\Model\ResourceModel\Rule\DateApplier::class);
391  }
392 
393  return $this->dateApplier;
394  }
395 }
__construct(\Magento\Framework\Data\Collection\EntityFactory $entityFactory, \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $date, \Magento\Framework\DB\Adapter\AdapterInterface $connection=null, \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource=null, Json $serializer=null)
Definition: Collection.php:55
$resource
Definition: bulk.php:12
$logger
$address
Definition: customer.php:38
getItemByColumnValue($column, $value)
Definition: Collection.php:380
$attributeCode
Definition: extend.phtml:12
addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now=null)
Definition: Collection.php:241
setValidationFilter( $websiteId, $customerGroupId, $couponCode='', $now=null, Address $address=null)
Definition: Collection.php:144
setOrder($field, $direction=self::SORT_ORDER_DESC)
Definition: AbstractDb.php:274
$connection
Definition: bulk.php:13