Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
restrictionmanager.php
1<?
3
5use Bitrix\Main\Entity\AddResult;
6use Bitrix\Main\Entity\UpdateResult;
18
20{
21 protected static $classNames;
22 protected static $cachedFields = array();
23
24 const ON_STARTUP_SERVICE_RESTRICTIONS_EVENT_NAME = "onStartupServiceRestrictions";
25
26 const MODE_CLIENT = 1;
27 const MODE_MANAGER = 2;
28
29 const SEVERITY_NONE = 0;
30 const SEVERITY_SOFT = 1;
31 const SEVERITY_STRICT = 2;
32
37
38 protected static function init()
39 {
40 if(static::$classNames != null)
41 {
42 return;
43 }
44
45 $classes = static::getBuildInRestrictions();
46
47 Loader::registerAutoLoadClasses('sale', $classes);
48
53 foreach ($classes as $class => $path)
54 {
55 if (!$class::isAvailable())
56 {
57 unset($classes[$class]);
58 }
59 }
60
61 $event = new Event('sale', static::getEventName());
62 $event->send();
63 $resultList = $event->getResults();
64
65 if (is_array($resultList) && !empty($resultList))
66 {
67 $customClasses = array();
68
69 foreach ($resultList as $eventResult)
70 {
72 if ($eventResult->getType() != EventResult::SUCCESS)
73 throw new SystemException("Can't add custom restriction class successfully");
74
75 $params = $eventResult->getParameters();
76
77 if(!empty($params) && is_array($params))
78 $customClasses = array_merge($customClasses, $params);
79 }
80
81 if(!empty($customClasses))
82 {
83 Loader::registerAutoLoadClasses(null, $customClasses);
84 $classes = array_merge($customClasses, $classes);
85 }
86 }
87
88 static::$classNames = array_keys($classes);
89 }
90
95 public static function getEventName()
96 {
98 }
99
104 public static function getClassesList()
105 {
106 if (static::$classNames === null)
107 self::init();
108
109 return static::$classNames;
110 }
111
119 public static function checkService($serviceId, Entity $entity, $mode = self::MODE_CLIENT)
120 {
121 if(intval($serviceId) <= 0)
122 return self::SEVERITY_NONE;
123
124 self::init();
125 $result = self::SEVERITY_NONE;
126 $restrictions = static::getRestrictionsList($serviceId);
127
128 foreach($restrictions as $rstrParams)
129 {
130 if(!$rstrParams['PARAMS'])
131 $rstrParams['PARAMS'] = array();
132
133 $res = $rstrParams['CLASS_NAME']::checkByEntity($entity, $rstrParams['PARAMS'], $mode, $serviceId);
134
135 if($res == self::SEVERITY_STRICT)
136 return $res;
137
138 if($res == self::SEVERITY_SOFT && $result != self::SEVERITY_SOFT)
139 $result = self::SEVERITY_SOFT;
140 }
141
142 return $result;
143 }
144
149 protected static function getServiceType()
150 {
151 throw new NotImplementedException;
152 }
153
158 public static function getRestrictionsList($serviceId)
159 {
160 if ((int)$serviceId <= 0)
161 return array();
162
163 $serviceType = static::getServiceType();
164
165 if (!isset(static::$cachedFields[$serviceType]))
166 {
167 $result = array();
168 $dbRes = ServiceRestrictionTable::getList(array(
169 'filter' => array(
170 '=SERVICE_TYPE' => $serviceType,
171 ),
172 'order' => array('SORT' => 'ASC'),
173 ));
174
175 while($restriction = $dbRes->fetch())
176 {
177 if (!isset($result[$restriction['SERVICE_ID']]))
178 $result[$restriction['SERVICE_ID']] = array();
179
180 $result[$restriction['SERVICE_ID']][$restriction["ID"]] = $restriction;
181 }
182
183 static::$cachedFields[$serviceType] = $result;
184 }
185
186 if (!isset(static::$cachedFields[$serviceType][$serviceId]))
187 return array();
188
189 return static::$cachedFields[$serviceType][$serviceId];
190 }
191
196 public static function getSitesByServiceId($id)
197 {
198 if($id <= 0)
199 return array();
200
201 $result = array();
202
203 foreach(static::getRestrictionsList($id) as $fields)
204 {
205 if($fields['CLASS_NAME'] == '\Bitrix\Sale\Delivery\Restrictions\BySite')
206 {
207 if(!empty($fields["PARAMS"]["SITE_ID"]))
208 {
209 if(is_array($fields["PARAMS"]["SITE_ID"]))
210 $result = $fields["PARAMS"]["SITE_ID"];
211 else
212 $result = array($fields["PARAMS"]["SITE_ID"]);
213 }
214
215 break;
216 }
217 }
218
219 return $result;
220 }
221
228 public static function prepareData(array $servicesIds, array $fields = array())
229 {
230 if(empty($servicesIds))
231 return;
232
233 $serviceType = static::getServiceType();
234 $cachedServices =
235 isset(static::$cachedFields[$serviceType]) && is_array(static::$cachedFields[$serviceType])
236 ? array_keys(static::$cachedFields[$serviceType])
237 : []
238 ;
239 $ids = array_diff($servicesIds, $cachedServices);
240 $idsForDb = array_diff($ids, array_keys($fields));
241
242 if(!empty($idsForDb))
243 {
244 $dbRes = ServiceRestrictionTable::getList(array(
245 'filter' => array(
246 '=SERVICE_ID' => $idsForDb,
247 '=SERVICE_TYPE' => $serviceType,
248 ),
249 'order' => array('SORT' =>'ASC'),
250 ));
251
252 while($restriction = $dbRes->fetch())
253 self::setCache($restriction["SERVICE_ID"], $serviceType, $restriction);
254 }
255
256 foreach($fields as $serviceId => $serviceRestrictions)
257 {
258 if(is_array($serviceRestrictions))
259 {
260 foreach($serviceRestrictions as $restrId => $restrFields)
261 self::setCache($serviceId, $serviceType, $restrFields);
262 }
263 }
264
265 foreach($ids as $serviceId)
266 self::setCache($serviceId, $serviceType);
267
269 foreach(static::getClassesList() as $className)
270 $className::prepareData($ids);
271 }
272
279 protected static function setCache($serviceId, $serviceType, array $fields = array())
280 {
281 if(intval($serviceId) <= 0)
282 throw new ArgumentNullException('serviceId');
283
284 if(!isset(static::$cachedFields[$serviceType]))
285 static::$cachedFields[$serviceType] = array();
286
287 if(!isset(static::$cachedFields[$serviceType][$serviceId]))
288 static::$cachedFields[$serviceType][$serviceId] = array();
289
290 if(!empty($fields))
291 static::$cachedFields[$serviceType][$serviceId][$fields["ID"]] = $fields;
292 }
293
300 protected static function getCache($serviceId, $serviceType)
301 {
302 $result = array();
303
304 if(intval($serviceId) > 0)
305 {
306 if(isset(static::$cachedFields[$serviceType][$serviceId]))
307 $result = static::$cachedFields[$serviceType][$serviceId];
308 }
309 else
310 {
311 if(isset(static::$cachedFields[$serviceType]))
312 $result = static::$cachedFields[$serviceType];
313 }
314
315 return $result;
316 }
317
322 protected static function getBuildInRestrictions()
323 {
324 throw new NotImplementedException;
325 }
326
332 public static function getList(array $params)
333 {
334 if (!$params['filter'])
335 $params['filter'] = array();
336
337 $params['filter']['SERVICE_TYPE'] = static::getServiceType();
338
339 return ServiceRestrictionTable::getList($params);
340 }
341
346 public static function getById($id)
347 {
348 return ServiceRestrictionTable::getById($id);
349 }
350
356 protected static function getRestriction(string $restrictionCode): ?string
357 {
358 foreach (static::getClassesList() as $className)
359 {
360 if (
361 self::isRestrictionClassname($className)
362 && $className::isMyCode($restrictionCode)
363 )
364 {
365 return $className;
366 }
367 }
368
369 return null;
370 }
371
372 private static function isRestrictionClassname(string $className): bool
373 {
374 try
375 {
376 $restrictionClass = new \ReflectionClass($className);
377 }
378 catch (\ReflectionException $e)
379 {
380 return false;
381 }
382
383 return $restrictionClass->isSubclassOf(Restriction::class);
384 }
385
394 public static function applyRestriction(int $serviceId, RestrictionInfo $restrictionInfo): Result
395 {
396 $result = new Result();
397
398 $restriction = static::getRestriction($restrictionInfo->getType());
399
400 $reflectionClass = new \ReflectionClass(static::class);
401 $methodPath = $reflectionClass->getName() . "::applyRestriction";
402
403 if (!$restriction)
404 {
405 Logger::addError("[{$methodPath}] restriction '{$restrictionInfo->getType()}' not found.");
406
407 $publicErrorMessage = Loc::getMessage('SALE_BASE_RSTR_MANAGER_FIND_RSTR_ERROR', [
408 '#RSTR_CLASSNAME#' => htmlspecialcharsbx($restrictionInfo->getType()),
409 ]);
410 $result->addError(new \Bitrix\Main\Error($publicErrorMessage));
411
412 return $result;
413 }
414
419 $restrictionApplyResult = $restriction::save([
420 'SERVICE_ID' => $serviceId,
421 'SERVICE_TYPE' => static::getServiceType(),
422 'PARAMS' => $restrictionInfo->getOptions(),
423 ]);
424
425 if (!$restrictionApplyResult->isSuccess())
426 {
427 foreach ($restrictionApplyResult->getErrors() as $error)
428 {
429 Logger::addError("[{$methodPath}] " . $error->getMessage());
430 }
431
432 $publicErrorMessage = $restriction::getOnApplyErrorMessage();
433 $result->addError(new Error($publicErrorMessage));
434 }
435
436 return $result;
437 }
438
446 public static function setupDefaultRestrictions(RestrictableService $service): Result
447 {
448 $result = new Result();
449
450 $startupRestrictions = $service->getStartupRestrictions();
451
452 (new Event(
453 'sale',
454 static::ON_STARTUP_SERVICE_RESTRICTIONS_EVENT_NAME,
455 [
456 'STARTUP_RESTRICTIONS_COLLECTION' => $startupRestrictions,
457 'SERVICE_ID' => $service->getServiceId(),
458 ]
459 ))->send();
460
461 self::clearAlreadyUsedByServiceRestrictions($service->getServiceId(), $startupRestrictions);
462
464 foreach ($startupRestrictions as $restrictionInfo)
465 {
466 $applyResult = static::applyRestriction($service->getServiceId(), $restrictionInfo);
467 $result->addErrors($applyResult->getErrors());
468 }
469
470 return $result;
471 }
472
473 private static function clearAlreadyUsedByServiceRestrictions(int $serviceId, RestrictionInfoCollection $collection): void
474 {
475 $serviceRestrictions = array_column(static::getRestrictionsList($serviceId), 'CLASS_NAME');
476
477 foreach ($serviceRestrictions as $restrictionClassName)
478 {
479 if (self::isRestrictionClassname($restrictionClassName))
480 {
482 $collection->delete($restrictionClassName::getCode());
483 }
484 }
485 }
486}
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static addError($error)
Definition logger.php:26
static checkService($serviceId, Entity $entity, $mode=self::MODE_CLIENT)
static getRestriction(string $restrictionCode)
static setCache($serviceId, $serviceType, array $fields=array())