1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
schedulerservice.php
См. документацию.
1<?php
2
5
7{
13 public static function getDelayMinLimit($withType = false)
14 {
15 $result = (int) \Bitrix\Main\Config\Option::get('bizproc', 'delay_min_limit', 0);
16 if (!$withType)
17 return $result;
18 $type = 's';
19 if ($result > 0)
20 {
21 if ($result % (3600 * 24) == 0)
22 {
23 $result = $result / (3600 * 24);
24 $type = 'd';
25 }
26 elseif ($result % 3600 == 0)
27 {
28 $result = $result / 3600;
29 $type = 'h';
30 }
31 elseif ($result % 60 == 0)
32 {
33 $result = $result / 60;
34 $type = 'm';
35 }
36 }
37 return array($result, $type);
38 }
39
40 public static function setDelayMinLimit($limit, $type = 's')
41 {
42 $limit = (int)$limit;
43 switch ($type)
44 {
45 case 'd':
46 $limit *= 3600 * 24;
47 break;
48 case 'h':
49 $limit *= 3600;
50 break;
51 case 'm':
52 $limit *= 60;
53 break;
54 default:
55 break;
56 }
57 \Bitrix\Main\Config\Option::set('bizproc', 'delay_min_limit', $limit);
58 }
59
60 public function subscribeOnTime($workflowId, $eventName, $expiresAt)
61 {
62 $workflowId = preg_replace('#[^a-z0-9.]#i', '', $workflowId);
63 $eventName = preg_replace('#[^a-z0-9._-]#i', '', $eventName);
64
65 $minLimit = static::getDelayMinLimit(false);
66 if ($minLimit > 0)
67 {
68 $minExpiresAt = time() + $minLimit;
69 if ($minExpiresAt > $expiresAt)
70 {
71 $expiresAt = $minExpiresAt;
72 }
73 }
74
75 return self::addAgent($workflowId, $eventName, $expiresAt);
76 }
77
78 private static function addAgent($workflowId, $eventName, $expiresAt, $counter = 0)
79 {
80 $params = '[\'SchedulerService\' => \'OnAgent\', \'Counter\' => '.((int) $counter).']';
81 $name = "CBPSchedulerService::OnAgent('{$workflowId}', '{$eventName}', {$params});";
82 return self::addAgentInternal($name, $expiresAt);
83 }
84
85 public function unSubscribeOnTime($id)
86 {
87 CAgent::Delete($id);
88 }
89
90 public static function onAgent($workflowId, $eventName, $eventParameters = array())
91 {
92 try
93 {
94 CBPRuntime::SendExternalEvent($workflowId, $eventName, $eventParameters);
95 }
96 catch (Exception $e)
97 {
98 if ($e->getCode() === \CBPRuntime::EXCEPTION_CODE_INSTANCE_LOCKED)
99 {
100 $counter = isset($eventParameters['Counter']) ? (int) $eventParameters['Counter'] : 0;
101 $expiresAt = self::getExpiresTimeByCounter($counter);
102 if ($expiresAt)
103 {
104 ++$counter;
105 self::addAgent($workflowId, $eventName, $expiresAt, $counter);
106 }
107 }
108 elseif (
109 $e->getCode() !== \CBPRuntime::EXCEPTION_CODE_INSTANCE_NOT_FOUND
110 && $e->getCode() !== \CBPRuntime::EXCEPTION_CODE_INSTANCE_TARIFF_LIMIT_EXCEED
111 )
112 {
113 self::logUnknownException($e);
114 }
115 }
116 }
117
118 public function subscribeOnEvent($workflowId, $eventHandlerName, $eventModule, $eventName, $entityId = null): ?int
119 {
120 $resultId = null;
121 $entityKey = null;
122 if (is_array($entityId))
123 {
124 foreach ($entityId as $entityKey => $entityId)
125 break;
126 }
127 elseif ($entityId !== null)
128 {
129 $entityKey = 0;
130 }
131
132 if (is_array($entityId))
133 {
134 $entityId = current(\CBPHelper::makeArrayFlat($entityId));
135 }
136
137 if (!SchedulerEventTable::isSubscribed($workflowId, $eventHandlerName, $eventModule, $eventName, $entityId))
138 {
139 $result = SchedulerEventTable::add(array(
140 'WORKFLOW_ID' => (string)$workflowId,
141 'HANDLER' => (string)$eventHandlerName,
142 'EVENT_MODULE' => (string)$eventModule,
143 'EVENT_TYPE' => (string)$eventName,
144 'ENTITY_ID' => (string)$entityId
145 ));
146 $resultId = (int)$result->getId();
147 }
148
150 $eventModule,
151 $eventName,
152 'bizproc',
153 'CBPSchedulerService',
154 'sendEvents',
155 100,
156 '',
157 array($eventModule, $eventName, $entityKey)
158 );
159
160 return $resultId;
161 }
162
163 public function unSubscribeOnEvent($workflowId, $eventHandlerName, $eventModule, $eventName, $entityId = null)
164 {
165 // Clean old-style registry entry.
167 $eventModule,
168 $eventName,
169 "bizproc",
170 "CBPSchedulerService",
171 "OnEvent",
172 "",
173 array($workflowId, $eventHandlerName, array('SchedulerService' => 'OnEvent', 'EntityId' => $entityId))
174 );
175
176 $entityKey = null;
177 if (is_array($entityId))
178 {
179 foreach ($entityId as $entityKey => $entityId)
180 break;
181 }
182 elseif ($entityId !== null)
183 {
184 $entityKey = 0;
185 }
186
187 if (is_array($entityId))
188 {
189 $entityId = current(\CBPHelper::makeArrayFlat($entityId));
190 }
191
192 SchedulerEventTable::deleteBySubscription($workflowId, $eventHandlerName, $eventModule, $eventName, $entityId);
193
194 if (!SchedulerEventTable::hasSubscriptions($eventModule, $eventName))
195 {
197 $eventModule,
198 $eventName,
199 'bizproc',
200 'CBPSchedulerService',
201 'sendEvents',
202 '',
203 array($eventModule, $eventName, $entityKey)
204 );
205 }
206 }
207
208 public function unSubscribeByEventId(int $eventId, $entityKey = null)
209 {
210 $event = SchedulerEventTable::getList([
211 'select' => ['WORKFLOW_ID', 'HANDLER','EVENT_MODULE', 'EVENT_TYPE', 'ENTITY_ID'],
212 'filter' => ['=ID' => $eventId]
213 ])->fetch();
214
215 if ($event)
216 {
217 $this->unSubscribeOnEvent(
218 $event['WORKFLOW_ID'],
219 $event['HANDLER'],
220 $event['EVENT_MODULE'],
221 $event['EVENT_TYPE'],
222 $entityKey ? [$entityKey => $event['ENTITY_ID']] : $event['ENTITY_ID']
223 );
224 }
225 }
226
233 public static function onEvent($workflowId, $eventName, $arEventParameters = array())
234 {
235 $num = func_num_args();
236 if ($num > 3)
237 {
238 for ($i = 3; $i < $num; $i++)
239 $arEventParameters[] = func_get_arg($i);
240 }
241
242 if (is_array($arEventParameters["EntityId"]))
243 {
244 foreach ($arEventParameters["EntityId"] as $key => $value)
245 {
246 if (!isset($arEventParameters[0][$key]) || $arEventParameters[0][$key] != $value)
247 return;
248 }
249 }
250 elseif ($arEventParameters["EntityId"] != null && $arEventParameters["EntityId"] != $arEventParameters[0])
251 return;
252
253 global $BX_MODULE_EVENT_LAST;
254 $lastEvent = $BX_MODULE_EVENT_LAST;
255
256 try
257 {
258 CBPRuntime::SendExternalEvent($workflowId, $eventName, $arEventParameters);
259 }
260 catch (Exception $e)
261 {
262 //Clean-up records if instance not found
263 if (
264 $e->getCode() === \CBPRuntime::EXCEPTION_CODE_INSTANCE_NOT_FOUND
265 && $lastEvent['TO_MODULE_ID'] == 'bizproc'
266 && $lastEvent['TO_CLASS'] == 'CBPSchedulerService'
267 && $lastEvent['TO_METHOD'] == 'OnEvent'
268 && is_array($lastEvent['TO_METHOD_ARG'])
269 && $lastEvent['TO_METHOD_ARG'][0] == $workflowId
270 )
271 {
273 $lastEvent['FROM_MODULE_ID'],
274 $lastEvent['MESSAGE_ID'],
275 "bizproc",
276 "CBPSchedulerService",
277 "OnEvent",
278 "",
279 $lastEvent['TO_METHOD_ARG']
280 );
281 }
282 elseif ($e->getCode() !== \CBPRuntime::EXCEPTION_CODE_INSTANCE_NOT_FOUND)
283 {
284 self::logUnknownException($e);
285 }
286 }
287 }
288
289 public static function sendEvents($eventModule, $eventName, $entityKey)
290 {
291 if ($eventModule === 'bizproc' && $eventName === 'OnWorkflowComplete' && $entityKey === null)
292 {
293 //delete invalid subscription
295 $eventModule,
296 $eventName,
297 'bizproc',
298 'CBPSchedulerService',
299 'sendEvents',
300 '',
301 array($eventModule, $eventName, $entityKey)
302 );
303
304 return false;
305 }
306
307 $eventParameters = array(
308 'SchedulerService' => 'OnEvent', // compatibility
309 'eventModule' => $eventModule,
310 'eventName' => $eventName
311 );
312
313 $num = func_num_args();
314 if ($num > 3)
315 {
316 for ($i = 3; $i < $num; $i++)
317 $eventParameters[] = func_get_arg($i);
318 }
319
320 $filter = array(
321 '=EVENT_MODULE' => $eventModule,
322 '=EVENT_TYPE' => $eventName
323 );
324
325 $entityId = null;
326 if ($entityKey === 0 && isset($eventParameters[0]))
327 $entityId = (string)$eventParameters[0];
328 elseif ($entityKey !== null && isset($eventParameters[0][$entityKey]))
329 $entityId = (string)$eventParameters[0][$entityKey];
330
331 if ($entityId !== null)
332 $filter['=ENTITY_ID'] = $entityId;
333
334 $iterator = SchedulerEventTable::getList(array(
335 'filter' => $filter
336 ));
337
338 while ($event = $iterator->fetch())
339 {
340 $event['EVENT_PARAMETERS'] = $eventParameters;
341 self::sendEventToWorkflow($event);
342 }
343 }
344
345 public static function repeatEvent($eventId, $counter = 0)
346 {
347 $iterator = SchedulerEventTable::getById($eventId);
348 $event = $iterator->fetch();
349
350 if ($event && Loader::includeModule($event['EVENT_MODULE']))
351 {
352 self::sendEventToWorkflow($event, $counter);
353 }
354 }
355
356 private static function sendEventToWorkflow($event, $counter = 0)
357 {
358 try
359 {
360 CBPRuntime::SendExternalEvent($event['WORKFLOW_ID'], $event['HANDLER'], $event['EVENT_PARAMETERS']);
361 }
362 catch (Exception $e)
363 {
364 if ($e->getCode() === \CBPRuntime::EXCEPTION_CODE_INSTANCE_NOT_FOUND)
365 {
366 SchedulerEventTable::delete($event['ID']);
367 }
368 elseif ($e->getCode() === \CBPRuntime::EXCEPTION_CODE_INSTANCE_LOCKED)
369 {
370 self::addEventRepeatAgent($event, $counter);
371 }
372 else if ($e->getCode() === \CBPRuntime::EXCEPTION_CODE_INSTANCE_TARIFF_LIMIT_EXCEED)
373 {
374 throw $e;
375 }
376 else
377 {
378 self::logUnknownException($e);
379 }
380 }
381 }
382
383 private static function filterEventParameters(array $parameters)
384 {
385 $filtered = [];
386 foreach ($parameters as $key => $parameter)
387 {
388 if (is_scalar($parameter))
389 {
390 $filtered[$key] = $parameter;
391 }
392 elseif (is_array($parameter))
393 {
394 $filtered[$key] = self::filterEventParameters($parameter);
395 }
396 }
397 return $filtered;
398 }
399
400 private static function addEventRepeatAgent($event, $counter = 0)
401 {
402 $expiresAt = self::getExpiresTimeByCounter($counter);
403
404 if ($expiresAt)
405 {
406 if ($counter === 0)
407 {
408 $filteredParameters = self::filterEventParameters($event['EVENT_PARAMETERS']);
409 SchedulerEventTable::update($event['ID'], ['EVENT_PARAMETERS' => $filteredParameters]);
410 }
411
412 ++$counter;
413 $eventId = $event['ID'];
414 $name = "CBPSchedulerService::repeatEvent({$eventId}, {$counter});";
415 self::addAgentInternal($name, $expiresAt);
416 }
417 }
418
419 private static function addAgentInternal($name, $expiresAt)
420 {
422 $result = CAgent::AddAgent(
423 $name,
424 "bizproc",
425 "N",
426 10,
427 "",
428 "Y",
429 date($GLOBALS["DB"]->DateFormatToPHP(FORMAT_DATETIME), $expiresAt)
430 );
432 return $result;
433 }
434
435 private static function getExpiresTimeByCounter($counter = 0)
436 {
437 if ($counter >= 0 && $counter < 3)
438 {
439 $minute = 60;
440 return time() + [0 => (1 * $minute), 1 => (5 * $minute), 2 => (10 * $minute)][$counter];
441 }
442 return false;
443 }
444
445 private static function logUnknownException(Throwable $exception): void
446 {
447 \Bitrix\Main\Application::getInstance()->getExceptionHandler()->writeToLog($exception);
448 }
449}
$type
Определения options.php:106
static set($moduleId, $name, $value="", $siteId="")
Определения option.php:261
Определения loader.php:13
unSubscribeOnEvent($workflowId, $eventHandlerName, $eventModule, $eventName, $entityId=null)
Определения schedulerservice.php:163
subscribeOnEvent($workflowId, $eventHandlerName, $eventModule, $eventName, $entityId=null)
Определения schedulerservice.php:118
subscribeOnTime($workflowId, $eventName, $expiresAt)
Определения schedulerservice.php:60
static repeatEvent($eventId, $counter=0)
Определения schedulerservice.php:345
unSubscribeByEventId(int $eventId, $entityKey=null)
Определения schedulerservice.php:208
static onEvent($workflowId, $eventName, $arEventParameters=array())
Определения schedulerservice.php:233
static getDelayMinLimit($withType=false)
Определения schedulerservice.php:13
static onAgent($workflowId, $eventName, $eventParameters=array())
Определения schedulerservice.php:90
unSubscribeOnTime($id)
Определения schedulerservice.php:85
static setDelayMinLimit($limit, $type='s')
Определения schedulerservice.php:40
static sendEvents($eventModule, $eventName, $entityKey)
Определения schedulerservice.php:289
static Disable()
Определения time.php:31
static Enable()
Определения time.php:36
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$filter
Определения iblock_catalog_list.php:54
const FORMAT_DATETIME
Определения include.php:64
RegisterModuleDependences($FROM_MODULE_ID, $MESSAGE_ID, $TO_MODULE_ID, $TO_CLASS="", $TO_METHOD="", $SORT=100, $TO_PATH="", $TO_METHOD_ARG=[])
Определения tools.php:5295
UnRegisterModuleDependences($FROM_MODULE_ID, $MESSAGE_ID, $TO_MODULE_ID, $TO_CLASS="", $TO_METHOD="", $TO_PATH="", $TO_METHOD_ARG=[])
Определения tools.php:5289
$name
Определения menu_edit.php:35
$entityId
Определения payment.php:4
$counter
Определения options.php:5
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$GLOBALS['_____370096793']
Определения update_client.php:1
$iterator
Определения yandex_run.php:610