1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
helper.php
См. документацию.
1<?php
2
3use Bitrix\HumanResources\Compatibility\Utils\DepartmentBackwardAccessCode;
4use Bitrix\HumanResources\Service\Container;
5use Bitrix\HumanResources\Type\MemberEntityType;
6use Bitrix\HumanResources\Type\MemberSubordinateRelationType;
8use Bitrix\Bitrix24;
11
13{
14 const DISTR_B24 = 'b24';
15 const DISTR_BOX = 'box';
16
17 private static $serverName;
18 protected static $cAccess;
19 protected static $groupsCache = array();
20
21 protected static function getAccessProvider()
22 {
23 if (self::$cAccess === null)
24 {
25 self::$cAccess = new CAccess;
26 }
27 return self::$cAccess;
28 }
29
30 private static function usersArrayToStringInternal($arUsers, $arWorkflowTemplate, $arAllowableUserGroups, $appendId = true)
31 {
32 if (is_array($arUsers))
33 {
34 $r = [];
35
36 $keys = array_keys($arUsers);
37 foreach ($keys as $key)
38 {
39 $r[$key] = self::UsersArrayToStringInternal($arUsers[$key], $arWorkflowTemplate, $arAllowableUserGroups, $appendId);
40 }
41
42 if (count($r) == 2)
43 {
44 $keys = array_keys($r);
45 if ($keys[0] == 0 && $keys[1] == 1 && is_string($r[0]) && is_string($r[1]))
46 {
47 if (in_array($r[0], array("Document", "Template", "Variable", "User"))
48 || preg_match('#^A\d+_\d+_\d+_\d+$#i', $r[0])
49 || is_array($arWorkflowTemplate) && CBPWorkflowTemplateLoader::FindActivityByName($arWorkflowTemplate, $r[0]) != null
50 )
51 {
52 return '{=' . $r[0] . ':' . $r[1] . '}';
53 }
54 }
55 }
56
57 return implode(", ", $r);
58 }
59 else
60 {
61 if (array_key_exists(mb_strtolower($arUsers), $arAllowableUserGroups))
62 {
63 return $arAllowableUserGroups[mb_strtolower($arUsers)];
64 }
65
66 if (CBPActivity::isExpression($arUsers))
67 {
68 return $arUsers;
69 }
70
71 $userId = 0;
72 if (mb_substr($arUsers, 0, mb_strlen("user_")) == "user_")
73 {
74 $userId = intval(mb_substr($arUsers, mb_strlen("user_")));
75 }
76
77 if ($userId > 0)
78 {
79 $db = CUser::GetList(
80 "LAST_NAME",
81 "asc",
82 ["ID_EQUAL_EXACT" => $userId],
83 [
84 "NAV_PARAMS" => false,
85 'FIELDS'=> [
86 'ID',
87 'LOGIN',
88 'EMAIL',
89 'NAME',
90 'LAST_NAME',
91 'SECOND_NAME',
92 ],
93 ]
94 );
95
96 if ($ar = $db->Fetch())
97 {
98 $str = CUser::FormatName(COption::GetOptionString("bizproc", "name_template", CSite::GetNameFormat(false), SITE_ID), $ar, true, false);
99 if ($appendId)
100 {
101 $str = $str." [".$ar["ID"]."]";
102 }
103 return str_replace(",", " ", $str);
104 }
105 }
106 else if (str_starts_with($arUsers, 'group_'))
107 {
108 $str = self::getExtendedGroupName($arUsers, $appendId);
109
110 return str_replace([',', ';'], [' ', ' '], $str);
111 }
112
113 return str_replace(",", " ", $arUsers);
114 }
115 }
116
117 public static function usersArrayToString($users, $arWorkflowTemplate, $documentType, $appendId = true)
118 {
119 if (static::isEmptyValue($users))
120 {
121 return '';
122 }
123
124 $uniqueUsers = is_array($users) ? [] : $users;
125 if (is_array($users))
126 {
127 foreach ($users as $user)
128 {
129 if (is_string($user))
130 {
131 $uniqueUsers[$user] = $user;
132 }
133 else
134 {
135 $uniqueUsers[] = $user;
136 }
137 }
138
139 $uniqueUsers = array_values($uniqueUsers);
140 }
141
142 $arAllowableUserGroups = [];
143 $arAllowableUserGroupsTmp = CBPDocument::GetAllowableUserGroups($documentType);
144 foreach ($arAllowableUserGroupsTmp as $k1 => $v1)
145 {
146 $arAllowableUserGroups[mb_strtolower($k1)] = str_replace(",", " ", $v1);
147 }
148
149 return self::UsersArrayToStringInternal($uniqueUsers, $arWorkflowTemplate, $arAllowableUserGroups, $appendId);
150 }
151
152 public static function usersStringToArray($strUsers, $documentType, &$arErrors, $callbackFunction = null)
153 {
154 $arErrors = [];
155
156 $strUsers = trim($strUsers);
157 if ($strUsers == '')
158 {
159 return ($callbackFunction != null) ? [[], []] : [];
160 }
161
162 if (CBPActivity::isExpression($strUsers))
163 {
164 return ($callbackFunction != null) ? [[$strUsers], []] : [$strUsers];
165 }
166
167 $arUsers = [];
168 $strUsers = str_replace(";", ",", $strUsers);
169 $arUsersTmp = explode(",", $strUsers);
170 foreach ($arUsersTmp as $user)
171 {
172 $user = trim($user);
173 if ($user <> '')
174 {
175 $arUsers[] = $user;
176 }
177 }
178
179 $arAllowableUserGroups = null;
180
181 $result = [];
182 $resultAlt = [];
183 foreach ($arUsers as $user)
184 {
185 $bCorrectUser = false;
186 $bNotFoundUser = true;
188 {
189 $bCorrectUser = true;
190 $result[] = $user;
191 }
192 else
193 {
194 if ($arAllowableUserGroups == null)
195 {
196 $arAllowableUserGroups = [];
197 $arAllowableUserGroupsTmp = CBPDocument::GetAllowableUserGroups($documentType);
198 foreach ($arAllowableUserGroupsTmp as $k1 => $v1)
199 {
200 $arAllowableUserGroups[mb_strtolower($k1)] = mb_strtolower($v1);
201 }
202 }
203
204 if (array_key_exists(mb_strtolower($user), $arAllowableUserGroups))
205 {
206 $bCorrectUser = true;
207 $result[] = $user;
208 }
209 elseif (($k1 = array_search(mb_strtolower($user), $arAllowableUserGroups)) !== false)
210 {
211 $bCorrectUser = true;
212 $result[] = $k1;
213 }
214 elseif (preg_match('#\[([A-Z]{1,}[0-9A-Z_]+)\]$#i', $user, $matches))
215 {
216 $bCorrectUser = true;
217 $code = $matches[1];
218
219 if (
220 preg_match('/^(D|DR)(\d+)$/', $code, $match)
221 && Loader::includeModule('humanresources')
222 )
223 {
224 $departmentId = $match[2];
225 $node =
226 Container::getNodeRepository()
227 ->getByAccessCode(
228 DepartmentBackwardAccessCode::makeById((int)$departmentId)
229 )
230 ;
231 if ($node)
232 {
233 $code = 'hr' . ($match[1] === 'DR' ? 'r' : '') . $node->id;
234 }
235 }
236
237 $result[] = 'group_' . mb_strtolower($code);
238 }
239 else
240 {
241 $ar = self::SearchUserByName($user);
242 $cnt = count($ar);
243 if ($cnt == 1)
244 {
245 $bCorrectUser = true;
246 $result[] = 'user_' . $ar[0];
247 }
248 elseif ($cnt > 1)
249 {
250 $bNotFoundUser = false;
251 $arErrors[] = [
252 'code' => 'Ambiguous',
253 'message' => str_replace(
254 '#USER#',
256 GetMessage('BPCGHLP_AMBIGUOUS_USER')
257 ),
258 ];
259 }
260 elseif ($callbackFunction != null)
261 {
262 $s = call_user_func_array($callbackFunction, [$user]);
263 if ($s != null)
264 {
265 $resultAlt[] = $s;
266 $bCorrectUser = true;
267 }
268 }
269 }
270 }
271
272 if (!$bCorrectUser)
273 {
274 if ($bNotFoundUser)
275 {
276 $arErrors[] = [
277 'code' => 'NotFound',
278 'message' => str_replace(
279 '#USER#',
281 GetMessage('BPCGHLP_INVALID_USER')
282 ),
283 ];
284 }
285 }
286 }
287
288 return ($callbackFunction != null) ? [$result, $resultAlt] : $result;
289 }
290
291 private static function searchUserByName($user)
292 {
293 $user = trim($user);
294 if ($user == '')
295 {
296 return [];
297 }
298
299 $userId = 0;
300 if ($user."|" == intval($user)."|")
301 {
302 $userId = intval($user);
303 }
304
305 if ($userId <= 0)
306 {
307 $arMatches = [];
308 if (preg_match('#\[(\d+)\]#i', $user, $arMatches))
309 {
310 $userId = intval($arMatches[1]);
311 }
312 }
313
314 $arResult = [];
315
316 $dbUsers = false;
317 if ($userId > 0)
318 {
319 $arFilter = array("ID_EQUAL_EXACT" => $userId);
320
321 $dbUsers = CUser::GetList(
322 "LAST_NAME",
323 "asc",
324 $arFilter,
325 [
326 'FIELDS' => ['ID'],
327 'NAV_PARAMS' => false,
328 ]
329 );
330 }
331 else
332 {
333 $userLogin = "";
334 $arMatches = [];
335 if (preg_match('#\‍((.+?)\‍)#i', $user, $arMatches))
336 {
337 $userLogin = $arMatches[1];
338 $user = trim(str_replace("(".$userLogin.")", "", $user));
339 }
340
341 $userEmail = "";
342 $arMatches = [];
343 if (preg_match("#<(.+?)>#i", $user, $arMatches))
344 {
345 if (check_email($arMatches[1]))
346 {
347 $userEmail = $arMatches[1];
348 $user = trim(Str_Replace("<".$userEmail.">", "", $user));
349 }
350 }
351
352 $arUser = [];
353 $arUserTmp = explode(" ", $user);
354 foreach ($arUserTmp as $s)
355 {
356 $s = trim($s);
357 if ($s <> '')
358 {
359 $arUser[] = $s;
360 }
361 }
362 if ($userLogin <> '')
363 {
364 $arUser[] = $userLogin;
365 }
366
367 $dbUsers = CUser::SearchUserByName($arUser, $userEmail, true);
368 }
369
370 if ($dbUsers)
371 {
372 while ($arUsers = $dbUsers->GetNext())
373 {
374 $arResult[] = $arUsers["ID"];
375 }
376 }
377
378 return $arResult;
379 }
380
381 public static function formatTimePeriod($period)
382 {
383 $period = intval($period);
384
385 $days = intval($period / 86400);
386 $period = $period - $days * 86400;
387
388 $hours = intval($period / 3600);
389 $period = $period - $hours * 3600;
390
391 $minutes = intval($period / 60);
392 $period = $period - $minutes * 60;
393
394 $seconds = intval($period);
395
396 $s = "";
397 if ($days > 0)
398 {
399 $s .= str_replace(
400 array("#VAL#", "#UNIT#"),
401 array($days, self::MakeWord($days, array(GetMessage("BPCGHLP_DAY1"), GetMessage("BPCGHLP_DAY2"), GetMessage("BPCGHLP_DAY3")))),
402 "#VAL# #UNIT# "
403 );
404 }
405 if ($hours > 0)
406 {
407 $s .= str_replace(
408 array("#VAL#", "#UNIT#"),
409 array($hours, self::MakeWord($hours, array(GetMessage("BPCGHLP_HOUR1"), GetMessage("BPCGHLP_HOUR2"), GetMessage("BPCGHLP_HOUR3")))),
410 "#VAL# #UNIT# "
411 );
412 }
413 if ($minutes > 0)
414 {
415 $s .= str_replace(
416 array("#VAL#", "#UNIT#"),
417 array($minutes, self::MakeWord($minutes, array(GetMessage("BPCGHLP_MIN1"), GetMessage("BPCGHLP_MIN2"), GetMessage("BPCGHLP_MIN3")))),
418 "#VAL# #UNIT# "
419 );
420 }
421 if ($seconds > 0)
422 {
423 $s .= str_replace(
424 array("#VAL#", "#UNIT#"),
425 array($seconds, self::MakeWord($seconds, array(GetMessage("BPCGHLP_SEC1"), GetMessage("BPCGHLP_SEC2"), GetMessage("BPCGHLP_SEC3")))),
426 "#VAL# #UNIT# "
427 );
428 }
429
430 return $s;
431 }
432
433 private static function makeWord($val, $arWords)
434 {
435 if ($val > 20)
436 {
437 $val = ($val % 10);
438 }
439
440 if ($val == 1)
441 {
442 return $arWords[0];
443 }
444 elseif ($val > 1 && $val < 5)
445 {
446 return $arWords[1];
447 }
448 else
449 {
450 return $arWords[2];
451 }
452 }
453
454 public static function getFilterOperation($key)
455 {
456 $strNegative = "N";
457 if (mb_substr($key, 0, 1) == "!")
458 {
459 $key = mb_substr($key, 1);
460 $strNegative = "Y";
461 }
462
463 $strOrNull = "N";
464 if (mb_substr($key, 0, 1) == "+")
465 {
466 $key = mb_substr($key, 1);
467 $strOrNull = "Y";
468 }
469
470 if (mb_substr($key, 0, 2) == ">=")
471 {
472 $key = mb_substr($key, 2);
473 $strOperation = ">=";
474 }
475 elseif (mb_substr($key, 0, 1) == ">")
476 {
477 $key = mb_substr($key, 1);
478 $strOperation = ">";
479 }
480 elseif (mb_substr($key, 0, 2) == "<=")
481 {
482 $key = mb_substr($key, 2);
483 $strOperation = "<=";
484 }
485 elseif (mb_substr($key, 0, 1) == "<")
486 {
487 $key = mb_substr($key, 1);
488 $strOperation = "<";
489 }
490 elseif (mb_substr($key, 0, 1) == "@")
491 {
492 $key = mb_substr($key, 1);
493 $strOperation = "=";
494 $strNegative = 'N';
495 }
496 elseif (mb_substr($key, 0, 1) == "~")
497 {
498 $key = mb_substr($key, 1);
499 $strOperation = "LIKE";
500 }
501 elseif (mb_substr($key, 0, 1) == "%")
502 {
503 $key = mb_substr($key, 1);
504 $strOperation = "QUERY";
505 }
506 else
507 {
508 $strOperation = "=";
509 }
510
511 return array("FIELD" => $key, "NEGATIVE" => $strNegative, "OPERATION" => $strOperation, "OR_NULL" => $strOrNull);
512 }
513
514 public static function prepareSql(&$arFields, $arOrder, $arFilter, $arGroupBy, $arSelectFields)
515 {
516 global $DB;
517
518 $strSqlSelect = "";
519 $strSqlFrom = "";
520 $strSqlWhere = "";
521 $strSqlGroupBy = "";
522 $strSqlOrderBy = "";
523
524 $arOrder = array_change_key_case($arOrder, CASE_UPPER);
525
526 $arGroupByFunct = array("COUNT", "AVG", "MIN", "MAX", "SUM");
527
528 $arAlreadyJoined = [];
529
530 // GROUP BY -->
531 if (is_array($arGroupBy) && count($arGroupBy)>0)
532 {
533 $arSelectFields = $arGroupBy;
534 foreach ($arGroupBy as $key => $val)
535 {
536 $val = mb_strtoupper($val);
537 $key = mb_strtoupper($key);
538 if (array_key_exists($val, $arFields) && !in_array($key, $arGroupByFunct))
539 {
540 if ($strSqlGroupBy <> '')
541 $strSqlGroupBy .= ", ";
542 $strSqlGroupBy .= $arFields[$val]["FIELD"];
543
544 if (!empty($arFields[$val]["FROM"]))
545 {
546 $toJoin = (array)$arFields[$val]["FROM"];
547 foreach ($toJoin as $join)
548 {
549 if (in_array($join, $arAlreadyJoined))
550 {
551 continue;
552 }
553 if ($strSqlFrom <> '')
554 {
555 $strSqlFrom .= " ";
556 }
557 $strSqlFrom .= $join;
558 $arAlreadyJoined[] = $join;
559 }
560 }
561 }
562 }
563 }
564 // <-- GROUP BY
565
566 // SELECT -->
567 $arFieldsKeys = array_keys($arFields);
568
569 if (is_array($arGroupBy) && count($arGroupBy)==0)
570 {
571 $strSqlSelect = "COUNT(%%_DISTINCT_%% ".$arFields[$arFieldsKeys[0]]["FIELD"].") as CNT ";
572 }
573 else
574 {
575 if (isset($arSelectFields) && !is_array($arSelectFields) && is_string($arSelectFields) && $arSelectFields <> '' && array_key_exists($arSelectFields, $arFields))
576 $arSelectFields = array($arSelectFields);
577
578 if (!isset($arSelectFields)
579 || !is_array($arSelectFields)
580 || count($arSelectFields)<=0
581 || in_array("*", $arSelectFields))
582 {
583 for ($i = 0, $cnt = count($arFieldsKeys); $i < $cnt; $i++)
584 {
585 if (isset($arFields[$arFieldsKeys[$i]]["WHERE_ONLY"])
586 && $arFields[$arFieldsKeys[$i]]["WHERE_ONLY"] == "Y")
587 {
588 continue;
589 }
590
591 if ($strSqlSelect <> '')
592 $strSqlSelect .= ", ";
593
594 if ($arFields[$arFieldsKeys[$i]]["TYPE"] == "datetime")
595 {
596 if (array_key_exists($arFieldsKeys[$i], $arOrder))
597 $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD"]." as ".$arFieldsKeys[$i]."_X1, ";
598
599 $strSqlSelect .= $DB->DateToCharFunction($arFields[$arFieldsKeys[$i]]["FIELD"], "FULL")." as ".$arFieldsKeys[$i];
600 }
601 elseif ($arFields[$arFieldsKeys[$i]]["TYPE"] == "date")
602 {
603 if (array_key_exists($arFieldsKeys[$i], $arOrder))
604 $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD"]." as ".$arFieldsKeys[$i]."_X1, ";
605
606 $strSqlSelect .= $DB->DateToCharFunction($arFields[$arFieldsKeys[$i]]["FIELD"], "SHORT")." as ".$arFieldsKeys[$i];
607 }
608 else
609 $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD"]." as ".$arFieldsKeys[$i];
610
611 if (!empty($arFields[$arFieldsKeys[$i]]["FROM"]))
612 {
613 $toJoin = (array)$arFields[$arFieldsKeys[$i]]["FROM"];
614 foreach ($toJoin as $join)
615 {
616 if (in_array($join, $arAlreadyJoined))
617 continue;
618 if ($strSqlFrom <> '')
619 $strSqlFrom .= " ";
620 $strSqlFrom .= $join;
621 $arAlreadyJoined[] = $join;
622 }
623 }
624 }
625 }
626 else
627 {
628 foreach ($arOrder as $by => $order)
629 {
630 if (
631 isset($arFields[$by])
632 && !in_array($by, $arSelectFields)
633 && ($arFields[$by]["TYPE"] == "date" || $arFields[$by]["TYPE"] == "datetime")
634 )
635 $arSelectFields[] = $by;
636 }
637
638 foreach ($arSelectFields as $key => $val)
639 {
640 $val = mb_strtoupper($val);
641 $key = mb_strtoupper($key);
642 if (array_key_exists($val, $arFields))
643 {
644 if ($strSqlSelect <> '')
645 $strSqlSelect .= ", ";
646
647 if (in_array($key, $arGroupByFunct))
648 {
649 $strSqlSelect .= $key."(".$arFields[$val]["FIELD"].") as ".$val;
650 }
651 else
652 {
653 if ($arFields[$val]["TYPE"] == "datetime")
654 {
655 if (array_key_exists($val, $arOrder))
656 $strSqlSelect .= $arFields[$val]["FIELD"]." as ".$val."_X1, ";
657
658 $strSqlSelect .= $DB->DateToCharFunction($arFields[$val]["FIELD"], "FULL")." as ".$val;
659 }
660 elseif ($arFields[$val]["TYPE"] == "date")
661 {
662 if (array_key_exists($val, $arOrder))
663 $strSqlSelect .= $arFields[$val]["FIELD"]." as ".$val."_X1, ";
664
665 $strSqlSelect .= $DB->DateToCharFunction($arFields[$val]["FIELD"], "SHORT")." as ".$val;
666 }
667 else
668 $strSqlSelect .= $arFields[$val]["FIELD"]." as ".$val;
669 }
670 if (!empty($arFields[$val]["FROM"]))
671 {
672 $toJoin = (array)$arFields[$val]["FROM"];
673 foreach ($toJoin as $join)
674 {
675 if (in_array($join, $arAlreadyJoined))
676 continue;
677 if ($strSqlFrom <> '')
678 $strSqlFrom .= " ";
679 $strSqlFrom .= $join;
680 $arAlreadyJoined[] = $join;
681 }
682 }
683 }
684 }
685 }
686
687 if ($strSqlGroupBy <> '')
688 {
689 if ($strSqlSelect <> '')
690 $strSqlSelect .= ", ";
691 $strSqlSelect .= "COUNT(%%_DISTINCT_%% ".$arFields[$arFieldsKeys[0]]["FIELD"].") as CNT";
692 }
693 else
694 $strSqlSelect = "%%_DISTINCT_%% ".$strSqlSelect;
695 }
696 // <-- SELECT
697
698 // WHERE -->
699 $arSqlSearch = [];
700
701 if (!is_array($arFilter))
702 $filter_keys = [];
703 else
704 $filter_keys = array_keys($arFilter);
705
706 for ($i = 0, $cnt = count($filter_keys); $i < $cnt; $i++)
707 {
708 $vals = $arFilter[$filter_keys[$i]];
709 if (!is_array($vals))
710 $vals = array($vals);
711
712 $key = $filter_keys[$i];
713 $key_res = CBPHelper::GetFilterOperation($key);
714 $key = $key_res["FIELD"];
715 $strNegative = $key_res["NEGATIVE"];
716 $strOperation = $key_res["OPERATION"];
717 $strOrNull = $key_res["OR_NULL"];
718
719 if (array_key_exists($key, $arFields))
720 {
721 $arSqlSearch_tmp = array();
722 for ($j = 0, $cntj = count($vals); $j < $cntj; $j++)
723 {
724 $val = $vals[$j];
725
726 if (isset($arFields[$key]["WHERE"]))
727 {
728 $arSqlSearch_tmp1 = call_user_func_array(
729 $arFields[$key]["WHERE"],
730 array($val, $key, $strOperation, $strNegative, $arFields[$key]["FIELD"], $arFields, $arFilter)
731 );
732 if ($arSqlSearch_tmp1 !== false)
733 $arSqlSearch_tmp[] = $arSqlSearch_tmp1;
734 }
735 else
736 {
737 if ($arFields[$key]["TYPE"] == "int")
738 {
739 if ((intval($val) == 0) && (mb_strpos($strOperation, "=") !== False))
740 $arSqlSearch_tmp[] = "(".$arFields[$key]["FIELD"]." IS ".(($strNegative == "Y") ? "NOT " : "")."NULL) ".(($strNegative == "Y") ? "AND" : "OR")." ".(($strNegative == "Y") ? "NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." 0)";
741 else
742 $arSqlSearch_tmp[] = (($strNegative == "Y") ? " ".$arFields[$key]["FIELD"]." IS NULL OR NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".intval($val)." )";
743 }
744 elseif ($arFields[$key]["TYPE"] == "double")
745 {
746 $val = str_replace(",", ".", $val);
747
748 if ((DoubleVal($val) == 0) && (mb_strpos($strOperation, "=") !== False))
749 $arSqlSearch_tmp[] = "(".$arFields[$key]["FIELD"]." IS ".(($strNegative == "Y") ? "NOT " : "")."NULL) ".(($strNegative == "Y") ? "AND" : "OR")." ".(($strNegative == "Y") ? "NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." 0)";
750 else
751 $arSqlSearch_tmp[] = (($strNegative == "Y") ? " ".$arFields[$key]["FIELD"]." IS NULL OR NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".DoubleVal($val)." )";
752 }
753 elseif ($arFields[$key]["TYPE"] == "string" || $arFields[$key]["TYPE"] == "char")
754 {
755 if ($strOperation == "QUERY")
756 {
757 $arSqlSearch_tmp[] = GetFilterQuery($arFields[$key]["FIELD"], $val, "Y");
758 }
759 else
760 {
761 if (($val == '') && (mb_strpos($strOperation, "=") !== False))
762 $arSqlSearch_tmp[] = "(".$arFields[$key]["FIELD"]." IS ".(($strNegative == "Y") ? "NOT " : "")."NULL) ".(($strNegative == "Y") ? "AND NOT" : "OR")." (".$DB->Length($arFields[$key]["FIELD"])." <= 0) ".(($strNegative == "Y") ? "AND NOT" : "OR")." (".$arFields[$key]["FIELD"]." ".$strOperation." '".$DB->ForSql($val)."' )";
763 else
764 $arSqlSearch_tmp[] = (($strNegative == "Y") ? " ".$arFields[$key]["FIELD"]." IS NULL OR NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." '".$DB->ForSql($val)."' )";
765 }
766 }
767 elseif ($arFields[$key]["TYPE"] == "datetime")
768 {
769 if ($val == '')
770 $arSqlSearch_tmp[] = ($strNegative=="Y"?"NOT":"")."(".$arFields[$key]["FIELD"]." IS NULL)";
771 else
772 $arSqlSearch_tmp[] = ($strNegative=="Y"?" ".$arFields[$key]["FIELD"]." IS NULL OR NOT ":"")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".$DB->CharToDateFunction($DB->ForSql($val), "FULL").")";
773 }
774 elseif ($arFields[$key]["TYPE"] == "date")
775 {
776 if ($val == '')
777 $arSqlSearch_tmp[] = ($strNegative=="Y"?"NOT":"")."(".$arFields[$key]["FIELD"]." IS NULL)";
778 else
779 $arSqlSearch_tmp[] = ($strNegative=="Y"?" ".$arFields[$key]["FIELD"]." IS NULL OR NOT ":"")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".$DB->CharToDateFunction($DB->ForSql($val), "SHORT").")";
780 }
781 }
782 }
783
784 if (!empty($arFields[$key]["FROM"]))
785 {
786 $toJoin = (array)$arFields[$key]["FROM"];
787 foreach ($toJoin as $join)
788 {
789 if (in_array($join, $arAlreadyJoined))
790 continue;
791 if ($strSqlFrom <> '')
792 $strSqlFrom .= " ";
793 $strSqlFrom .= $join;
794 $arAlreadyJoined[] = $join;
795 }
796 }
797
798 $strSqlSearch_tmp = "";
799 for ($j = 0, $cntj = count($arSqlSearch_tmp); $j < $cntj; $j++)
800 {
801 if ($j > 0)
802 $strSqlSearch_tmp .= ($strNegative=="Y" ? " AND " : " OR ");
803 $strSqlSearch_tmp .= "(".$arSqlSearch_tmp[$j].")";
804 }
805 if ($strOrNull == "Y")
806 {
807 if ($strSqlSearch_tmp <> '')
808 $strSqlSearch_tmp .= ($strNegative=="Y" ? " AND " : " OR ");
809 $strSqlSearch_tmp .= "(".$arFields[$key]["FIELD"]." IS ".($strNegative=="Y" ? "NOT " : "")."NULL)";
810
811 if ($strSqlSearch_tmp <> '')
812 $strSqlSearch_tmp .= ($strNegative=="Y" ? " AND " : " OR ");
813 if ($arFields[$key]["TYPE"] == "int" || $arFields[$key]["TYPE"] == "double")
814 $strSqlSearch_tmp .= "(".$arFields[$key]["FIELD"]." ".($strNegative=="Y" ? "<>" : "=")." 0)";
815 elseif ($arFields[$key]["TYPE"] == "string" || $arFields[$key]["TYPE"] == "char")
816 $strSqlSearch_tmp .= "(".$arFields[$key]["FIELD"]." ".($strNegative=="Y" ? "<>" : "=")." '')";
817 }
818
819 if ($strSqlSearch_tmp != "")
820 $arSqlSearch[] = "(".$strSqlSearch_tmp.")";
821 }
822 }
823
824 for ($i = 0, $cnt = count($arSqlSearch); $i < $cnt; $i++)
825 {
826 if ($strSqlWhere <> '')
827 $strSqlWhere .= " AND ";
828 $strSqlWhere .= "(".$arSqlSearch[$i].")";
829 }
830 // <-- WHERE
831
832 // ORDER BY -->
833 $arSqlOrder = Array();
834 foreach ($arOrder as $by => $order)
835 {
836 $by = mb_strtoupper($by);
837 $order = $order ? mb_strtoupper($order) : '';
838
839 if ($order != "ASC")
840 $order = "DESC";
841 else
842 $order = "ASC";
843
844 if (array_key_exists($by, $arFields))
845 {
846 if ($arFields[$by]["TYPE"] == "datetime" || $arFields[$by]["TYPE"] == "date")
847 $arSqlOrder[] = " ".$by."_X1 ".$order." ";
848 else
849 $arSqlOrder[] = " ".$arFields[$by]["FIELD"]." ".$order." ";
850
851 if (!empty($arFields[$by]["FROM"]))
852 {
853 $toJoin = (array)$arFields[$by]["FROM"];
854 foreach ($toJoin as $join)
855 {
856 if (in_array($join, $arAlreadyJoined))
857 continue;
858 if ($strSqlFrom <> '')
859 $strSqlFrom .= " ";
860 $strSqlFrom .= $join;
861 $arAlreadyJoined[] = $join;
862 }
863 }
864 }
865 }
866
867 $strSqlOrderBy = "";
868 DelDuplicateSort($arSqlOrder);
869 for ($i = 0, $cnt = count($arSqlOrder); $i < $cnt; $i++)
870 {
871 if ($strSqlOrderBy <> '')
872 $strSqlOrderBy .= ", ";
873
874 $strSqlOrderBy .= $arSqlOrder[$i];
875 }
876 // <-- ORDER BY
877
878 return array(
879 "SELECT" => $strSqlSelect,
880 "FROM" => $strSqlFrom,
881 "WHERE" => $strSqlWhere,
882 "GROUPBY" => $strSqlGroupBy,
883 "ORDERBY" => $strSqlOrderBy,
884 );
885 }
886
887 public static function parseDocumentId($parameterDocumentId)
888 {
889 if (!is_array($parameterDocumentId))
890 {
891 $parameterDocumentId = array($parameterDocumentId);
892 }
893
894 $moduleId = "";
895 $entity = "";
896 $documentId = "";
897
898 $cnt = count($parameterDocumentId);
899 if ($cnt > 2)
900 {
901 $documentId = $parameterDocumentId[2];
902 $entity = $parameterDocumentId[1];
903 $moduleId = $parameterDocumentId[0];
904 }
905 elseif ($cnt == 2)
906 {
907 $documentId = $parameterDocumentId[1];
908 $entity = $parameterDocumentId[0];
909 }
910
911 $moduleId = is_scalar($moduleId) ? trim($moduleId) : '';
912 $entity = is_scalar($entity) ? trim($entity) : '';
913 $documentId = is_scalar($documentId) ? trim($documentId) : '';
914
915 if ($documentId === '')
916 {
917 throw new CBPArgumentNullException("documentId");
918 }
919
920 if ($entity === '')
921 {
922 throw new CBPArgumentNullException("entity");
923 }
924
926 {
927 throw new CBPArgumentNullException("moduleId");
928 }
929
930 return [$moduleId, $entity, $documentId];
931 }
932
933 public static function parseDocumentIdArray($parameterDocumentId)
934 {
935 if (!is_array($parameterDocumentId))
936 {
937 $parameterDocumentId = array($parameterDocumentId);
938 }
939
940 $moduleId = "";
941 $entity = "";
942 $documentId = "";
943
944 $cnt = count($parameterDocumentId);
945 if ($cnt > 2)
946 {
947 $documentId = $parameterDocumentId[2];
948 $entity = $parameterDocumentId[1];
949 $moduleId = $parameterDocumentId[0];
950 }
951 elseif ($cnt == 2)
952 {
953 $documentId = $parameterDocumentId[1];
954 $entity = $parameterDocumentId[0];
955 }
956
957 $moduleId = trim($moduleId);
958
959 $entity = trim($entity);
960 if ($entity == '')
961 {
962 throw new CBPArgumentNullException("entity");
963 }
964
965 if (is_array($documentId))
966 {
967 $a = [];
968 foreach ($documentId as $v)
969 {
970 $v = trim($v);
971 if ($v <> '')
972 {
973 $a[] = $v;
974 }
975 }
976 $documentId = $a;
977 if (count($documentId) <= 0)
978 {
979 throw new CBPArgumentNullException("documentId");
980 }
981 }
982 else
983 {
984 $documentId = trim($documentId);
985 if ($documentId == '')
986 {
987 throw new CBPArgumentNullException("documentId");
988 }
989 $documentId = array($documentId);
990 }
991
992 return [$moduleId, $entity, $documentId];
993 }
994
995 public static function getFieldValuePrintable($fieldName, $fieldType, $result)
996 {
997 $newResult = null;
998
999 switch ($fieldType)
1000 {
1001 case "user":
1002 if (is_array($result))
1003 {
1004 $newResult = [];
1005 foreach ($result as $r)
1006 {
1007 $newResult[] = CBPHelper::ConvertUserToPrintableForm($r);
1008 }
1009 }
1010 else
1011 {
1012 $newResult = CBPHelper::ConvertUserToPrintableForm($result);
1013 }
1014 break;
1015
1016 case "file":
1017 if (is_array($result))
1018 {
1019 $newResult = array();
1020 foreach ($result as $r)
1021 {
1022 $r = intval($r);
1023 $dbImg = CFile::GetByID($r);
1024 if ($arImg = $dbImg->Fetch())
1025 {
1026 $newResult[] = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$r."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
1027 }
1028 }
1029 }
1030 else
1031 {
1032 $result = intval($result);
1033 $dbImg = CFile::GetByID($result);
1034 if ($arImg = $dbImg->Fetch())
1035 {
1036 $newResult = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$result."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
1037 }
1038 }
1039 break;
1040
1041 default:
1042 $newResult = $result;
1043 }
1044
1045 return $newResult;
1046 }
1047
1048 public static function convertUserToPrintableForm($userId, $nameTemplate = "", $htmlSpecialChars = true)
1049 {
1050 if (mb_substr($userId, 0, mb_strlen("user_")) == "user_")
1051 {
1052 $userId = mb_substr($userId, mb_strlen("user_"));
1053 }
1054
1055 if (empty($nameTemplate))
1056 {
1057 $nameTemplate = COption::GetOptionString("bizproc", "name_template", CSite::GetNameFormat(false), SITE_ID);
1058 }
1059
1060 $userId = intval($userId);
1061
1062 $db = CUser::GetList(
1063 "LAST_NAME",
1064 "asc",
1065 ["ID_EQUAL_EXACT" => $userId],
1066 [
1067 "NAV_PARAMS" => false,
1068 'FIELDS'=> [
1069 'ID',
1070 'LOGIN',
1071 'EMAIL',
1072 'NAME',
1073 'LAST_NAME',
1074 'SECOND_NAME',
1075 ],
1076 ]
1077 );
1078
1079 $str = "";
1080 if ($ar = $db->Fetch())
1081 {
1082 $str = CUser::FormatName($nameTemplate, $ar, true, $htmlSpecialChars);
1083 $str = $str." [".$ar["ID"]."]";
1084 $str = str_replace(",", " ", $str);
1085 }
1086
1087 return $str;
1088 }
1089
1097 public static function getJSFunctionsForFields($objectName, $arDocumentFields, $arDocumentFieldTypes)
1098 {
1099 ob_start();
1101
1102 return ob_get_clean();
1103 }
1104
1105 public static function getDocumentFieldTypes()
1106 {
1107 $arResult = array(
1108 "string" => array("Name" => GetMessage("BPCGHLP_PROP_STRING"), "BaseType" => "string"),
1109 "text" => array("Name" => GetMessage("BPCGHLP_PROP_TEXT"), "BaseType" => "text"),
1110 "int" => array("Name" => GetMessage("BPCGHLP_PROP_INT"), "BaseType" => "int"),
1111 "double" => array("Name" => GetMessage("BPCGHLP_PROP_DOUBLE"), "BaseType" => "double"),
1112 "select" => array("Name" => GetMessage("BPCGHLP_PROP_SELECT"), "BaseType" => "select"),
1113 "internalselect" => array("Name" => GetMessage("BPCGHLP_PROP_INTERNALSELECT_1"), "BaseType" => "internalselect"),
1114 "bool" => array("Name" => GetMessage("BPCGHLP_PROP_BOOL"), "BaseType" => "bool"),
1115 "date" => array("Name" => GetMessage("BPCGHLP_PROP_DATA"), "BaseType" => "date"),
1116 "datetime" => array("Name" => GetMessage("BPCGHLP_PROP_DATETIME"), "BaseType" => "datetime"),
1117 "user" => array("Name" => GetMessage("BPCGHLP_PROP_USER"), "BaseType" => "user"),
1118 "file" => array("Name" => GetMessage("BPCGHLP_PROP_FILE"), "BaseType" => "file"),
1119 );
1120
1121 return $arResult;
1122 }
1123
1127 public static function getGUIFieldEdit($documentType, $formName, $fieldName, $fieldValue, $arDocumentField, $bAllowSelection)
1128 {
1129 return self::GetFieldInputControl(
1130 $documentType,
1131 $arDocumentField,
1132 array("Form" => $formName, "Field" => $fieldName),
1133 $fieldValue,
1134 $bAllowSelection
1135 );
1136 }
1137
1138 public static function getFieldInputControl($documentType, $arFieldType, $arFieldName, $fieldValue, $bAllowSelection = false)
1139 {
1140 if (!is_array($fieldValue) || is_array($fieldValue) && CBPHelper::IsAssociativeArray($fieldValue))
1141 {
1142 $fieldValue = array($fieldValue);
1143 }
1144
1145 ob_start();
1146
1147 if ($arFieldType["Type"] == "select")
1148 {
1149 $fieldValueTmp = $fieldValue;
1150 ?>
1151 <select id="id_<?= $arFieldName["Field"] ?>" name="<?= $arFieldName["Field"].($arFieldType["Multiple"] ? "[]" : "") ?>"<?= ($arFieldType["Multiple"] ? ' size="5" multiple' : '') ?>>
1152 <?
1153 if (!$arFieldType["Required"])
1154 echo '<option value="">['.GetMessage("BPCGHLP_NOT_SET").']</option>';
1155 foreach ($arFieldType["Options"] as $k => $v)
1156 {
1157 $ind = array_search($k, $fieldValueTmp);
1158 echo '<option value="'.htmlspecialcharsbx($k).'"'.($ind !== false ? ' selected' : '').'>'.htmlspecialcharsbx($v).'</option>';
1159 if ($ind !== false)
1160 unset($fieldValueTmp[$ind]);
1161 }
1162 ?>
1163 </select>
1164 <?
1165 if ($bAllowSelection)
1166 {
1167 ?>
1168 <br /><input type="text" id="id_<?= $arFieldName["Field"] ?>_text" name="<?= $arFieldName["Field"] ?>_text" value="<?
1169 if (count($fieldValueTmp) > 0)
1170 {
1171 $a = array_values($fieldValueTmp);
1172 echo htmlspecialcharsbx($a[0]);
1173 }
1174 ?>"><?
1175 echo CBPHelper::renderControlSelectorButton('id_'.$arFieldName["Field"].'_text', 'select');
1176 }
1177 }
1178 elseif ($arFieldType["Type"] == "user")
1179 {
1180 $fieldValue = CBPHelper::UsersArrayToString($fieldValue, null, $documentType);
1181 ?><input type="text" size="40" id="id_<?= $arFieldName["Field"] ?>" name="<?= $arFieldName["Field"] ?>" value="<?= htmlspecialcharsbx($fieldValue) ?>"><? echo CBPHelper::renderControlSelectorButton('id_'.$arFieldName["Field"], 'user');
1182 }
1183 else
1184 {
1185 if (!array_key_exists("CBPVirtualDocumentCloneRowPrinted", $GLOBALS) && $arFieldType["Multiple"])
1186 {
1187 $GLOBALS["CBPVirtualDocumentCloneRowPrinted"] = 1;
1188 ?>
1189 <script>
1190 <!--
1191 function CBPVirtualDocumentCloneRow(tableID)
1192 {
1193 var tbl = document.getElementById(tableID);
1194 var cnt = tbl.rows.length;
1195 var oRow = tbl.insertRow(cnt);
1196 var oCell = oRow.insertCell(0);
1197 var sHTML = tbl.rows[cnt - 1].cells[0].innerHTML;
1198 var p = 0;
1199 while (true)
1200 {
1201 var s = sHTML.indexOf('[n', p);
1202 if (s < 0)
1203 break;
1204 var e = sHTML.indexOf(']', s);
1205 if (e < 0)
1206 break;
1207 var n = parseInt(sHTML.substr(s + 2, e - s));
1208 sHTML = sHTML.substr(0, s) + '[n' + (++n) + ']' + sHTML.substr(e + 1);
1209 p = s + 1;
1210 }
1211 var p = 0;
1212 while (true)
1213 {
1214 var s = sHTML.indexOf('__n', p);
1215 if (s < 0)
1216 break;
1217 var e = sHTML.indexOf('_', s + 2);
1218 if (e < 0)
1219 break;
1220 var n = parseInt(sHTML.substr(s + 3, e - s));
1221 sHTML = sHTML.substr(0, s) + '__n' + (++n) + '_' + sHTML.substr(e + 1);
1222 p = e + 1;
1223 }
1224 oCell.innerHTML = sHTML;
1225 var patt = new RegExp('<' + 'script' + '>[^\000]*?<' + '\/' + 'script' + '>', 'ig');
1226 var code = sHTML.match(patt);
1227 if (code)
1228 {
1229 for (var i = 0; i < code.length; i++)
1230 {
1231 if (code[i] != '')
1232 {
1233 var s = code[i].substring(8, code[i].length - 9);
1234 jsUtils.EvalGlobal(s);
1235 }
1236 }
1237 }
1238 }
1239 //-->
1240 </script>
1241 <?
1242 }
1243
1244 if ($arFieldType["Multiple"])
1245 echo '<table width="100%" border="0" cellpadding="2" cellspacing="2" id="CBPVirtualDocument_'.$arFieldName["Field"].'_Table">';
1246
1247 if ($bAllowSelection)
1248 {
1249 $arFieldType["BaseType"] = "string";
1250
1251 static $arDocumentTypes = null;
1252 if (is_null($arDocumentTypes))
1253 $arDocumentTypes = self::GetDocumentFieldTypes($documentType);
1254
1255 if (array_key_exists($arFieldType["Type"], $arDocumentTypes))
1256 $arFieldType["BaseType"] = $arDocumentTypes[$arFieldType["Type"]]["BaseType"];
1257 }
1258
1259 $fieldValueTmp = $fieldValue;
1260
1261 $ind = -1;
1262 foreach ($fieldValue as $key => $value)
1263 {
1264 $ind++;
1265 $fieldNameId = 'id_'.$arFieldName["Field"].'__n'.$ind.'_';
1266 $fieldNameName = $arFieldName["Field"].($arFieldType["Multiple"] ? "[n".$ind."]" : "");
1267
1268 if ($arFieldType["Multiple"])
1269 echo '<tr><td>';
1270
1271 switch ($arFieldType["Type"])
1272 {
1273 case "int":
1274 case "double":
1275 unset($fieldValueTmp[$key]);
1276 ?><input type="text" size="10" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>" value="<?= htmlspecialcharsbx($value) ?>"><?
1277 break;
1278 case "file":
1279 unset($fieldValueTmp[$key]);
1280 ?><input type="file" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>"><?
1281 break;
1282 case "bool":
1283 if (in_array($value, array("Y", "N")))
1284 unset($fieldValueTmp[$key]);
1285 ?>
1286 <select id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>">
1287 <?
1288 if (!$arFieldType["Required"])
1289 echo '<option value="">['.GetMessage("BPCGHLP_NOT_SET").']</option>';
1290 ?>
1291 <option value="Y"<?= (in_array("Y", $fieldValue) ? ' selected' : '') ?>><?= GetMessage("BPCGHLP_YES") ?></option>
1292 <option value="N"<?= (in_array("N", $fieldValue) ? ' selected' : '') ?>><?= GetMessage("BPCGHLP_NO") ?></option>
1293 </select>
1294 <?
1295 break;
1296 case "text":
1297 unset($fieldValueTmp[$key]);
1298 ?><textarea rows="5" cols="40" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>"><?= htmlspecialcharsbx($value) ?></textarea><?
1299 break;
1300 case "date":
1301 case "datetime":
1302 $v = "";
1303 if (!CBPActivity::isExpression($value))
1304 {
1305 $v = $value;
1306 unset($fieldValueTmp[$key]);
1307 }
1308 echo CAdminCalendar::CalendarDate($fieldNameName, $v, 19, ($arFieldType["Type"] == "date"));
1309 break;
1310 default:
1311 unset($fieldValueTmp[$key]);
1312 ?><input type="text" size="40" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>" value="<?= htmlspecialcharsbx($value) ?>"><?
1313 }
1314
1315 if ($bAllowSelection)
1316 {
1317 if (!in_array($arFieldType["Type"], array("file", "bool", "date", "datetime")))
1318 {
1319 echo CBPHelper::renderControlSelectorButton($fieldNameId, $arFieldType["BaseType"]);
1320 }
1321 }
1322
1323 if ($arFieldType["Multiple"])
1324 echo '</td></tr>';
1325 }
1326
1327 if ($arFieldType["Multiple"])
1328 echo "</table>";
1329
1330 if ($arFieldType["Multiple"])
1331 echo '<input type="button" value="'.GetMessage("BPCGHLP_ADD").'" onclick="CBPVirtualDocumentCloneRow(\'CBPVirtualDocument_'.$arFieldName["Field"].'_Table\')"/><br />';
1332
1333 if ($bAllowSelection)
1334 {
1335 if (in_array($arFieldType["Type"], array("file", "bool", "date", "datetime")))
1336 {
1337 ?>
1338 <input type="text" id="id_<?= $arFieldName["Field"] ?>_text" name="<?= $arFieldName["Field"] ?>_text" value="<?
1339 if (count($fieldValueTmp) > 0)
1340 {
1341 $a = array_values($fieldValueTmp);
1342 echo htmlspecialcharsbx($a[0]);
1343 }
1344 ?>"><?
1345 echo CBPHelper::renderControlSelectorButton('id_'.$arFieldName["Field"].'_text', $arFieldType["BaseType"]);
1346 }
1347 }
1348 }
1349
1350 $s = ob_get_contents();
1351 ob_end_clean();
1352
1353 return $s;
1354 }
1355
1356 public static function getFieldInputValue($documentType, $arFieldType, $arFieldName, $arRequest, &$arErrors)
1357 {
1358 $result = [];
1359
1360 if ($arFieldType["Type"] == "user")
1361 {
1362 $value = $arRequest[$arFieldName["Field"]];
1363 if ($value <> '')
1364 {
1365 $result = CBPHelper::UsersStringToArray($value, $documentType, $arErrors);
1366 if (count($arErrors) > 0)
1367 {
1368 foreach ($arErrors as $e)
1369 {
1370 $arErrors[] = $e;
1371 }
1372 }
1373 }
1374 }
1375 elseif (array_key_exists($arFieldName["Field"], $arRequest) || array_key_exists($arFieldName["Field"]."_text", $arRequest))
1376 {
1377 $arValue = [];
1378 if (array_key_exists($arFieldName["Field"], $arRequest))
1379 {
1380 $arValue = $arRequest[$arFieldName["Field"]];
1381 if (!is_array($arValue) || is_array($arValue) && CBPHelper::IsAssociativeArray($arValue))
1382 {
1383 $arValue = array($arValue);
1384 }
1385 }
1386 if (array_key_exists($arFieldName["Field"]."_text", $arRequest))
1387 {
1388 $arValue[] = $arRequest[$arFieldName["Field"]."_text"];
1389 }
1390
1391 foreach ($arValue as $value)
1392 {
1393 if (!CBPActivity::isExpression($value))
1394 {
1395 if ($arFieldType["Type"] == "int")
1396 {
1397 if ($value <> '')
1398 {
1399 $value = str_replace(" ", "", $value);
1400 if ($value."|" == intval($value)."|")
1401 {
1402 $value = intval($value);
1403 }
1404 else
1405 {
1406 $value = null;
1407 $arErrors[] = array(
1408 "code" => "ErrorValue",
1409 "message" => GetMessage("BPCGWTL_INVALID1"),
1410 "parameter" => $arFieldName["Field"],
1411 );
1412 }
1413 }
1414 else
1415 {
1416 $value = null;
1417 }
1418 }
1419 elseif ($arFieldType["Type"] == "double")
1420 {
1421 if ($value <> '')
1422 {
1423 $value = str_replace(" ", "", str_replace(",", ".", $value));
1424 if ($value."|" == doubleval($value)."|")
1425 {
1426 $value = doubleval($value);
1427 }
1428 else
1429 {
1430 $value = null;
1431 $arErrors[] = array(
1432 "code" => "ErrorValue",
1433 "message" => GetMessage("BPCGWTL_INVALID11"),
1434 "parameter" => $arFieldName["Field"],
1435 );
1436 }
1437 }
1438 else
1439 {
1440 $value = null;
1441 }
1442 }
1443 elseif ($arFieldType["Type"] == "select")
1444 {
1445 if (!is_array($arFieldType["Options"]) || count($arFieldType["Options"]) <= 0 || $value == '')
1446 {
1447 $value = null;
1448 }
1449 elseif (!array_key_exists($value, $arFieldType["Options"]))
1450 {
1451 $value = null;
1452 $arErrors[] = array(
1453 "code" => "ErrorValue",
1454 "message" => GetMessage("BPCGWTL_INVALID35"),
1455 "parameter" => $arFieldName["Field"],
1456 );
1457 }
1458 }
1459 elseif ($arFieldType["Type"] == "bool")
1460 {
1461 if ($value !== "Y" && $value !== "N")
1462 {
1463 if ($value === true)
1464 {
1465 $value = "Y";
1466 }
1467 elseif ($value === false)
1468 {
1469 $value = "N";
1470 }
1471 elseif ($value <> '')
1472 {
1473 $value = mb_strtolower($value);
1474 if (in_array($value, array("y", "yes", "true", "1")))
1475 {
1476 $value = "Y";
1477 }
1478 elseif (in_array($value, array("n", "no", "false", "0")))
1479 {
1480 $value = "N";
1481 }
1482 else
1483 {
1484 $value = null;
1485 $arErrors[] = array(
1486 "code" => "ErrorValue",
1487 "message" => GetMessage("BPCGWTL_INVALID45"),
1488 "parameter" => $arFieldName["Field"],
1489 );
1490 }
1491 }
1492 else
1493 {
1494 $value = null;
1495 }
1496 }
1497 }
1498 elseif ($arFieldType["Type"] == "file")
1499 {
1500 if (array_key_exists("name", $value) && $value["name"] <> '')
1501 {
1502 if (!array_key_exists("MODULE_ID", $value) || $value["MODULE_ID"] == '')
1503 $value["MODULE_ID"] = "bizproc";
1504
1505 $value = CFile::SaveFile($value, "bizproc_wf");
1506 if (!$value)
1507 {
1508 $value = null;
1509 $arErrors[] = array(
1510 "code" => "ErrorValue",
1511 "message" => GetMessage("BPCGWTL_INVALID915"),
1512 "parameter" => $arFieldName["Field"],
1513 );
1514 }
1515 }
1516 else
1517 {
1518 $value = null;
1519 }
1520 }
1521 else
1522 {
1523 if (!is_array($value) && $value == '')
1524 $value = null;
1525 }
1526 }
1527
1528 if ($value != null)
1529 $result[] = $value;
1530 }
1531 }
1532
1533 if (!$arFieldType["Multiple"])
1534 {
1535 if (count($result) > 0)
1536 $result = $result[0];
1537 else
1538 $result = null;
1539 }
1540
1541 return $result;
1542 }
1543
1544 public static function getFieldInputValuePrintable($documentType, $arFieldType, $fieldValue)
1545 {
1546 $result = $fieldValue;
1547
1548 switch ($arFieldType['Type'])
1549 {
1550 case "user":
1551 $result = CBPHelper::UsersArrayToString($fieldValue, null, $documentType);
1552 break;
1553
1554 case "bool":
1555 if (is_array($fieldValue))
1556 {
1557 $result = array();
1558 foreach ($fieldValue as $r)
1559 $result[] = ((mb_strtoupper($r) == "Y") ? GetMessage("BPVDX_YES") : GetMessage("BPVDX_NO"));
1560 }
1561 else
1562 {
1563 $result = ((mb_strtoupper($fieldValue) == "Y") ? GetMessage("BPVDX_YES") : GetMessage("BPVDX_NO"));
1564 }
1565 break;
1566
1567 case "file":
1568 if (is_array($fieldValue))
1569 {
1570 $result = array();
1571 foreach ($fieldValue as $r)
1572 {
1573 $r = intval($r);
1574 $dbImg = CFile::GetByID($r);
1575 if ($arImg = $dbImg->Fetch())
1576 $result[] = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$r."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
1577 }
1578 }
1579 else
1580 {
1581 $fieldValue = intval($fieldValue);
1582 $dbImg = CFile::GetByID($fieldValue);
1583 if ($arImg = $dbImg->Fetch())
1584 $result = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$fieldValue."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
1585 }
1586 break;
1587 case "select":
1588 if (isset($arFieldType["Options"][$fieldValue]))
1589 $result = $arFieldType["Options"][$fieldValue];
1590
1591 break;
1592 }
1593
1594 return $result;
1595 }
1596
1597 public static function setGUIFieldEdit($documentType, $fieldName, $arRequest, &$arErrors, $arDocumentField = null)
1598 {
1599 return self::GetFieldInputValue($documentType, $arDocumentField, array("Field" => $fieldName), $arRequest, $arErrors);
1600 }
1601
1609 public static function convertTextForMail($text, $siteId = false)
1610 {
1611 if (is_array($text))
1612 {
1613 $text = implode(', ', $text);
1614 }
1615
1616 $text = trim($text);
1617 if ($text == '')
1618 {
1619 return "";
1620 }
1621
1622 if (!$siteId)
1623 {
1624 $siteId = SITE_ID;
1625 }
1626
1627 $arPattern = $arReplace = [];
1628
1629 $arPattern[] = "/\[(code|quote)(.*?)\]/isu";
1630 $arReplace[] = "\n>================== \\1 ===================\n";
1631
1632 $arPattern[] = "/\[\/(code|quote)(.*?)\]/isu";
1633 $arReplace[] = "\n>===========================================\n";
1634
1635 $arPattern[] = "/<WBR[\s\/]?>/isu";
1636 $arReplace[] = "";
1637
1638 $arPattern[] = "/^(\r|\n)+?(.*)$/";
1639 $arReplace[] = "\\2";
1640
1641 $arPattern[] = "/\[b\](.+?)\[\/b\]/isu";
1642 $arReplace[] = "\\1";
1643
1644 $arPattern[] = "/\[i\](.+?)\[\/i\]/isu";
1645 $arReplace[] = "\\1";
1646
1647 $arPattern[] = "/\[u\](.+?)\[\/u\]/isu";
1648 $arReplace[] = "_\\1_";
1649
1650 $arPattern[] = "/\[s\](.+?)\[\/s\]/isu";
1651 $arReplace[] = "_\\1_";
1652
1653 $arPattern[] = "/\[(\/?)(color|font|size)([^\]]*)\]/isu";
1654 $arReplace[] = "";
1655
1656 //$arPattern[] = "/\[url\](\S+?)\[\/url\]/isu";
1657 //$arReplace[] = "(URL: \\1)";
1658
1659 //$arPattern[] = "/\[url\s*=\s*(\S+?)\s*\](.*?)\[\/url\]/isu";
1660 //$arReplace[] = "\\2 (URL: \\1)";
1661
1662 $arPattern[] = "/\[img\](.+?)\[\/img\]/isu";
1663 $arReplace[] = "(IMAGE: \\1)";
1664
1665 $arPattern[] = "/\[video([^\]]*)\](.+?)\[\/video[\s]*\]/isu";
1666 $arReplace[] = "(VIDEO: \\2)";
1667
1668 $arPattern[] = "/\[(\/?)list\]/isu";
1669 $arReplace[] = "\n";
1670
1671 $text = preg_replace($arPattern, $arReplace, $text);
1672
1673
1674 $dbSite = CSite::GetByID($siteId);
1675 $arSite = $dbSite->Fetch();
1676 static::$serverName = $arSite["SERVER_NAME"];
1677 if (static::$serverName == '')
1678 {
1679 if (defined("SITE_SERVER_NAME") && SITE_SERVER_NAME <> '')
1680 {
1681 static::$serverName = SITE_SERVER_NAME;
1682 }
1683 else
1684 {
1685 static::$serverName = COption::GetOptionString("main", "server_name", "");
1686 }
1687 }
1688
1689 $text = preg_replace_callback(
1690 "/\[url\]([^\]]+?)\[\/url\]/iu",
1691 array("CBPHelper", "__ConvertAnchorTag"),
1692 $text
1693 );
1694 $text = preg_replace_callback(
1695 "/\[url\s*=\s*([^\]]+?)\s*\](.*?)\[\/url\]/isu",
1696 array("CBPHelper", "__ConvertAnchorTag"),
1697 $text
1698 );
1699
1700 return $text;
1701 }
1702
1703 public static function convertBBtoText(string $text): string
1704 {
1705 $textParser = new CTextParser();
1706 $textParser->allow = [
1707 'HTML' => 'N',
1708 'USER' => 'N',
1709 'ANCHOR' => 'Y',
1710 'BIU' => 'Y',
1711 'IMG' => 'Y',
1712 'QUOTE' => 'N',
1713 'CODE' => 'N',
1714 'FONT' => 'Y',
1715 'LIST' => 'Y',
1716 'SMILES' => 'N',
1717 'NL2BR' => 'Y',
1718 'VIDEO' => 'N',
1719 'TABLE' => 'N',
1720 'CUT_ANCHOR' => 'N',
1721 'ALIGN' => 'N',
1722 ];
1723
1724 return $textParser->convertText($text);
1725 }
1726
1727 public static function __ConvertAnchorTag($url, $text = '', $serverName = '')
1728 {
1729 if (is_array($url))
1730 {
1731 $text = isset($url[2]) ? $url[2] : $url[1];
1732 $url = $url[1];
1733 $serverName = static::$serverName;
1734 }
1735
1736 $scheme = \CMain::IsHTTPS() ? 'https' : 'http';
1737
1738 if (mb_substr($url, 0, 1) != "/" && !preg_match("/^(http|news|https|ftp|aim|mailto)\:\/\//iu", $url))
1739 $url = $scheme.'://'.$url;
1740 if (!preg_match("/^(http|https|news|ftp|aim):\/\/[-_:.a-z0-9@]+/iu", $url))
1741 $url = $serverName.$url;
1742 if (!preg_match("/^(http|news|https|ftp|aim|mailto)\:\/\//iu", $url))
1743 $url = $scheme.'://'.$url;
1744
1745 $url = str_replace(' ', '%20', $url);
1746
1747 if ($text <> '' && $text !== $url)
1748 {
1749 return $text." ( ".$url." )";
1750 }
1751
1752 return $url;
1753 }
1754
1755 public static function isAssociativeArray($ar)
1756 {
1757 if (!is_array($ar))
1758 {
1759 return false;
1760 }
1761
1762 $fl = false;
1763
1764 $arKeys = array_keys($ar);
1765 $ind = -1;
1766 $indn = -1;
1767 foreach ($arKeys as $key)
1768 {
1769 $ind++;
1770 if ($key."!" !== $ind."!")
1771 {
1772 if (mb_substr($key, 0, 1) === 'n')
1773 {
1774 $indn++;
1775 if (($indn === 0) && ("".$key === "n1"))
1776 $indn++;
1777
1778 if ("".$key !== "n".$indn)
1779 {
1780 $fl = true;
1781 break;
1782 }
1783 }
1784 else
1785 {
1786 $fl = true;
1787 break;
1788 }
1789 }
1790 }
1791
1792 return $fl;
1793 }
1794
1795 public static function extractUsersFromUserGroups($value, $activity)
1796 {
1797 $result = [];
1798
1799 if (!is_array($value))
1800 {
1801 $value = array($value);
1802 }
1803
1804 $l = mb_strlen("user_");
1805 $runtime = CBPRuntime::GetRuntime();
1806 $documentService = $runtime->GetService("DocumentService");
1807
1808 foreach ($value as $v)
1809 {
1810 if (mb_substr($v, 0, $l) == "user_")
1811 {
1812 $result[] = $v;
1813 }
1814 else
1815 {
1816 $arDSUsers = self::extractUsersFromExtendedGroup($v);
1817 if ($arDSUsers === false)
1818 {
1819 $arDSUsers = $documentService->GetUsersFromUserGroup($v, $activity->GetDocumentId());
1820 }
1821 foreach ($arDSUsers as $v1)
1822 {
1823 $result[] = "user_".$v1;
1824 }
1825 }
1826 }
1827
1828 return $result;
1829 }
1830
1838 public static function extractUsersFromExtendedGroup($code)
1839 {
1840 static $cache = [];
1841
1842 if (isset($cache[$code]))
1843 {
1844 return $cache[$code];
1845 }
1846
1847 if (!str_starts_with($code, 'group_'))
1848 {
1849 return false;
1850 }
1851
1852 $code = mb_strtoupper(mb_substr($code, mb_strlen('group_')));
1853 $userService = CBPRuntime::getRuntime()->getUserService();
1854
1855 if (str_starts_with($code, 'G'))
1856 {
1857 $groupId = (int)mb_substr($code, 1);
1858 $cache[$code] = $userService->extractUsersFromGroup($groupId);
1859
1860 return $cache[$code];
1861 }
1862
1863 if (preg_match('/^(U|IU|SU)([0-9]+)$/i', $code, $match))
1864 {
1865 return [(int)$match[2]];
1866 }
1867
1868 if ($code === 'UA')
1869 {
1870 $cache[$code] = $userService->extractUsersFromAllDepartments();
1871
1872 return $cache[$code];
1873 }
1874
1875 if (preg_match('/^(D|DR)(\d+)$/', $code, $match))
1876 {
1877 $cache[$code] = $userService->extractUsersFromDepartment($match[2], $match[1] === 'DR');
1878
1879 return $cache[$code];
1880 }
1881
1882 if (preg_match('/^SG([0-9]+)_?([AEK])?$/', $code, $match))
1883 {
1884 $groupId = (int)$match[1];
1885 $role = $match[2] ?? 'K';
1886 $cache[$code] = $userService->extractUsersFromSocNetGroup($groupId, $role);
1887
1888 return $cache[$code];
1889 }
1890
1891 if (preg_match('/^(HR|HRR)(\d+)$/', $code, $match))
1892 {
1893 $nodeId = (int)$match[2];
1894 $cache[$code] = $userService->extractUsersFromHrNode($nodeId, $match[1] === 'HRR');
1895
1896 return $cache[$code];
1897 }
1898
1899 return false;
1900 }
1901
1902 public static function extractUsers($arUsersDraft, $documentId, $bFirst = false)
1903 {
1904 $result = [];
1905
1906 if (!is_array($arUsersDraft))
1907 {
1908 $arUsersDraft = array($arUsersDraft);
1909 }
1910
1911 $l = mb_strlen("user_");
1912 $documentService = CBPRuntime::GetRuntime(true)->getDocumentService();
1913
1914 foreach ($arUsersDraft as $user)
1915 {
1916 if (!is_scalar($user))
1917 {
1918 continue;
1919 }
1920
1921 if (mb_substr($user, 0, $l) === "user_")
1922 {
1923 $user = intval(mb_substr($user, $l));
1924 if (($user > 0) && !in_array($user, $result))
1925 {
1926 if ($bFirst)
1927 {
1928 return $user;
1929 }
1930 $result[] = $user;
1931 }
1932 }
1934 {
1936 if ($parsed && $parsed['object'] === 'Document')
1937 {
1938 $document = $documentService->GetDocument($documentId, select: [$parsed['field']]);
1939 if ($document && $document[$parsed['field']])
1940 {
1941 foreach ((array) $document[$parsed['field']] as $docUser)
1942 {
1943 if (mb_substr($docUser, 0, $l) === "user_")
1944 {
1945 $user = intval(mb_substr($docUser, $l));
1946 if (($user > 0) && !in_array($user, $result))
1947 {
1948 if ($bFirst)
1949 {
1950 return $user;
1951 }
1952 $result[] = $user;
1953 }
1954 }
1955 }
1956 }
1957 }
1958 }
1959 else
1960 {
1961 $users = self::extractUsersFromExtendedGroup($user);
1962 if ($users === false)
1963 {
1964 $users = $documentService->GetUsersFromUserGroup($user, $documentId);
1965 }
1966 foreach ($users as $u)
1967 {
1968 $u = (int)$u;
1969 if (($u > 0) && !in_array($u, $result))
1970 {
1971 if ($bFirst)
1972 {
1973 return $u;
1974 }
1975 $result[] = $u;
1976 }
1977 }
1978 }
1979 }
1980
1981 if (!$bFirst)
1982 {
1983 return $result;
1984 }
1985
1986 if (count($result) > 0)
1987 {
1988 return $result[0];
1989 }
1990
1991 return null;
1992 }
1993
1994 public static function extractFirstUser($userGroups, $documentId): ?int
1995 {
1996 return static::extractUsers($userGroups, $documentId, true);
1997 }
1998
1999 public static function makeArrayFlat($ar)
2000 {
2001 if (!is_array($ar))
2002 {
2003 return array($ar);
2004 }
2005
2006 $result = [];
2007
2008 if (
2010 && (count($ar) === 2)
2011 && isset($ar[0], $ar[1])
2012 && in_array($ar[0], ["Variable", "Document", "Template", "Workflow", "User", "System"])
2013 && is_string($ar[1])
2014 )
2015 {
2016 $result[] = $ar;
2017 return $result;
2018 }
2019
2020 foreach ($ar as $val)
2021 {
2022 if (!is_array($val))
2023 {
2024 if (trim($val) !== "")
2025 $result[] = $val;
2026 }
2027 else
2028 {
2029 foreach (self::MakeArrayFlat($val) as $val1)
2030 $result[] = $val1;
2031 }
2032 }
2033
2034 return $result;
2035 }
2036
2037 public static function flatten($array): array
2038 {
2039 if (!is_array($array))
2040 {
2041 return [$array];
2042 }
2043
2044 $result = [];
2045 array_walk_recursive($array, function($a) use (&$result) { $result[] = $a; });
2046
2047 return $result;
2048 }
2049
2050 public static function stringify($mixed): string
2051 {
2052 if (is_array($mixed))
2053 {
2054 return implode(', ', static::flatten($mixed));
2055 }
2056
2057 return (string)$mixed;
2058 }
2059
2060 public static function getBool($value)
2061 {
2062 if (
2063 empty($value)
2064 || $value === 'false'
2065 || (is_int($value) && ($value == 0))
2066 || (is_scalar($value) && mb_strtoupper($value) == 'N')
2067 )
2068 {
2069 return false;
2070 }
2071
2072 return (bool)$value;
2073 }
2074
2075 public static function isEmptyValue($value)
2076 {
2077 $filter = function ($value)
2078 {
2079 return ($value !== null && $value !== '' && $value !== false);
2080 };
2081
2082 return (
2083 $value === null
2084 ||
2085 $value === ''
2086 ||
2087 $value === false
2088 ||
2089 (is_array($value) && count(array_filter($value, $filter)) === 0)
2090 );
2091 }
2092
2093 public static function convertParameterValues($val)
2094 {
2095 $result = $val;
2096
2097 if (is_string($val) && preg_match(CBPActivity::ValuePattern, $val, $arMatches))
2098 {
2099 $result = null;
2100 if ($arMatches['object'] == "User")
2101 {
2102 if ($GLOBALS["USER"]->IsAuthorized())
2103 $result = "user_".$GLOBALS["USER"]->GetID();
2104 }
2105 elseif ($arMatches['object'] == "System")
2106 {
2107 if (mb_strtolower($arMatches['field']) === "now")
2108 $result = date($GLOBALS["DB"]->DateFormatToPHP(CSite::GetDateFormat("FULL")));
2109 elseif (mb_strtolower($arMatches['field']) == "date")
2110 $result = date($GLOBALS["DB"]->DateFormatToPHP(CSite::GetDateFormat("SHORT")));
2111 }
2112 }
2113
2114 return $result;
2115 }
2116
2117 public static function stripUserPrefix($value)
2118 {
2119 if (is_array($value) && !CBPHelper::IsAssociativeArray($value))
2120 {
2121 foreach ($value as &$v)
2122 {
2123 if (mb_substr($v, 0, 5) == "user_")
2124 $v = mb_substr($v, 5);
2125 }
2126 }
2127 elseif (is_string($value))
2128 {
2129 if (mb_substr($value, 0, 5) == "user_")
2130 $value = mb_substr($value, 5);
2131 }
2132
2133 return $value;
2134 }
2135
2140 public static function getUserExtendedGroups($userId)
2141 {
2142 $canUseHrModule = Loader::includeModule('humanresources');
2143
2144 if (!isset(self::$groupsCache[$userId]))
2145 {
2146 self::$groupsCache[$userId] = [];
2147 $access = static::getAccessProvider();
2148 $userCodes = $access::GetUserCodesArray($userId);
2149
2150 foreach ($userCodes as $code)
2151 {
2152 self::$groupsCache[$userId][] = 'group_' . mb_strtolower($code);
2153 if ($canUseHrModule && preg_match('/^(d|dr)(\d+)$/', mb_strtolower($code), $match))
2154 {
2155 $node = Container::getNodeRepository()->getByAccessCode($code);
2156 if ($node)
2157 {
2158 self::$groupsCache[$userId][] = 'group_' . ($match[1] === 'dr' ? 'hrr' : 'hr') . $node->id;
2159 }
2160 }
2161 }
2162 }
2163
2164 return self::$groupsCache[$userId];
2165 }
2166
2172 public static function getExtendedGroupName($group, $appendId = true)
2173 {
2174 if (str_starts_with($group, 'group_'))
2175 {
2176 $group = mb_substr($group, mb_strlen('group_'));
2177 }
2178
2179 if (
2180 preg_match('/^(d|dr)(\d+)$/', $group, $match)
2181 && Loader::includeModule('humanresources')
2182 )
2183 {
2184 $departmentId = $match[2];
2185 $node =
2186 Container::getNodeRepository()
2187 ->getByAccessCode(DepartmentBackwardAccessCode::makeById((int)$departmentId))
2188 ;
2189 if ($node)
2190 {
2191 return ($node->name ?? '') . ($appendId ? ' [HR' . ($match[1] === 'dr' ? 'R' : '') . $node->id . ']' : '');
2192 }
2193 }
2194
2195 if (preg_match('/^(hr|hrr)(\d+)$/', $group, $match))
2196 {
2197 $groupId = $match[2];
2198 $groupName = '';
2199 if (Loader::includeModule('humanresources'))
2200 {
2201 $nodeRepository = Container::getNodeRepository();
2202 $node = $nodeRepository->getById((int)$groupId);
2203 $groupName = $node->name ?? '';
2204 }
2205
2206 return $groupName . ($appendId ? ' [' . mb_strtoupper($group) . ']' : '');
2207 }
2208
2209 $group = mb_strtoupper($group);
2210 $access = static::getAccessProvider();
2211 $arNames = $access->GetNames(array($group));
2212 $groupName = $arNames[$group]['name'] ?? null;
2213
2214 return $groupName . ($appendId ? ' [' . $group . ']' : '');
2215 }
2216
2221
2222 public static function convertToExtendedGroups($users)
2223 {
2224 $users = (array)$users;
2225 foreach ($users as &$user)
2226 {
2227 if (!is_scalar($user))
2228 continue;
2229 $user = (string) $user;
2230 if (mb_strpos($user, 'user_') === 0)
2231 {
2232 $user = 'group_u'.mb_substr($user, mb_strlen('user_'));
2233 }
2234 elseif (preg_match('#^[0-9]+$#', $user))
2235 {
2236 $user = 'group_g'.$user;
2237 }
2238 else
2239 $user = mb_strtolower($user);
2240 }
2241 return $users;
2242 }
2243
2249
2250 public static function convertToSimpleGroups($users, $extractUsers = false)
2251 {
2252 $users = (array)$users;
2253 $converted = [];
2254
2255 foreach ($users as $user)
2256 {
2257 if (!is_scalar($user))
2258 continue;
2259 $user = mb_strtolower((string)$user);
2260 if (mb_strpos($user, 'group_u') === 0)
2261 {
2262 $converted[] = 'user_'.mb_substr($user, mb_strlen('group_u'));
2263 }
2264 elseif (mb_strpos($user, 'group_g') === 0)
2265 {
2266 $converted[] = mb_substr($user, mb_strlen('group_g'));
2267 }
2268 elseif (mb_strpos($user, 'group_') === 0)
2269 {
2270 if ($extractUsers)
2271 {
2272 $extracted = self::extractUsersFromExtendedGroup($user);
2273 if ($extracted !== false)
2274 {
2275 foreach ($extracted as $exUser)
2276 {
2277 $converted[] = 'user_'.$exUser;
2278 }
2279 }
2280 }
2281 }
2282 else
2283 $converted[] = $user;
2284 }
2285 return $converted;
2286 }
2287
2288 public static function getForumId()
2289 {
2290 $forumId = COption::GetOptionString('bizproc', 'forum_id', 0);
2291 if (!$forumId && CModule::includeModule('forum'))
2292 {
2293 $defaultSiteId = CSite::GetDefSite();
2294 $forumId = CForumNew::Add(array(
2295 'NAME' => 'Bizproc Workflow',
2296 'XML_ID' => 'bizproc_workflow',
2297 'SITES' => array($defaultSiteId => '/'),
2298 'ACTIVE' => 'Y',
2299 'DEDUPLICATION' => 'N',
2300 ));
2301 COption::SetOptionString("bizproc", "forum_id", $forumId);
2302 }
2303
2304 return (int)$forumId;
2305 }
2306
2307 public static function getDistrName()
2308 {
2309 return CModule::IncludeModule('bitrix24') ? static::DISTR_B24 : static::DISTR_BOX;
2310 }
2311
2317 public static function checkUserSubordination(mixed $headUserId, mixed $subUserId): bool
2318 {
2319 if (Loader::includeModule('intranet'))
2320 {
2321 if (Loader::IncludeModule('humanresources'))
2322 {
2323 $headNodes = Container::getNodeMemberRepository()->findAllByEntityIdAndEntityType(
2324 (int)$headUserId,
2325 MemberEntityType::USER,
2326 );
2327 $subNodes = Container::getNodeMemberRepository()->findAllByEntityIdAndEntityType(
2328 (int)$subUserId,
2329 MemberEntityType::USER,
2330 );
2331
2332 foreach ($headNodes as $headNode)
2333 {
2334 foreach ($subNodes as $subNode)
2335 {
2336 $relation = Container::getNodeMemberService()->getMemberSubordination(
2337 $headNode->id,
2338 $subNode->id,
2339 );
2340 if ($relation === MemberSubordinateRelationType::RELATION_HIGHER)
2341 {
2342 return true;
2343 }
2344 }
2345 }
2346 }
2347 else
2348 {
2349 return self::checkUserSubordinationDeprecated((int)$headUserId, (int)$subUserId);
2350 }
2351 }
2352
2353 return false;
2354 }
2355
2356 private static function checkUserSubordinationDeprecated(int $headUserId, int $subUserId): bool
2357 {
2358 if ($headUserId && $subUserId)
2359 {
2360 $headDepts = (array) CIntranetUtils::GetSubordinateDepartments($headUserId, true);
2361 if (!empty($headDepts))
2362 {
2363 $subDepts = (array) CIntranetUtils::GetUserDepartments($subUserId);
2364 return (sizeof(array_intersect($headDepts, $subDepts)) > 0);
2365 }
2366 }
2367
2368 return false;
2369 }
2370
2371 public static function renderControlSelectorButton($controlId, $baseType = 'string', array $options = null)
2372 {
2373 $selectorProps = \Bitrix\Main\Web\Json::encode(array(
2374 'controlId' => $controlId,
2375 'baseType' => $baseType,
2376 ));
2377
2378 $mode = isset($options['mode']) ? $options['mode'] : '';
2379 $additional = array();
2380
2381 if (isset($options['style']))
2382 $additional[] = 'style="'.htmlspecialcharsbx($options['style']).'"';
2383
2384 if (isset($options['title']))
2385 $additional[] = 'title="'.htmlspecialcharsbx($options['title']).'"';
2386
2387 return '<input type="button" value="..." onclick="BPAShowSelector(\''
2388 .Cutil::JSEscape(htmlspecialcharsbx($controlId))
2389 .'\', \''.Cutil::JSEscape(htmlspecialcharsbx($baseType))
2390 .'\', \''.Cutil::JSEscape(htmlspecialcharsbx($mode)).'\');"'
2391 .' data-role="bp-selector-button" data-bp-selector-props="'.htmlspecialcharsbx($selectorProps).'" '.implode(' ', $additional).'>';
2392 }
2393
2394 public static function decodeTemplatePostData(&$data)
2395 {
2396 $jsonParams = [
2397 'arWorkflowTemplate',
2398 'arWorkflowParameters',
2399 'arWorkflowGlobalVariables',
2400 'arWorkflowVariables',
2401 'arWorkflowGlobalConstants',
2402 'arWorkflowConstants',
2403 'USER_PARAMS',
2404 'documentCategories',
2405 'workflowTemplateSettings',
2406 ];
2407
2408 foreach ($jsonParams as $k)
2409 {
2410 if (!isset($data[$k]) || !is_array($data[$k]))
2411 {
2412 $data[$k] = isset($data[$k]) ? (array) CUtil::JsObjectToPhp($data[$k]) : array();
2413 }
2414 }
2415 }
2416
2417 public static function makeTimestamp($date, bool $appendOffset = false)
2418 {
2419 if (!$date)
2420 {
2421 return 0;
2422 }
2423
2424 if (is_array($date))
2425 {
2426 $date = current(static::flatten($date));
2427 }
2428
2429 //serialized date string
2430 if (is_string($date) && Bizproc\BaseType\Value\DateTime::isSerialized($date))
2431 {
2432 $date = new Bizproc\BaseType\Value\DateTime($date);
2433 }
2434
2435 if ($date instanceof Bizproc\BaseType\Value\Date)
2436 {
2437 return $date->getTimestamp() + ($appendOffset ? $date->getOffset() : 0);
2438 }
2439
2440 if ($date instanceof Main\Type\Date)
2441 {
2442 return $date->getTimestamp();
2443 }
2444
2445 if ($date instanceof Bitrix\Bizproc\BaseType\Value\Time)
2446 {
2447 $time = $date->toSystemObject();
2448 $currentDate = new \Bitrix\Main\Type\DateTime();
2449
2450 return $time->setDate(
2451 $currentDate->format('Y'),
2452 $currentDate->format('m'),
2453 $currentDate->format('d')
2454 )->getTimestamp();
2455 }
2456
2457 if (intval($date) . '!' === $date . '!')
2458 {
2459 return $date;
2460 }
2461
2462 if (($result = MakeTimeStamp($date, FORMAT_DATETIME)) === false)
2463 {
2464 if (($result = MakeTimeStamp($date, FORMAT_DATE)) === false)
2465 {
2466 if (($result = MakeTimeStamp($date, 'YYYY-MM-DD HH:MI:SS')) === false)
2467 {
2468 $result = MakeTimeStamp($date, 'YYYY-MM-DD');
2469 }
2470 }
2471 }
2472
2473 return (int) $result;
2474 }
2475
2476 public static function isWorkTimeAvailable(): bool
2477 {
2478 if (
2479 Loader::includeModule('bitrix24')
2480 && !Bitrix24\Feature::isFeatureEnabled('bizproc_timeman')
2481 )
2482 {
2483 return false;
2484 }
2485
2486 if (Loader::includeModule('intranet'))
2487 {
2488 $workTime = \Bitrix\Intranet\Site\Sections\TimemanSection::getWorkTime();
2489
2490 return $workTime['available'] && Loader::includeModule('timeman');
2491 }
2492
2493 return false;
2494 }
2495
2496 public static function hasStringRepresentation($value): bool
2497 {
2498 return (is_scalar($value) || (is_object($value) && method_exists($value, '__toString')));
2499 }
2500
2501 public static function isEqualDocument(array $documentA, array $documentB): bool
2502 {
2503 return (
2504 (string)$documentA[0] === (string)$documentB[0]
2505 && (string)$documentA[1] === (string)$documentB[1]
2506 && (string)$documentA[2] === (string)$documentB[2]
2507 );
2508 }
2509
2513 public static function isWorkflowFinished(string $workflowId): bool
2514 {
2515 if (!$workflowId)
2516 {
2517 throw new CBPArgumentNullException('workflowId');
2518 }
2519
2520 $runtime = CBPRuntime::getRuntime();
2521 if ($runtime->hasWorkflow($workflowId))
2522 {
2523 return $runtime->getWorkflow($workflowId)->isFinished();
2524 }
2525
2526 return !Bizproc\WorkflowInstanceTable::exists($workflowId);
2527 }
2528}
return select
Определения access_edit.php:440
$arResult
Определения generate_coupon.php:16
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
Определения loader.php:13
static includeModule($moduleName)
Определения loader.php:67
static isValidModule(string $moduleName)
Определения modulemanager.php:184
static encode($data, $options=null)
Определения json.php:22
Определения access.php:15
static CalendarDate($sFieldName, $sValue="", $size="10", $bTime=false)
Определения admin_calendar.php:78
static ShowScript()
Определения admin_calendar.php:55
static GetList($by='', $order='', $arFilter=[], $arParams=[])
Определения user.php:358
static SearchUserByName($arName, $email='', $bLoginMode=false)
Определения user.php:5354
static FormatName($NAME_TEMPLATE, $arUser, $bUseLogin=false, $bHTMLSpec=true, $enabledEmptyNameStub=true)
Определения user.php:5614
static parseExpression($exp)
Определения activity.php:1736
const ValuePattern
Определения activity.php:26
static isExpression($text)
Определения activity.php:1718
Определения helper.php:13
static getAccessProvider()
Определения helper.php:21
static checkUserSubordination(mixed $headUserId, mixed $subUserId)
Определения helper.php:2317
static getGUIFieldEdit($documentType, $formName, $fieldName, $fieldValue, $arDocumentField, $bAllowSelection)
Определения helper.php:1127
static convertParameterValues($val)
Определения helper.php:2093
static extractFirstUser($userGroups, $documentId)
Определения helper.php:1994
static convertToSimpleGroups($users, $extractUsers=false)
Определения helper.php:2250
static getFieldInputValue($documentType, $arFieldType, $arFieldName, $arRequest, &$arErrors)
Определения helper.php:1356
static convertBBtoText(string $text)
Определения helper.php:1703
static $cAccess
Определения helper.php:18
static getFieldValuePrintable($fieldName, $fieldType, $result)
Определения helper.php:995
static parseDocumentIdArray($parameterDocumentId)
Определения helper.php:933
static isAssociativeArray($ar)
Определения helper.php:1755
static setGUIFieldEdit($documentType, $fieldName, $arRequest, &$arErrors, $arDocumentField=null)
Определения helper.php:1597
static getExtendedGroupName($group, $appendId=true)
Определения helper.php:2172
static convertToExtendedGroups($users)
Определения helper.php:2222
static renderControlSelectorButton($controlId, $baseType='string', array $options=null)
Определения helper.php:2371
static usersArrayToString($users, $arWorkflowTemplate, $documentType, $appendId=true)
Определения helper.php:117
static extractUsersFromUserGroups($value, $activity)
Определения helper.php:1795
static parseDocumentId($parameterDocumentId)
Определения helper.php:887
static formatTimePeriod($period)
Определения helper.php:381
static extractUsersFromExtendedGroup($code)
Определения helper.php:1838
static $groupsCache
Определения helper.php:19
static getDistrName()
Определения helper.php:2307
static getJSFunctionsForFields($objectName, $arDocumentFields, $arDocumentFieldTypes)
Определения helper.php:1097
static getForumId()
Определения helper.php:2288
const DISTR_BOX
Определения helper.php:15
static __ConvertAnchorTag($url, $text='', $serverName='')
Определения helper.php:1727
static getDocumentFieldTypes()
Определения helper.php:1105
static isEmptyValue($value)
Определения helper.php:2075
static convertTextForMail($text, $siteId=false)
Определения helper.php:1609
static flatten($array)
Определения helper.php:2037
static stringify($mixed)
Определения helper.php:2050
static getFieldInputControl($documentType, $arFieldType, $arFieldName, $fieldValue, $bAllowSelection=false)
Определения helper.php:1138
static prepareSql(&$arFields, $arOrder, $arFilter, $arGroupBy, $arSelectFields)
Определения helper.php:514
static getFieldInputValuePrintable($documentType, $arFieldType, $fieldValue)
Определения helper.php:1544
static getUserExtendedGroups($userId)
Определения helper.php:2140
static convertUserToPrintableForm($userId, $nameTemplate="", $htmlSpecialChars=true)
Определения helper.php:1048
static getBool($value)
Определения helper.php:2060
static usersStringToArray($strUsers, $documentType, &$arErrors, $callbackFunction=null)
Определения helper.php:152
static makeArrayFlat($ar)
Определения helper.php:1999
static getFilterOperation($key)
Определения helper.php:454
const DISTR_B24
Определения helper.php:14
static stripUserPrefix($value)
Определения helper.php:2117
static extractUsers($arUsersDraft, $documentId, $bFirst=false)
Определения helper.php:1902
static Add($arFields)
Определения forum_new.php:15
Определения textparser.php:21
$options
Определения commerceml2.php:49
$str
Определения commerceml2.php:63
$hours
Определения cron_html_pages.php:15
$arFields
Определения dblapprove.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
GetFilterQuery($field, $val, $procent="Y", $ex_sep=array(), $clob="N", $div_fields="Y", $clob_upper="N")
Определения filter_tools.php:383
$result
Определения get_property_values.php:14
$entity
$moduleId
$activity
Определения options.php:214
$filter
Определения iblock_catalog_list.php:54
global $DB
Определения cron_frame.php:29
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$l
Определения options.php:783
if(!is_array($deviceNotifyCodes)) $access
Определения options.php:174
$arNames
Определения options.php:175
$siteId
Определения ajax.php:8
DelDuplicateSort(&$arSort)
Определения tools.php:2055
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
GetMessage($name, $aReplace=null)
Определения tools.php:3397
check_email($email, $strict=false, $domainCheck=false)
Определения tools.php:4571
$user
Определения mysql_to_pgsql.php:33
$GLOBALS['____1690880296']
Определения license.php:1
$order
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
if(empty($signedUserToken)) $key
Определения quickway.php:257
$text
Определения template_pdf.php:79
$i
Определения factura.php:643
font size
Определения invoice.php:442
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
else $a
Определения template.php:137
$val
Определения options.php:1793
$matches
Определения index.php:22
const SITE_ID
Определения sonet_set_content_view.php:12
$k
Определения template_pdf.php:567
$arFilter
Определения user_search.php:106
$url
Определения iframe.php:7