Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
dateconverter.php
1<?php
2namespace Bitrix\Main\Text;
3
5
7{
17 public static function decode($text, $limit = 0)
18 {
19 $result = Array();
20 if ($text == '')
21 {
22 return $result;
23 }
24
25 $metrics = Array();
26 $date = new \Bitrix\Main\Type\DateTime();
27
28 if ($limit > 0 && mb_strlen($text) > $limit)
29 {
30 $text = mb_substr($text, 0, $limit);
31 }
32
33 $originalText = $text;
34 $text = mb_strtolower($text);
35
36 $workTimeStart = explode('.', \Bitrix\Main\Config\Option::get('calendar', 'work_time_start', '9'));
37 $timeOfStartDate = str_pad(intval($workTimeStart[0] ?? 0), 2, "0", STR_PAD_LEFT).':'.str_pad(intval($workTimeStart[1] ?? 0), 2, "0", STR_PAD_LEFT);
38
39 $workTimeEnd = explode('.', \Bitrix\Main\Config\Option::get('calendar', 'work_time_end', '18'));
40 $timeOfEndDate = str_pad(intval($workTimeEnd[0] ?? 0), 2, "0", STR_PAD_LEFT).':'.str_pad(intval($workTimeEnd[1] ?? 0), 2, "0", STR_PAD_LEFT);
41
42 $defaultPregExceptionSearch = Array('.', '/', '-', ':');
43 $defaultPregExceptionReplace = Array('\.', '\/', '\-', '\:');
44
45 // metric 1: near date
46 $pattern = Array();
47 for ($i = 1; $i <= 11; $i++)
48 {
49 $pattern[$i] = mb_strtolower(Loc::getMessage("MAIN_TDC_METRIC_1_".$i));
50 $pattern[$i] = $pattern[$i] <> ''? $pattern[$i]: 'bxt2dmetricskip';
51 $pattern[$i] = str_replace($defaultPregExceptionSearch, $defaultPregExceptionReplace, $pattern[$i]);
52 }
53 if (preg_match_all("/(".implode('|', $pattern).")/", $text, $match, PREG_OFFSET_CAPTURE))
54 {
55 foreach ($match[0] as $matchPattern)
56 {
57 $matchType = '';
58 switch($matchPattern[0])
59 {
60 case $pattern[1]:
61 $matchType = 'DAYAFTERTOMORROW';
62 break;
63 case $pattern[2]:
64 $matchType = 'TOMORROW';
65 break;
66 case $pattern[3]:
67 $matchType = 'TODAY';
68 break;
69 case $pattern[4]:
70 $matchType = 'YESTERDAY';
71 break;
72 case $pattern[5]:
73 $matchType = 'DAYBEFOREYESTERDAY';
74 break;
75 case $pattern[9]:
76 $matchType = 'WEEK';
77 break;
78 case $pattern[10]:
79 $matchType = 'WEEKEND';
80 break;
81 case $pattern[11]:
82 $matchType = 'MONTH';
83 break;
84 }
85 if ($matchType <> '')
86 {
87 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
88 $matchWord = self::getMatchWord($originalText, $position);
89
90 $metrics[1][] = Array(
91 'TYPE' => $matchType,
92 'COUNT' => mb_strlen($matchWord),
93 'POSITION' => $position,
94 'MATCH' => $matchWord
95 );
96 }
97 }
98 }
99
100 // metric 2: day of weeks
101 $pattern = Array();
102 for ($i = 1; $i <= 10; $i++)
103 {
104 $pattern[$i] = mb_strtolower(Loc::getMessage("MAIN_TDC_METRIC_2_".$i));
105 $pattern[$i] = $pattern[$i] <> ''? $pattern[$i]: 'bxt2dmetricskip';
106 $pattern[$i] = str_replace($defaultPregExceptionSearch, $defaultPregExceptionReplace, $pattern[$i]);
107 }
108 if (preg_match_all("/(".implode('|', $pattern).")/", $text, $match, PREG_OFFSET_CAPTURE))
109 {
110 foreach ($match[0] as $matchPattern)
111 {
112 $matchType = '';
113 switch($matchPattern[0])
114 {
115 case $pattern[1]:
116 $matchType = 'MONDAY';
117 if (is_array($metrics[1]))
118 {
119 foreach ($metrics[1] as $key => $metric)
120 {
121 if ($metric['TYPE'] == 'WEEK')
122 {
123 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
124 $matchWord = self::getMatchWord($originalText, $position);
125
126 if ($matchPattern[1] < $metric['POSITION'] && $matchPattern[1] + mb_strlen($matchWord) >= $metric['POSITION'] + $metric['COUNT'])
127 {
128 unset($metrics[1][$key]);
129 if (empty($metrics[1]))
130 {
131 unset($metrics[1]);
132 }
133 }
134 }
135 }
136 }
137 break;
138 case $pattern[2]:
139 $matchType = 'TUESDAY';
140 break;
141 case $pattern[3]:
142 case $pattern[4]:
143 case $pattern[5]:
144 $matchType = 'WEDNESDAY';
145 break;
146 case $pattern[6]:
147 $matchType = 'THURSDAY';
148 break;
149 case $pattern[7]:
150 $matchType = 'FRIDAY';
151 break;
152 case $pattern[8]:
153 $matchType = 'SATURDAY';
154 break;
155 case $pattern[9]:
156 case $pattern[10]:
157 $matchType = 'SUNDAY';
158 break;
159 }
160
161 if ($matchType <> '')
162 {
163 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
164 $matchWord = self::getMatchWord($originalText, $position);
165
166 $metrics[2][] = Array(
167 'TYPE' => $matchType,
168 'COUNT' => mb_strlen($matchWord),
169 'POSITION' => $position,
170 'MATCH' => $matchWord
171 );
172 }
173 }
174 }
175
176 // metric 3: modificators before/after and time
177 $pattern = Array();
178 for ($i = 1; $i <= 9; $i++)
179 {
180 $pattern[$i] = mb_strtolower(Loc::getMessage("MAIN_TDC_METRIC_3_".$i));
181 $pattern[$i] = $pattern[$i] <> ''? $pattern[$i]: 'bxt2dmetricskip';
182 $pattern[$i] = str_replace($defaultPregExceptionSearch, $defaultPregExceptionReplace, $pattern[$i]);
183 }
184 if (preg_match_all("/(".implode('|', $pattern).")/", $text, $match, PREG_OFFSET_CAPTURE))
185 {
186 foreach ($match[0] as $matchPattern)
187 {
188 $matchType = '';
189 switch($matchPattern[0])
190 {
191 case $pattern[1]:
192 $matchType = 'BEFORE';
193 break;
194 case $pattern[2]:
195 $matchType = 'AFTER';
196 break;
197 case $pattern[3]:
198 $matchType = 'NEXT';
199 break;
200 case $pattern[4]:
201 $matchType = 'PREVIOUS';
202 break;
203 case $pattern[5]:
204 case $pattern[6]:
205 $matchType = 'ENDOF';
206 break;
207 case $pattern[7]:
208 $matchType = 'MIDDLEOF';
209 break;
210 case $pattern[8]:
211 $matchType = 'STARTOF';
212 break;
213 case $pattern[9]:
214 case $pattern[10]:
215 $matchType = 'THIS';
216 break;
217 }
218
219 if (in_array($matchType, Array('BEFORE', 'AFTER')) && isset($metrics[1]))
220 {
221 foreach ($metrics[1] as $key => $metric)
222 {
223 if (in_array($metric['TYPE'], Array('DAYAFTERTOMORROW', 'DAYBEFOREYESTERDAY')))
224 {
225 if ($metric['POSITION'] == $matchPattern[1])
226 {
227 $matchType = '';
228 }
229 }
230 else if (in_array($metric['TYPE'], Array('TOMORROW', 'YESTERDAY')))
231 {
232 if ($metric['POSITION'] == $matchPattern[1] + mb_strlen($matchPattern[0])+1)
233 {
234 if ($metric['TYPE'] == 'TOMORROW')
235 {
236 $metrics[1][$key]['TYPE'] = $matchType == 'AFTER'? 'DAYAFTERTOMORROW': 'TODAY';
237 }
238 else
239 {
240 $metrics[1][$key]['TYPE'] = $matchType == 'AFTER'? 'TODAY': 'DAYBEFOREYESTERDAY';
241 }
242 $matchType = '';
243 }
244 }
245 }
246 }
247
248 if ($matchType <> '')
249 {
250 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
251 $matchWord = self::getMatchWord($originalText, $position);
252
253 $metrics[3][] = Array(
254 'TYPE' => $matchType,
255 'COUNT' => mb_strlen($matchWord),
256 'POSITION' => $position,
257 'MATCH' => $matchWord
258 );
259 }
260 }
261 }
262 if (preg_match_all("/([0-2][0-9]:[0-5][0-9])/", $text, $match, PREG_OFFSET_CAPTURE))
263 {
264 foreach ($match[0] as $matchPattern)
265 {
266 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
267 $matchWord = self::getMatchWord($originalText, $position);
268
269 $metrics[3][] = Array(
270 'TYPE' => 'HHMM',
271 'VALUE' => $matchPattern[0],
272 'COUNT' => mb_strlen($matchPattern[0]),
273 'POSITION' => $position,
274 'MATCH' => $matchWord
275 );
276 }
277 }
278
279 // metric 4: date
280 $pattern = Array();
281 $patternOriginal = Array();
282 $patternLength = Array();
283 for ($i = 1; $i <= 3; $i++)
284 {
285 $patternOriginal[$i] = mb_strtolower(Loc::getMessage("MAIN_TDC_METRIC_4_".$i));
286 $patternOriginal[$i] = $patternOriginal[$i] <> ''? $patternOriginal[$i]: 'bxt2dmetricskip';
287 $patternLength[$i] = mb_strlen($patternOriginal[$i]);
288 if ($patternOriginal[$i] != 'bxt2dmetricskip')
289 {
290 $pattern[$i] = str_replace($defaultPregExceptionSearch, $defaultPregExceptionReplace, $patternOriginal[$i]);
291 $pattern[$i] = str_replace(
292 Array('yyyy', 'yy', 'mm', 'dd'),
293 Array('[1-2][0-9][0-9][0-9]', '[0-9][0-9]', '[0-1][0-9]', '[0-3][0-9]'),
294 $pattern[$i]
295 );
296 $pattern[$i] = '^(?>[\s|\t]?)('.$pattern[$i].')|[\s|^|\t]('.$pattern[$i].')(?=[\s|$|\r|\t])';
297 }
298 }
299 if (preg_match_all("/".implode('|', $pattern)."/", $text, $match, PREG_OFFSET_CAPTURE))
300 {
301 $count = count($match)-1;
302 for ($i = 1; $i <= $count; $i++)
303 {
304 foreach ($match[$i] as $matchPattern)
305 {
306 if (!$matchPattern[0])
307 {
308 continue;
309 }
310
311 $matchType = '';
312 $matchLength = '';
313 switch(mb_strlen($matchPattern[0]))
314 {
315 case $patternLength[1]:
316 $matchType = 'DDMMYYYY';
317 $matchYear = mb_substr($matchPattern[0], mb_strpos($patternOriginal[1], 'yyyy'), 4);
318 $matchMonth = mb_substr($matchPattern[0], mb_strpos($patternOriginal[1], 'mm'), 2);
319 $matchDay = mb_substr($matchPattern[0], mb_strpos($patternOriginal[1], 'dd'), 2);
320 $matchPattern[0] = $matchYear.'-'.$matchMonth.'-'.$matchDay;
321 $matchLength = $patternLength[1];
322 break;
323 case $patternLength[2]:
324 $matchType = 'DDMMYY';
325 $matchYear = mb_substr($matchPattern[0], mb_strpos($patternOriginal[2], 'yy'), 2);
326 $matchMonth = mb_substr($matchPattern[0], mb_strpos($patternOriginal[2], 'mm'), 2);
327 $matchDay = mb_substr($matchPattern[0], mb_strpos($patternOriginal[2], 'dd'), 2);
328 $matchPattern[0] = '20'.$matchYear.'-'.$matchMonth.'-'.$matchDay;
329 $matchLength = $patternLength[2];
330 break;
331 case $patternLength[3]:
332 $matchType = 'DDMM';
333 $matchMonth = mb_substr($matchPattern[0], mb_strpos($patternOriginal[3], 'mm'), 2);
334 $matchDay = mb_substr($matchPattern[0], mb_strpos($patternOriginal[3], 'dd'), 2);
335 $matchPattern[0] = $date->format('Y').'-'.$matchMonth.'-'.$matchDay;
336 $matchLength = $patternLength[3];
337 break;
338 }
339
340 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
341 $matchWord = mb_substr($originalText, $position, $matchLength);
342
343 $metrics[4][] = Array(
344 'TYPE' => $matchType,
345 'VALUE' => $matchPattern[0],
346 'COUNT' => $matchLength,
347 'POSITION' => $position,
348 'MATCH' => $matchWord
349 );
350 }
351 }
352 }
353
354 // metric 5: modificators of time
355 $pattern = Array();
356 for ($i = 1; $i <= 5; $i++)
357 {
358 $pattern[$i] = mb_strtolower(Loc::getMessage("MAIN_TDC_METRIC_5_".$i));
359 $pattern[$i] = $pattern[$i] <> ''? $pattern[$i]: 'bxt2dmetricskip';
360 $pattern[$i] = str_replace($defaultPregExceptionSearch, $defaultPregExceptionReplace, $pattern[$i]);
361 }
362 if (preg_match_all("/(".implode('|', $pattern).")/", $text, $match, PREG_OFFSET_CAPTURE))
363 {
364 foreach ($match[0] as $matchPattern)
365 {
366 $matchType = '';
367 $matchValue = '';
368 switch($matchPattern[0])
369 {
370 case $pattern[1]:
371 $matchType = 'MORNING';
372 $matchValue = $timeOfStartDate;
373 break;
374 case $pattern[2]:
375 $matchType = 'LUNCH';
376 $matchValue = '14:00';
377 break;
378 case $pattern[3]:
379 break;
380 case $pattern[4]:
381 $matchType = 'WORKDAY';
382 $matchValue = $timeOfEndDate;
383
384 if (isset($metrics[1]))
385 {
386 foreach ($metrics[1] as $key => $metric)
387 {
388 if ($metric['TYPE'] == 'TODAY')
389 {
390 if ($metric['POSITION'] == $matchPattern[1] + mb_strlen($matchPattern[3]))
391 {
392 $matchType = '';
393 }
394 }
395 }
396 }
397 break;
398 case $pattern[5]:
399 $matchType = 'EVENING';
400 $matchValue = '20:00';
401 break;
402 }
403 if ($matchType <> '')
404 {
405 $position = defined("BX_UTF")? mb_strlen(substr($text, 0, $matchPattern[1])) : $matchPattern[1];
406 $matchWord = self::getMatchWord($originalText, $position);
407
408 $metrics[5][] = Array(
409 'TYPE' => $matchType,
410 'VALUE' => $matchValue,
411 'COUNT' => mb_strlen($matchWord),
412 'POSITION' => $position,
413 'MATCH' => $matchWord
414 );
415 }
416 }
417 }
418
419 $countOfMetrics = 0;
420 foreach ($metrics as $values)
421 {
422 if (!empty($values))
423 {
424 $countOfMetrics++;
425 }
426 }
427
428 $useDefault = false;
429 if ($countOfMetrics == 1 && (isset($metrics[3]) || isset($metrics[5])))
430 {}
431 else if ($countOfMetrics == 1)
432 {
433 $useDefault = true;
434 }
435 else if ($countOfMetrics == 2 && isset($metrics[3]))
436 {
437 $useDefault = !isset($metrics[5]);
438 }
439 else if ($countOfMetrics == 2 && isset($metrics[5]) && (isset($metrics[1]) || isset($metrics[2]) || isset($metrics[4])))
440 {
441 if (isset($metrics[1]))
442 {
443 foreach ($metrics[1] as $metric)
444 {
445 $progressDate = self::createDateUsingMetrics(1, $metric, $metrics[5]);
446 $matchParams = self::getTextForReplace($originalText, $metric, $metrics[5]);
447 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_RELATIVE, $metric, $metrics[5]);
448 }
449 }
450 else if (isset($metrics[2]))
451 {
452 foreach ($metrics[2] as $metric)
453 {
454 $progressDate = self::createDateUsingMetrics(2, $metric, $metrics[5]);
455 $matchParams = self::getTextForReplace($originalText, $metric, $metrics[5]);
456 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_DAYOFWEEK, $metric, $metrics[5]);
457 }
458 }
459 else if (isset($metrics[4]))
460 {
461 foreach ($metrics[4] as $metric)
462 {
463 $progressDate = self::createDateUsingMetrics(4, $metric, $metrics[5]);
464 $matchParams = self::getTextForReplace($originalText, $metric, $metrics[5]);
465 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_CALENDAR, $metric, $metrics[5]);
466 }
467 }
468 }
469 else if ($countOfMetrics == 2 && isset($metrics[1]) && (isset($metrics[2]) || isset($metrics[4])))
470 {
471 if (isset($metrics[2]))
472 {
473 foreach ($metrics[2] as $metric)
474 {
475 $array = array();
476 $progressDate = self::createDateUsingMetrics(2, $metric, $array);
477 $matchParams = self::getTextForReplace($originalText, $metric, array());
478 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_DAYOFWEEK, $metric);
479 }
480 }
481 elseif (isset($metrics[4]))
482 {
483 foreach ($metrics[4] as $metric)
484 {
485 $array = array();
486 $progressDate = self::createDateUsingMetrics(4, $metric, $array);
487 $matchParams = self::getTextForReplace($originalText, $metric, array());
488 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_CALENDAR, $metric);
489 }
490 }
491 }
492 else
493 {
494 $useDefault = true;
495 }
496
497 if ($useDefault)
498 {
499 $modificators = $metrics[3] ?? array();
500 if (isset($metrics[4]) && count($metrics[4]))
501 {
502 foreach ($metrics[4] as $metric)
503 {
504 $progressDate = self::createDateUsingMetrics(4, $metric, $modificators);
505 $matchParams = self::getTextForReplace($originalText, $metric, $modificators);
506 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_CALENDAR, $metric, $modificators);
507 }
508 }
509 else if (isset($metrics[2]) && count($metrics[2]))
510 {
511 foreach ($metrics[2] as $metric)
512 {
513 $progressDate = self::createDateUsingMetrics(2, $metric, $modificators);
514 $matchParams = self::getTextForReplace($originalText, $metric, $modificators);
515 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_DAYOFWEEK, $metric, $modificators);
516 }
517 }
518 else if (isset($metrics[1]) && count($metrics[1]))
519 {
520 foreach ($metrics[1] as $metric)
521 {
522 $progressDate = self::createDateUsingMetrics(1, $metric, $modificators);
523 $matchParams = self::getTextForReplace($originalText, $metric, $modificators);
524 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_RELATIVE, $metric, $modificators);
525 }
526 }
527 else if (isset($metrics[5]) && count($metrics[5]))
528 {
529 foreach ($metrics[5] as $metric)
530 {
531 $progressDate = self::createDateUsingMetrics(5, $metric, $modificators);
532 $matchParams = self::getTextForReplace($originalText, $metric, $modificators);
533 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_PARTOFDAY, $metric, $modificators);
534 }
535 }
536 else if (isset($metrics[3]) && count($metrics[3]))
537 {
538 foreach ($metrics[3] as $metric)
539 {
540 $array = array();
541 $progressDate = self::createDateUsingMetrics(3, $metric, $array);
542 $matchParams = self::getTextForReplace($originalText, $metric, $modificators);
543 $result[] = new DateConverterResult($progressDate, $matchParams, DateConverterResult::TYPE_MODIFIER, $metric);
544 }
545 }
546
547 }
548
549 return $result;
550 }
551
562 private static function createDateUsingMetrics($type, $metric, &$metricModificator = array(), \Bitrix\Main\Type\DateTime $date = null)
563 {
564 $defaultDate = $date? $date: new \Bitrix\Main\Type\DateTime();
565 $metricModificator = is_array($metricModificator)? $metricModificator: array();
566
567 $workTimeStart = explode('.', \Bitrix\Main\Config\Option::get('calendar', 'work_time_start', '9'));
568 $timeOfStartDate = str_pad(intval($workTimeStart[0]), 2, "0", STR_PAD_LEFT).':'.str_pad(intval($workTimeStart[1] ?? 0), 2, "0", STR_PAD_LEFT);
569
570 $workTimeEnd = explode('.', \Bitrix\Main\Config\Option::get('calendar', 'work_time_end', '18'));
571 $timeOfEndDate = str_pad(intval($workTimeEnd[0]), 2, "0", STR_PAD_LEFT).':'.str_pad(intval($workTimeEnd[1] ?? 0), 2, "0", STR_PAD_LEFT);
572
573 $result = null;
574 switch($type)
575 {
576 case 1:
577 $metricDate = $defaultDate;
578 switch($metric['TYPE'])
579 {
580 case 'DAYAFTERTOMORROW':
581 $metricDate->add('TOMORROW')->add('TOMORROW');
582 break;
583 case 'TOMORROW':
584 $metricDate->add('TOMORROW');
585 break;
586 case 'YESTERDAY':
587 $metricDate->add('YESTERDAY');
588 break;
589 case 'DAYBEFOREYESTERDAY':
590 $metricDate->add('YESTERDAY')->add('YESTERDAY');
591 break;
592 }
593
594 $modificator = '';
595 $metricTime = $timeOfEndDate;
596
597 $metricModificator = self::checkModifierPosition($metric, $metricModificator);
598
599 foreach ($metricModificator as $currentModificator)
600 {
601 if ($metric['TYPE'] == 'WEEK')
602 {
603 if (in_array($currentModificator['TYPE'], Array('BEFORE', 'PREVIOUS')))
604 {
605 $metricDate->add('-1 WEEK');
606 }
607 else if (in_array($currentModificator['TYPE'], Array('AFTER', 'NEXT')))
608 {
609 $metricDate->add('1 WEEK');
610 }
611 else if ($currentModificator['TYPE'] == 'MIDDLEOF')
612 {
613 $metricDate = self::getDateOfDayOfCurrentWeek('WEDNESDAY', $metricDate);
614 $modificator = true;
615 }
616 else if ($currentModificator['TYPE'] == 'STARTOF')
617 {
618 $metricDate = self::getDateOfDayOfCurrentWeek('MONDAY', $metricDate);
619 $modificator = true;
620 }
621 else if ($currentModificator['TYPE'] == 'ENDOF')
622 {
623 $metricDate = self::getDateOfDayOfCurrentWeek('FRIDAY', $metricDate);
624 $modificator = true;
625 }
626 }
627 else if ($metric['TYPE'] == 'WEEKEND')
628 {
629 if (in_array($currentModificator['TYPE'], Array('BEFORE')))
630 {
631 $metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
632 $metricDate->add('-1 DAY');
633 $modificator = true;
634 }
635 else if (in_array($currentModificator['TYPE'], Array('PREVIOUS')))
636 {
637 $metricDate->add('-1 WEEK');
638 $metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
639 $modificator = true;
640 }
641 else if (in_array($currentModificator['TYPE'], Array('NEXT')))
642 {
643 $metricDate->add('1 WEEK');
644 $metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
645 $modificator = true;
646 }
647 else if (in_array($currentModificator['TYPE'], Array('AFTER')))
648 {
649 $metricDate = self::getDateOfDayOfCurrentWeek('SUNDAY', $metricDate);
650 $metricDate->add('1 DAY');
651 $modificator = true;
652 }
653 else if ($currentModificator['TYPE'] == 'MIDDLEOF')
654 {
655 $metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
656 $modificator = true;
657 }
658 else if ($currentModificator['TYPE'] == 'STARTOF')
659 {
660 $metricDate = self::getDateOfDayOfCurrentWeek('SATURDAY', $metricDate);
661 $metricTime = $timeOfStartDate;
662 $modificator = true;
663 }
664 else if ($currentModificator['TYPE'] == 'ENDOF')
665 {
666 $metricDate = self::getDateOfDayOfCurrentWeek('SUNDAY', $metricDate);
667 $modificator = true;
668 }
669 }
670 else if ($metric['TYPE'] == 'MONTH')
671 {
672 if (in_array($currentModificator['TYPE'], Array('BEFORE', 'PREVIOUS')))
673 {
674 $metricDate->add('-1 MONTH');
675 $numberOfMonth = $metricDate->format('t');
676 $metricDate = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m').'-'.$numberOfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
677 $modificator = true;
678 }
679 else if (in_array($currentModificator['TYPE'], Array('AFTER', 'NEXT')))
680 {
681 $metricDate->add('1 MONTH');
682 $numberOfMonth = $metricDate->format('t');
683 $metricDate = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m').'-'.$numberOfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
684 $modificator = true;
685 }
686 else if ($currentModificator['TYPE'] == 'MIDDLEOF')
687 {
688 $numberOfHalfMonth = ceil($metricDate->format('t')/2);
689 $metricDate = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m').'-'.$numberOfHalfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
690 $modificator = true;
691 }
692 else if ($currentModificator['TYPE'] == 'STARTOF')
693 {
694 $metricDate = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m').'-01 '.$timeOfStartDate.':00', 'Y-m-d H:i:s');
695 $modificator = true;
696 }
697 else if ($currentModificator['TYPE'] == 'ENDOF')
698 {
699 $numberOfMonth = $metricDate->format('t');
700 $metricDate = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m').'-'.$numberOfMonth.' '.$timeOfEndDate.':00', 'Y-m-d H:i:s');
701 $modificator = true;
702 }
703 }
704 else
705 {
706 if (in_array($currentModificator['TYPE'], Array('BEFORE', 'PREVIOUS')))
707 {
708 $metricDate->add('-1 DAY');
709 }
710 else if (in_array($currentModificator['TYPE'], Array('AFTER', 'NEXT')))
711 {
712 $metricDate->add('1 DAY');
713 }
714 else if ($currentModificator['TYPE'] == 'MIDDLEOF')
715 {
716 $metricTime = '14:00';
717 }
718 else if ($currentModificator['TYPE'] == 'STARTOF')
719 {
720 $metricTime = $timeOfStartDate;
721 }
722 $modificator = true;
723 }
724
725 if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
726 {
727 $metricTime = $currentModificator['VALUE'];
728 $modificator = true;
729 }
730 }
731 if (!$modificator)
732 {
733 if ($metric['TYPE'] == 'WEEK')
734 {
735 if ($metricDate->format('N') == 3)
736 {
737 $metricDate->add('FRIDAY');
738 }
739 else if ($metricDate->format('N') < 3)
740 {
741 $metricDate->add('THURSDAY');
742 }
743 else if ($metricDate->format('N') != 7)
744 {
745 $metricDate->add('SUNDAY');
746 }
747 }
748 else if ($metric['TYPE'] == 'WEEKEND')
749 {
750 if (strtolower($metricDate->format('l')) == 'saturday')
751 $metricDate->add('SUNDAY');
752 else if (strtolower($metricDate->format('l')) != 'sunday')
753 $metricDate->add('SATURDAY');
754 }
755 else if ($metric['TYPE'] == 'MONTH')
756 {
757 $numberOfMonth = $metricDate->format('j');
758 if ($numberOfMonth > 15)
759 {
760 $plus = $metricDate->format('t')-$numberOfMonth;
761 if ($plus >= 1)
762 {
763 $metricDate->add($plus.' DAY');
764 }
765 }
766 elseif ($numberOfMonth >= 10)
767 {
768 $plus = 20-$numberOfMonth;
769 $metricDate->add($plus.' DAY');
770 }
771 else
772 {
773 $plus = 15-$numberOfMonth;
774 $metricDate->add($plus.' DAY');
775 }
776 }
777 }
778
779 $result = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');
780
781 break;
782 case 2:
783
784 $metricDate = $defaultDate;
785 $modificator = '';
786 $metricTime = $timeOfEndDate;
787
788 $metricModificator = self::checkModifierPosition($metric, $metricModificator);
789
790 foreach ($metricModificator as $currentModificator)
791 {
792 $metricDate = self::getDateOfDayOfCurrentWeek($metric['TYPE'], $metricDate);
793 if ($currentModificator['TYPE'] == 'BEFORE')
794 {
795 $metricDate->add('-1 DAY');
796 }
797 else if ($currentModificator['TYPE'] == 'AFTER')
798 {
799 $metricDate->add('1 DAY');
800 }
801 else if ($currentModificator['TYPE'] == 'THIS')
802 {
803 $metricDate->add('LAST '.$metric['TYPE']);
804 }
805 else if (in_array($currentModificator['TYPE'], Array('NEXT', 'PREVIOUS')))
806 {
807 if ($currentModificator['TYPE'] == 'NEXT')
808 {
809 $metricDate->add('NEXT '.$metric['TYPE']);
810 }
811 else
812 {
813 $metricDate->add('PREVIOUS '.$metric['TYPE']);
814 }
815 }
816 else if ($currentModificator['TYPE'] == 'MIDDLEOF')
817 {
818 $metricTime = '14:00';
819 }
820 else if ($currentModificator['TYPE'] == 'STARTOF')
821 {
822 $metricTime = $timeOfStartDate;
823 }
824 else if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
825 {
826 $metricTime = $currentModificator['VALUE'];
827 }
828 $modificator = true;
829 }
830 if (!$modificator)
831 {
832 $modificator = strtolower($metric['TYPE']) == strtolower($metricDate->format('l'))? 'NEXT ': '';
833 $metricDate->add($modificator.$metric['TYPE']);
834 }
835
836 $result = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');
837
838 break;
839 case 3:
840 $metricDate = $defaultDate;
841 $metricTime = $timeOfEndDate;
842 switch($metric['TYPE'])
843 {
844 case 'BEFORE':
845 $metricDate->add('TOMORROW')->add('TOMORROW');
846 break;
847 case 'AFTER':
848 $metricDate->add('TOMORROW');
849 break;
850 case 'NEXT':
851 $metricDate->add('YESTERDAY');
852 break;
853 case 'PREVIOUS':
854 $metricDate->add('YESTERDAY')->add('YESTERDAY');
855 break;
856 case 'MIDDLEOF':
857 $metricTime = '14:00';
858 break;
859 case 'STARTOF':
860 $metricTime = $timeOfStartDate;
861 break;
862 case 'HHMM':
863 $metricTime = $metric['VALUE'];
864 break;
865 }
866 $result = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');
867
868 break;
869 case 4:
870 $modificator = '';
871 $metricTime = $timeOfEndDate;
872
873 $metricModificator = self::checkModifierPosition($metric, $metricModificator);
874
875 foreach ($metricModificator as $currentModificator)
876 {
877 if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
878 {
879 $metricTime = $currentModificator['VALUE'];
880 }
881 }
882
883 $result = new \Bitrix\Main\Type\DateTime($metric['VALUE'].' '.$metricTime.':00', 'Y-m-d H:i:s');
884
885 break;
886 case 5:
887
888 $metricDate = $defaultDate;
889 $modificator = '';
890 $metricTime = $metric['VALUE'];
891
892 $metricModificator = self::checkModifierPosition($metric, $metricModificator);
893
894 foreach ($metricModificator as $currentModificator)
895 {
896 if ($currentModificator['TYPE'] == 'BEFORE')
897 {
898 $metricDate->add('-1 DAY');
899 }
900 else if ($currentModificator['TYPE'] == 'AFTER')
901 {
902 $metricDate->add('1 DAY');
903 }
904 else if (in_array($currentModificator['TYPE'], Array('NEXT', 'PREVIOUS')))
905 {
906 if ($currentModificator['TYPE'] == 'NEXT')
907 {
908 $metricDate->add('NEXT '.$metric['TYPE']);
909 }
910 else
911 {
912 $metricDate->add('PREVIOUS '.$metric['TYPE']);
913 }
914 }
915 else if ($currentModificator['TYPE'] == 'MIDDLEOF')
916 {
917 $metricTime = '14:00';
918 }
919 else if ($currentModificator['TYPE'] == 'STARTOF')
920 {
921 $metricTime = $timeOfStartDate;
922 }
923 else if (in_array($currentModificator['TYPE'], Array('MORNING', 'LUNCH', 'EVENING', 'HHMM')))
924 {
925 $metricTime = $currentModificator['VALUE'];
926 }
927 $modificator = true;
928
929 }
930
931 if (!$modificator)
932 {
933 $modificator = strtolower($metric['TYPE']) == strtolower($metricDate->format('l'))? 'NEXT ': '';
934 $metricDate->add($modificator.$metric['TYPE']);
935 }
936
937 $result = new \Bitrix\Main\Type\DateTime($metricDate->format('Y-m-d').' '.$metricTime.':00', 'Y-m-d H:i:s');
938 break;
939 }
940
941 return $result;
942 }
943
952 private static function getDateOfDayOfCurrentWeek($nameOfday, \Bitrix\Main\Type\DateTime $date = null)
953 {
954 $date = $date? $date: new \Bitrix\Main\Type\DateTime();
955
956 $nameOfday = mb_strtoupper($nameOfday);
957 if (!in_array($nameOfday, Array('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY')))
958 return false;
959
960 $relation = '';
961 $day = $date->format('N');
962 if (
963 $nameOfday == 'MONDAY' && $day == 1 ||
964 $nameOfday == 'TUESDAY' && $day <= 2 ||
965 $nameOfday == 'WEDNESDAY' && $day <= 3 ||
966 $nameOfday == 'THURSDAY' && $day <= 4 ||
967 $nameOfday == 'FRIDAY' && $day <= 5 ||
968 $nameOfday == 'SATURDAY' && $day <= 6 ||
969 $nameOfday == 'SUNDAY' && $day <= 7
970 )
971 {
972 $relation = 'THIS';
973 }
974 $date->add($relation.' '.$nameOfday);
975
976 return $date;
977 }
978
984 private static function getMatchWord($text, $position)
985 {
986 $letters = array_merge(Array(" ", "\n", "\t", "\r"), str_split('"-.,?!#$%^&*();:<>\|{}-=^@[]`'));
987 $spaceFound = self::findFirstOccurrence($text, $letters, $position);
988 if ($spaceFound !== false)
989 {
990 $result = mb_substr($text, $position, $spaceFound - $position);
991 }
992 else
993 {
994 $result = mb_substr($text, $position);
995 }
996 return $result;
997 }
998
999 private static function getTextForReplace($text, $metrics, $metricModifier)
1000 {
1001 $found = false;
1002
1003 $minStartPosition = null;
1004 $maxEndPosition = null;
1005
1006 if (!empty($metrics))
1007 {
1008 $minStartPosition = $metrics['POSITION'];
1009 $maxEndPosition = $metrics['POSITION'] + $metrics['COUNT'];
1010 $found = true;
1011 }
1012
1013 if (is_array($metricModifier))
1014 {
1015 foreach ($metricModifier as $metrics)
1016 {
1017 if (!$found)
1018 {
1019 $minStartPosition = $metrics['POSITION'];
1020 $maxEndPosition = $metrics['POSITION'] + $metrics['COUNT'];
1021 $found = true;
1022 }
1023 else
1024 {
1025 if ($minStartPosition > $metrics['POSITION'])
1026 {
1027 $minStartPosition = $metrics['POSITION'];
1028 }
1029 if ($maxEndPosition < $metrics['POSITION'] + $metrics['COUNT'])
1030 {
1031 $maxEndPosition = $metrics['POSITION'] + $metrics['COUNT'];
1032 }
1033 }
1034 }
1035 }
1036
1037 if (is_null($minStartPosition) || is_null($maxEndPosition))
1038 {
1039 $result = false;
1040 }
1041 else
1042 {
1043 $result = mb_substr($text, $minStartPosition, $maxEndPosition - $minStartPosition);
1044 $result = Array('TEXT' => $result, 'POSITION' => $minStartPosition, 'LENGTH' => mb_strlen($result));
1045 }
1046
1047 return $result;
1048 }
1049
1050 private static function checkModifierPosition($metrics, $metricModifier)
1051 {
1052 $newMetrics = $metrics;
1053
1054 $stackMetrics = Array();
1055
1056 $while = true;
1057 $maxWhile = 100;
1058 while ($while && $maxWhile > 0)
1059 {
1060 $while = false;
1061 foreach ($metricModifier as $key => $currentModificator)
1062 {
1063 $diffResult = abs($newMetrics['POSITION'] - ($currentModificator['POSITION'] + $currentModificator['COUNT']));
1064 if ($diffResult < 5)
1065 {
1066 $while = true;
1067 $newMetrics = $currentModificator;
1068 $stackMetrics[] = $currentModificator;
1069 unset($metricModifier[$key]);
1070 }
1071 else
1072 {
1073 $diffResult = abs($newMetrics['POSITION']+$newMetrics['COUNT'] - ($currentModificator['POSITION']));
1074 if ($diffResult < 5)
1075 {
1076 $while = true;
1077 $newMetrics = $currentModificator;
1078 $stackMetrics[] = $currentModificator;
1079 unset($metricModifier[$key]);
1080 }
1081 }
1082 }
1083 $maxWhile--;
1084 }
1085
1086 return $stackMetrics;
1087 }
1088
1089 private static function findFirstOccurrence($haystack, $needle, $offset=0)
1090 {
1091 $haystack = mb_substr($haystack, 0, 25 + $offset);
1092 if(!is_array($needle))
1093 {
1094 $needle = array($needle);
1095 }
1096
1097 $positions = array();
1098 if ($offset < mb_strlen($haystack))
1099 {
1100 foreach ($needle as $query)
1101 {
1102 $result = mb_strpos($haystack, $query, $offset);
1103 if ($result !== false)
1104 {
1105 $positions[] = $result;
1106 }
1107 }
1108 }
1109
1110 return empty($positions)? false: min($positions);
1111 }
1112}
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static decode($text, $limit=0)