PageRenderTime 50ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/bizproc/classes/general/helper.php

https://gitlab.com/alexprowars/bitrix
PHP | 1871 lines | 1641 code | 207 blank | 23 comment | 403 complexity | 747d5d33a359ca6122325893fea7632e MD5 | raw file
  1. <?php
  2. IncludeModuleLangFile(__FILE__);
  3. use Bitrix\Bizproc;
  4. class CBPHelper
  5. {
  6. const DISTR_B24 = 'b24';
  7. const DISTR_BOX = 'box';
  8. private static $serverName;
  9. protected static $cAccess;
  10. protected static $groupsCache = array();
  11. protected static function getAccessProvider()
  12. {
  13. if (self::$cAccess === null)
  14. {
  15. self::$cAccess = new CAccess;
  16. }
  17. return self::$cAccess;
  18. }
  19. private static function UsersArrayToStringInternal($arUsers, $arWorkflowTemplate, $arAllowableUserGroups, $appendId = true)
  20. {
  21. if (is_array($arUsers))
  22. {
  23. $r = [];
  24. $keys = array_keys($arUsers);
  25. foreach ($keys as $key)
  26. {
  27. $r[$key] = self::UsersArrayToStringInternal($arUsers[$key], $arWorkflowTemplate, $arAllowableUserGroups, $appendId);
  28. }
  29. if (count($r) == 2)
  30. {
  31. $keys = array_keys($r);
  32. if ($keys[0] == 0 && $keys[1] == 1 && is_string($r[0]) && is_string($r[1]))
  33. {
  34. if (in_array($r[0], array("Document", "Template", "Variable", "User"))
  35. || preg_match('#^A\d+_\d+_\d+_\d+$#i', $r[0])
  36. || is_array($arWorkflowTemplate) && CBPWorkflowTemplateLoader::FindActivityByName($arWorkflowTemplate, $r[0]) != null
  37. )
  38. {
  39. return "{=".$r[0].":".$r[1]."}";
  40. }
  41. }
  42. }
  43. return implode(", ", $r);
  44. }
  45. else
  46. {
  47. if (array_key_exists(mb_strtolower($arUsers), $arAllowableUserGroups))
  48. {
  49. return $arAllowableUserGroups[mb_strtolower($arUsers)];
  50. }
  51. if (CBPActivity::isExpression($arUsers))
  52. {
  53. return $arUsers;
  54. }
  55. $userId = 0;
  56. if (mb_substr($arUsers, 0, mb_strlen("user_")) == "user_")
  57. {
  58. $userId = intval(mb_substr($arUsers, mb_strlen("user_")));
  59. }
  60. if ($userId > 0)
  61. {
  62. $db = CUser::GetList(
  63. "LAST_NAME",
  64. "asc",
  65. ["ID_EQUAL_EXACT" => $userId],
  66. [
  67. "NAV_PARAMS" => false,
  68. 'FIELDS'=> [
  69. 'ID',
  70. 'LOGIN',
  71. 'EMAIL',
  72. 'NAME',
  73. 'LAST_NAME',
  74. 'SECOND_NAME'
  75. ],
  76. ]
  77. );
  78. if ($ar = $db->Fetch())
  79. {
  80. $str = CUser::FormatName(COption::GetOptionString("bizproc", "name_template", CSite::GetNameFormat(false), SITE_ID), $ar, true, false);
  81. if ($appendId)
  82. {
  83. $str = $str." [".$ar["ID"]."]";
  84. }
  85. return str_replace(",", " ", $str);
  86. }
  87. }
  88. else if (mb_strpos($arUsers, 'group_') === 0)
  89. {
  90. $str = self::getExtendedGroupName($arUsers, $appendId);
  91. return str_replace(array(',', ';'), array(' ', ' '), $str);
  92. }
  93. return str_replace(",", " ", $arUsers);
  94. }
  95. }
  96. public static function UsersArrayToString($users, $arWorkflowTemplate, $documentType, $appendId = true)
  97. {
  98. if (static::isEmptyValue($users))
  99. {
  100. return "";
  101. }
  102. if (is_array($users))
  103. {
  104. $users = array_unique($users);
  105. }
  106. $arAllowableUserGroups = [];
  107. $arAllowableUserGroupsTmp = CBPDocument::GetAllowableUserGroups($documentType);
  108. foreach ($arAllowableUserGroupsTmp as $k1 => $v1)
  109. {
  110. $arAllowableUserGroups[mb_strtolower($k1)] = str_replace(",", " ", $v1);
  111. }
  112. return self::UsersArrayToStringInternal($users, $arWorkflowTemplate, $arAllowableUserGroups, $appendId);
  113. }
  114. public static function UsersStringToArray($strUsers, $documentType, &$arErrors, $callbackFunction = null)
  115. {
  116. $arErrors = [];
  117. $strUsers = trim($strUsers);
  118. if ($strUsers == '')
  119. {
  120. return ($callbackFunction != null) ? array(array(), array()) : array();
  121. }
  122. if (CBPActivity::isExpression($strUsers))
  123. {
  124. return ($callbackFunction != null) ? array(array($strUsers), array()) : array($strUsers);
  125. }
  126. $arUsers = [];
  127. $strUsers = str_replace(";", ",", $strUsers);
  128. $arUsersTmp = explode(",", $strUsers);
  129. foreach ($arUsersTmp as $user)
  130. {
  131. $user = trim($user);
  132. if ($user <> '')
  133. {
  134. $arUsers[] = $user;
  135. }
  136. }
  137. $arAllowableUserGroups = null;
  138. $arResult = $arResultAlt = [];
  139. foreach ($arUsers as $user)
  140. {
  141. $bCorrectUser = false;
  142. $bNotFoundUser = true;
  143. if (preg_match(CBPActivity::ValuePattern, $user, $arMatches))
  144. {
  145. $bCorrectUser = true;
  146. $arResult[] = $arMatches[0];
  147. }
  148. else
  149. {
  150. if ($arAllowableUserGroups == null)
  151. {
  152. $arAllowableUserGroups = [];
  153. $arAllowableUserGroupsTmp = CBPDocument::GetAllowableUserGroups($documentType);
  154. foreach ($arAllowableUserGroupsTmp as $k1 => $v1)
  155. {
  156. $arAllowableUserGroups[mb_strtolower($k1)] = mb_strtolower($v1);
  157. }
  158. }
  159. if (array_key_exists(mb_strtolower($user), $arAllowableUserGroups))
  160. {
  161. $bCorrectUser = true;
  162. $arResult[] = $user;
  163. }
  164. elseif (($k1 = array_search(mb_strtolower($user), $arAllowableUserGroups)) !== false)
  165. {
  166. $bCorrectUser = true;
  167. $arResult[] = $k1;
  168. }
  169. elseif (preg_match('#\[([A-Z]{1,}[0-9A-Z_]+)\]#i', $user, $arMatches))
  170. {
  171. $bCorrectUser = true;
  172. $arResult[] = "group_".mb_strtolower($arMatches[1]);
  173. }
  174. else
  175. {
  176. $ar = self::SearchUserByName($user);
  177. $cnt = count($ar);
  178. if ($cnt == 1)
  179. {
  180. $bCorrectUser = true;
  181. $arResult[] = "user_".$ar[0];
  182. }
  183. elseif ($cnt > 1)
  184. {
  185. $bNotFoundUser = false;
  186. $arErrors[] = array(
  187. "code" => "Ambiguous",
  188. "message" => str_replace("#USER#", htmlspecialcharsbx($user), GetMessage("BPCGHLP_AMBIGUOUS_USER")),
  189. );
  190. }
  191. elseif ($callbackFunction != null)
  192. {
  193. $s = call_user_func_array($callbackFunction, array($user));
  194. if ($s != null)
  195. {
  196. $arResultAlt[] = $s;
  197. $bCorrectUser = true;
  198. }
  199. }
  200. }
  201. }
  202. if (!$bCorrectUser)
  203. {
  204. if ($bNotFoundUser)
  205. {
  206. $arErrors[] = array(
  207. "code" => "NotFound",
  208. "message" => str_replace("#USER#", htmlspecialcharsbx($user), GetMessage("BPCGHLP_INVALID_USER")),
  209. );
  210. }
  211. }
  212. }
  213. return ($callbackFunction != null) ? array($arResult, $arResultAlt) : $arResult;
  214. }
  215. private static function SearchUserByName($user)
  216. {
  217. $user = trim($user);
  218. if ($user == '')
  219. {
  220. return [];
  221. }
  222. $userId = 0;
  223. if ($user."|" == intval($user)."|")
  224. {
  225. $userId = intval($user);
  226. }
  227. if ($userId <= 0)
  228. {
  229. $arMatches = [];
  230. if (preg_match('#\[(\d+)\]#i', $user, $arMatches))
  231. {
  232. $userId = intval($arMatches[1]);
  233. }
  234. }
  235. $arResult = [];
  236. $dbUsers = false;
  237. if ($userId > 0)
  238. {
  239. $arFilter = array("ID_EQUAL_EXACT" => $userId);
  240. $dbUsers = CUser::GetList(
  241. "LAST_NAME",
  242. "asc",
  243. $arFilter,
  244. [
  245. 'FIELDS' => ['ID'],
  246. 'NAV_PARAMS' => false
  247. ]
  248. );
  249. }
  250. else
  251. {
  252. $userLogin = "";
  253. $arMatches = [];
  254. if (preg_match('#\((.+?)\)#i', $user, $arMatches))
  255. {
  256. $userLogin = $arMatches[1];
  257. $user = trim(str_replace("(".$userLogin.")", "", $user));
  258. }
  259. $userEmail = "";
  260. $arMatches = [];
  261. if (preg_match("#<(.+?)>#i", $user, $arMatches))
  262. {
  263. if (check_email($arMatches[1]))
  264. {
  265. $userEmail = $arMatches[1];
  266. $user = trim(Str_Replace("<".$userEmail.">", "", $user));
  267. }
  268. }
  269. $arUser = [];
  270. $arUserTmp = explode(" ", $user);
  271. foreach ($arUserTmp as $s)
  272. {
  273. $s = trim($s);
  274. if ($s <> '')
  275. {
  276. $arUser[] = $s;
  277. }
  278. }
  279. if ($userLogin <> '')
  280. {
  281. $arUser[] = $userLogin;
  282. }
  283. $dbUsers = CUser::SearchUserByName($arUser, $userEmail, true);
  284. }
  285. if ($dbUsers)
  286. {
  287. while ($arUsers = $dbUsers->GetNext())
  288. {
  289. $arResult[] = $arUsers["ID"];
  290. }
  291. }
  292. return $arResult;
  293. }
  294. public static function FormatTimePeriod($period)
  295. {
  296. $period = intval($period);
  297. $days = intval($period / 86400);
  298. $period = $period - $days * 86400;
  299. $hours = intval($period / 3600);
  300. $period = $period - $hours * 3600;
  301. $minutes = intval($period / 60);
  302. $period = $period - $minutes * 60;
  303. $seconds = intval($period);
  304. $s = "";
  305. if ($days > 0)
  306. {
  307. $s .= str_replace(
  308. array("#VAL#", "#UNIT#"),
  309. array($days, self::MakeWord($days, array(GetMessage("BPCGHLP_DAY1"), GetMessage("BPCGHLP_DAY2"), GetMessage("BPCGHLP_DAY3")))),
  310. "#VAL# #UNIT# "
  311. );
  312. }
  313. if ($hours > 0)
  314. {
  315. $s .= str_replace(
  316. array("#VAL#", "#UNIT#"),
  317. array($hours, self::MakeWord($hours, array(GetMessage("BPCGHLP_HOUR1"), GetMessage("BPCGHLP_HOUR2"), GetMessage("BPCGHLP_HOUR3")))),
  318. "#VAL# #UNIT# "
  319. );
  320. }
  321. if ($minutes > 0)
  322. {
  323. $s .= str_replace(
  324. array("#VAL#", "#UNIT#"),
  325. array($minutes, self::MakeWord($minutes, array(GetMessage("BPCGHLP_MIN1"), GetMessage("BPCGHLP_MIN2"), GetMessage("BPCGHLP_MIN3")))),
  326. "#VAL# #UNIT# "
  327. );
  328. }
  329. if ($seconds > 0)
  330. {
  331. $s .= str_replace(
  332. array("#VAL#", "#UNIT#"),
  333. array($seconds, self::MakeWord($seconds, array(GetMessage("BPCGHLP_SEC1"), GetMessage("BPCGHLP_SEC2"), GetMessage("BPCGHLP_SEC3")))),
  334. "#VAL# #UNIT# "
  335. );
  336. }
  337. return $s;
  338. }
  339. private static function MakeWord($val, $arWords)
  340. {
  341. if ($val > 20)
  342. {
  343. $val = ($val % 10);
  344. }
  345. if ($val == 1)
  346. {
  347. return $arWords[0];
  348. }
  349. elseif ($val > 1 && $val < 5)
  350. {
  351. return $arWords[1];
  352. }
  353. else
  354. {
  355. return $arWords[2];
  356. }
  357. }
  358. public static function GetFilterOperation($key)
  359. {
  360. $strNegative = "N";
  361. if (mb_substr($key, 0, 1) == "!")
  362. {
  363. $key = mb_substr($key, 1);
  364. $strNegative = "Y";
  365. }
  366. $strOrNull = "N";
  367. if (mb_substr($key, 0, 1) == "+")
  368. {
  369. $key = mb_substr($key, 1);
  370. $strOrNull = "Y";
  371. }
  372. if (mb_substr($key, 0, 2) == ">=")
  373. {
  374. $key = mb_substr($key, 2);
  375. $strOperation = ">=";
  376. }
  377. elseif (mb_substr($key, 0, 1) == ">")
  378. {
  379. $key = mb_substr($key, 1);
  380. $strOperation = ">";
  381. }
  382. elseif (mb_substr($key, 0, 2) == "<=")
  383. {
  384. $key = mb_substr($key, 2);
  385. $strOperation = "<=";
  386. }
  387. elseif (mb_substr($key, 0, 1) == "<")
  388. {
  389. $key = mb_substr($key, 1);
  390. $strOperation = "<";
  391. }
  392. elseif (mb_substr($key, 0, 1) == "@")
  393. {
  394. $key = mb_substr($key, 1);
  395. $strOperation = "=";
  396. $strNegative = 'N';
  397. }
  398. elseif (mb_substr($key, 0, 1) == "~")
  399. {
  400. $key = mb_substr($key, 1);
  401. $strOperation = "LIKE";
  402. }
  403. elseif (mb_substr($key, 0, 1) == "%")
  404. {
  405. $key = mb_substr($key, 1);
  406. $strOperation = "QUERY";
  407. }
  408. else
  409. {
  410. $strOperation = "=";
  411. }
  412. return array("FIELD" => $key, "NEGATIVE" => $strNegative, "OPERATION" => $strOperation, "OR_NULL" => $strOrNull);
  413. }
  414. public static function PrepareSql(&$arFields, $arOrder, $arFilter, $arGroupBy, $arSelectFields)
  415. {
  416. global $DB;
  417. $strSqlSelect = "";
  418. $strSqlFrom = "";
  419. $strSqlWhere = "";
  420. $strSqlGroupBy = "";
  421. $strSqlOrderBy = "";
  422. $arOrder = array_change_key_case($arOrder, CASE_UPPER);
  423. $arGroupByFunct = array("COUNT", "AVG", "MIN", "MAX", "SUM");
  424. $arAlreadyJoined = [];
  425. // GROUP BY -->
  426. if (is_array($arGroupBy) && count($arGroupBy)>0)
  427. {
  428. $arSelectFields = $arGroupBy;
  429. foreach ($arGroupBy as $key => $val)
  430. {
  431. $val = mb_strtoupper($val);
  432. $key = mb_strtoupper($key);
  433. if (array_key_exists($val, $arFields) && !in_array($key, $arGroupByFunct))
  434. {
  435. if ($strSqlGroupBy <> '')
  436. $strSqlGroupBy .= ", ";
  437. $strSqlGroupBy .= $arFields[$val]["FIELD"];
  438. if (!empty($arFields[$val]["FROM"]))
  439. {
  440. $toJoin = (array)$arFields[$val]["FROM"];
  441. foreach ($toJoin as $join)
  442. {
  443. if (in_array($join, $arAlreadyJoined))
  444. {
  445. continue;
  446. }
  447. if ($strSqlFrom <> '')
  448. {
  449. $strSqlFrom .= " ";
  450. }
  451. $strSqlFrom .= $join;
  452. $arAlreadyJoined[] = $join;
  453. }
  454. }
  455. }
  456. }
  457. }
  458. // <-- GROUP BY
  459. // SELECT -->
  460. $arFieldsKeys = array_keys($arFields);
  461. if (is_array($arGroupBy) && count($arGroupBy)==0)
  462. {
  463. $strSqlSelect = "COUNT(%%_DISTINCT_%% ".$arFields[$arFieldsKeys[0]]["FIELD"].") as CNT ";
  464. }
  465. else
  466. {
  467. if (isset($arSelectFields) && !is_array($arSelectFields) && is_string($arSelectFields) && $arSelectFields <> '' && array_key_exists($arSelectFields, $arFields))
  468. $arSelectFields = array($arSelectFields);
  469. if (!isset($arSelectFields)
  470. || !is_array($arSelectFields)
  471. || count($arSelectFields)<=0
  472. || in_array("*", $arSelectFields))
  473. {
  474. for ($i = 0, $cnt = count($arFieldsKeys); $i < $cnt; $i++)
  475. {
  476. if (isset($arFields[$arFieldsKeys[$i]]["WHERE_ONLY"])
  477. && $arFields[$arFieldsKeys[$i]]["WHERE_ONLY"] == "Y")
  478. {
  479. continue;
  480. }
  481. if ($strSqlSelect <> '')
  482. $strSqlSelect .= ", ";
  483. if ($arFields[$arFieldsKeys[$i]]["TYPE"] == "datetime")
  484. {
  485. if (array_key_exists($arFieldsKeys[$i], $arOrder))
  486. $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD"]." as ".$arFieldsKeys[$i]."_X1, ";
  487. $strSqlSelect .= $DB->DateToCharFunction($arFields[$arFieldsKeys[$i]]["FIELD"], "FULL")." as ".$arFieldsKeys[$i];
  488. }
  489. elseif ($arFields[$arFieldsKeys[$i]]["TYPE"] == "date")
  490. {
  491. if (array_key_exists($arFieldsKeys[$i], $arOrder))
  492. $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD"]." as ".$arFieldsKeys[$i]."_X1, ";
  493. $strSqlSelect .= $DB->DateToCharFunction($arFields[$arFieldsKeys[$i]]["FIELD"], "SHORT")." as ".$arFieldsKeys[$i];
  494. }
  495. else
  496. $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD"]." as ".$arFieldsKeys[$i];
  497. if (!empty($arFields[$arFieldsKeys[$i]]["FROM"]))
  498. {
  499. $toJoin = (array)$arFields[$arFieldsKeys[$i]]["FROM"];
  500. foreach ($toJoin as $join)
  501. {
  502. if (in_array($join, $arAlreadyJoined))
  503. continue;
  504. if ($strSqlFrom <> '')
  505. $strSqlFrom .= " ";
  506. $strSqlFrom .= $join;
  507. $arAlreadyJoined[] = $join;
  508. }
  509. }
  510. }
  511. }
  512. else
  513. {
  514. foreach ($arOrder as $by => $order)
  515. {
  516. if (
  517. isset($arFields[$by])
  518. && !in_array($by, $arSelectFields)
  519. && ($arFields[$by]["TYPE"] == "date" || $arFields[$by]["TYPE"] == "datetime")
  520. )
  521. $arSelectFields[] = $by;
  522. }
  523. foreach ($arSelectFields as $key => $val)
  524. {
  525. $val = mb_strtoupper($val);
  526. $key = mb_strtoupper($key);
  527. if (array_key_exists($val, $arFields))
  528. {
  529. if ($strSqlSelect <> '')
  530. $strSqlSelect .= ", ";
  531. if (in_array($key, $arGroupByFunct))
  532. {
  533. $strSqlSelect .= $key."(".$arFields[$val]["FIELD"].") as ".$val;
  534. }
  535. else
  536. {
  537. if ($arFields[$val]["TYPE"] == "datetime")
  538. {
  539. if (array_key_exists($val, $arOrder))
  540. $strSqlSelect .= $arFields[$val]["FIELD"]." as ".$val."_X1, ";
  541. $strSqlSelect .= $DB->DateToCharFunction($arFields[$val]["FIELD"], "FULL")." as ".$val;
  542. }
  543. elseif ($arFields[$val]["TYPE"] == "date")
  544. {
  545. if (array_key_exists($val, $arOrder))
  546. $strSqlSelect .= $arFields[$val]["FIELD"]." as ".$val."_X1, ";
  547. $strSqlSelect .= $DB->DateToCharFunction($arFields[$val]["FIELD"], "SHORT")." as ".$val;
  548. }
  549. else
  550. $strSqlSelect .= $arFields[$val]["FIELD"]." as ".$val;
  551. }
  552. if (!empty($arFields[$val]["FROM"]))
  553. {
  554. $toJoin = (array)$arFields[$val]["FROM"];
  555. foreach ($toJoin as $join)
  556. {
  557. if (in_array($join, $arAlreadyJoined))
  558. continue;
  559. if ($strSqlFrom <> '')
  560. $strSqlFrom .= " ";
  561. $strSqlFrom .= $join;
  562. $arAlreadyJoined[] = $join;
  563. }
  564. }
  565. }
  566. }
  567. }
  568. if ($strSqlGroupBy <> '')
  569. {
  570. if ($strSqlSelect <> '')
  571. $strSqlSelect .= ", ";
  572. $strSqlSelect .= "COUNT(%%_DISTINCT_%% ".$arFields[$arFieldsKeys[0]]["FIELD"].") as CNT";
  573. }
  574. else
  575. $strSqlSelect = "%%_DISTINCT_%% ".$strSqlSelect;
  576. }
  577. // <-- SELECT
  578. // WHERE -->
  579. $arSqlSearch = [];
  580. if (!is_array($arFilter))
  581. $filter_keys = [];
  582. else
  583. $filter_keys = array_keys($arFilter);
  584. for ($i = 0, $cnt = count($filter_keys); $i < $cnt; $i++)
  585. {
  586. $vals = $arFilter[$filter_keys[$i]];
  587. if (!is_array($vals))
  588. $vals = array($vals);
  589. $key = $filter_keys[$i];
  590. $key_res = CBPHelper::GetFilterOperation($key);
  591. $key = $key_res["FIELD"];
  592. $strNegative = $key_res["NEGATIVE"];
  593. $strOperation = $key_res["OPERATION"];
  594. $strOrNull = $key_res["OR_NULL"];
  595. if (array_key_exists($key, $arFields))
  596. {
  597. $arSqlSearch_tmp = array();
  598. for ($j = 0, $cntj = count($vals); $j < $cntj; $j++)
  599. {
  600. $val = $vals[$j];
  601. if (isset($arFields[$key]["WHERE"]))
  602. {
  603. $arSqlSearch_tmp1 = call_user_func_array(
  604. $arFields[$key]["WHERE"],
  605. array($val, $key, $strOperation, $strNegative, $arFields[$key]["FIELD"], $arFields, $arFilter)
  606. );
  607. if ($arSqlSearch_tmp1 !== false)
  608. $arSqlSearch_tmp[] = $arSqlSearch_tmp1;
  609. }
  610. else
  611. {
  612. if ($arFields[$key]["TYPE"] == "int")
  613. {
  614. if ((intval($val) == 0) && (mb_strpos($strOperation, "=") !== False))
  615. $arSqlSearch_tmp[] = "(".$arFields[$key]["FIELD"]." IS ".(($strNegative == "Y") ? "NOT " : "")."NULL) ".(($strNegative == "Y") ? "AND" : "OR")." ".(($strNegative == "Y") ? "NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." 0)";
  616. else
  617. $arSqlSearch_tmp[] = (($strNegative == "Y") ? " ".$arFields[$key]["FIELD"]." IS NULL OR NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".intval($val)." )";
  618. }
  619. elseif ($arFields[$key]["TYPE"] == "double")
  620. {
  621. $val = str_replace(",", ".", $val);
  622. if ((DoubleVal($val) == 0) && (mb_strpos($strOperation, "=") !== False))
  623. $arSqlSearch_tmp[] = "(".$arFields[$key]["FIELD"]." IS ".(($strNegative == "Y") ? "NOT " : "")."NULL) ".(($strNegative == "Y") ? "AND" : "OR")." ".(($strNegative == "Y") ? "NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." 0)";
  624. else
  625. $arSqlSearch_tmp[] = (($strNegative == "Y") ? " ".$arFields[$key]["FIELD"]." IS NULL OR NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".DoubleVal($val)." )";
  626. }
  627. elseif ($arFields[$key]["TYPE"] == "string" || $arFields[$key]["TYPE"] == "char")
  628. {
  629. if ($strOperation == "QUERY")
  630. {
  631. $arSqlSearch_tmp[] = GetFilterQuery($arFields[$key]["FIELD"], $val, "Y");
  632. }
  633. else
  634. {
  635. if (($val == '') && (mb_strpos($strOperation, "=") !== False))
  636. $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)."' )";
  637. else
  638. $arSqlSearch_tmp[] = (($strNegative == "Y") ? " ".$arFields[$key]["FIELD"]." IS NULL OR NOT " : "")."(".$arFields[$key]["FIELD"]." ".$strOperation." '".$DB->ForSql($val)."' )";
  639. }
  640. }
  641. elseif ($arFields[$key]["TYPE"] == "datetime")
  642. {
  643. if ($val == '')
  644. $arSqlSearch_tmp[] = ($strNegative=="Y"?"NOT":"")."(".$arFields[$key]["FIELD"]." IS NULL)";
  645. else
  646. $arSqlSearch_tmp[] = ($strNegative=="Y"?" ".$arFields[$key]["FIELD"]." IS NULL OR NOT ":"")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".$DB->CharToDateFunction($DB->ForSql($val), "FULL").")";
  647. }
  648. elseif ($arFields[$key]["TYPE"] == "date")
  649. {
  650. if ($val == '')
  651. $arSqlSearch_tmp[] = ($strNegative=="Y"?"NOT":"")."(".$arFields[$key]["FIELD"]." IS NULL)";
  652. else
  653. $arSqlSearch_tmp[] = ($strNegative=="Y"?" ".$arFields[$key]["FIELD"]." IS NULL OR NOT ":"")."(".$arFields[$key]["FIELD"]." ".$strOperation." ".$DB->CharToDateFunction($DB->ForSql($val), "SHORT").")";
  654. }
  655. }
  656. }
  657. if (!empty($arFields[$key]["FROM"]))
  658. {
  659. $toJoin = (array)$arFields[$key]["FROM"];
  660. foreach ($toJoin as $join)
  661. {
  662. if (in_array($join, $arAlreadyJoined))
  663. continue;
  664. if ($strSqlFrom <> '')
  665. $strSqlFrom .= " ";
  666. $strSqlFrom .= $join;
  667. $arAlreadyJoined[] = $join;
  668. }
  669. }
  670. $strSqlSearch_tmp = "";
  671. for ($j = 0, $cntj = count($arSqlSearch_tmp); $j < $cntj; $j++)
  672. {
  673. if ($j > 0)
  674. $strSqlSearch_tmp .= ($strNegative=="Y" ? " AND " : " OR ");
  675. $strSqlSearch_tmp .= "(".$arSqlSearch_tmp[$j].")";
  676. }
  677. if ($strOrNull == "Y")
  678. {
  679. if ($strSqlSearch_tmp <> '')
  680. $strSqlSearch_tmp .= ($strNegative=="Y" ? " AND " : " OR ");
  681. $strSqlSearch_tmp .= "(".$arFields[$key]["FIELD"]." IS ".($strNegative=="Y" ? "NOT " : "")."NULL)";
  682. if ($strSqlSearch_tmp <> '')
  683. $strSqlSearch_tmp .= ($strNegative=="Y" ? " AND " : " OR ");
  684. if ($arFields[$key]["TYPE"] == "int" || $arFields[$key]["TYPE"] == "double")
  685. $strSqlSearch_tmp .= "(".$arFields[$key]["FIELD"]." ".($strNegative=="Y" ? "<>" : "=")." 0)";
  686. elseif ($arFields[$key]["TYPE"] == "string" || $arFields[$key]["TYPE"] == "char")
  687. $strSqlSearch_tmp .= "(".$arFields[$key]["FIELD"]." ".($strNegative=="Y" ? "<>" : "=")." '')";
  688. }
  689. if ($strSqlSearch_tmp != "")
  690. $arSqlSearch[] = "(".$strSqlSearch_tmp.")";
  691. }
  692. }
  693. for ($i = 0, $cnt = count($arSqlSearch); $i < $cnt; $i++)
  694. {
  695. if ($strSqlWhere <> '')
  696. $strSqlWhere .= " AND ";
  697. $strSqlWhere .= "(".$arSqlSearch[$i].")";
  698. }
  699. // <-- WHERE
  700. // ORDER BY -->
  701. $arSqlOrder = Array();
  702. foreach ($arOrder as $by => $order)
  703. {
  704. $by = mb_strtoupper($by);
  705. $order = mb_strtoupper($order);
  706. if ($order != "ASC")
  707. $order = "DESC";
  708. else
  709. $order = "ASC";
  710. if (array_key_exists($by, $arFields))
  711. {
  712. if ($arFields[$by]["TYPE"] == "datetime" || $arFields[$by]["TYPE"] == "date")
  713. $arSqlOrder[] = " ".$by."_X1 ".$order." ";
  714. else
  715. $arSqlOrder[] = " ".$arFields[$by]["FIELD"]." ".$order." ";
  716. if (!empty($arFields[$by]["FROM"]))
  717. {
  718. $toJoin = (array)$arFields[$by]["FROM"];
  719. foreach ($toJoin as $join)
  720. {
  721. if (in_array($join, $arAlreadyJoined))
  722. continue;
  723. if ($strSqlFrom <> '')
  724. $strSqlFrom .= " ";
  725. $strSqlFrom .= $join;
  726. $arAlreadyJoined[] = $join;
  727. }
  728. }
  729. }
  730. }
  731. $strSqlOrderBy = "";
  732. DelDuplicateSort($arSqlOrder);
  733. for ($i = 0, $cnt = count($arSqlOrder); $i < $cnt; $i++)
  734. {
  735. if ($strSqlOrderBy <> '')
  736. $strSqlOrderBy .= ", ";
  737. $strSqlOrderBy .= $arSqlOrder[$i];
  738. }
  739. // <-- ORDER BY
  740. return array(
  741. "SELECT" => $strSqlSelect,
  742. "FROM" => $strSqlFrom,
  743. "WHERE" => $strSqlWhere,
  744. "GROUPBY" => $strSqlGroupBy,
  745. "ORDERBY" => $strSqlOrderBy
  746. );
  747. }
  748. public static function ParseDocumentId($parameterDocumentId)
  749. {
  750. if (!is_array($parameterDocumentId))
  751. {
  752. $parameterDocumentId = array($parameterDocumentId);
  753. }
  754. $moduleId = "";
  755. $entity = "";
  756. $documentId = "";
  757. $cnt = count($parameterDocumentId);
  758. if ($cnt > 2)
  759. {
  760. $documentId = $parameterDocumentId[2];
  761. $entity = $parameterDocumentId[1];
  762. $moduleId = $parameterDocumentId[0];
  763. }
  764. elseif ($cnt == 2)
  765. {
  766. $documentId = $parameterDocumentId[1];
  767. $entity = $parameterDocumentId[0];
  768. }
  769. $moduleId = trim($moduleId);
  770. if (!is_array($documentId))
  771. {
  772. $documentId = trim($documentId);
  773. }
  774. if ($documentId === '')
  775. {
  776. throw new CBPArgumentNullException("documentId");
  777. }
  778. $entity = trim($entity);
  779. if ($entity === '')
  780. {
  781. throw new CBPArgumentNullException("entity");
  782. }
  783. return [$moduleId, $entity, $documentId];
  784. }
  785. public static function ParseDocumentIdArray($parameterDocumentId)
  786. {
  787. if (!is_array($parameterDocumentId))
  788. {
  789. $parameterDocumentId = array($parameterDocumentId);
  790. }
  791. $moduleId = "";
  792. $entity = "";
  793. $documentId = "";
  794. $cnt = count($parameterDocumentId);
  795. if ($cnt > 2)
  796. {
  797. $documentId = $parameterDocumentId[2];
  798. $entity = $parameterDocumentId[1];
  799. $moduleId = $parameterDocumentId[0];
  800. }
  801. elseif ($cnt == 2)
  802. {
  803. $documentId = $parameterDocumentId[1];
  804. $entity = $parameterDocumentId[0];
  805. }
  806. $moduleId = trim($moduleId);
  807. $entity = trim($entity);
  808. if ($entity == '')
  809. {
  810. throw new Exception("entity");
  811. }
  812. if (is_array($documentId))
  813. {
  814. $a = [];
  815. foreach ($documentId as $v)
  816. {
  817. $v = trim($v);
  818. if ($v <> '')
  819. {
  820. $a[] = $v;
  821. }
  822. }
  823. $documentId = $a;
  824. if (count($documentId) <= 0)
  825. {
  826. throw new CBPArgumentNullException("documentId");
  827. }
  828. }
  829. else
  830. {
  831. $documentId = trim($documentId);
  832. if ($documentId == '')
  833. {
  834. throw new CBPArgumentNullException("documentId");
  835. }
  836. $documentId = array($documentId);
  837. }
  838. return [$moduleId, $entity, $documentId];
  839. }
  840. public static function GetFieldValuePrintable($fieldName, $fieldType, $result)
  841. {
  842. $newResult = null;
  843. switch ($fieldType)
  844. {
  845. case "user":
  846. if (is_array($result))
  847. {
  848. $newResult = [];
  849. foreach ($result as $r)
  850. {
  851. $newResult[] = CBPHelper::ConvertUserToPrintableForm($r);
  852. }
  853. }
  854. else
  855. {
  856. $newResult = CBPHelper::ConvertUserToPrintableForm($result);
  857. }
  858. break;
  859. case "file":
  860. if (is_array($result))
  861. {
  862. $newResult = array();
  863. foreach ($result as $r)
  864. {
  865. $r = intval($r);
  866. $dbImg = CFile::GetByID($r);
  867. if ($arImg = $dbImg->Fetch())
  868. {
  869. $newResult[] = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$r."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
  870. }
  871. }
  872. }
  873. else
  874. {
  875. $result = intval($result);
  876. $dbImg = CFile::GetByID($result);
  877. if ($arImg = $dbImg->Fetch())
  878. {
  879. $newResult = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$result."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
  880. }
  881. }
  882. break;
  883. default:
  884. $newResult = $result;
  885. }
  886. return $newResult;
  887. }
  888. public static function ConvertUserToPrintableForm($userId, $nameTemplate = "")
  889. {
  890. if (mb_substr($userId, 0, mb_strlen("user_")) == "user_")
  891. {
  892. $userId = mb_substr($userId, mb_strlen("user_"));
  893. }
  894. if (empty($nameTemplate))
  895. {
  896. $nameTemplate = COption::GetOptionString("bizproc", "name_template", CSite::GetNameFormat(false), SITE_ID);
  897. }
  898. $userId = intval($userId);
  899. $db = CUser::GetList(
  900. "LAST_NAME",
  901. "asc",
  902. ["ID_EQUAL_EXACT" => $userId],
  903. [
  904. "NAV_PARAMS" => false,
  905. 'FIELDS'=> [
  906. 'ID',
  907. 'LOGIN',
  908. 'EMAIL',
  909. 'NAME',
  910. 'LAST_NAME',
  911. 'SECOND_NAME'
  912. ]
  913. ]
  914. );
  915. $str = "";
  916. if ($ar = $db->Fetch())
  917. {
  918. $str = CUser::FormatName($nameTemplate, $ar, true);
  919. $str = $str." [".$ar["ID"]."]";
  920. $str = str_replace(",", " ", $str);
  921. }
  922. return $str;
  923. }
  924. public static function GetJSFunctionsForFields($objectName, $arDocumentFields, $arDocumentFieldTypes)
  925. {
  926. ob_start();
  927. echo CAdminCalendar::ShowScript();
  928. ?>
  929. <script type="text/javascript">
  930. <?= $objectName ?>.GetGUIFieldEdit = function(field, value, showAddButton, inputName)
  931. {
  932. alert("Deprecated method GetGUIFieldEdit used");
  933. if (!this.arDocumentFields[field])
  934. return "";
  935. if (typeof showAddButton == "undefined")
  936. showAddButton = false;
  937. if (typeof inputName == "undefined")
  938. inputName = field;
  939. var type = this.arDocumentFields[field]["Type"];
  940. var bAddSelection = false;
  941. var bAddButton = true;
  942. s = "";
  943. if (type == "int" || type == "double")
  944. {
  945. s += '<input type="text" size="10" id="id_' + field + '" name="' + inputName + '" value="' + this.HtmlSpecialChars(value) + '">';
  946. }
  947. else if (type == "select")
  948. {
  949. s += '<select name="' + inputName + '_1">';
  950. s += '<option value=""></option>';
  951. for (k in this.arDocumentFields[field]["Options"])
  952. {
  953. s += '<option value="' + k + '"' + (value == this.arDocumentFields[field]["Options"][k] ? " selected" : "") + '>' + this.arDocumentFields[field]["Options"][k] + '</option>';
  954. if (value == this.arDocumentFields[field]["Options"][k])
  955. value = "";
  956. }
  957. s += '</select>';
  958. bAddSelection = true;
  959. }
  960. else if (type == "file")
  961. {
  962. s += '<input type="file" id="id_' + field + '_1" name="' + inputName + '">';
  963. bAddSelection = true;
  964. bAddButton = true;
  965. }
  966. else if (type == "bool")
  967. {
  968. s += '<select name="' + inputName + '_1">';
  969. s += '<option value=""></option>';
  970. s += '<option value="Y"' + (value == "Y" ? " selected" : "") + '><?= GetMessage("BPCGHLP_YES") ?></option>';
  971. s += '<option value="N"' + (value == "N" ? " selected" : "") + '><?= GetMessage("BPCGHLP_NO") ?></option>';
  972. s += '</select>';
  973. bAddSelection = true;
  974. if (value == "Y" || value == "N")
  975. value = "";
  976. }
  977. else if (type == "datetime" || type == "date")
  978. {
  979. s += '<span style="white-space:nowrap;">';
  980. s += '<input type="text" name="' + inputName + '" id="id_' + field + '" size="10" value="' + this.HtmlSpecialChars(value) + '">';
  981. s += '<a href="javascript:void(0);" title="<?= GetMessage("BPCGHLP_CALENDAR") ?>">';
  982. s += '<img src="<?= ADMIN_THEMES_PATH ?>/<?= ADMIN_THEME_ID ?>/images/calendar/icon.gif" alt="<?= GetMessage("BPCGHLP_CALENDAR") ?>" class="calendar-icon" onclick="jsAdminCalendar.Show(this, \'' + inputName + '\', \'\', \'\', ' + ((type == "datetime") ? 'true' : 'false') + ', <?= time() + date("Z") + CTimeZone::GetOffset() ?>);" onmouseover="this.className+=\' calendar-icon-hover\';" onmouseout="this.className = this.className.replace(/\s*calendar-icon-hover/ig, \'\');">';
  983. s += '</a></span>';
  984. }
  985. else // type == "S"
  986. {
  987. s += '<input type="text" size="40" id="id_' + field + '" name="' + inputName + '" value="' + this.HtmlSpecialChars(value) + '">';
  988. }
  989. if (bAddSelection)
  990. s += '<br /><input type="text" id="id_' + field + '" name="' + inputName + '" value="' + this.HtmlSpecialChars(value) + '">';
  991. if (bAddButton && showAddButton)
  992. s += '<input type="button" value="..." onclick="BPAShowSelector(\'id_' + field + '\', \'' + type + '\');">';
  993. return s;
  994. }
  995. <?= $objectName ?>.SetGUIFieldEdit = function(field)
  996. {
  997. alert("Deprecated method SetGUIFieldEdit used");
  998. }
  999. <?= $objectName ?>.GetGUIFieldEditSimple = function(type, value, name)
  1000. {
  1001. alert("Deprecated method GetGUIFieldEditSimple used");
  1002. if (typeof name == "undefined" || name.length <= 0)
  1003. name = "BPVDDefaultValue";
  1004. if (typeof value == "undefined")
  1005. {
  1006. value = "";
  1007. var obj = document.getElementById('id_' + name);
  1008. if (obj)
  1009. {
  1010. if (obj.type.substr(0, "select".length) == "select")
  1011. value = obj.options[obj.selectedIndex].value;
  1012. else
  1013. value = obj.value;
  1014. }
  1015. }
  1016. s = "";
  1017. if (type == "file")
  1018. {
  1019. s += '';
  1020. }
  1021. else if (type == "bool")
  1022. {
  1023. s += '<select name="' + name + '" id="id_' + name + '">';
  1024. s += '<option value=""></option>';
  1025. s += '<option value="Y"' + (value == "Y" ? " selected" : "") + '><?= GetMessage("BPCGHLP_YES") ?></option>';
  1026. s += '<option value="N"' + (value == "N" ? " selected" : "") + '><?= GetMessage("BPCGHLP_NO") ?></option>';
  1027. s += '</select>';
  1028. }
  1029. else if (type == "user")
  1030. {
  1031. s += '<input type="text" size="10" id="id_' + name + '" name="' + name + '" value="' + this.HtmlSpecialChars(value) + '">';
  1032. s += '<input type="button" value="..." onclick="BPAShowSelector(\'id_' + name + '\', \'user\')">';
  1033. }
  1034. else
  1035. {
  1036. s += '<input type="text" size="10" id="id_' + name + '" name="' + name + '" value="' + this.HtmlSpecialChars(value) + '">';
  1037. }
  1038. return s;
  1039. }
  1040. <?= $objectName ?>.SetGUIFieldEditSimple = function(type, name)
  1041. {
  1042. alert("Deprecated method SetGUIFieldEditSimple used");
  1043. if (typeof name == "undefined" || name.length <= 0)
  1044. name = "BPVDDefaultValue";
  1045. s = "";
  1046. if (type != "file")
  1047. {
  1048. var obj = document.getElementById('id_' + name);
  1049. if (obj)
  1050. {
  1051. if (obj.type.substr(0, "select".length) == "select")
  1052. s = obj.options[obj.selectedIndex].value;
  1053. else
  1054. s = obj.value;
  1055. }
  1056. }
  1057. return s;
  1058. }
  1059. </script>
  1060. <?
  1061. $str = ob_get_contents();
  1062. ob_end_clean();
  1063. return $str;
  1064. }
  1065. public static function GetDocumentFieldTypes()
  1066. {
  1067. $arResult = array(
  1068. "string" => array("Name" => GetMessage("BPCGHLP_PROP_STRING"), "BaseType" => "string"),
  1069. "text" => array("Name" => GetMessage("BPCGHLP_PROP_TEXT"), "BaseType" => "text"),
  1070. "int" => array("Name" => GetMessage("BPCGHLP_PROP_INT"), "BaseType" => "int"),
  1071. "double" => array("Name" => GetMessage("BPCGHLP_PROP_DOUBLE"), "BaseType" => "double"),
  1072. "select" => array("Name" => GetMessage("BPCGHLP_PROP_SELECT"), "BaseType" => "select"),
  1073. "internalselect" => array("Name" => GetMessage("BPCGHLP_PROP_INTERNALSELECT_1"), "BaseType" => "internalselect"),
  1074. "bool" => array("Name" => GetMessage("BPCGHLP_PROP_BOOL"), "BaseType" => "bool"),
  1075. "date" => array("Name" => GetMessage("BPCGHLP_PROP_DATA"), "BaseType" => "date"),
  1076. "datetime" => array("Name" => GetMessage("BPCGHLP_PROP_DATETIME"), "BaseType" => "datetime"),
  1077. "user" => array("Name" => GetMessage("BPCGHLP_PROP_USER"), "BaseType" => "user"),
  1078. "file" => array("Name" => GetMessage("BPCGHLP_PROP_FILE"), "BaseType" => "file"),
  1079. );
  1080. return $arResult;
  1081. }
  1082. /**
  1083. * @deprecated
  1084. */
  1085. public static function GetGUIFieldEdit($documentType, $formName, $fieldName, $fieldValue, $arDocumentField, $bAllowSelection)
  1086. {
  1087. return self::GetFieldInputControl(
  1088. $documentType,
  1089. $arDocumentField,
  1090. array("Form" => $formName, "Field" => $fieldName),
  1091. $fieldValue,
  1092. $bAllowSelection
  1093. );
  1094. }
  1095. public static function GetFieldInputControl($documentType, $arFieldType, $arFieldName, $fieldValue, $bAllowSelection = false)
  1096. {
  1097. if (!is_array($fieldValue) || is_array($fieldValue) && CBPHelper::IsAssociativeArray($fieldValue))
  1098. {
  1099. $fieldValue = array($fieldValue);
  1100. }
  1101. ob_start();
  1102. if ($arFieldType["Type"] == "select")
  1103. {
  1104. $fieldValueTmp = $fieldValue;
  1105. ?>
  1106. <select id="id_<?= $arFieldName["Field"] ?>" name="<?= $arFieldName["Field"].($arFieldType["Multiple"] ? "[]" : "") ?>"<?= ($arFieldType["Multiple"] ? ' size="5" multiple' : '') ?>>
  1107. <?
  1108. if (!$arFieldType["Required"])
  1109. echo '<option value="">['.GetMessage("BPCGHLP_NOT_SET").']</option>';
  1110. foreach ($arFieldType["Options"] as $k => $v)
  1111. {
  1112. $ind = array_search($k, $fieldValueTmp);
  1113. echo '<option value="'.htmlspecialcharsbx($k).'"'.($ind !== false ? ' selected' : '').'>'.htmlspecialcharsbx($v).'</option>';
  1114. if ($ind !== false)
  1115. unset($fieldValueTmp[$ind]);
  1116. }
  1117. ?>
  1118. </select>
  1119. <?
  1120. if ($bAllowSelection)
  1121. {
  1122. ?>
  1123. <br /><input type="text" id="id_<?= $arFieldName["Field"] ?>_text" name="<?= $arFieldName["Field"] ?>_text" value="<?
  1124. if (count($fieldValueTmp) > 0)
  1125. {
  1126. $a = array_values($fieldValueTmp);
  1127. echo htmlspecialcharsbx($a[0]);
  1128. }
  1129. ?>"><?
  1130. echo CBPHelper::renderControlSelectorButton('id_'.$arFieldName["Field"].'_text', 'select');
  1131. }
  1132. }
  1133. elseif ($arFieldType["Type"] == "user")
  1134. {
  1135. $fieldValue = CBPHelper::UsersArrayToString($fieldValue, null, $documentType);
  1136. ?><input type="text" size="40" id="id_<?= $arFieldName["Field"] ?>" name="<?= $arFieldName["Field"] ?>" value="<?= htmlspecialcharsbx($fieldValue) ?>"><? echo CBPHelper::renderControlSelectorButton('id_'.$arFieldName["Field"], 'user');
  1137. }
  1138. else
  1139. {
  1140. if (!array_key_exists("CBPVirtualDocumentCloneRowPrinted", $GLOBALS) && $arFieldType["Multiple"])
  1141. {
  1142. $GLOBALS["CBPVirtualDocumentCloneRowPrinted"] = 1;
  1143. ?>
  1144. <script language="JavaScript">
  1145. <!--
  1146. function CBPVirtualDocumentCloneRow(tableID)
  1147. {
  1148. var tbl = document.getElementById(tableID);
  1149. var cnt = tbl.rows.length;
  1150. var oRow = tbl.insertRow(cnt);
  1151. var oCell = oRow.insertCell(0);
  1152. var sHTML = tbl.rows[cnt - 1].cells[0].innerHTML;
  1153. var p = 0;
  1154. while (true)
  1155. {
  1156. var s = sHTML.indexOf('[n', p);
  1157. if (s < 0)
  1158. break;
  1159. var e = sHTML.indexOf(']', s);
  1160. if (e < 0)
  1161. break;
  1162. var n = parseInt(sHTML.substr(s + 2, e - s));
  1163. sHTML = sHTML.substr(0, s) + '[n' + (++n) + ']' + sHTML.substr(e + 1);
  1164. p = s + 1;
  1165. }
  1166. var p = 0;
  1167. while (true)
  1168. {
  1169. var s = sHTML.indexOf('__n', p);
  1170. if (s < 0)
  1171. break;
  1172. var e = sHTML.indexOf('_', s + 2);
  1173. if (e < 0)
  1174. break;
  1175. var n = parseInt(sHTML.substr(s + 3, e - s));
  1176. sHTML = sHTML.substr(0, s) + '__n' + (++n) + '_' + sHTML.substr(e + 1);
  1177. p = e + 1;
  1178. }
  1179. oCell.innerHTML = sHTML;
  1180. var patt = new RegExp('<' + 'script' + '>[^\000]*?<' + '\/' + 'script' + '>', 'ig');
  1181. var code = sHTML.match(patt);
  1182. if (code)
  1183. {
  1184. for (var i = 0; i < code.length; i++)
  1185. {
  1186. if (code[i] != '')
  1187. {
  1188. var s = code[i].substring(8, code[i].length - 9);
  1189. jsUtils.EvalGlobal(s);
  1190. }
  1191. }
  1192. }
  1193. }
  1194. //-->
  1195. </script>
  1196. <?
  1197. }
  1198. if ($arFieldType["Multiple"])
  1199. echo '<table width="100%" border="0" cellpadding="2" cellspacing="2" id="CBPVirtualDocument_'.$arFieldName["Field"].'_Table">';
  1200. if ($bAllowSelection)
  1201. {
  1202. $arFieldType["BaseType"] = "string";
  1203. static $arDocumentTypes = null;
  1204. if (is_null($arDocumentTypes))
  1205. $arDocumentTypes = self::GetDocumentFieldTypes($documentType);
  1206. if (array_key_exists($arFieldType["Type"], $arDocumentTypes))
  1207. $arFieldType["BaseType"] = $arDocumentTypes[$arFieldType["Type"]]["BaseType"];
  1208. }
  1209. $fieldValueTmp = $fieldValue;
  1210. $ind = -1;
  1211. foreach ($fieldValue as $key => $value)
  1212. {
  1213. $ind++;
  1214. $fieldNameId = 'id_'.$arFieldName["Field"].'__n'.$ind.'_';
  1215. $fieldNameName = $arFieldName["Field"].($arFieldType["Multiple"] ? "[n".$ind."]" : "");
  1216. if ($arFieldType["Multiple"])
  1217. echo '<tr><td>';
  1218. switch ($arFieldType["Type"])
  1219. {
  1220. case "int":
  1221. case "double":
  1222. unset($fieldValueTmp[$key]);
  1223. ?><input type="text" size="10" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>" value="<?= htmlspecialcharsbx($value) ?>"><?
  1224. break;
  1225. case "file":
  1226. unset($fieldValueTmp[$key]);
  1227. ?><input type="file" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>"><?
  1228. break;
  1229. case "bool":
  1230. if (in_array($value, array("Y", "N")))
  1231. unset($fieldValueTmp[$key]);
  1232. ?>
  1233. <select id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>">
  1234. <?
  1235. if (!$arFieldType["Required"])
  1236. echo '<option value="">['.GetMessage("BPCGHLP_NOT_SET").']</option>';
  1237. ?>
  1238. <option value="Y"<?= (in_array("Y", $fieldValue) ? ' selected' : '') ?>><?= GetMessage("BPCGHLP_YES") ?></option>
  1239. <option value="N"<?= (in_array("N", $fieldValue) ? ' selected' : '') ?>><?= GetMessage("BPCGHLP_NO") ?></option>
  1240. </select>
  1241. <?
  1242. break;
  1243. case "text":
  1244. unset($fieldValueTmp[$key]);
  1245. ?><textarea rows="5" cols="40" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>"><?= htmlspecialcharsbx($value) ?></textarea><?
  1246. break;
  1247. case "date":
  1248. case "datetime":
  1249. $v = "";
  1250. if (!CBPActivity::isExpression($value))
  1251. {
  1252. $v = $value;
  1253. unset($fieldValueTmp[$key]);
  1254. }
  1255. echo CAdminCalendar::CalendarDate($fieldNameName, $v, 19, ($arFieldType["Type"] == "date"));
  1256. break;
  1257. default:
  1258. unset($fieldValueTmp[$key]);
  1259. ?><input type="text" size="40" id="<?= $fieldNameId ?>" name="<?= $fieldNameName ?>" value="<?= htmlspecialcharsbx($value) ?>"><?
  1260. }
  1261. if ($bAllowSelection)
  1262. {
  1263. if (!in_array($arFieldType["Type"], array("file", "bool", "date", "datetime")))
  1264. {
  1265. echo CBPHelper::renderControlSelectorButton($fieldNameId, $arFieldType["BaseType"]);
  1266. }
  1267. }
  1268. if ($arFieldType["Multiple"])
  1269. echo '</td></tr>';
  1270. }
  1271. if ($arFieldType["Multiple"])
  1272. echo "</table>";
  1273. if ($arFieldType["Multiple"])
  1274. echo '<input type="button" value="'.GetMessage("BPCGHLP_ADD").'" onclick="CBPVirtualDocumentCloneRow(\'CBPVirtualDocument_'.$arFieldName["Field"].'_Table\')"/><br />';
  1275. if ($bAllowSelection)
  1276. {
  1277. if (in_array($arFieldType["Type"], array("file", "bool", "date", "datetime")))
  1278. {
  1279. ?>
  1280. <input type="text" id="id_<?= $arFieldName["Field"] ?>_text" name="<?= $arFieldName["Field"] ?>_text" value="<?
  1281. if (count($fieldValueTmp) > 0)
  1282. {
  1283. $a = array_values($fieldValueTmp);
  1284. echo htmlspecialcharsbx($a[0]);
  1285. }
  1286. ?>"><?
  1287. echo CBPHelper::renderControlSelectorButton('id_'.$arFieldName["Field"].'_text', $arFieldType["BaseType"]);
  1288. }
  1289. }
  1290. }
  1291. $s = ob_get_contents();
  1292. ob_end_clean();
  1293. return $s;
  1294. }
  1295. public static function GetFieldInputValue($documentType, $arFieldType, $arFieldName, $arRequest, &$arErrors)
  1296. {
  1297. $result = [];
  1298. if ($arFieldType["Type"] == "user")
  1299. {
  1300. $value = $arRequest[$arFieldName["Field"]];
  1301. if ($value <> '')
  1302. {
  1303. $result = CBPHelper::UsersStringToArray($value, $documentType, $arErrors);
  1304. if (count($arErrors) > 0)
  1305. {
  1306. foreach ($arErrors as $e)
  1307. {
  1308. $arErrors[] = $e;
  1309. }
  1310. }
  1311. }
  1312. }
  1313. elseif (array_key_exists($arFieldName["Field"], $arRequest) || array_key_exists($arFieldName["Field"]."_text", $arRequest))
  1314. {
  1315. $arValue = [];
  1316. if (array_key_exists($arFieldName["Field"], $arRequest))
  1317. {
  1318. $arValue = $arRequest[$arFieldName["Field"]];
  1319. if (!is_array($arValue) || is_array($arValue) && CBPHelper::IsAssociativeArray($arValue))
  1320. {
  1321. $arValue = array($arValue);
  1322. }
  1323. }
  1324. if (array_key_exists($arFieldName["Field"]."_text", $arRequest))
  1325. {
  1326. $arValue[] = $arRequest[$arFieldName["Field"]."_text"];
  1327. }
  1328. foreach ($arValue as $value)
  1329. {
  1330. if (!CBPActivity::isExpression($value))
  1331. {
  1332. if ($arFieldType["Type"] == "int")
  1333. {
  1334. if ($value <> '')
  1335. {
  1336. $value = str_replace(" ", "", $value);
  1337. if ($value."|" == intval($value)."|")
  1338. {
  1339. $value = intval($value);
  1340. }
  1341. else
  1342. {
  1343. $value = null;
  1344. $arErrors[] = array(
  1345. "code" => "ErrorValue",
  1346. "message" => GetMessage("BPCGWTL_INVALID1"),
  1347. "parameter" => $arFieldName["Field"],
  1348. );
  1349. }
  1350. }
  1351. else
  1352. {
  1353. $value = null;
  1354. }
  1355. }
  1356. elseif ($arFieldType["Type"] == "double")
  1357. {
  1358. if ($value <> '')
  1359. {
  1360. $value = str_replace(" ", "", str_replace(",", ".", $value));
  1361. if ($value."|" == doubleval($value)."|")
  1362. {
  1363. $value = doubleval($value);
  1364. }
  1365. else
  1366. {
  1367. $value = null;
  1368. $arErrors[] = array(
  1369. "code" => "ErrorValue",
  1370. "message" => GetMessage("BPCGWTL_INVALID11"),
  1371. "parameter" => $arFieldName["Field"],
  1372. );
  1373. }
  1374. }
  1375. else
  1376. {
  1377. $value = null;
  1378. }
  1379. }
  1380. elseif ($arFieldType["Type"] == "select")
  1381. {
  1382. if (!is_array($arFieldType["Options"]) || count($arFieldType["Options"]) <= 0 || $value == '')
  1383. {
  1384. $value = null;
  1385. }
  1386. elseif (!array_key_exists($value, $arFieldType["Options"]))
  1387. {
  1388. $value = null;
  1389. $arErrors[] = array(
  1390. "code" => "ErrorValue",
  1391. "message" => GetMessage("BPCGWTL_INVALID35"),
  1392. "parameter" => $arFieldName["Field"],
  1393. );
  1394. }
  1395. }
  1396. elseif ($arFieldType["Type"] == "bool")
  1397. {
  1398. if ($value !== "Y" && $value !== "N")
  1399. {
  1400. if ($value === true)
  1401. {
  1402. $value = "Y";
  1403. }
  1404. elseif ($value === false)
  1405. {
  1406. $value = "N";
  1407. }
  1408. elseif ($value <> '')
  1409. {
  1410. $value = mb_strtolower($value);
  1411. if (in_array($value, array("y", "yes", "true", "1")))
  1412. {
  1413. $value = "Y";
  1414. }
  1415. elseif (in_array($value, array("n", "no", "false", "0")))
  1416. {
  1417. $value = "N";
  1418. }
  1419. else
  1420. {
  1421. $value = null;
  1422. $arErrors[] = array(
  1423. "code" => "ErrorValue",
  1424. "message" => GetMessage("BPCGWTL_INVALID45"),
  1425. "parameter" => $arFieldName["Field"],
  1426. );
  1427. }
  1428. }
  1429. else
  1430. {
  1431. $value = null;
  1432. }
  1433. }
  1434. }
  1435. elseif ($arFieldType["Type"] == "file")
  1436. {
  1437. if (array_key_exists("name", $value) && $value["name"] <> '')
  1438. {
  1439. if (!array_key_exists("MODULE_ID", $value) || $value["MODULE_ID"] == '')
  1440. $value["MODULE_ID"] = "bizproc";
  1441. $value = CFile::SaveFile($value, "bizproc_wf");
  1442. if (!$value)
  1443. {
  1444. $value = null;
  1445. $arErrors[] = array(
  1446. "code" => "ErrorValue",
  1447. "message" => GetMessage("BPCGWTL_INVALID915"),
  1448. "parameter" => $arFieldName["Field"],
  1449. );
  1450. }
  1451. }
  1452. else
  1453. {
  1454. $value = null;
  1455. }
  1456. }
  1457. else
  1458. {
  1459. if (!is_array($value) && $value == '')
  1460. $value = null;
  1461. }
  1462. }
  1463. if ($value != null)
  1464. $result[] = $value;
  1465. }
  1466. }
  1467. if (!$arFieldType["Multiple"])
  1468. {
  1469. if (count($result) > 0)
  1470. $result = $result[0];
  1471. else
  1472. $result = null;
  1473. }
  1474. return $result;
  1475. }
  1476. public static function GetFieldInputValuePrintable($documentType, $arFieldType, $fieldValue)
  1477. {
  1478. $result = $fieldValue;
  1479. switch ($arFieldType['Type'])
  1480. {
  1481. case "user":
  1482. $result = CBPHelper::UsersArrayToString($fieldValue, null, $documentType);
  1483. break;
  1484. case "bool":
  1485. if (is_array($fieldValue))
  1486. {
  1487. $result = array();
  1488. foreach ($fieldValue as $r)
  1489. $result[] = ((mb_strtoupper($r) == "Y") ? GetMessage("BPVDX_YES") : GetMessage("BPVDX_NO"));
  1490. }
  1491. else
  1492. {
  1493. $result = ((mb_strtoupper($fieldValue) == "Y") ? GetMessage("BPVDX_YES") : GetMessage("BPVDX_NO"));
  1494. }
  1495. break;
  1496. case "file":
  1497. if (is_array($fieldValue))
  1498. {
  1499. $result = array();
  1500. foreach ($fieldValue as $r)
  1501. {
  1502. $r = intval($r);
  1503. $dbImg = CFile::GetByID($r);
  1504. if ($arImg = $dbImg->Fetch())
  1505. $result[] = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$r."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
  1506. }
  1507. }
  1508. else
  1509. {
  1510. $fieldValue = intval($fieldValue);
  1511. $dbImg = CFile::GetByID($fieldValue);
  1512. if ($arImg = $dbImg->Fetch())
  1513. $result = "[url=/bitrix/tools/bizproc_show_file.php?f=".urlencode($arImg["FILE_NAME"])."&i=".$fieldValue."]".htmlspecialcharsbx($arImg["ORIGINAL_NAME"])."[/url]";
  1514. }
  1515. break;
  1516. case "select":
  1517. if (isset($arFieldType["Options"][$fieldValue]))
  1518. $result = $arFieldType["Options"][$fieldValue];
  1519. break;
  1520. }
  1521. return $result;
  1522. }
  1523. public static function SetGUIFieldEdit($documentType, $fieldName, $arRequest, &$arErrors, $arDocumentField = null)
  1524. {
  1525. return self::GetFieldInputValue($documentType, $arDocumentField, array("Field" => $fieldName), $arRequest, $arErrors);
  1526. }
  1527. /**
  1528. * @deprecated
  1529. * @see \CBPHelper::convertBBtoText
  1530. * @param $text
  1531. * @param false $siteId
  1532. * @return array|string|string[]|null
  1533. */
  1534. public static function ConvertTextForMail($text, $siteId = false)
  1535. {
  1536. if (is_array($text))
  1537. {
  1538. $text = implode(', ', $text);
  1539. }
  1540. $text = trim($text);
  1541. if ($text == '')
  1542. {
  1543. return "";
  1544. }
  1545. if (!$siteId)
  1546. {
  1547. $siteId = SITE_ID;
  1548. }
  1549. $arPattern = $arReplace = [];
  1550. $arPattern[] = "/\[(code|quote)(.*?)\]/is".BX_UTF_PCRE_MODIFIER;
  1551. $arReplace[] = "\n>================== \\1 ===================\n";
  1552. $arPattern[] = "/\[\/(code|quote)(.*?)\]/is".BX_UTF_PCRE_MODIFIER;
  1553. $arReplace[] = "\n>===========================================\n";
  1554. $arPattern[] = "/\<WBR[\s\/]?\>/is".BX_UTF_PCRE_MODIFIER;
  1555. $arReplace[] = "";
  1556. $arPattern[] = "/^(\r|\n)+?(.*)$/";
  1557. $arReplace[] = "\\2";
  1558. $arPattern[] = "/\[b\](.+?)\[\/b\]/is".BX_UTF_PCRE_MODIFIER;
  1559. $arReplace[] = "\\1";
  1560. $arPattern[] = "/\[i\](.+?)\[\/i\]/is".BX_UTF_PCRE_MODIFIER;
  1561. $arReplace[] = "\\1";
  1562. $arPattern[] = "/\[u\](.+?)\[\/u\]/is".BX_UTF_PCRE_MODIFIER;
  1563. $arReplace[] = "_\\1_";
  1564. $arPattern[] = "/\[s\](.+?)\[\/s\]/is".BX_UTF_PCRE_MODIFIER;
  1565. $arReplace[] = "_\\1_";
  1566. $arPattern[] = "/\[(\/?)(color|font|size)([^\]]*)\]/is".BX_UTF_PCRE_MODIFIER;
  1567. $arReplace[] = "";
  1568. //$arPattern[] = "/\[url\](\S+?)\[\/url\]/is".BX_UTF_PCRE_MODIFIER;
  1569. //$arReplace[] = "(URL: \\1)";
  1570. //$arPattern[] = "/\[url\s*=\s*(\S+?)\s*\](.*?)\[\/url\]/is".BX_UTF_PCRE_MODIFIER;
  1571. //$arReplace[] = "\\2 (URL: \\1)";
  1572. $arPattern[] = "/\[img\](.+?)\[\/img\]/is".BX_UTF_PCRE_MODIFIER;
  1573. $arReplace[] = "(IMAGE: \\1)";
  1574. $arPattern[] = "/\[video([^\]]*)\](.+?)\[\/video[\s]*\]/is".BX_UTF_PCRE_MODIFIER;
  1575. $arReplace[] = "(VIDEO: \\2)";
  1576. $arPattern[] = "/\[(\/?)list\]/is".BX_UTF_PCRE_MODIFIER;
  1577. $arReplace[] = "\n";
  1578. $text = preg_replace($arPattern, $arReplace, $text);
  1579. $dbSite = CSite::GetByID($siteId);
  1580. $arSite = $dbSite->Fetch();
  1581. static::$serverName = $arSite["SERVER_NAME"];
  1582. if (static::$serverName == '')
  1583. {
  1584. if (defined("SITE_SERVER_NAME") && SITE_SERVER_NAME <> '')
  1585. {
  1586. static::$serverName = SITE_SERVER_NAME;
  1587. }
  1588. else
  1589. {
  1590. static::$serverName = COption::GetOptionString("main", "server_name", "");
  1591. }
  1592. }
  1593. $text = preg_replace_callback(
  1594. "/\[url\]([^\]]+?)\[\/url\]/i".BX_UTF_PCRE_MODIFIER,
  1595. array("CBPHelper", "__ConvertAnchorTag"),
  1596. $text
  1597. );
  1598. $text = preg_replace_callback(
  1599. "/\[url\s*=\s*([^\]]+?)\s*\](.*?)\[\/url\]/is".BX_UTF_PCRE_MODIFIER,
  1600. array("CBPHelper", "__ConvertAnchorTag"),
  1601. $text
  1602. );
  1603. return $text;
  1604. }
  1605. public static function convertBBtoText(string $text): string
  1606. {
  1607. $textParser = new CTextParser();
  1608. $textParser->allow = [
  1609. 'HTML' => 'N',
  1610. 'USER' => 'N',
  1611. 'ANCHOR' => 'Y',
  1612. 'BIU' => 'Y',
  1613. 'IMG' => 'Y',
  1614. 'QUOTE' => 'N',
  1615. 'CODE' => 'N',
  1616. 'FONT' => 'Y',
  1617. 'LIST' => 'Y',
  1618. 'SMILES' => 'N',
  1619. 'NL2BR' => 'Y',
  1620. 'VIDEO' => 'N',
  1621. 'TABLE' => 'N',
  1622. 'CUT_ANCHOR' => 'N',
  1623. 'ALIGN' => 'N'
  1624. ];
  1625. return $textParser->convertText($text);
  1626. }
  1627. public static function __ConvertAnchorTag($url, $text = '', $serverName = '')
  1628. {
  1629. if (is_array($url))
  1630. {
  1631. $text = isset($url[2]) ? $url[2] : $url[1];
  1632. $url = $url[1];
  1633. $serverName = static::$serverName;
  1634. }
  1635. $scheme = \CMain::IsHTTPS() ? 'https' : 'http';
  1636. if (mb_substr($url, 0, 1) != "/" && !preg_match("/^(http|news|https|ftp|aim|mailto)\:\/\//i".BX_UTF_PCRE_MODIFIER, $url))
  1637. $url = $scheme.'://'.$url;
  1638. if (!preg_match("/^(http|https|news|ftp|aim):\/\/[-_:.a-z0-9@]+/i".BX_UTF_PCRE_MODIFIER, $url))
  1639. $url = $serverName.$url;
  1640. if (!preg_match("/^(http|news|https|ftp|aim|mailto)\:\/\//i".BX_UTF_PCRE_MODIFIER, $url))
  1641. $url = $scheme.'://'.$url;
  1642. $url = str_replace(' ', '%20', $url);
  1643. if ($text <> '' && $text !== $url)
  1644. {
  1645. return $text." ( ".$url." )";
  1646. }
  1647. return $url;
  1648. }
  1649. public static function IsAssociativeArray($ar)
  1650. {
  1651. if (!is_array($ar))
  1652. {
  1653. return false;
  1654. }
  1655. $fl = false;
  1656. $arKeys = array_keys($ar);
  1657. $ind = -1;
  1658. $indn = -1;
  1659. foreach ($arKeys as $key)
  1660. {
  1661. $ind++;
  1662. if ($key."!" !== $ind."!")
  1663. {
  1664. if (mb_substr($key,