PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 347 lines | 207 code | 40 blank | 100 comment | 9 complexity | 719c40718d393bb75e45b89791002639 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. // @codingStandardsIgnoreFile
  7. namespace Magento\SalesRule\Model\ResourceModel\Rule;
  8. use Magento\Quote\Model\Quote\Address;
  9. /**
  10. * Sales Rules resource collection model.
  11. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  12. */
  13. class Collection extends \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection
  14. {
  15. /**
  16. * Store associated with rule entities information map
  17. *
  18. * @var array
  19. */
  20. protected $_associatedEntitiesMap;
  21. /**
  22. * @var \Magento\SalesRule\Model\ResourceModel\Rule\DateApplier
  23. */
  24. protected $dateApplier;
  25. /**
  26. * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
  27. */
  28. protected $_date;
  29. /**
  30. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
  31. * @param \Psr\Log\LoggerInterface $logger
  32. * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
  33. * @param \Magento\Framework\Event\ManagerInterface $eventManager
  34. * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $date
  35. * @param mixed $connection
  36. * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
  37. */
  38. public function __construct(
  39. \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
  40. \Psr\Log\LoggerInterface $logger,
  41. \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
  42. \Magento\Framework\Event\ManagerInterface $eventManager,
  43. \Magento\Framework\Stdlib\DateTime\TimezoneInterface $date,
  44. \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
  45. \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
  46. ) {
  47. parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
  48. $this->_date = $date;
  49. $this->_associatedEntitiesMap = $this->getAssociatedEntitiesMap();
  50. }
  51. /**
  52. * Set resource model and determine field mapping
  53. *
  54. * @return void
  55. */
  56. protected function _construct()
  57. {
  58. $this->_init(\Magento\SalesRule\Model\Rule::class, \Magento\SalesRule\Model\ResourceModel\Rule::class);
  59. $this->_map['fields']['rule_id'] = 'main_table.rule_id';
  60. }
  61. /**
  62. * @param string $entityType
  63. * @param string $objectField
  64. * @throws \Magento\Framework\Exception\LocalizedException
  65. * @return void
  66. */
  67. protected function mapAssociatedEntities($entityType, $objectField)
  68. {
  69. if (!$this->_items) {
  70. return;
  71. }
  72. $entityInfo = $this->_getAssociatedEntityInfo($entityType);
  73. $ruleIdField = $entityInfo['rule_id_field'];
  74. $entityIds = $this->getColumnValues($ruleIdField);
  75. $select = $this->getConnection()->select()->from(
  76. $this->getTable($entityInfo['associations_table'])
  77. )->where(
  78. $ruleIdField . ' IN (?)',
  79. $entityIds
  80. );
  81. $associatedEntities = $this->getConnection()->fetchAll($select);
  82. array_map(function ($associatedEntity) use ($entityInfo, $ruleIdField, $objectField) {
  83. $item = $this->getItemByColumnValue($ruleIdField, $associatedEntity[$ruleIdField]);
  84. $itemAssociatedValue = $item->getData($objectField) === null ? [] : $item->getData($objectField);
  85. $itemAssociatedValue[] = $associatedEntity[$entityInfo['entity_id_field']];
  86. $item->setData($objectField, $itemAssociatedValue);
  87. }, $associatedEntities);
  88. }
  89. /**
  90. * @return $this
  91. * @throws \Exception
  92. */
  93. protected function _afterLoad()
  94. {
  95. $this->mapAssociatedEntities('website', 'website_ids');
  96. $this->mapAssociatedEntities('customer_group', 'customer_group_ids');
  97. $this->setFlag('add_websites_to_result', false);
  98. return parent::_afterLoad();
  99. }
  100. /**
  101. * Filter collection by specified website, customer group, coupon code, date.
  102. * Filter collection to use only active rules.
  103. * Involved sorting by sort_order column.
  104. *
  105. * @param int $websiteId
  106. * @param int $customerGroupId
  107. * @param string $couponCode
  108. * @param string|null $now
  109. * @param Address $address allow extensions to further filter out rules based on quote address
  110. * @use $this->addWebsiteGroupDateFilter()
  111. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  112. * @return $this
  113. */
  114. public function setValidationFilter(
  115. $websiteId,
  116. $customerGroupId,
  117. $couponCode = '',
  118. $now = null,
  119. Address $address = null
  120. ) {
  121. if (!$this->getFlag('validation_filter')) {
  122. /* We need to overwrite joinLeft if coupon is applied */
  123. $this->getSelect()->reset();
  124. parent::_initSelect();
  125. $this->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now);
  126. $select = $this->getSelect();
  127. $connection = $this->getConnection();
  128. if (strlen($couponCode)) {
  129. $select->joinLeft(
  130. ['rule_coupons' => $this->getTable('salesrule_coupon')],
  131. $connection->quoteInto(
  132. 'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?',
  133. \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
  134. ),
  135. ['code']
  136. );
  137. $orWhereConditions = [
  138. $connection->quoteInto(
  139. 'main_table.coupon_type = ? ',
  140. \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
  141. ),
  142. $connection->quoteInto(
  143. '(main_table.coupon_type = ? AND rule_coupons.type = 0)',
  144. \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO
  145. ),
  146. $connection->quoteInto(
  147. '(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)',
  148. \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
  149. ),
  150. $connection->quoteInto(
  151. '(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)',
  152. \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
  153. ),
  154. ];
  155. $andWhereConditions = [
  156. $connection->quoteInto(
  157. 'rule_coupons.code = ?',
  158. $couponCode
  159. ),
  160. $connection->quoteInto(
  161. '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)',
  162. $this->_date->date()->format('Y-m-d')
  163. ),
  164. ];
  165. $orWhereCondition = implode(' OR ', $orWhereConditions);
  166. $andWhereCondition = implode(' AND ', $andWhereConditions);
  167. $select->where('(' . $orWhereCondition . ') AND ' . $andWhereCondition);
  168. } else {
  169. $this->addFieldToFilter(
  170. 'main_table.coupon_type',
  171. \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
  172. );
  173. }
  174. $this->setOrder('sort_order', self::SORT_ORDER_ASC);
  175. $this->setFlag('validation_filter', true);
  176. }
  177. return $this;
  178. }
  179. /**
  180. * Filter collection by website(s), customer group(s) and date.
  181. * Filter collection to only active rules.
  182. * Sorting is not involved
  183. *
  184. * @param int $websiteId
  185. * @param int $customerGroupId
  186. * @param string|null $now
  187. * @use $this->addWebsiteFilter()
  188. * @return $this
  189. */
  190. public function addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now = null)
  191. {
  192. if (!$this->getFlag('website_group_date_filter')) {
  193. if (is_null($now)) {
  194. $now = $this->_date->date()->format('Y-m-d');
  195. }
  196. $this->addWebsiteFilter($websiteId);
  197. $entityInfo = $this->_getAssociatedEntityInfo('customer_group');
  198. $connection = $this->getConnection();
  199. $this->getSelect()->joinInner(
  200. ['customer_group_ids' => $this->getTable($entityInfo['associations_table'])],
  201. $connection->quoteInto(
  202. 'main_table.' .
  203. $entityInfo['rule_id_field'] .
  204. ' = customer_group_ids.' .
  205. $entityInfo['rule_id_field'] .
  206. ' AND customer_group_ids.' .
  207. $entityInfo['entity_id_field'] .
  208. ' = ?',
  209. (int)$customerGroupId
  210. ),
  211. []
  212. );
  213. $this->getDateApplier()->applyDate($this->getSelect(), $now);
  214. $this->addIsActiveFilter();
  215. $this->setFlag('website_group_date_filter', true);
  216. }
  217. return $this;
  218. }
  219. /**
  220. * Add primary coupon to collection
  221. *
  222. * @return $this
  223. */
  224. public function _initSelect()
  225. {
  226. parent::_initSelect();
  227. $this->getSelect()->joinLeft(
  228. ['rule_coupons' => $this->getTable('salesrule_coupon')],
  229. 'main_table.rule_id = rule_coupons.rule_id AND rule_coupons.is_primary = 1',
  230. ['code']
  231. );
  232. return $this;
  233. }
  234. /**
  235. * Find product attribute in conditions or actions
  236. *
  237. * @param string $attributeCode
  238. * @return $this
  239. */
  240. public function addAttributeInConditionFilter($attributeCode)
  241. {
  242. $match = sprintf('%%%s%%', substr(serialize(['attribute' => $attributeCode]), 5, -1));
  243. $field = $this->_getMappedField('conditions_serialized');
  244. $cCond = $this->_getConditionSql($field, ['like' => $match]);
  245. $field = $this->_getMappedField('actions_serialized');
  246. $aCond = $this->_getConditionSql($field, ['like' => $match]);
  247. $this->getSelect()->where(sprintf('(%s OR %s)', $cCond, $aCond), null, \Magento\Framework\DB\Select::TYPE_CONDITION);
  248. return $this;
  249. }
  250. /**
  251. * Excludes price rules with generated specific coupon codes from collection
  252. *
  253. * @return $this
  254. */
  255. public function addAllowedSalesRulesFilter()
  256. {
  257. $this->addFieldToFilter('main_table.use_auto_generation', ['neq' => 1]);
  258. return $this;
  259. }
  260. /**
  261. * Limit rules collection by specific customer group
  262. *
  263. * @param int $customerGroupId
  264. * @return $this
  265. */
  266. public function addCustomerGroupFilter($customerGroupId)
  267. {
  268. $entityInfo = $this->_getAssociatedEntityInfo('customer_group');
  269. if (!$this->getFlag('is_customer_group_joined')) {
  270. $this->setFlag('is_customer_group_joined', true);
  271. $this->getSelect()->join(
  272. ['customer_group' => $this->getTable($entityInfo['associations_table'])],
  273. $this->getConnection()
  274. ->quoteInto('customer_group.' . $entityInfo['entity_id_field'] . ' = ?', $customerGroupId)
  275. . ' AND main_table.' . $entityInfo['rule_id_field'] . ' = customer_group.'
  276. . $entityInfo['rule_id_field'],
  277. []
  278. );
  279. }
  280. return $this;
  281. }
  282. /**
  283. * @return array
  284. * @deprecated
  285. */
  286. private function getAssociatedEntitiesMap()
  287. {
  288. if (!$this->_associatedEntitiesMap) {
  289. $this->_associatedEntitiesMap = \Magento\Framework\App\ObjectManager::getInstance()
  290. ->get(\Magento\SalesRule\Model\ResourceModel\Rule\AssociatedEntityMap::class)
  291. ->getData();
  292. }
  293. return $this->_associatedEntitiesMap;
  294. }
  295. /**
  296. * @return DateApplier
  297. * @deprecated
  298. */
  299. private function getDateApplier()
  300. {
  301. if (null === $this->dateApplier) {
  302. $this->dateApplier = \Magento\Framework\App\ObjectManager::getInstance()
  303. ->get(\Magento\SalesRule\Model\ResourceModel\Rule\DateApplier::class);
  304. }
  305. return $this->dateApplier;
  306. }
  307. }