1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
workflow.php
См. документацию.
1<?php
2
4
6{
7 public static function OnPanelCreate()
8 {
9 global $APPLICATION, $USER;
10 $cur_page_param = $APPLICATION->GetCurPageParam();
11 $cur_page = $APPLICATION->GetCurPage(true);
12 $cur_dir = $APPLICATION->GetCurDir();
13
14 // New page
15 $flow_link_new = self::GetEditLink([SITE_ID, rtrim(GetDirPath($cur_page), '/') . '/untitled.php'], $status_id, $status_title, 'standart.php', LANGUAGE_ID, $cur_page_param);
16 $create_permission = $flow_link_new <> '' && $USER->CanDoFileOperation('fm_edit_in_workflow', [SITE_ID, $cur_dir]);
17 // Document history
18 $flow_link_hist = '/bitrix/admin/workflow_history_list.php?lang=' . LANGUAGE_ID . '&find_filename=' . urlencode($cur_page) . '&find_filename_exact_match=Y&set_filter=Y';
19 $history_permission = $USER->CanDoFileOperation('fm_edit_in_workflow', [SITE_ID, $cur_page]);
20 // Current page
21 $flow_link_edit = self::GetEditLink([SITE_ID, $cur_page], $status_id, $status_title, '', LANGUAGE_ID, $cur_page_param);
22 $edit_permission = $flow_link_edit <> '' && $history_permission;
23
24 //Big button
25 if ($edit_permission)
26 {
27 $public_edit = $APPLICATION->GetPopupLink([
28 'URL' => $flow_link_edit . '&bxpublic=Y&from_module=workflow',
29 'PARAMS' => [
30 'min_width' => 700,
31 'min_height' => 400,
32 'height' => 700,
33 'width' => 400,
34 ],
35 ]);
36
37 $APPLICATION->AddPanelButton([
38 'HREF' => 'javascript:' . $public_edit,
39 'TYPE' => 'BIG',
40 'ID' => 'edit',
41 'ICON' => 'bx-panel-edit-page-icon',
42 'ALT' => GetMessage('top_panel_edit_title'),
43 'TEXT' => GetMessage('top_panel_edit_new'),
44 'MAIN_SORT' => '200',
45 'SORT' => 10,
46 'MENU' => [],
47 'HK_ID' => 'top_panel_edit_new',
48 'RESORT_MENU' => true,
49 'HINT' => [
50 'TITLE' => GetMessage('top_panel_edit_new_tooltip_title'),
51 'TEXT' => GetMessage('top_panel_edit_new_tooltip'),
52 ],
53 ]);
54 }
55
56 // New page
57 if ($create_permission)
58 {
59 $APPLICATION->AddPanelButtonMenu('create', ['SEPARATOR' => true, 'SORT' => 49]);
60 $APPLICATION->AddPanelButtonMenu('create', [
61 'SRC' => '/bitrix/images/workflow/new_page.gif',
62 'TEXT' => GetMessage('FLOW_PANEL_CREATE_WITH_WF'),
63 'TITLE' => GetMessage('FLOW_PANEL_CREATE_ALT'),
64 'ACTION' => "jsUtils.Redirect([], '" . CUtil::JSEscape($flow_link_new) . "')",
65 'HK_ID' => 'FLOW_PANEL_CREATE_WITH_WF',
66 'SORT' => 50,
67 ]);
68 }
69
70 if ($edit_permission || $history_permission)
71 {
72 $APPLICATION->AddPanelButtonMenu('edit', ['SEPARATOR' => true, 'SORT' => 79]);
73 }
74
75 // Current page
76 if ($edit_permission)
77 {
78 $APPLICATION->AddPanelButtonMenu('edit', [
79 'SRC' => '/bitrix/images/workflow/edit_flow_public.gif',
80 'TEXT' => GetMessage('FLOW_PANEL_EDIT_WITH_WF'),
81 'TITLE' => (intval($status_id) > 0 ? GetMessage('FLOW_CURRENT_STATUS') . ' [' . $status_id . '] ' . $status_title : GetMessage('FLOW_PANEL_EDIT_ALT')),
82 'ACTION' => "jsUtils.Redirect([], '" . CUtil::JSEscape($flow_link_edit) . "')",
83 'HK_ID' => 'FLOW_PANEL_EDIT_WITH_WF',
84 'SORT' => 80,
85 ]);
86 }
87
88 // Document history
89 if ($history_permission)
90 {
91 $flow_link_hist = '/bitrix/admin/workflow_history_list.php?lang=' . LANGUAGE_ID . '&find_filename=' . urlencode($cur_page) . '&find_filename_exact_match=Y&set_filter=Y';
92 $APPLICATION->AddPanelButtonMenu('edit', [
93 'SRC' => '/bitrix/images/workflow/history.gif',
94 'TEXT' => GetMessage('FLOW_PANEL_HISTORY'),
95 'TITLE' => GetMessage('FLOW_PANEL_HISTORY_ALT'),
96 'ACTION' => "jsUtils.Redirect([], '" . CUtil::JSEscape($flow_link_hist) . "')",
97 'HK_ID' => 'FLOW_PANEL_HISTORY',
98 'SORT' => 81,
99 ]);
100 }
101 }
102
103 public static function OnChangeFile($path, $site)
104 {
105 global $BX_WORKFLOW_PUBLISHED_PATH, $BX_WORKFLOW_PUBLISHED_SITE;
106 if ($BX_WORKFLOW_PUBLISHED_PATH == $path && $BX_WORKFLOW_PUBLISHED_SITE == $site)
107 {
108 return;
109 }
110
111 global $DB, $USER, $APPLICATION;
112 $HISTORY_SIMPLE_EDITING = COption::GetOptionString('workflow', 'HISTORY_SIMPLE_EDITING', 'N');
113 if ($HISTORY_SIMPLE_EDITING == 'Y')
114 {
115 $HISTORY_COPIES = intval(COption::GetOptionString('workflow', 'HISTORY_COPIES', '10'));
116 self::CleanUpHistoryCopies_SE($path, $HISTORY_COPIES - 1);
117 if ($HISTORY_COPIES > 0)
118 {
120 $filesrc = $APPLICATION->GetFileContent($DOC_ROOT . $path);
121 $arContent = ParseFileContent($filesrc);
122 $TITLE = $arContent['TITLE'];
123 $BODY = $arContent['CONTENT'];
124 $arFields = [
125 'DOCUMENT_ID' => 0,
126 'MODIFIED_BY' => $USER ? $USER->GetID() : 1,
127 'TITLE' => $TITLE,
128 'FILENAME' => $path,
129 'SITE_ID' => $site,
130 'BODY' => $BODY,
131 'BODY_TYPE' => 'html',
132 'STATUS_ID' => 1,
133 '~TIMESTAMP_X' => $DB->CurrentTimeFunction(),
134 ];
135 $DB->Add('b_workflow_log', $arFields, ['BODY'], 'workflow');
136 }
137 }
138 }
139
140 public static function SetHistory($DOCUMENT_ID)
141 {
142 global $DB;
143
144 $LOG_ID = false;
145 $DOCUMENT_ID = intval($DOCUMENT_ID);
146 $HISTORY_COPIES = intval(COption::GetOptionString('workflow', 'HISTORY_COPIES', '10'));
147 $z = self::GetByID($DOCUMENT_ID);
148 if ($zr = $z->Fetch())
149 {
150 self::CleanUpHistoryCopies($DOCUMENT_ID, $HISTORY_COPIES - 1);
151 if ($HISTORY_COPIES > 0)
152 {
153 $arFields = [
154 'DOCUMENT_ID' => $DOCUMENT_ID,
155 'MODIFIED_BY' => $zr['MODIFIED_BY'],
156 'TITLE' => $zr['TITLE'],
157 'FILENAME' => $zr['FILENAME'],
158 'SITE_ID' => $zr['SITE_ID'],
159 'BODY' => $zr['BODY'],
160 'BODY_TYPE' => $zr['BODY_TYPE'],
161 'STATUS_ID' => $zr['STATUS_ID'],
162 'COMMENTS' => $zr['COMMENTS'],
163 '~TIMESTAMP_X' => $DB->CurrentTimeFunction(),
164 ];
165 $LOG_ID = $DB->Add('b_workflow_log', $arFields, ['BODY'], 'workflow');
166 }
167 }
168
169 return $LOG_ID;
170 }
171
172 // Deletes old copies from document's history
173 public static function CleanUpHistoryCopies($DOCUMENT_ID=false, $HISTORY_COPIES=false)
174 {
175 global $DB;
176
177 if ($HISTORY_COPIES === false)
178 {
179 $HISTORY_COPIES = intval(COption::GetOptionString('workflow', 'HISTORY_COPIES', '10'));
180 }
181
182 $DOCUMENT_ID = intval($DOCUMENT_ID);
183 if ($DOCUMENT_ID > 0)
184 {
185 $strSqlSearch = ' and ID = ' . $DOCUMENT_ID . ' ';
186 }
187 else
188 {
189 $strSqlSearch = '';
190 }
191
192 $strSql = 'SELECT ID FROM b_workflow_document WHERE 1=1 ' . $strSqlSearch;
193 $z = $DB->Query($strSql);
194 while ($zr = $z->Fetch())
195 {
196 $DID = $zr['ID'];
197 $strSql = '
198 SELECT
199 ID
200 FROM
201 b_workflow_log
202 WHERE
203 DOCUMENT_ID = ' . $DID . '
204 ORDER BY
205 ID desc
206 ';
207 $t = $DB->Query($strSql);
208 $i = 0;
209 $str_id = '0';
210 while ($tr = $t->Fetch())
211 {
212 $i++;
213 if ($i > $HISTORY_COPIES)
214 {
215 $str_id .= ', ' . $tr['ID'];
216 }
217 }
218 $strSql = 'DELETE FROM b_workflow_log WHERE ID in (' . $str_id . ')';
219 $DB->Query($strSql);
220 }
221 }
222
223 // Deletes old copies from document's history (simple edit - SE)
224 public static function CleanUpHistoryCopies_SE($FILENAME, $HISTORY_COPIES=false)
225 {
226 global $DB;
227
228 if ($HISTORY_COPIES === false)
229 {
230 $HISTORY_COPIES = intval(COption::GetOptionString('workflow', 'HISTORY_COPIES', '10'));
231 }
232 $strSql = "
233 SELECT
234 ID
235 FROM
236 b_workflow_log
237 WHERE
238 FILENAME = '" . $DB->ForSql($FILENAME, 255) . "'
239 and DOCUMENT_ID = 0
240 ORDER BY
241 ID desc
242 ";
243 $t = $DB->Query($strSql);
244 $i = 0;
245 $str_id = '0';
246 while ($tr = $t->Fetch())
247 {
248 $i++;
249 if ($i > $HISTORY_COPIES)
250 {
251 $str_id .= ', ' . $tr['ID'];
252 }
253 }
254 $strSql = 'DELETE FROM b_workflow_log WHERE ID in (' . $str_id . ')';
255 $DB->Query($strSql);
256 }
257
258 // saves changes history and send e-mails on status change
259 public static function SetMove($DOCUMENT_ID, $STATUS_ID, $OLD_STATUS_ID, $LOG_ID)
260 {
261 global $DB, $USER, $APPLICATION;
262
263 $DOCUMENT_ID = intval($DOCUMENT_ID);
264 $STATUS_ID = intval($STATUS_ID);
265 $OLD_STATUS_ID = intval($OLD_STATUS_ID);
266 $LOG_ID = intval($LOG_ID);
267
268 $arFields = [
269 'TIMESTAMP_X' => $DB->GetNowFunction(),
270 'DOCUMENT_ID' => $DOCUMENT_ID,
271 'OLD_STATUS_ID' => $OLD_STATUS_ID,
272 'STATUS_ID' => $STATUS_ID,
273 'LOG_ID' => $LOG_ID,
274 'USER_ID' => intval($USER->GetID()),
275 ];
276 $DB->Insert('b_workflow_move', $arFields);
277
278 if ($STATUS_ID != $OLD_STATUS_ID)
279 {
280 CTimeZone::Disable();
281 $d = self::GetByID($DOCUMENT_ID);
282 CTimeZone::Enable();
283
284 if ($dr = $d->Fetch())
285 {
286 $STATUS_ID = $dr['STATUS_ID'];
287
288 // gather email of the workflow admins
289 $WORKFLOW_ADMIN_GROUP_ID = COption::GetOptionInt('workflow', 'WORKFLOW_ADMIN_GROUP_ID', 0);
290 $strSql = '
291 SELECT
292 U.ID,
293 U.EMAIL
294 FROM
295 b_user U,
296 b_user_group UG
297 WHERE
298 UG.GROUP_ID = ' . $WORKFLOW_ADMIN_GROUP_ID . "
299 and U.ID = UG.USER_ID
300 and U.ACTIVE = 'Y'
301 ";
302 $a = $DB->Query($strSql);
303 $arAdmin = [];
304 while ($ar = $a->Fetch())
305 {
306 $arAdmin[$ar['ID']] = $ar['EMAIL'];
307 }
308
309 // gather email for BCC
310 $arBCC = [];
311
312 // gather all who changed doc in its current status
313 $strSql = '
314 SELECT
315 USER_ID
316 FROM
317 b_workflow_move
318 WHERE
319 DOCUMENT_ID = ' . $DOCUMENT_ID . '
320 and OLD_STATUS_ID = ' . $STATUS_ID . '
321 ';
322 $z = $DB->Query($strSql);
323 while ($zr = $z->Fetch())
324 {
325 $arBCC[$zr['EMAIL']] = $zr['EMAIL'];
326 }
327
328 // gather all editors
329 // in case status have notifier flag
330 $strSql = '
331 SELECT DISTINCT
332 UG.USER_ID
333 ,U.EMAIL
334 FROM
335 b_workflow_status S,
336 b_workflow_status2group SG,
337 b_user U,
338 b_user_group UG
339 WHERE
340 S.ID = ' . $STATUS_ID . "
341 and S.NOTIFY = 'Y'
342 and SG.STATUS_ID = S.ID
343 and SG.PERMISSION_TYPE = '2'
344 and UG.GROUP_ID = SG.GROUP_ID
345 and U.ID = UG.USER_ID
346 and U.ACTIVE = 'Y'
347 ";
348 $z = $DB->Query($strSql);
349 while ($zr = $z->Fetch())
350 {
351 if (!array_key_exists($zr['EMAIL'], $arBCC))
352 {
353 $grp = [];
354 $rs = $USER->GetUserGroupList($zr['USER_ID']);
355 while ($ar = $rs->Fetch())
356 {
357 $grp[] = $ar['GROUP_ID'];
358 }
359
360 $arTasks = $APPLICATION->GetFileAccessPermission($dr['FILENAME'], $grp, true);
361 foreach ($arTasks as $task_id)
362 {
363 $arOps = CTask::GetOperations($task_id, true);
364 if (in_array('fm_edit_in_workflow', $arOps))
365 {
366 $arBCC[$zr['EMAIL']] = $zr['EMAIL'];
367
368 break;
369 }
370 }
371 }
372 }
373
374 unset($arBCC[$dr['EUSER_EMAIL']]);
375
376 if (array_key_exists($dr['ENTERED_BY'], $arAdmin))
377 {
378 $dr['EUSER_NAME'] .= ' (Admin)';
379 }
380
381 // it is not new doc
382 if ($OLD_STATUS_ID > 0)
383 {
384 if (array_key_exists($dr['MODIFIED_BY'], $arAdmin))
385 {
386 $dr['MUSER_NAME'] .= ' (Admin)';
387 }
388 $q = CWorkflowStatus::GetByID($OLD_STATUS_ID);
389 $qr = $q->Fetch();
390 // send change notification
391 $arEventFields = [
392 'ID' => $dr['ID'],
393 'ADMIN_EMAIL' => implode(',', $arAdmin),
394 'BCC' => implode(',', $arBCC),
395 'PREV_STATUS_ID' => $OLD_STATUS_ID,
396 'PREV_STATUS_TITLE' => $qr['TITLE'],
397 'STATUS_ID' => $dr['STATUS_ID'],
398 'STATUS_TITLE' => $dr['STATUS_TITLE'],
399 'DATE_ENTER' => $dr['DATE_ENTER'],
400 'ENTERED_BY_ID' => $dr['ENTERED_BY'],
401 'ENTERED_BY_NAME' => $dr['EUSER_NAME'],
402 'ENTERED_BY_EMAIL' => $dr['EUSER_EMAIL'],
403 'DATE_MODIFY' => $dr['DATE_MODIFY'],
404 'MODIFIED_BY_ID' => $dr['MODIFIED_BY'],
405 'MODIFIED_BY_NAME' => $dr['MUSER_NAME'],
406 'FILENAME' => $dr['FILENAME'],
407 'SITE_ID' => $dr['SITE_ID'],
408 'TITLE' => $dr['TITLE'],
409 'BODY_HTML' => ($dr['BODY_TYPE'] == 'html' ? $dr['BODY'] : TxtToHTML($dr['BODY'])),
410 'BODY_TEXT' => ($dr['BODY_TYPE'] == 'text' ? $dr['BODY'] : HtmlToTxt($dr['BODY'])),
411 'BODY' => $dr['BODY'],
412 'BODY_TYPE' => $dr['BODY_TYPE'],
413 'COMMENTS' => $dr['COMMENTS'],
414 ];
415 CEvent::Send('WF_STATUS_CHANGE', $dr['SITE_ID'], $arEventFields);
416 }
417 else // otherwise
418 {
419 // it was new one
420 $arEventFields = [
421 'ID' => $dr['ID'],
422 'ADMIN_EMAIL' => implode(',', $arAdmin),
423 'BCC' => implode(',', $arBCC),
424 'STATUS_ID' => $dr['STATUS_ID'],
425 'STATUS_TITLE' => $dr['STATUS_TITLE'],
426 'DATE_ENTER' => $dr['DATE_ENTER'],
427 'ENTERED_BY_ID' => $dr['ENTERED_BY'],
428 'ENTERED_BY_NAME' => $dr['EUSER_NAME'],
429 'ENTERED_BY_EMAIL' => $dr['EUSER_EMAIL'],
430 'FILENAME' => $dr['FILENAME'],
431 'SITE_ID' => $dr['SITE_ID'],
432 'TITLE' => $dr['TITLE'],
433 'BODY_HTML' => ($dr['BODY_TYPE'] == 'html' ? $dr['BODY'] : TxtToHTML($dr['BODY'])),
434 'BODY_TEXT' => ($dr['BODY_TYPE'] == 'text' ? $dr['BODY'] : HtmlToTxt($dr['BODY'])),
435 'BODY' => $dr['BODY'],
436 'BODY_TYPE' => $dr['BODY_TYPE'],
437 'COMMENTS' => $dr['COMMENTS'],
438 ];
439 CEvent::Send('WF_NEW_DOCUMENT', $dr['SITE_ID'], $arEventFields);
440 }
441 }
442 }
443 }
444
445 public static function Delete($DOCUMENT_ID)
446 {
447 global $DB;
448
449 self::CleanUpFiles($DOCUMENT_ID);
450 self::CleanUpPreview($DOCUMENT_ID);
451 $DB->Query('DELETE FROM b_workflow_move WHERE DOCUMENT_ID = ' . intval($DOCUMENT_ID));
452 $DB->Query('DELETE FROM b_workflow_document WHERE ID = ' . intval($DOCUMENT_ID));
453 }
454
455 public static function IsAdmin()
456 {
457 global $USER;
458
459 if ($USER->IsAdmin())
460 {
461 return true;
462 }
463 else
464 {
465 $WORKFLOW_ADMIN_GROUP_ID = COption::GetOptionString('workflow', 'WORKFLOW_ADMIN_GROUP_ID');
466 if (in_array($WORKFLOW_ADMIN_GROUP_ID, $USER->GetUserGroupArray()))
467 {
468 return true;
469 }
470 }
471
472 return false;
473 }
474
475 // check edit rights for the document
476 // depending on it's status and lock
477 public static function IsAllowEdit($DOCUMENT_ID, &$locked_by, &$date_lock, $CHECK_RIGHTS='Y')
478 {
479
480 $DOCUMENT_ID = intval($DOCUMENT_ID);
481 $LOCK_STATUS = self::GetLockStatus($DOCUMENT_ID, $locked_by, $date_lock);
482 if ($LOCK_STATUS == 'red')
483 {
484 return false;
485 }
486 if ($LOCK_STATUS == 'yellow')
487 {
488 return true;
489 }
490 if ($LOCK_STATUS == 'green')
491 {
492 if ($CHECK_RIGHTS == 'Y')
493 {
494 return self::IsHaveEditRights($DOCUMENT_ID);
495 }
496 else
497 {
498 return true;
499 }
500 }
501
502 return false;
503 }
504
505 public static function GetStatus($DOCUMENT_ID)
506 {
507 global $DB;
508
509 $DOCUMENT_ID = intval($DOCUMENT_ID);
510 $strSql = '
511 SELECT
512 S.*
513 FROM
514 b_workflow_document D,
515 b_workflow_status S
516 WHERE
517 D.ID=' . $DOCUMENT_ID . '
518 and S.ID = D.STATUS_ID
519 ';
520 $z = $DB->Query($strSql);
521
522 return $z;
523 }
524
525 // check edit rights for the document
526 // check is based only on status no lock
527 public static function IsHaveEditRights($DOCUMENT_ID)
528 {
529 global $DB, $USER;
530
531 if (self::IsAdmin())
532 {
533 return true;
534 }
535
536 $arGroups = $USER->GetUserGroupArray();
537 if (!is_array($arGroups) || count($arGroups) <= 0)
538 {
539 $arGroups = [2];
540 }
541
542 $strSql = '
543 SELECT
544 G.ID
545 FROM
546 b_workflow_document D,
547 b_workflow_status2group G
548 WHERE
549 D.ID = ' . intval($DOCUMENT_ID) . "
550 and G.STATUS_ID = D.STATUS_ID
551 and G.PERMISSION_TYPE >= '2'
552 and G.GROUP_ID in (" . implode(', ', $arGroups) . ')
553 ';
554 $z = $DB->Query($strSql);
555
556 if ($zr = $z->Fetch())
557 {
558 return true;
559 }
560 else
561 {
562 return false;
563 }
564 }
565
566 public static function UnLock($DOCUMENT_ID)
567 {
568 global $DB, $USER;
569
570 $DOCUMENT_ID = intval($DOCUMENT_ID);
571 $z = self::GetByID($DOCUMENT_ID);
572 $zr = $z->Fetch();
573 if (self::IsAdmin() || $zr['LOCKED_BY'] == $USER->GetID())
574 {
575 $arFields = [
576 'DATE_LOCK' => 'null',
577 'LOCKED_BY' => 'null',
578 ];
579 $rows = $DB->Update('b_workflow_document', $arFields, 'WHERE ID=' . $DOCUMENT_ID);
580
581 return intval($rows);
582 }
583
584 return false;
585 }
586
587 public static function Lock($DOCUMENT_ID)
588 {
589 global $DB, $USER;
590
591 $DOCUMENT_ID = intval($DOCUMENT_ID);
592 $z = self::GetByID($DOCUMENT_ID);
593 if ($zr = $z->Fetch())
594 {
595 if ($zr['STATUS_ID'] != 1)
596 {
597 $arFields = [
598 'DATE_LOCK' => $DB->GetNowFunction(),
599 'LOCKED_BY' => $USER->GetID(),
600 ];
601 $DB->Update('b_workflow_document', $arFields, "WHERE ID='" . $DOCUMENT_ID . "'");
602 }
603 }
604 }
605
606 // return edit link depending on rights and status
607 public static function GetEditLink($FILENAME, &$status_id, &$status_title, $template='', $lang=LANGUAGE_ID, $return_url='')
608 {
609 global $USER;
610
611 $link = '';
612 CMain::InitPathVars($SITE_ID, $FILENAME);
613
614 if ($USER->CanDoFileOperation('fm_edit_in_workflow', [$SITE_ID, $FILENAME]))
615 {
616 //Check if user have access at least to one status
617 if (!self::IsAdmin())
618 {
619 $arGroups = $USER->GetUserGroupArray();
620 if (!is_array($arGroups))
621 {
622 $arGroups = [2];
623 }
624 $arFilter = [
625 'GROUP_ID' => $arGroups,
626 'PERMISSION_TYPE_1' => 1,
627 ];
628 $rsStatuses = CWorkflowStatus::GetList('s_c_sort', 'asc', $arFilter, null, ['ID']);
629 if (!$rsStatuses->Fetch())
630 {
631 return '';
632 }
633 }
634
635 $link = '/bitrix/admin/workflow_edit.php?lang=' . $lang . '&site=' . $SITE_ID . '&fname=' . $FILENAME;
636 if ($template <> '')
637 {
638 $link .= '&template=' . urlencode($template);
639 }
640 if ($return_url <> '')
641 {
642 $link .= '&return_url=' . urlencode($return_url);
643 }
644 $z = self::GetByFilename($FILENAME, $SITE_ID);
645 if ($zr = $z->Fetch())
646 {
647 $status_id = $zr['STATUS_ID'];
648 $status_title = $zr['STATUS_TITLE'];
649 if ($status_id != 1)
650 {
651 $DOCUMENT_ID = $zr['ID'];
652 if (self::IsHaveEditRights($DOCUMENT_ID))
653 {
654 $link .= '&ID=' . $DOCUMENT_ID;
655 }
656 else
657 {
658 return '';
659 }
660 }
661 }
662 }
663
664 return $link;
665 }
666
667 public static function DeleteHistory($ID)
668 {
669 global $DB;
670 $DB->Query('
671 DELETE FROM b_workflow_log
672 WHERE ID = ' . intval($ID) . '
673 ');
674 }
675
676 public static function CleanUp()
677 {
682
683 return 'CWorkflow::CleanUp();';
684 }
685
686 public static function CleanUpFiles($DOCUMENT_ID=false, $FILE_ID=false)
687 {
688 global $DB;
689
690 if ($DOCUMENT_ID === false)
691 {
692 $strSql = 'SELECT TEMP_FILENAME FROM b_workflow_file WHERE DOCUMENT_ID is null';
693 }
694 else
695 {
696 $DOCUMENT_ID = intval($DOCUMENT_ID);
697 $strSql = 'SELECT TEMP_FILENAME FROM b_workflow_file WHERE DOCUMENT_ID = ' . $DOCUMENT_ID;
698 }
699 if ($FILE_ID !== false)
700 {
701 $FILE_ID = intval($FILE_ID);
702 $strSql .= ' and ID = ' . $FILE_ID;
703 }
704 $z = $DB->Query($strSql);
705 while ($zr = $z->Fetch())
706 {
707 self::DeleteFile($zr['TEMP_FILENAME']);
708 }
709 }
710
711 public static function CleanUpPreview($DOCUMENT_ID=false)
712 {
713 global $DB;
714
715 if ($DOCUMENT_ID === false)
716 {
717 $strSql = '
718 SELECT
719 P.FILENAME, D.SITE_ID
720 FROM
721 b_workflow_document D,
722 b_workflow_preview P
723 WHERE
724 D.STATUS_ID = 1
725 and P.DOCUMENT_ID = D.ID
726 ';
727 }
728 else
729 {
730 $DOCUMENT_ID = intval($DOCUMENT_ID);
731 $strSql = '
732 SELECT
733 FILENAME
734 FROM
735 b_workflow_preview
736 WHERE
737 DOCUMENT_ID = ' . $DOCUMENT_ID . '
738 ';
739 }
740 $z = $DB->Query($strSql);
741 while ($zr = $z->Fetch())
742 {
743 self::DeletePreview($zr['FILENAME'], $zr['SITE']);
744 }
745 }
746
747 public static function DeletePreview($FILENAME, $site = false)
748 {
749 global $DB;
750
751 $strSql = "DELETE FROM b_workflow_preview WHERE FILENAME='" . $DB->ForSql($FILENAME, 255) . "'";
752 $DB->Query($strSql);
754 $path = $DOC_ROOT . $FILENAME;
755 if (file_exists($path))
756 {
757 unlink($path);
758 }
759 }
760
761 public static function DeleteFile($FILENAME)
762 {
763 global $DB;
764
765 $strSql = "DELETE FROM b_workflow_file WHERE TEMP_FILENAME='" . $DB->ForSql($FILENAME, 255) . "'";
766 $DB->Query($strSql);
767 $temp_path = self::GetTempDir() . $FILENAME;
768 if (file_exists($temp_path))
769 {
770 unlink($temp_path);
771 }
772 }
773
774 public static function IsFilenameExists($FILENAME)
775 {
776 global $DB;
777
778 $strSql = "SELECT ID FROM b_workflow_file WHERE TEMP_FILENAME='" . $DB->ForSql($FILENAME, 255) . "'";
779 $z = $DB->Query($strSql);
780 $zr = $z->Fetch();
781
782 return intval($zr['ID']);
783 }
784
785 public static function GetUniqueFilename($filename)
786 {
788 $temp_file = md5($filename . uniqid(rand())) . '.' . $ext;
789 while (self::IsFilenameExists($temp_file))
790 {
791 $temp_file = md5($filename . uniqid(rand())) . '.' . $ext;
792 }
793
794 return $temp_file;
795 }
796
797 public static function IsPreviewExists($FILENAME)
798 {
799 global $DB;
800
801 $z = $DB->Query("
802 SELECT ID
803 FROM b_workflow_preview
804 WHERE FILENAME='" . $DB->ForSql($FILENAME, 255) . "'
805 ");
806
807 $zr = $z->Fetch();
808
809 return intval($zr['ID']);
810 }
811
812 public static function GetUniquePreview($DOCUMENT_ID)
813 {
814 global $DB;
815
816 $z = $DB->Query('
817 SELECT FILENAME
818 FROM b_workflow_document
819 WHERE ID = ' . intval($DOCUMENT_ID) . '
820 ');
821
822 $zr = $z->Fetch();
823 if ($zr)
824 {
825 $DOCUMENT_PATH = GetDirPath($zr['FILENAME']);
826 do
827 {
828 $temp_file = $DOCUMENT_PATH . md5(uniqid(rand())) . '.php';
829 }
830 while (self::IsPreviewExists($temp_file));
831 }
832
833 return $temp_file;
834 }
835
836 public static function SetStatus($DOCUMENT_ID, $STATUS_ID, $OLD_STATUS_ID, $history=true)
837 {
839
840 //$arMsg = Array();
841 $DOCUMENT_ID = intval($DOCUMENT_ID);
842 $STATUS_ID = intval($STATUS_ID);
843 $OLD_STATUS_ID = intval($OLD_STATUS_ID);
844 if ($STATUS_ID == 1) // if "[1] Published"
845 {
846 // get all files associated with the document
847 $files = self::GetFileList($DOCUMENT_ID);
848 while ($file = $files->Fetch())
849 {
850 $path = $file['FILENAME'];
851 $DOC_ROOT = \Bitrix\Main\SiteTable::getDocumentRoot($file['SITE_ID'] === false ? null : $file['SITE_ID']);
852 $pathto = $DOC_ROOT . $path;
853 $pathfrom = self::GetTempDir() . $file['TEMP_FILENAME'];
854 if (
855 $USER->CanDoFileOperation('fm_edit_in_workflow', [$file['SITE_ID'], $path])
856 && $USER->CanDoFileOperation('fm_edit_existent_file', [$file['SITE_ID'], $path])
857 && $USER->CanDoFileOperation('fm_create_new_file', [$file['SITE_ID'], $path])
858 )
859 {
860 if (!copy($pathfrom, $pathto))
861 {
862 $str = GetMessage('FLOW_CAN_NOT_WRITE_FILE', ['#FILENAME#' => $path]);
863 $strError .= $str . '<br>';
864 }
865 }
866 else
867 {
868 $str = GetMessage('FLOW_ACCESS_DENIED_FOR_FILE_WRITE', ['#FILENAME#' => $path]);
869 $strError .= $str . '<br>';
870 }
871 }
872
873 // still good
874 if ($strError == '')
875 {
876 // publish the document
877 $y = self::GetByID($DOCUMENT_ID);
878 $yr = $y->Fetch();
879 if (
880 $USER->CanDoFileOperation('fm_edit_in_workflow', [$yr['SITE_ID'], $yr['FILENAME']])
881 && $USER->CanDoFileOperation('fm_edit_existent_file', [$yr['SITE_ID'], $yr['FILENAME']])
882 && $USER->CanDoFileOperation('fm_create_new_file', [$yr['SITE_ID'], $yr['FILENAME']])
883 )
884 {
885 // save file
886 $prolog = $yr['PROLOG'];
887 if ($prolog <> '')
888 {
889 $title = $yr['TITLE'];
890 $prolog = SetPrologTitle($prolog, $title);
891 }
892 $content = ($yr['BODY_TYPE'] == 'text') ? TxtToHTML($yr['BODY']) : $yr['BODY'];
894 $epilog = $yr['EPILOG'];
895 $filesrc = $prolog . $content . $epilog;
896 global $BX_WORKFLOW_PUBLISHED_PATH, $BX_WORKFLOW_PUBLISHED_SITE;
897 $BX_WORKFLOW_PUBLISHED_PATH = $yr['FILENAME'];
898 $BX_WORKFLOW_PUBLISHED_SITE = $yr['SITE_ID'];
899 $DOC_ROOT = \Bitrix\Main\SiteTable::getDocumentRoot($yr['SITE_ID'] === false ? null : $yr['SITE_ID']);
900 $APPLICATION->SaveFileContent($DOC_ROOT . $yr['FILENAME'], $filesrc);
901 $BX_WORKFLOW_PUBLISHED_PATH = '';
902 $BX_WORKFLOW_PUBLISHED_SITE = '';
903 }
904 else // otherwise
905 {
906 // throw error
907 $str = GetMessage('FLOW_ACCESS_DENIED_FOLDER', ['#FILENAME#' => $yr['FILENAME']]);
908 $strError .= GetMessage('FLOW_ERROR') . htmlspecialcharsbx($str) . '<br>';
909 }
910 }
911 }
912
913 if ($strError == '')
914 {
915 // update db
916 $arFields = [
917 'DATE_MODIFY' => $DB->GetNowFunction(),
918 'MODIFIED_BY' => $USER->GetID(),
919 'STATUS_ID' => intval($STATUS_ID),
920 ];
921 $DB->Update('b_workflow_document', $arFields, 'WHERE ID=' . $DOCUMENT_ID);
922 if ($history === true)
923 {
924 $LOG_ID = self::SetHistory($DOCUMENT_ID);
925 self::SetMove($DOCUMENT_ID, $STATUS_ID, $OLD_STATUS_ID, $LOG_ID);
926 }
927 }
928 else
929 {
930 $strError = GetMessage('FLOW_DOCUMENT_NOT_PUBLISHED') . '<br>' . $strError;
931 }
933 }
934
935 public static function LinkFiles2Document($arUploadedFiles, $DOCUMENT_ID)
936 {
937 global $DB;
938
939 $DOCUMENT_ID = intval($DOCUMENT_ID);
940 if (is_array($arUploadedFiles) && count($arUploadedFiles) > 0)
941 {
942 foreach ($arUploadedFiles as $FILE_ID)
943 {
944 $FILE_ID = intval($FILE_ID);
945 $strSql = 'UPDATE b_workflow_file SET DOCUMENT_ID=' . $DOCUMENT_ID . ' WHERE ID=' . $FILE_ID;
946 $DB->Query($strSql);
947 }
948 }
950 }
951
952 public static function GetFileByID($DOCUMENT_ID, $FILENAME)
953 {
954 global $DB;
955
956 $DOCUMENT_ID = intval($DOCUMENT_ID);
957 $strSql = '
958 SELECT
959 F.*
960 FROM
961 b_workflow_file F
962 WHERE
963 F.DOCUMENT_ID = ' . $DOCUMENT_ID . "
964 and F.FILENAME = '" . $DB->ForSql($FILENAME, 255) . "'
965 ";
966 $z = $DB->Query($strSql);
967
968 return $z;
969 }
970
971 public static function GetTempDir()
972 {
973 $upload_dir = COption::GetOptionString('', 'upload_dir', '/upload/');
974 $dir = $_SERVER['DOCUMENT_ROOT'] . '/' . $upload_dir . '/workflow/';
975 $dir = str_replace('//', '/', $dir);
976
977 return $dir;
978 }
979
980 public static function GetFileContent($did, $fname, $wf_path='', $site=false)
981 {
982 global $DB, $APPLICATION, $USER;
983
984 $did = intval($did);
986
987 // check if executable
988 if (
989 $USER->IsAdmin()
990 || (
991 $io->ValidatePathString($fname)
992 && !HasScriptExtension($fname)
993 )
994 )
995 {
996 if ($did > 0)
997 {
998 // check if it is associated wtih document
999 $z = self::GetFileByID($did, $fname);
1000 // found one
1001 if ($zr = $z->Fetch())
1002 {
1003 // get it's contents
1004 $path = self::GetTempDir() . $zr['TEMP_FILENAME'];
1005 if (file_exists($path))
1006 {
1007 return $APPLICATION->GetFileContent($path);
1008 }
1009 }
1010 else
1011 {
1012 // lookup in database
1013 $strSql = 'SELECT FILENAME, SITE_ID FROM b_workflow_document WHERE ID = ' . $did;
1014 $y = $DB->Query($strSql);
1015 // found
1016 if ($yr = $y->Fetch())
1017 {
1018 // get it's directory
1019 $path = GetDirPath($yr['FILENAME']);
1020 // absolute path
1021 $pathto = Rel2Abs($path, $fname);
1022 $DOC_ROOT = \Bitrix\Main\SiteTable::getDocumentRoot($yr['SITE_ID'] === false ? null : $yr['SITE_ID']);
1023 $path = $DOC_ROOT . $pathto;
1024 // give it another try
1025 $u = self::GetFileByID($did, $pathto);
1026 // found
1027 if ($ur = $u->Fetch())
1028 {
1029 // get it's contents
1030 $path = self::GetTempDir() . $ur['TEMP_FILENAME'];
1031 if (file_exists($path))
1032 {
1033 return $APPLICATION->GetFileContent($path);
1034 }
1035 }
1036 elseif (file_exists($path)) // it is already on disk
1037 {
1038 // get it's contents
1039 if ($USER->CanDoFileOperation('fm_view_file', [$yr['SITE_ID'], $pathto]))
1040 {
1041 return $APPLICATION->GetFileContent($path);
1042 }
1043 }
1044 }
1045 }
1046 }
1048 // new one
1049 if ($wf_path <> '')
1050 {
1051 $pathto = Rel2Abs($wf_path, $fname);
1052 $path = $DOC_ROOT . $pathto;
1053 if (file_exists($path)) // it is already on disk
1054 {
1055 // get it's contents
1056 if ($USER->CanDoFileOperation('fm_view_file', [$site, $pathto]))
1057 {
1058 $src = $APPLICATION->GetFileContent($path);
1059
1060 return $src;
1061 }
1062 }
1063 }
1064
1065 // still failed to find
1066 // get path
1067 $path = $DOC_ROOT . $fname;
1068 if (file_exists($path))
1069 {
1070 // get it's contents
1071 if ($USER->CanDoFileOperation('fm_view_file', [$site, $fname]))
1072 {
1073 return $APPLICATION->GetFileContent($path);
1074 }
1075 }
1076 }
1077// it is executable
1078 else
1079 {
1080 return GetMessage('FLOW_ACCESS_DENIED_PHP_VIEW');
1081 }
1082 }
1083
1084 public static function __CheckSite($site)
1085 {
1086 if ($site !== false)
1087 {
1088 if ($site <> '')
1089 {
1090 $res = CSite::GetByID($site);
1091 if (!$res->Fetch())
1092 {
1093 $site = false;
1094 }
1095 }
1096 else
1097 {
1098 $site = false;
1099 }
1100 }
1101
1102 return $site;
1103 }
1104
1105 public static function Insert($arFields)
1106 {
1107 global $DB;
1108
1109 $arFields['~DATE_MODIFY'] = $DB->CurrentTimeFunction();
1110 $arFields['~DATE_ENTER'] = $DB->CurrentTimeFunction();
1111 $ID = $DB->Add('b_workflow_document', $arFields, [], 'workflow');
1112 $LOG_ID = self::SetHistory($ID);
1113 self::SetMove($ID, $arFields['STATUS_ID'], 0, $LOG_ID);
1114
1115 return $ID;
1116 }
1117
1118 public static function Update($arFields, $DOCUMENT_ID)
1119 {
1120 global $DB;
1121
1122 $z = self::GetByID($DOCUMENT_ID);
1123 $change = false;
1124 if ($zr = $z->Fetch())
1125 {
1126 if (
1127 $zr['STATUS_ID'] != $arFields['STATUS_ID']
1128 || $zr['BODY'] != $arFields['BODY']
1129 || $zr['BODY_TYPE'] != $arFields['BODY_TYPE']
1130 || $zr['COMMENTS'] != $arFields['COMMENTS']
1131 || $zr['FILENAME'] != $arFields['FILENAME']
1132 || $zr['SITE_ID'] != $arFields['SITE_ID']
1133 || $zr['TITLE'] != $arFields['TITLE']
1134 )
1135 {
1136 $change = true;
1137 }
1138 }
1139
1140 $strUpdate = $DB->PrepareUpdate('b_workflow_document', $arFields, 'workflow');
1141 if ($strUpdate)
1142 {
1143 $DB->Query('
1144 UPDATE b_workflow_document
1145 SET ' . $strUpdate . ', DATE_MODIFY=now(), DATE_ENTER=now()
1146 WHERE ID = ' . $DOCUMENT_ID,
1147 );
1148 }
1149
1150 if ($change)
1151 {
1152 $LOG_ID = self::SetHistory($DOCUMENT_ID);
1153 self::SetMove($DOCUMENT_ID, $arFields['STATUS_ID'], $zr['STATUS_ID'], $LOG_ID);
1154 }
1155 }
1156
1157 public static function GetLockStatus($DOCUMENT_ID, &$locked_by, &$date_lock)
1158 {
1159 global $DB, $USER;
1161 $helper = $connection->getSqlHelper();
1162
1163 $DOCUMENT_ID = intval($DOCUMENT_ID);
1164 $MAX_LOCK = COption::GetOptionInt('workflow', 'MAX_LOCK_TIME', '60');
1165 $uid = intval($USER->GetID());
1166 $strSql = '
1167 SELECT
1168 LOCKED_BY,
1169 ' . $DB->DateToCharFunction('DATE_LOCK') . " DATE_LOCK,
1170 case
1171 when DATE_LOCK is null then 'green'
1172 when " . $helper->addSecondsToDateTime($MAX_LOCK * 60, 'DATE_LOCK') . " < now() then 'green'
1173 when LOCKED_BY = " . $uid . " then 'yellow'
1174 else 'red' end LOCK_STATUS
1175 FROM
1176 b_workflow_document
1177 WHERE
1178 ID = " . $DOCUMENT_ID . '
1179 ';
1180 $z = $DB->Query($strSql);
1181 $zr = $z->Fetch();
1182 $locked_by = $zr ? $zr['LOCKED_BY'] : 0;
1183 $date_lock = $zr? $zr['DATE_LOCK'] : false;
1184
1185 return $zr['LOCK_STATUS'];
1186 }
1187
1188 public static function GetList($by = 's_date_modify', $order = 'desc', $arFilter = [])
1189 {
1190 global $DB, $USER;
1192 $helper = $connection->getSqlHelper();
1193
1194 $obQueryWhere = new CSQLWhere();
1195 static $arWhereFields = [
1196 'ID' => [
1197 'TABLE_ALIAS' => 'D',
1198 'FIELD_NAME' => 'D.ID',
1199 'FIELD_TYPE' => 'int', //int, double, file, enum, int, string, date, datetime
1200 'JOIN' => false,
1201 ],
1202 'MODIFIED_BY' => [
1203 'TABLE_ALIAS' => 'D',
1204 'FIELD_NAME' => 'D.MODIFIED_BY',
1205 'FIELD_TYPE' => 'int',
1206 'JOIN' => false,
1207 ],
1208 'STATUS_ID' => [
1209 'TABLE_ALIAS' => 'D',
1210 'FIELD_NAME' => 'D.STATUS_ID',
1211 'FIELD_TYPE' => 'int',
1212 'JOIN' => false,
1213 ],
1214 ];
1215 $obQueryWhere->SetFields($arWhereFields);
1216
1217 $arSqlSearch = [];
1218 $MAX_LOCK = COption::GetOptionInt('workflow', 'MAX_LOCK_TIME', '60');
1219 $arGroups = $USER->GetUserGroupArray();
1220 if (!is_array($arGroups))
1221 {
1222 $arGroups[] = 2;
1223 }
1224 $groups = implode(', ', $arGroups);
1225 $uid = intval($USER->GetID());
1226 if (is_array($arFilter))
1227 {
1228 foreach ($arFilter as $key => $val)
1229 {
1230 if ((string)$val == '' || (string)$val == 'NOT_REF')
1231 {
1232 continue;
1233 }
1234 if (is_array($val) && count($val) <= 0)
1235 {
1236 continue;
1237 }
1238 $match_value_set = array_key_exists($key . '_EXACT_MATCH', $arFilter);
1239 $key = strtoupper($key);
1240 switch ($key)
1241 {
1242 case 'ID':
1243 case 'STATUS_ID':
1244 $arSqlSearch[] = $obQueryWhere->GetQuery([$key => $val]);
1245
1246 break;
1247 case 'DATE_MODIFY_1':
1248 if (CheckDateTime($val))
1249 {
1250 $arSqlSearch[] = 'D.DATE_MODIFY >= ' . $DB->CharToDateFunction($val, 'SHORT');
1251 }
1252
1253 break;
1254 case 'DATE_MODIFY_2':
1255 if (CheckDateTime($val))
1256 {
1257 $arSqlSearch[] = 'D.DATE_MODIFY < ' . $DB->CharToDateFunction($val, 'SHORT') . ' + INTERVAL 1 DAY';
1258 }
1259
1260 break;
1261 case 'MODIFIED_BY':
1262 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1263 $filter = GetFilterQuery('UM.LOGIN, UM.NAME, UM.LAST_NAME', $val, $match);
1264 if ($filter)
1265 {
1266 $arSqlSearch[] = $obQueryWhere->GetQuery(['MODIFIED_BY' => $val]) . ' or ' . $filter;
1267 }
1268
1269 break;
1270 case 'MODIFIED_USER_ID':
1271 $arSqlSearch[] = $obQueryWhere->GetQuery(['MODIFIED_BY' => $val]);
1272
1273 break;
1274 case 'LOCK_STATUS':
1275 $arSqlSearch[] = "
1276 case
1277 when D.DATE_LOCK is null then 'green'
1278 when " . $helper->addSecondsToDateTime($MAX_LOCK * 60, 'D.DATE_LOCK') . " < now() then 'green'
1279 when D.LOCKED_BY = " . $uid . " then 'yellow'
1280 else 'red' end = '" . $DB->ForSql($val) . "'";
1281
1282 break;
1283 case 'STATUS':
1284 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1285 $filter = GetFilterQuery('S.TITLE', $val, $match);
1286 if ($filter)
1287 {
1288 $arSqlSearch[] = $obQueryWhere->GetQuery(['STATUS_ID' => $val]) . ' or ' . $filter;
1289 }
1290
1291 break;
1292 case 'SITE_ID':
1293 case 'TITLE':
1294 case 'BODY':
1295 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1296 $arSqlSearch[] = GetFilterQuery('D.' . $key, $val, $match);
1297
1298 break;
1299 case 'FILENAME':
1300 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1301 $arSqlSearch[] = GetFilterQuery('D.FILENAME', $val, $match, ['/', '\\', '.', '_']);
1302
1303 break;
1304 }
1305 }
1306 }
1307
1308 if ($by === 's_id')
1309 {
1310 $strSqlOrder = 'ORDER BY D.ID';
1311 }
1312 elseif ($by === 's_lock_status')
1313 {
1314 $strSqlOrder = 'ORDER BY LOCK_STATUS';
1315 }
1316 elseif ($by === 's_date_modify')
1317 {
1318 $strSqlOrder = 'ORDER BY D.DATE_MODIFY';
1319 }
1320 elseif ($by === 's_modified_by')
1321 {
1322 $strSqlOrder = 'ORDER BY D.MODIFIED_BY';
1323 }
1324 elseif ($by === 's_filename')
1325 {
1326 $strSqlOrder = 'ORDER BY D.FILENAME';
1327 }
1328 elseif ($by === 's_title')
1329 {
1330 $strSqlOrder = 'ORDER BY D.TITLE';
1331 }
1332 elseif ($by === 's_site_id')
1333 {
1334 $strSqlOrder = 'ORDER BY D.SITE_ID';
1335 }
1336 elseif ($by === 's_status')
1337 {
1338 $strSqlOrder = 'ORDER BY D.STATUS_ID';
1339 }
1340 else
1341 {
1342 $strSqlOrder = 'ORDER BY D.DATE_MODIFY';
1343 }
1344
1345 if ($order != 'asc')
1346 {
1347 $strSqlOrder .= ' desc ';
1348 }
1349
1350 $strSqlSearch = GetFilterSqlSearch($arSqlSearch);
1351 if (self::IsAdmin())
1352 {
1353 $strSql = '
1354 SELECT DISTINCT
1355 D.*,
1356 ' . $DB->DateToCharFunction('D.DATE_ENTER') . ' DATE_ENTER,
1357 ' . $DB->DateToCharFunction('D.DATE_MODIFY') . ' DATE_MODIFY,
1358 ' . $DB->DateToCharFunction('D.DATE_LOCK') . " DATE_LOCK,
1359 concat_ws(' ', " . $DB->Concat("'('", 'UM.LOGIN', "')'") . ", nullif(UM.NAME, ''), nullif(UM.LAST_NAME, '')) MUSER_NAME,
1360 concat_ws(' ', " . $DB->Concat("'('", 'UE.LOGIN', "')'") . ", nullif(UE.NAME, ''), nullif(UE.LAST_NAME, '')) EUSER_NAME,
1361 S.TITLE STATUS_TITLE,
1362 case
1363 when D.DATE_LOCK is null then 'green'
1364 when " . $helper->addSecondsToDateTime($MAX_LOCK * 60, 'D.DATE_LOCK') . " < now() then 'green'
1365 when D.LOCKED_BY = " . $uid . " then 'yellow'
1366 else 'red' end LOCK_STATUS
1367 FROM
1368 b_workflow_document D
1369 LEFT JOIN b_workflow_status S ON (S.ID = D.STATUS_ID)
1370 LEFT JOIN b_user UM ON (UM.ID = D.MODIFIED_BY)
1371 LEFT JOIN b_user UE ON (UE.ID = D.ENTERED_BY)
1372 WHERE
1373 " . $strSqlSearch . '
1374 ' . $strSqlOrder . '
1375 ';
1376 }
1377 else
1378 {
1379 $strSql = '
1380 SELECT DISTINCT
1381 D.*,
1382 ' . $DB->DateToCharFunction('D.DATE_ENTER') . ' DATE_ENTER,
1383 ' . $DB->DateToCharFunction('D.DATE_MODIFY') . ' DATE_MODIFY,
1384 ' . $DB->DateToCharFunction('D.DATE_LOCK') . " DATE_LOCK,
1385 concat_ws(' ', " . $DB->Concat("'('", 'UM.LOGIN', "')'") . ", nullif(UM.NAME, ''), nullif(UM.LAST_NAME, '')) MUSER_NAME,
1386 concat_ws(' ', " . $DB->Concat("'('", 'UE.LOGIN', "')'") . ", nullif(UE.NAME, ''), nullif(UE.LAST_NAME, '')) EUSER_NAME,
1387 S.TITLE STATUS_TITLE,
1388 case
1389 when D.DATE_LOCK is null then 'green'
1390 when " . $helper->addSecondsToDateTime($MAX_LOCK * 60, 'D.DATE_LOCK') . " < now() then 'green'
1391 when D.LOCKED_BY = " . $uid . " then 'yellow'
1392 else 'red' end LOCK_STATUS
1393 FROM
1394 b_workflow_document D
1395 INNER JOIN b_workflow_status2group G ON (G.STATUS_ID = D.STATUS_ID)
1396 LEFT JOIN b_workflow_status S ON (S.ID = D.STATUS_ID)
1397 LEFT JOIN b_user UM ON (UM.ID = D.MODIFIED_BY)
1398 LEFT JOIN b_user UE ON (UE.ID = D.ENTERED_BY)
1399 WHERE
1400 " . $strSqlSearch . '
1401 and G.GROUP_ID in (' . $groups . ")
1402 and G.PERMISSION_TYPE >= '2'
1403 " . $strSqlOrder . '
1404 ';
1405 }
1406
1407 $rs = $DB->Query($strSql);
1408 $arr = [];
1409 while ($ar = $rs->Fetch())
1410 {
1411 if ($USER->CanDoFileOperation('fm_edit_in_workflow', [$ar['SITE_ID'], $ar['FILENAME']]))
1412 {
1413 $arr[] = $ar;
1414 }
1415 }
1416 $rs = new CDBResult();
1417 $rs->InitFromArray($arr);
1418
1419 return $rs;
1420 }
1421
1422 public static function GetByID($ID)
1423 {
1424 global $DB, $USER;
1426 $helper = $connection->getSqlHelper();
1427
1428 $ID = intval($ID);
1429 $MAX_LOCK = COption::GetOptionInt('workflow', 'MAX_LOCK_TIME', '60');
1430 $uid = intval($USER->GetID());
1431 $strSql = '
1432 SELECT
1433 D.*,
1434 ' . $DB->DateToCharFunction('D.DATE_ENTER') . ' DATE_ENTER,
1435 ' . $DB->DateToCharFunction('D.DATE_MODIFY') . ' DATE_MODIFY,
1436 ' . $DB->DateToCharFunction('D.DATE_LOCK') . " DATE_LOCK,
1437 concat_ws(' ', " . $DB->Concat("'('", 'UM.LOGIN', "')'") . ", nullif(UM.NAME, ''), nullif(UM.LAST_NAME, '')) MUSER_NAME,
1438 concat_ws(' ', " . $DB->Concat("'('", 'UE.LOGIN', "')'") . ", nullif(UE.NAME, ''), nullif(UE.LAST_NAME, '')) EUSER_NAME,
1439 concat_ws(' ', " . $DB->Concat("'('", 'UL.LOGIN', "')'") . ", nullif(UL.NAME, ''), nullif(UL.LAST_NAME, '')) LUSER_NAME,
1440 UE.EMAIL EUSER_EMAIL,
1441 S.TITLE STATUS_TITLE,
1442 case
1443 when D.DATE_LOCK is null then 'green'
1444 when " . $helper->addSecondsToDateTime($MAX_LOCK * 60, 'D.DATE_LOCK') . " < now() then 'green'
1445 when D.LOCKED_BY = " . $uid . " then 'yellow'
1446 else 'red' end LOCK_STATUS
1447 FROM
1448 b_workflow_document D
1449 LEFT JOIN b_user UM ON (UM.ID = D.MODIFIED_BY)
1450 LEFT JOIN b_user UE ON (UE.ID = D.ENTERED_BY)
1451 LEFT JOIN b_user UL ON (UL.ID = D.LOCKED_BY)
1452 LEFT JOIN b_workflow_status S ON (S.ID = D.STATUS_ID)
1453 WHERE
1454 D.ID = " . $ID . '
1455 ';
1456 $res = $DB->Query($strSql);
1457
1458 return $res;
1459 }
1460
1461 public static function GetByFilename($FILENAME, $SITE_ID, $arFilter = false)
1462 {
1463 if (!is_array($arFilter))
1464 {
1465 $arFilter = [
1466 '!STATUS_ID' => 1,
1467 ];
1468 }
1469
1470 $obQueryWhere = new CSQLWhere();
1471 $obQueryWhere->SetFields([
1472 'STATUS_ID' => [
1473 'TABLE_ALIAS' => 'D',
1474 'FIELD_NAME' => 'D.STATUS_ID',
1475 'FIELD_TYPE' => 'int',
1476 'JOIN' => false,
1477 ],
1478 ]);
1479 $strSqlWhere = $obQueryWhere->GetQuery($arFilter);
1480
1481 global $DB, $USER;
1483 $helper = $connection->getSqlHelper();
1484
1485 $MAX_LOCK = COption::GetOptionInt('workflow', 'MAX_LOCK_TIME', '60');
1486 $uid = intval($USER->GetID());
1487 $strSql = '
1488 SELECT
1489 D.*,
1490 ' . $DB->DateToCharFunction('D.DATE_ENTER') . ' DATE_ENTER,
1491 ' . $DB->DateToCharFunction('D.DATE_MODIFY') . ' DATE_MODIFY,
1492 ' . $DB->DateToCharFunction('D.DATE_LOCK') . " DATE_LOCK,
1493 concat_ws(' ', " . $DB->Concat("'('", 'UM.LOGIN', "')'") . ", nullif(UM.NAME, ''), nullif(UM.LAST_NAME, '')) MUSER_NAME,
1494 concat_ws(' ', " . $DB->Concat("'('", 'UE.LOGIN', "')'") . ", nullif(UE.NAME, ''), nullif(UE.LAST_NAME, '')) EUSER_NAME,
1495 concat_ws(' ', " . $DB->Concat("'('", 'UL.LOGIN', "')'") . ", nullif(UL.NAME, ''), nullif(UL.LAST_NAME, '')) LUSER_NAME,
1496 S.TITLE STATUS_TITLE,
1497 case
1498 when D.DATE_LOCK is null then 'green'
1499 when " . $helper->addSecondsToDateTime($MAX_LOCK * 60, 'D.DATE_LOCK') . " < now() then 'green'
1500 when D.LOCKED_BY = " . $uid . " then 'yellow'
1501 else 'red' end LOCK_STATUS
1502 FROM
1503 b_workflow_document D
1504 LEFT JOIN b_user UM ON (UM.ID = D.MODIFIED_BY)
1505 LEFT JOIN b_user UE ON (UE.ID = D.ENTERED_BY)
1506 LEFT JOIN b_user UL ON (UL.ID = D.LOCKED_BY)
1507 LEFT JOIN b_workflow_status S ON (S.ID = D.STATUS_ID)
1508 WHERE
1509 SITE_ID = '" . $DB->ForSql($SITE_ID, 2) . "'
1510 AND D.FILENAME = '" . $DB->ForSql($FILENAME, 255) . "'
1511 " . ($strSqlWhere ? 'AND ' . $strSqlWhere : '') . '
1512 ';
1513 $res = $DB->Query($strSql);
1514
1515 return $res;
1516 }
1517
1518 public static function GetHistoryList($by = 's_id', $order = 'desc', $arFilter = [])
1519 {
1520 global $DB;
1522 $helper = $connection->getSqlHelper();
1523
1524 $obQueryWhere = new CSQLWhere();
1525 static $arWhereFields = [
1526 'ID' => [
1527 'TABLE_ALIAS' => 'L',
1528 'FIELD_NAME' => 'L.ID',
1529 'FIELD_TYPE' => 'int', //int, double, file, enum, int, string, date, datetime
1530 'JOIN' => false,
1531 ],
1532 'DOCUMENT_ID' => [
1533 'TABLE_ALIAS' => 'L',
1534 'FIELD_NAME' => 'L.DOCUMENT_ID',
1535 'FIELD_TYPE' => 'int',
1536 'JOIN' => false,
1537 ],
1538 'MODIFIED_BY' => [
1539 'TABLE_ALIAS' => 'L',
1540 'FIELD_NAME' => 'L.MODIFIED_BY',
1541 'FIELD_TYPE' => 'int',
1542 'JOIN' => false,
1543 ],
1544 'STATUS_ID' => [
1545 'TABLE_ALIAS' => 'L',
1546 'FIELD_NAME' => 'L.STATUS_ID',
1547 'FIELD_TYPE' => 'int',
1548 'JOIN' => false,
1549 ],
1550 ];
1551 $obQueryWhere->SetFields($arWhereFields);
1552
1553 $arSqlSearch = [];
1554 if (is_array($arFilter))
1555 {
1556 foreach ($arFilter as $key => $val)
1557 {
1558 if ((string)$val == '' || (string)$val == 'NOT_REF')
1559 {
1560 continue;
1561 }
1562 if (is_array($val) && !$val)
1563 {
1564 continue;
1565 }
1566 $match_value_set = array_key_exists($key . '_EXACT_MATCH', $arFilter);
1567 $key = strtoupper($key);
1568 switch ($key)
1569 {
1570 case 'ID':
1571 case 'DOCUMENT_ID':
1572 case 'MODIFIED_BY':
1573 case 'STATUS_ID':
1574 $arSqlSearch[] = $obQueryWhere->GetQuery([$key => $val]);
1575
1576 break;
1577 case 'DATE_MODIFY_1':
1578 if (CheckDateTime($val))
1579 {
1580 $arSqlSearch[] = 'L.TIMESTAMP_X >= ' . $DB->CharToDateFunction($val, 'SHORT');
1581 }
1582
1583 break;
1584 case 'DATE_MODIFY_2':
1585 if (CheckDateTime($val))
1586 {
1587 $arSqlSearch[] = 'L.TIMESTAMP_X < ' . $helper->addDaysToDateTime(1, $DB->CharToDateFunction($val, 'SHORT'));
1588 }
1589
1590 break;
1591 case 'MODIFIED_USER':
1592 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1593 $filter = GetFilterQuery('U.LOGIN, U.NAME, U.LAST_NAME', $val, $match);
1594 if ($filter)
1595 {
1596 $arSqlSearch[] = $obQueryWhere->GetQuery(['MODIFIED_BY' => $val]) . ' or ' . $filter;
1597 }
1598
1599 break;
1600 case 'TITLE':
1601 case 'SITE_ID':
1602 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1603 $arSqlSearch[] = GetFilterQuery('L.' . $key, $val, $match);
1604
1605 break;
1606 case 'FILENAME':
1607 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1608 $arSqlSearch[] = GetFilterQuery('L.FILENAME', $val, $match, ['/', '\\', '.', '_']);
1609
1610 break;
1611 case 'BODY':
1612 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'N') ? 'Y' : 'N';
1613 $arSqlSearch[] = GetFilterQuery('L.BODY', $val, $match, [], 'Y');
1614
1615 break;
1616 case 'STATUS':
1617 $match = ($match_value_set && $arFilter[$key . '_EXACT_MATCH'] == 'Y') ? 'N' : 'Y';
1618 $filter = GetFilterQuery('S.TITLE', $val, $match);
1619 if ($filter)
1620 {
1621 $arSqlSearch[] = $obQueryWhere->GetQuery(['STATUS_ID' => $val]) . ' or ' . $filter;
1622 }
1623
1624 break;
1625 }
1626 }
1627 }
1628
1629 if ($by === 's_id')
1630 {
1631 $strSqlOrder = 'ORDER BY L.ID';
1632 }
1633 elseif ($by === 's_document_id')
1634 {
1635 $strSqlOrder = 'ORDER BY L.DOCUMENT_ID';
1636 }
1637 elseif ($by === 's_date_modify')
1638 {
1639 $strSqlOrder = 'ORDER BY L.TIMESTAMP_X';
1640 }
1641 elseif ($by === 's_modified_by')
1642 {
1643 $strSqlOrder = 'ORDER BY L.MODIFIED_BY';
1644 }
1645 elseif ($by === 's_filename')
1646 {
1647 $strSqlOrder = 'ORDER BY L.FILENAME';
1648 }
1649 elseif ($by === 's_site_id')
1650 {
1651 $strSqlOrder = 'ORDER BY L.SITE_ID';
1652 }
1653 elseif ($by === 's_title')
1654 {
1655 $strSqlOrder = 'ORDER BY L.TITLE';
1656 }
1657 elseif ($by === 's_status')
1658 {
1659 $strSqlOrder = 'ORDER BY L.STATUS_ID';
1660 }
1661 else
1662 {
1663 $strSqlOrder = 'ORDER BY L.ID';
1664 }
1665
1666 if ($order != 'asc')
1667 {
1668 $strSqlOrder .= ' desc ';
1669 }
1670
1671 $strSqlSearch = GetFilterSqlSearch($arSqlSearch);
1672 $strSql = '
1673 SELECT DISTINCT
1674 L.*,
1675 ' . $DB->DateToCharFunction('L.TIMESTAMP_X') . " TIMESTAMP_X,
1676 concat_ws(' ', " . $DB->Concat("'('", 'U.LOGIN', "')'") . ", nullif(U.NAME, ''), nullif(U.LAST_NAME, '')) USER_NAME,
1677 S.TITLE STATUS_TITLE
1678 FROM
1679 b_workflow_log L
1680 LEFT JOIN b_workflow_status S ON (S.ID = L.STATUS_ID)
1681 LEFT JOIN b_user U ON (U.ID = L.MODIFIED_BY)
1682 WHERE
1683 " . $strSqlSearch . '
1684 ' . $strSqlOrder . '
1685 ';
1686
1687 $res = $DB->Query($strSql);
1688
1689 return $res;
1690 }
1691
1692 public static function GetHistoryByID($ID)
1693 {
1694 global $DB;
1695
1696 $ID = intval($ID);
1697 $strSql = '
1698 SELECT DISTINCT
1699 L.*,
1700 ' . $DB->DateToCharFunction('L.TIMESTAMP_X') . " TIMESTAMP_X,
1701 concat_ws(' ', " . $DB->Concat("'('", 'U.LOGIN', "')'") . ", nullif(U.NAME, ''), nullif(U.LAST_NAME, '')) USER_NAME,
1702 S.TITLE STATUS_TITLE
1703 FROM
1704 b_workflow_log L
1705 LEFT JOIN b_workflow_status S ON (S.ID = L.STATUS_ID)
1706 LEFT JOIN b_user U ON (U.ID = L.MODIFIED_BY)
1707 WHERE
1708 L.ID = " . $ID . '
1709 ';
1710 $res = $DB->Query($strSql);
1711
1712 return $res;
1713 }
1714
1715 public static function CleanUpHistory()
1716 {
1718 $helper = $connection->getSqlHelper();
1719
1720 $HISTORY_DAYS = COption::GetOptionInt('workflow', 'HISTORY_DAYS', '-1');
1721 if ($HISTORY_DAYS >= 0)
1722 {
1723 $strSql = 'DELETE FROM b_workflow_log WHERE TIMESTAMP_X < ' . $helper->addDaysToDateTime(-$HISTORY_DAYS);
1724 $connection->query($strSql);
1725 }
1726
1727 if (CModule::IncludeModule('iblock'))
1728 {
1729 CIblockElement::WF_CleanUpHistory();
1730 }
1731 }
1732
1733 public static function CleanUpPublished()
1734 {
1736 $helper = $connection->getSqlHelper();
1737
1738 $DAYS_AFTER_PUBLISHING = COption::GetOptionInt('workflow', 'DAYS_AFTER_PUBLISHING', '0');
1739 if ($DAYS_AFTER_PUBLISHING >= 0)
1740 {
1741 $strSql = '
1742 SELECT
1743 ID
1744 FROM
1745 b_workflow_document
1746 WHERE
1747 STATUS_ID = 1
1748 and DATE_MODIFY < ' . $helper->addDaysToDateTime(-$DAYS_AFTER_PUBLISHING) . '
1749 ';
1750 $z = $connection->query($strSql);
1751 while ($zr = $z->fetch())
1752 {
1753 self::Delete($zr['ID']);
1754 }
1755 }
1756 }
1757
1758 public static function GetFileList($DOCUMENT_ID)
1759 {
1760 global $DB;
1761
1762 $DOCUMENT_ID = intval($DOCUMENT_ID);
1763 $strSql = '
1764 SELECT
1765 F.*, D.SITE_ID,
1766 ' . $DB->DateToCharFunction('F.TIMESTAMP_X') . " TIMESTAMP_X,
1767 concat_ws(' ', " . $DB->Concat("'('", 'U.LOGIN', "')'") . ", nullif(U.NAME, ''), nullif(U.LAST_NAME, '')) USER_NAME
1768 FROM
1769 b_workflow_document D
1770 INNER JOIN b_workflow_file F ON (F.DOCUMENT_ID = D.ID)
1771 LEFT JOIN b_user U ON (U.ID = F.MODIFIED_BY)
1772 WHERE
1773 D.ID = " . $DOCUMENT_ID . '
1774 ORDER BY
1775 F.TIMESTAMP_X desc
1776 ';
1777 $z = $DB->Query($strSql);
1778
1779 return $z;
1780 }
1781}
$path
Определения access_edit.php:21
$connection
Определения actionsdefinitions.php:38
global $APPLICATION
Определения include.php:80
static getConnection($name="")
Определения application.php:638
static getDocumentRoot($siteId=null)
Определения site.php:36
static GetOperations($ID, $return_names=false)
Определения task.php:230
static GetInstance()
Определения virtual_io.php:60
Определения sqlwhere.php:1359
Определения workflow.php:6
static Lock($DOCUMENT_ID)
Определения workflow.php:587
static CleanUpPublished()
Определения workflow.php:1733
static IsHaveEditRights($DOCUMENT_ID)
Определения workflow.php:527
static GetFileByID($DOCUMENT_ID, $FILENAME)
Определения workflow.php:952
static CleanUpHistory()
Определения workflow.php:1715
static GetHistoryByID($ID)
Определения workflow.php:1692
static IsFilenameExists($FILENAME)
Определения workflow.php:774
static OnChangeFile($path, $site)
Определения workflow.php:103
static OnPanelCreate()
Определения workflow.php:7
static IsPreviewExists($FILENAME)
Определения workflow.php:797
static GetStatus($DOCUMENT_ID)
Определения workflow.php:505
static GetFileList($DOCUMENT_ID)
Определения workflow.php:1758
static GetByID($ID)
Определения workflow.php:1422
static Insert($arFields)
Определения workflow.php:1105
static IsAllowEdit($DOCUMENT_ID, &$locked_by, &$date_lock, $CHECK_RIGHTS='Y')
Определения workflow.php:477
static LinkFiles2Document($arUploadedFiles, $DOCUMENT_ID)
Определения workflow.php:935
static GetList($by='s_date_modify', $order='desc', $arFilter=[])
Определения workflow.php:1188
static __CheckSite($site)
Определения workflow.php:1084
static SetStatus($DOCUMENT_ID, $STATUS_ID, $OLD_STATUS_ID, $history=true)
Определения workflow.php:836
static GetFileContent($did, $fname, $wf_path='', $site=false)
Определения workflow.php:980
static CleanUpHistoryCopies($DOCUMENT_ID=false, $HISTORY_COPIES=false)
Определения workflow.php:173
static DeletePreview($FILENAME, $site=false)
Определения workflow.php:747
static IsAdmin()
Определения workflow.php:455
static Update($arFields, $DOCUMENT_ID)
Определения workflow.php:1118
static CleanUpHistoryCopies_SE($FILENAME, $HISTORY_COPIES=false)
Определения workflow.php:224
static SetHistory($DOCUMENT_ID)
Определения workflow.php:140
static GetHistoryList($by='s_id', $order='desc', $arFilter=[])
Определения workflow.php:1518
static CleanUp()
Определения workflow.php:676
static CleanUpPreview($DOCUMENT_ID=false)
Определения workflow.php:711
static GetEditLink($FILENAME, &$status_id, &$status_title, $template='', $lang=LANGUAGE_ID, $return_url='')
Определения workflow.php:607
static GetByFilename($FILENAME, $SITE_ID, $arFilter=false)
Определения workflow.php:1461
static Delete($DOCUMENT_ID)
Определения workflow.php:445
static GetUniquePreview($DOCUMENT_ID)
Определения workflow.php:812
static GetLockStatus($DOCUMENT_ID, &$locked_by, &$date_lock)
Определения workflow.php:1157
static GetUniqueFilename($filename)
Определения workflow.php:785
static DeleteHistory($ID)
Определения workflow.php:667
static GetTempDir()
Определения workflow.php:971
static CleanUpFiles($DOCUMENT_ID=false, $FILE_ID=false)
Определения workflow.php:686
static SetMove($DOCUMENT_ID, $STATUS_ID, $OLD_STATUS_ID, $LOG_ID)
Определения workflow.php:259
static UnLock($DOCUMENT_ID)
Определения workflow.php:566
static DeleteFile($FILENAME)
Определения workflow.php:761
static GetByID($ID)
Определения status.php:278
static GetList($by='s_c_sort', $order='asc', $arFilter=[], $is_filtered=null, $arSelect=[])
Определения status.php:8
$str
Определения commerceml2.php:63
$content
Определения commerceml.php:144
$filesrc
Определения component_props.php:53
$arFields
Определения dblapprove.php:5
$filename
Определения file_edit.php:47
$DOC_ROOT
Определения file_edit.php:66
$template
Определения file_edit.php:49
$arr
Определения file_new.php:624
$arGroups
Определения options.php:1766
$res
Определения filter_act.php:7
GetFilterSqlSearch($arSqlSearch=array(), $FilterLogic="FILTER_logic")
Определения filter_tools.php:397
GetFilterQuery($field, $val, $procent="Y", $ex_sep=array(), $clob="N", $div_fields="Y", $clob_upper="N")
Определения filter_tools.php:383
$zr
Определения options.php:5
if($ajaxMode) $ID
Определения get_user.php:27
$uid
Определения hot_keys_act.php:8
$filter
Определения iblock_catalog_list.php:54
$strError
Определения options_user_settings.php:4
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
global $DB
Определения cron_frame.php:29
global $USER
Определения csv_new_run.php:40
$io
Определения csv_new_run.php:98
SetPrologTitle($prolog, $title)
Определения admin_tools.php:374
if(!defined('SITE_ID')) $lang
Определения include.php:91
$groups
Определения options.php:30
$z
Определения options.php:31
$arTasks
Определения options.php:777
GetFileExtension($path)
Определения tools.php:2972
ParseFileContent($filesrc, $params=[])
Определения tools.php:4780
HasScriptExtension($check_name)
Определения tools.php:2956
GetDirPath($sPath)
Определения tools.php:3245
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
TxtToHTML( $str, $bMakeUrls=true, $iMaxStringLen=0, $QUOTE_ENABLED="N", $NOT_CONVERT_AMPERSAND="Y", $CODE_ENABLED="N", $BIU_ENABLED="N", $quote_table_class="quotetable", $quote_head_class="tdquotehead", $quote_body_class="tdquote", $code_table_class="codetable", $code_head_class="tdcodehead", $code_body_class="tdcodebody", $code_textarea_class="codetextarea", $link_class="txttohtmllink", $arUrlEvent=[], $link_target="_self")
Определения tools.php:2442
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
Rel2Abs($curdir, $relpath)
Определения tools.php:3297
GetMessage($name, $aReplace=null)
Определения tools.php:3397
CheckDateTime($datetime, $format=false)
Определения tools.php:398
$TITLE
Определения menu_edit.php:223
$order
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
$dir
Определения quickway.php:303
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
</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
$title
Определения pdf.php:123
$val
Определения options.php:1793
const SITE_ID
Определения sonet_set_content_view.php:12
$rows
Определения options.php:264
$rs
Определения action.php:82
$arFilter
Определения user_search.php:106
WFToPath($text)
Определения include.php:50
$SITE_ID
Определения yandex_run.php:607
$site
Определения yandex_run.php:614