15 private $cutQueue = [];
37 self::DeleteByWorkflow($workflowId);
44 $workflowId = trim($workflowId);
45 if ($workflowId ==
'')
46 throw new Exception(
"workflowId");
49 "SELECT ID, TYPE, MODIFIED, ACTION_NAME, ACTION_TITLE, EXECUTION_STATUS, EXECUTION_RESULT, ACTION_NOTE, MODIFIED_BY ".
50 "FROM b_bp_tracking ".
51 "WHERE WORKFLOW_ID = '".
$DB->ForSql($workflowId).
"' ".
63 $arResult[
"PREFIX"] = str_repeat(
" ", $level > 0 ? $level : 0);
68 $arResult[
"PREFIX"] = str_repeat(
" ", $level > 0 ? $level : 0);
74 $arResult[
"PREFIX"] = str_repeat(
" ", $level > 0 ? $level : 0);
87 $navStartParams = $limit > 0 ? [
'nTopCount' => $limit] :
false;
88 $order = [
'ID' => $limit > 0 ?
'DESC' :
'ASC'];
95 [
"ID",
"MODIFIED",
"ACTION_NOTE"]
115 $workflowId = trim($workflowId);
118 throw new Exception(
"workflowId");
121 $queryString = sprintf(
122 "SELECT ID FROM b_bp_tracking t WHERE WORKFLOW_ID = '%s'",
123 $helper->forSql($workflowId)
126 $ids =
$connection->query($queryString)->fetchAll();
128 while ($partIds = array_splice($ids, 0, static::CLEAR_LOG_DELETE_LIMIT))
132 'DELETE from b_bp_tracking WHERE ID IN(%s)',
133 implode(
',', array_column($partIds,
'ID'))
143 $workflowId = trim($workflowId);
147 throw new Exception(
"workflowId");
150 $value1 = $flag ?
'Y' :
'N';
151 $value2 =
$DB->ForSql($workflowId, 32);
154 "UPDATE b_bp_tracking SET COMPLETED = '{$value1}' WHERE WORKFLOW_ID = '{$value2}'"
160 if (
Main\ModuleManager::isModuleInstalled(
'bitrix24'))
166 static::ClearOld(COption::GetOptionString(
"bizproc",
"log_cleanup_days",
"90"));
169 return "CBPTrackingService::ClearOldAgent();";
189 $limit = static::CLEAR_LOG_SELECT_LIMIT;
190 $partLimit = static::CLEAR_LOG_DELETE_LIMIT;
191 $sqlInterval = $helper->addDaysToDateTime(-90);
193 $strSql =
"SELECT ID FROM b_bp_tracking t WHERE t.MODIFIED < {$sqlInterval} LIMIT {$limit}";
199 while ($partIds = array_splice($ids, 0, $partLimit))
203 'DELETE from b_bp_tracking WHERE ID IN(%s)',
204 implode(
',', array_column($partIds,
'ID'))
211 if (
$result->getSelectedRowsCount() === $limit)
217 $pPERIOD = strtotime(
'tomorrow 01:00') - time();
227 $documentType = [
'',
'',
''];
230 return preg_replace_callback(
232 static function (
$matches) use ($documentType, $htmlSpecialChars)
234 return CBPAllTrackingService::parseStringParameterMatches(
236 [$documentType[0], $documentType[1], $documentType[2]],
247 $documentType = is_array($documentType) ? array_filter($documentType) :
null;
253 $l = mb_strlen(
"user_");
254 if (mb_strpos(
$user,
"user_") === 0)
256 $result = CBPHelper::ConvertUserToPrintableForm((
int)(mb_substr(
$user,
$l)),
'', $htmlSpecialChars);
263 : CBPHelper::getExtendedGroupName(
$user)
268 $v = implode(
",", $documentType);
269 if (!array_key_exists($v,self::$userGroupsCache ))
271 self::$userGroupsCache[$v] = CBPDocument::GetAllowableUserGroups($documentType);
283 if (mb_strpos(
$matches[2],
'group_') === 0)
288 : CBPHelper::getExtendedGroupName(
$matches[2])
293 $v = implode(
",", $documentType);
294 if (!array_key_exists($v, self::$userGroupsCache))
296 self::$userGroupsCache[$v] = CBPDocument::GetAllowableUserGroups($documentType);
316 $this->forcedModeWorkflows[] = $workflowId;
322 return in_array($workflowId, $this->forcedModeWorkflows);
327 if (in_array((
int)
$type, self::DEBUG_TRACK_TYPES,
true))
353 $workflowId = trim($workflowId);
354 if ($workflowId ==
'')
355 throw new Exception(
"workflowId");
357 $actionName = trim($actionName);
358 if ($actionName ==
'')
359 throw new Exception(
"actionName");
362 $executionStatus = intval($executionStatus);
363 $executionResult = intval($executionResult);
364 $actionNote = trim($actionNote);
366 $modifiedBy = intval($modifiedBy);
368 $actionTitle = is_string($actionTitle) ? $actionTitle :
'';
371 "INSERT INTO b_bp_tracking(WORKFLOW_ID, TYPE, MODIFIED, ACTION_NAME, ACTION_TITLE, EXECUTION_STATUS, EXECUTION_RESULT, ACTION_NOTE, MODIFIED_BY) ".
372 "VALUES('".
$DB->ForSql($workflowId, 32).
"', ".intval(
$type).
", ".
$DB->CurrentTimeFunction().
", '".
$DB->ForSql($actionName, 128).
"', '".
$DB->ForSql($actionTitle, 255).
"', ".intval($executionStatus).
", ".intval($executionResult).
", ".($actionNote <>
'' ?
"'".
$DB->ForSql($actionNote).
"'" :
"NULL").
", ".($modifiedBy > 0 ? $modifiedBy :
"NULL").
")"
376 if (self::getLogSizeLimit() && !$this->
isForcedMode($workflowId))
378 $this->cutLogSizeDeferred($workflowId);
385 $arOrder = [
"ID" =>
"DESC"],
388 $arNavStartParams =
false,
394 if (
count($arSelectFields) <= 0)
411 "ID" => [
"FIELD" =>
"T.ID",
"TYPE" =>
"int"],
412 "WORKFLOW_ID" => [
"FIELD" =>
"T.WORKFLOW_ID",
"TYPE" =>
"string"],
413 "TYPE" => [
"FIELD" =>
"T.TYPE",
"TYPE" =>
"int"],
414 "ACTION_NAME" => [
"FIELD" =>
"T.ACTION_NAME",
"TYPE" =>
"string"],
415 "ACTION_TITLE" => [
"FIELD" =>
"T.ACTION_TITLE",
"TYPE" =>
"string"],
416 "MODIFIED" => [
"FIELD" =>
"T.MODIFIED",
"TYPE" =>
"datetime"],
417 "EXECUTION_STATUS" => [
"FIELD" =>
"T.EXECUTION_STATUS",
"TYPE" =>
"int"],
418 "EXECUTION_RESULT" => [
"FIELD" =>
"T.EXECUTION_RESULT",
"TYPE" =>
"int"],
419 "ACTION_NOTE" => [
"FIELD" =>
"T.ACTION_NOTE",
"TYPE" =>
"string"],
420 "MODIFIED_BY" => [
"FIELD" =>
"T.MODIFIED_BY",
"TYPE" =>
"int"],
423 $arSqls = CBPHelper::PrepareSql(
$arFields, $arOrder,
$arFilter, $arGroupBy, $arSelectFields);
425 $arSqls[
"SELECT"] = str_replace(
"%%_DISTINCT_%%",
"", $arSqls[
"SELECT"]);
427 if (is_array($arGroupBy) &&
count($arGroupBy)==0)
430 "SELECT ".$arSqls[
"SELECT"].
" ".
431 "FROM b_bp_tracking T ".
432 " ".$arSqls[
"FROM"].
" ";
433 if ($arSqls[
"WHERE"] <>
'')
434 $strSql .=
"WHERE ".$arSqls[
"WHERE"].
" ";
435 if ($arSqls[
"GROUPBY"] <>
'')
436 $strSql .=
"GROUP BY ".$arSqls[
"GROUPBY"].
" ";
448 "SELECT ".$arSqls[
"SELECT"].
" ".
449 "FROM b_bp_tracking T ".
450 " ".$arSqls[
"FROM"].
" ";
451 if ($arSqls[
"WHERE"] <>
'')
452 $strSql .=
"WHERE ".$arSqls[
"WHERE"].
" ";
453 if ($arSqls[
"GROUPBY"] <>
'')
454 $strSql .=
"GROUP BY ".$arSqls[
"GROUPBY"].
" ";
455 if ($arSqls[
"ORDERBY"] <>
'')
456 $strSql .=
"ORDER BY ".$arSqls[
"ORDERBY"].
" ";
458 if (is_array($arNavStartParams) && intval($arNavStartParams[
"nTopCount"]) <= 0)
461 "SELECT COUNT('x') as CNT ".
462 "FROM b_bp_tracking T ".
463 " ".$arSqls[
"FROM"].
" ";
464 if ($arSqls[
"WHERE"] <>
'')
465 $strSql_tmp .=
"WHERE ".$arSqls[
"WHERE"].
" ";
466 if ($arSqls[
"GROUPBY"] <>
'')
467 $strSql_tmp .=
"GROUP BY ".$arSqls[
"GROUPBY"].
" ";
471 if ($arSqls[
"GROUPBY"] ==
'')
481 $cnt =
$dbRes->SelectedRowsCount();
485 $dbRes->NavQuery($strSql, $cnt, $arNavStartParams);
489 if (is_array($arNavStartParams) && intval($arNavStartParams[
"nTopCount"]) > 0)
490 $strSql .=
"LIMIT ".intval($arNavStartParams[
"nTopCount"]);
509 $limit = static::CLEAR_LOG_SELECT_LIMIT;
510 $partLimit = static::CLEAR_LOG_DELETE_LIMIT;
511 $sqlInterval = $helper->addDaysToDateTime(-1 * $days);
513 $strSql =
"SELECT ID FROM b_bp_tracking t WHERE t.COMPLETED {$completed} "
514 .
" AND t.MODIFIED < {$sqlInterval}"
515 .
" AND t.TYPE IN (0,1,2,3,4,5,7,8,9) LIMIT {$limit}"
520 while ($partIds = array_splice($ids, 0, $partLimit))
524 'DELETE from b_bp_tracking WHERE ID IN(%s)',
525 implode(
',', array_column($partIds,
'ID'))
533 private function cutLogSize(
string $workflowId,
int $size): bool
537 $queryResult =
$DB->Query(
539 "SELECT ID FROM b_bp_tracking"
540 .
" WHERE WORKFLOW_ID = '%s' AND " .
$DB->quote(
'TYPE') .
" IN (0,1,2,3,4,5,7,8,9) ORDER BY ID DESC LIMIT %d,100",
541 $DB->ForSql($workflowId),
547 while ($row = $queryResult->fetch())
556 'DELETE FROM b_bp_tracking WHERE ID IN (%s)',
566 private function cutLogSizeDeferred(
string $workflowId)
568 $this->cutQueue[$workflowId] =
true;
572 private function setCutJob()
574 static $inserted =
false;
578 Main\Application::getInstance()->addBackgroundJob(
579 [$this,
'doBackgroundCut'],
581 Main\Application::JOB_PRIORITY_LOW - 10
589 $size = self::getLogSizeLimit();
590 $list = array_keys($this->cutQueue);
591 $this->cutQueue = [];
593 foreach ($list as $workflowId)
595 $this->cutLogSize($workflowId, $size);
599 private static function getLogSizeLimit(): int
612 if (
Main\ModuleManager::isModuleInstalled(
'bitrix24'))
630 $actionNote =
$result[
'ACTION_NOTE'];
634 $decodedActionNote = [];
642 if (is_array($decodedActionNote))
644 array_walk_recursive($decodedActionNote,
static function (&$value) {
645 if (is_string($value))
647 $value = Emoji::decode($value);
652 if (isset($decodedActionNote[
'propertyValue']) && is_string($decodedActionNote[
'propertyValue']))
665 $actionNote = self::convertTimestampTag($actionNote);
667 $result[
'ACTION_NOTE'] = $actionNote;
674 private static function convertTimestampTag($string): string
676 return preg_replace_callback(
677 '/\[timestamp=(\d+)\].*\[\/timestamp\]/i',
682 $datetime = new \Bitrix\Bizproc\BaseType\Value\DateTime($timestamp, CTimeZone::GetOffset());
683 if ($datetime->getTimestamp() ===
null)
688 return (
string)$datetime;
static getConnection($name="")
static get($moduleId, $name, $default="", $siteId=false)
static isModuleInstalled($moduleName)
static encode($data, $options=null)
static deleteByWorkflow($workflowId)
isForcedMode($workflowId)
static parseStringParameterMatches($matches, $documentType=null, $htmlSpecialChars=true)
const CLEAR_LOG_SELECT_LIMIT
static shouldClearCompletedTracksOnly()
setCompletedByWorkflow($workflowId, $flag=true)
static getList( $arOrder=["ID"=> "DESC"], $arFilter=[], $arGroupBy=false, $arNavStartParams=false, $arSelectFields=[])
static parseStringParameter($string, $documentType=null, $htmlSpecialChars=true)
canWrite($type, $workflowId)
write( $workflowId, $type, $actionName, $executionStatus, $executionResult, $actionTitle="", $actionNote="", $modifiedBy=0)
loadReport($workflowId, int $limit=0)
const CLEAR_LOG_DELETE_LIMIT
setForcedMode($workflowId)
deleteAllWorkflowTracking($workflowId)
static dumpWorkflow($workflowId)
start(CBPRuntime $runtime=null)
</td ></tr ></table ></td ></tr ><?endif?><? $propertyIndex=0;foreach( $arGlobalProperties as $propertyCode=> $propertyValue
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</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."%"