Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
discountcache.php
1<?php
2
4
5
13
14final class DiscountCache
15{
17 private static $instance;
18 private $discounts = array();
19 private $discountIds = array();
20 private $discountModules = array();
21 private $discountEntities = array();
22
23 private function __construct()
24 {}
25
26 private function __clone()
27 {}
28
33 public static function getInstance()
34 {
35 if (!isset(self::$instance))
36 {
37 self::$instance = new static;
38 }
39
40 return self::$instance;
41 }
42
43 public function getDiscountIds(array $userGroups)
44 {
45 Collection::normalizeArrayValuesByInt($userGroups);
46 $cacheKey = md5('G' . implode('|', $userGroups));
47
48 if(!isset($this->discountIds[$cacheKey]))
49 {
50 $this->discountIds[$cacheKey] = array();
51
52 $groupDiscountIterator = DiscountGroupTable::getList(array(
53 'select' => array('DISCOUNT_ID'),
54 'filter' => array(
55 '@GROUP_ID' => $userGroups,
56 '=ACTIVE' => 'Y',
57 ),
58 'order' => array('DISCOUNT_ID' => 'ASC')
59 ));
60 while ($groupDiscount = $groupDiscountIterator->fetch())
61 {
62 $groupDiscount['DISCOUNT_ID'] = (int)$groupDiscount['DISCOUNT_ID'];
63 if ($groupDiscount['DISCOUNT_ID'] > 0)
64 {
65 $this->discountIds[$cacheKey][$groupDiscount['DISCOUNT_ID']] = $groupDiscount['DISCOUNT_ID'];
66 }
67 }
68
69 }
70
71 return $this->discountIds[$cacheKey];
72 }
73
74 public function getDiscountModules(array $discountIds)
75 {
76 if(empty($discountIds))
77 {
78 return array();
79 }
80
81 Collection::normalizeArrayValuesByInt($discountIds);
82
83 $discountIds = array_combine($discountIds, $discountIds);
84 $needToLoad = array_diff($discountIds, array_keys($this->discountModules));
85
86 foreach(DiscountModuleTable::getByDiscount($needToLoad) as $discountId => $modules)
87 {
88 $this->discountModules[$discountId] = $modules;
89 }
90
91 return array_intersect_key($this->discountModules, $discountIds);
92 }
93
94 public function getDiscountEntities(array $discountIds)
95 {
96 if(empty($discountIds))
97 {
98 return array();
99 }
100 Collection::normalizeArrayValuesByInt($discountIds);
101 if(empty($discountIds))
102 {
103 return array();
104 }
105
106 $cacheKey = 'D' . implode('_', $discountIds);
107 if (!isset($this->discountEntities[$cacheKey]))
108 {
109 $needToLoad = $discountIds;
110 $resultEntities = array();
111
112 foreach ($this->discountEntities as $data)
113 {
114 list($loadedDiscountIds, $entities) = $data;
115
116 $needToLoadPortion = array_diff($needToLoad, $loadedDiscountIds);
117
118 if (count($needToLoad) > count($needToLoadPortion))
119 {
120 $resultEntities = array_merge($resultEntities, $entities);
121 }
122
123 $needToLoad = $needToLoadPortion;
124 if (empty($needToLoad))
125 {
126 break;
127 }
128 }
129
130 if (!empty($needToLoad))
131 self::recursiveMerge($resultEntities, DiscountEntitiesTable::getByDiscount($needToLoad));
132
133 $this->discountEntities[$cacheKey] = array($discountIds, $resultEntities);
134 }
135 return $this->discountEntities[$cacheKey][1];
136 }
137
138 public function getDiscounts(array $discountIds, array $executeModuleFilter, $siteId, array $couponList = array())
139 {
140 $cacheKey = 'D'.implode('_', $discountIds).'-S'.$siteId;
141 if(!empty($couponList))
142 {
143 $cacheKey .= '-C'. implode('_', array_keys($couponList));
144 }
145
146 $cacheKey .= '-MF'.implode('_', $executeModuleFilter);
147 $cacheKey = md5($cacheKey);
148
149 if(!isset($this->discounts[$cacheKey]))
150 {
151 $currentList = array();
152
153 \CTimeZone::Disable();
154 $currentDatetime = new DateTime();
155 $discountSelect = array(
156 'ID', 'PRIORITY', 'SORT', 'LAST_DISCOUNT', 'LAST_LEVEL_DISCOUNT', 'UNPACK', 'APPLICATION', 'USE_COUPONS', 'EXECUTE_MODULE',
157 'NAME', 'CONDITIONS_LIST', 'ACTIONS_LIST', 'ACTIVE_FROM', 'ACTIVE_TO', 'PREDICTIONS_LIST', 'PREDICTIONS_APP',
158 'PREDICTION_TEXT', 'PRESET_ID', 'CURRENCY', 'LID', 'SHORT_DESCRIPTION', 'SHORT_DESCRIPTION_STRUCTURE',
159 );
160 $discountFilter = array(
161 '@ID' => $discountIds,
162 '=LID' => $siteId,
163 '@EXECUTE_MODULE' => $executeModuleFilter,
164 array(
165 'LOGIC' => 'OR',
166 '=ACTIVE_FROM' => null,
167 '<=ACTIVE_FROM' => $currentDatetime
168 ),
169 array(
170 'LOGIC' => 'OR',
171 '=ACTIVE_TO' => null,
172 '>=ACTIVE_TO' => $currentDatetime
173 )
174 );
175
176 $couponsDiscount = array();
177 if (!empty($couponList))
178 {
179 $iterator = DiscountCouponTable::getList(array(
180 'select' => array('DISCOUNT_ID', 'COUPON'),
181 'filter' => array('@DISCOUNT_ID' => $discountIds,'@COUPON' => array_keys($couponList)),
182 'order' => array('DISCOUNT_ID' => 'ASC')
183 ));
184 while ($row = $iterator->fetch())
185 {
186 $id = (int)$row['DISCOUNT_ID'];
187 if (isset($couponsDiscount[$id]))
188 continue;
189 $couponsDiscount[$id] = $row['COUPON'];
190 }
191 unset($id, $row, $iterator);
192 }
193
194 if (empty($couponsDiscount))
195 {
196 $discountFilter['=USE_COUPONS'] = 'N';
197 }
198 else
199 {
200 $discountFilter[] = array(
201 'LOGIC' => 'OR',
202 '=USE_COUPONS' => 'N',
203 array(
204 '=USE_COUPONS' => 'Y',
205 '@ID' => array_keys($couponsDiscount)
206 )
207 );
208 }
209
210 //todo remove order. It's unnecessary because we rearrange discounts after by benefit for client.
211 $discountIterator = DiscountTable::getList(array(
212 'select' => $discountSelect,
213 'filter' => $discountFilter,
214 'order' => array('PRIORITY' => 'DESC', 'SORT' => 'ASC', 'ID' => 'ASC')
215 ));
216
217 while($discount = $discountIterator->fetch())
218 {
219 $discount['ID'] = (int)$discount['ID'];
220 if ($discount['USE_COUPONS'] == 'Y')
221 $discount['COUPON'] = $couponList[$couponsDiscount[$discount['ID']]];
222 $discount['CONDITIONS'] = $discount['CONDITIONS_LIST'];
223 $discount['ACTIONS'] = $discount['ACTIONS_LIST'];
224 $discount['PREDICTIONS'] = $discount['PREDICTIONS_LIST'];
225 $discount['MODULE_ID'] = 'sale';
226 $discount['MODULES'] = array();
227 unset($discount['ACTIONS_LIST'], $discount['CONDITIONS_LIST'], $discount['PREDICTIONS_LIST']);
228 $currentList[$discount['ID']] = $discount;
229 }
230 unset($discount, $discountIterator);
231
232 \CTimeZone::Enable();
233
234 if (!empty($currentList))
235 {
236 $discountModules = static::getDiscountModules(array_keys($currentList));
237 foreach ($discountModules as $id => $modules)
238 $currentList[$id]['MODULES'] = $modules;
239 unset($id, $modules, $discountModules);
240 }
241
242 $this->discounts[$cacheKey] = $currentList;
243 }
244
245 return $this->discounts[$cacheKey];
246 }
247
255 private static function recursiveMerge(&$dest, $src)
256 {
257 if (!is_array($dest) || !is_array($src))
258 return;
259 if (empty($dest))
260 {
261 $dest = $src;
262 return;
263 }
264 foreach ($src as $key => $value)
265 {
266 if (!isset($dest[$key]))
267 {
268 $dest[$key] = $value;
269 continue;
270 }
271 if (is_array($dest[$key]))
272 self::recursiveMerge($dest[$key], $value);
273 }
274 unset($value, $key);
275 }
276}
getDiscounts(array $discountIds, array $executeModuleFilter, $siteId, array $couponList=array())
static getByDiscount($discountList, $filter=array(), $groupModule=true)
static getByDiscount($discountList, $filter=array())