Пример #1
0
 public static function tasks_extended_meta_occurInLogsAs($args)
 {
     $arMessages = array();
     $parsedReturnValue = null;
     $withoutExceptions = false;
     try {
         if (!(CTasksTools::IsAdmin() || CTasksTools::IsPortalB24Admin())) {
             throw new TasksException('Only root can do this', TasksException::TE_ACCESS_DENIED);
         }
         CTaskAssert::assert(is_array($args) && count($args) == 1);
         $userId = array_pop($args);
         CTasksTools::setOccurAsUserId($userId);
         $parsedReturnValue = CTasksTools::getOccurAsUserId();
         $withoutExceptions = true;
     } catch (CTaskAssertException $e) {
         $arMessages[] = array('id' => 'TASKS_ERROR_ASSERT_EXCEPTION', 'text' => 'TASKS_ERROR_ASSERT_EXCEPTION');
     } catch (TasksException $e) {
         $errCode = $e->getCode();
         $errMsg = $e->getMessage();
         if ($e->GetCode() & TasksException::TE_FLAG_SERIALIZED_ERRORS_IN_MESSAGE) {
             $arMessages = unserialize($errMsg);
         } else {
             $arMessages[] = array('id' => 'TASKS_ERROR_EXCEPTION_#' . $errCode, 'text' => 'TASKS_ERROR_EXCEPTION_#' . $errCode . '; ' . $errMsg . '; ' . TasksException::renderErrorCode($e));
         }
     } catch (Exception $e) {
         $errMsg = $e->getMessage();
         if ($errMsg !== '') {
             $arMessages[] = array('text' => $errMsg, 'id' => 'TASKS_ERROR');
         }
     }
     if ($withoutExceptions) {
         return $parsedReturnValue;
     } else {
         self::_emitError($arMessages);
         throw new Exception();
     }
 }
Пример #2
0
 public function delete()
 {
     global $DB;
     $taskId = (int) $this->oTaskItem->getId();
     $executiveUserId = (int) $this->oTaskItem->getExecutiveUserId();
     /** @noinspection PhpDynamicAsStaticMethodCallInspection */
     $curDatetime = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time() + CTimeZone::GetOffset());
     if (!$this->isActionAllowed(self::ACTION_REMOVE)) {
         throw new TasksException('', TasksException::TE_ACTION_NOT_ALLOWED);
     }
     $arCurrentData = $this->getData();
     $rc = $DB->Query("DELETE FROM b_tasks_checklist_items \n\t\t\tWHERE ID = " . $this->itemId . " AND TASK_ID = " . $taskId, $bIgnoreErrors = true);
     // Reset cache
     $this->resetCache();
     if ($rc === false) {
         throw new TasksException('', TasksException::TE_ACTION_FAILED_TO_BE_PROCESSED);
     }
     $occurAsUserId = CTasksTools::getOccurAsUserId();
     if (!$occurAsUserId) {
         $occurAsUserId = $executiveUserId;
     }
     // changes log
     $arLogFields = array('TASK_ID' => $taskId, 'USER_ID' => $occurAsUserId, 'CREATED_DATE' => $curDatetime, 'FIELD' => 'CHECKLIST_ITEM_REMOVE', 'FROM_VALUE' => $arCurrentData['~TITLE'], 'TO_VALUE' => '');
     $log = new CTaskLog();
     $log->Add($arLogFields);
 }
Пример #3
0
 /**
  * @deprecated
  */
 public static function runRestMethod($executiveUserId, $methodName, $args, $navigation)
 {
     static $arManifest = null;
     static $arMethodsMetaInfo = null;
     if ($arManifest === null) {
         $arManifest = self::getManifest();
         $arMethodsMetaInfo = $arManifest['REST: available methods'];
     }
     // Check and parse params
     CTaskAssert::assert(isset($arMethodsMetaInfo[$methodName]));
     $arMethodMetaInfo = $arMethodsMetaInfo[$methodName];
     $argsParsed = CTaskRestService::_parseRestParams('ctaskcomments', $methodName, $args);
     $returnValue = null;
     if (isset($arMethodMetaInfo['staticMethod']) && $arMethodMetaInfo['staticMethod']) {
         if ($methodName === 'add') {
             $occurAsUserId = CTasksTools::getOccurAsUserId();
             if (!$occurAsUserId) {
                 $occurAsUserId = $executiveUserId;
             }
             $taskId = $argsParsed[0];
             $commentText = $argsParsed[1];
             $commentAuthorId = $occurAsUserId;
             $returnValue = self::add($taskId, $commentAuthorId, $commentText);
         }
     } else {
         $taskId = array_shift($argsParsed);
         $oTask = self::getInstanceFromPool($taskId, $executiveUserId);
         $returnValue = call_user_func_array(array($oTask, $methodName), $argsParsed);
     }
     return array($returnValue, null);
 }
Пример #4
0
 public static function onAfterCommentAdd($entityType, $entityId, $arData)
 {
     global $USER;
     // 'TK' is our entity type
     if ($entityType !== 'TK' || intval($entityId) <= 0 || !CModule::IncludeModule('tasks') || !CModule::IncludeModule('socialnetwork')) {
         return;
     }
     $taskId = (int) $entityId;
     $messageId = $arData['MESSAGE_ID'];
     $parser = new CTextParser();
     $messageAuthorId = null;
     if (array_key_exists('AUTHOR_ID', $arData['PARAMS']) && array_key_exists('EDIT_DATE', $arData['PARAMS']) && array_key_exists('POST_DATE', $arData['PARAMS'])) {
         $messageAuthorId = $arData['PARAMS']['AUTHOR_ID'];
     } else {
         $arMessage = CForumMessage::GetByID($messageId);
         $messageAuthorId = $arMessage['AUTHOR_ID'];
     }
     $occurAsUserId = CTasksTools::getOccurAsUserId();
     if (!$occurAsUserId) {
         $occurAsUserId = $messageAuthorId ? $messageAuthorId : 1;
     }
     $rsTask = CTasks::GetList(false, array('ID' => $taskId), array('UF_CRM_TASK'));
     $arTask = $rsTask->GetNext();
     if (!isset($arTask) || !isset($arTask['UF_CRM_TASK']) || is_array($arTask['UF_CRM_TASK']) && (!isset($arTask['UF_CRM_TASK'][0]) || strlen($arTask['UF_CRM_TASK'][0]) <= 0) || !is_array($arTask['UF_CRM_TASK']) && strlen($arTask['UF_CRM_TASK']) <= 0) {
         return;
     }
     $dbCrmActivity = CCrmActivity::GetList(array(), array('TYPE_ID' => CCrmActivityType::Task, 'ASSOCIATED_ENTITY_ID' => $taskId, 'CHECK_PERMISSIONS' => 'N'), false, false, array('ID'));
     $arCrmActivity = $dbCrmActivity->Fetch();
     if (!$arCrmActivity) {
         return;
     }
     $crmActivityId = $arCrmActivity['ID'];
     // sonet log
     $dbLog = CSocNetLog::GetList(array(), array("EVENT_ID" => "crm_activity_add", "ENTITY_ID" => $crmActivityId), false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID"));
     if ($arLog = $dbLog->Fetch()) {
         $log_id = $arLog["ID"];
         $entity_type = $arLog["ENTITY_TYPE"];
         $entity_id = $arLog["ENTITY_ID"];
         $strURL = $GLOBALS['APPLICATION']->GetCurPageParam("", array("IFRAME", "MID", "SEF_APPLICATION_CUR_PAGE_URL", BX_AJAX_PARAM_ID, "result"));
         $strURL = ForumAddPageParams($strURL, array("MID" => $messageId, "result" => "reply"), false, false);
         $sText = COption::GetOptionString("forum", "FILTER", "Y") == "Y" ? $arMessage["POST_MESSAGE_FILTER"] : $arMessage["POST_MESSAGE"];
         $arFieldsForSocnet = array("ENTITY_TYPE" => $entity_type, "ENTITY_ID" => $entity_id, "EVENT_ID" => "crm_activity_add_comment", "MESSAGE" => $sText, "TEXT_MESSAGE" => $parser->convert4mail($sText), "URL" => str_replace("?IFRAME=Y", "", str_replace("&IFRAME=Y", "", str_replace("IFRAME=Y&", "", $strURL))), "MODULE_ID" => "crm", "SOURCE_ID" => $messageId, "LOG_ID" => $log_id, "RATING_TYPE_ID" => "FORUM_POST", "RATING_ENTITY_ID" => $messageId);
         $arFieldsForSocnet["USER_ID"] = $occurAsUserId;
         $arFieldsForSocnet["=LOG_DATE"] = $GLOBALS['DB']->CurrentTimeFunction();
         $ufFileID = array();
         $dbAddedMessageFiles = CForumFiles::GetList(array("ID" => "ASC"), array("MESSAGE_ID" => $messageId));
         while ($arAddedMessageFiles = $dbAddedMessageFiles->Fetch()) {
             $ufFileID[] = $arAddedMessageFiles["FILE_ID"];
         }
         if (count($ufFileID) > 0) {
             $arFieldsForSocnet["UF_SONET_COM_FILE"] = $ufFileID;
         }
         $ufDocID = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFieldValue("FORUM_MESSAGE", "UF_FORUM_MESSAGE_DOC", $messageId, LANGUAGE_ID);
         if ($ufDocID) {
             $arFieldsForSocnet["UF_SONET_COM_DOC"] = $ufDocID;
         }
         $comment_id = CSocNetLogComments::Add($arFieldsForSocnet, false, false);
         CSocNetLog::CounterIncrement($comment_id, false, false, "LC");
     }
 }
Пример #5
0
 public static function Delete($ID, $arParams = array())
 {
     global $DB, $USER;
     $ID = intval($ID);
     if ($ID < 1) {
         return false;
     }
     $executiveUserId = null;
     if (isset($arParams['USER_ID'])) {
         $executiveUserId = (int) $arParams['USER_ID'];
     } elseif (is_object($USER) && method_exists($USER, 'getId')) {
         $executiveUserId = (int) $USER->getId();
     }
     /** @noinspection PhpDeprecationInspection */
     $rsRemovingLogItem = self::getByID($ID);
     if ($rsRemovingLogItem && ($arRemovingLogItem = $rsRemovingLogItem->fetch())) {
         $taskId = $arRemovingLogItem['TASK_ID'];
     } else {
         return false;
     }
     $curDuration = 0;
     $rsTask = CTasks::getList(array(), array('ID' => $taskId), array('ID', 'TIME_SPENT_IN_LOGS'));
     if ($rsTask && ($arTask = $rsTask->fetch())) {
         $curDuration = (int) $arTask['TIME_SPENT_IN_LOGS'];
     }
     foreach (GetModuleEvents('tasks', 'OnBeforeTaskElapsedTimeDelete', true) as $arEvent) {
         if (ExecuteModuleEventEx($arEvent, array($ID, $arRemovingLogItem)) === false) {
             return false;
         }
     }
     $strSql = "DELETE FROM b_tasks_elapsed_time WHERE ID = " . $ID;
     $rc = $DB->Query($strSql, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
     $occurAsUserId = CTasksTools::getOccurAsUserId();
     if (!$occurAsUserId) {
         $occurAsUserId = $executiveUserId ? $executiveUserId : 1;
     }
     $oLog = new CTaskLog();
     $oLog->Add(array('TASK_ID' => $taskId, 'USER_ID' => $occurAsUserId, '~CREATED_DATE' => $DB->currentTimeFunction(), 'FIELD' => 'TIME_SPENT_IN_LOGS', 'FROM_VALUE' => $curDuration, 'TO_VALUE' => $curDuration - (int) $arRemovingLogItem['SECONDS']));
     foreach (GetModuleEvents('tasks', 'OnTaskElapsedTimeDelete', true) as $arEvent) {
         ExecuteModuleEventEx($arEvent, array($ID, &$arRemovingLogItem));
     }
     return $rc;
 }
Пример #6
0
 protected static function SendMessageToSocNet($arFields, $bSpawnedByAgent, $arChanges = null, $arTask = null, array $parameters = array())
 {
     global $USER, $DB;
     $effectiveUserId = self::getEffectiveUserId($arFields, array(), $bSpawnedByAgent, $parameters);
     if (!CModule::IncludeModule('socialnetwork')) {
         return null;
     }
     $bCrmTask = isset($arTask) && isset($arTask["UF_CRM_TASK"]) && (is_array($arTask["UF_CRM_TASK"]) && (isset($arTask["UF_CRM_TASK"][0]) && strlen($arTask["UF_CRM_TASK"][0]) > 0) || !is_array($arTask["UF_CRM_TASK"]) && strlen($arTask["UF_CRM_TASK"]) > 0);
     $arLogFilter = false;
     if (!$bCrmTask) {
         $arLogFilter = array("EVENT_ID" => "tasks", "SOURCE_ID" => $arTask["ID"]);
     } elseif (CModule::IncludeModule("crm")) {
         $dbCrmActivity = CCrmActivity::GetList(array(), array('TYPE_ID' => CCrmActivityType::Task, 'ASSOCIATED_ENTITY_ID' => $arTask["ID"], 'CHECK_PERMISSIONS' => 'N'), false, false, array('ID'));
         if ($arCrmActivity = $dbCrmActivity->Fetch()) {
             $arLogFilter = array("EVENT_ID" => "crm_activity_add", "ENTITY_ID" => $arCrmActivity["ID"]);
         }
     }
     if (!$arLogFilter) {
         return null;
     }
     static $arCheckedUsers = array();
     // users that checked for their existing
     static $cachedSiteTimeFormat = -1;
     // select "real" author
     $occurAsUserId = CTasksTools::getOccurAsUserId();
     if (!$occurAsUserId) {
         $occurAsUserId = $effectiveUserId;
     }
     if ($cachedSiteTimeFormat === -1) {
         $cachedSiteTimeFormat = CSite::GetDateFormat('FULL', SITE_ID);
     }
     static $cachedAllSitesIds = -1;
     if ($cachedAllSitesIds === -1) {
         $cachedAllSitesIds = array();
         $dbSite = CSite::GetList($by = 'sort', $order = 'desc', array('ACTIVE' => 'Y'));
         while ($arSite = $dbSite->Fetch()) {
             $cachedAllSitesIds[] = $arSite['ID'];
         }
     }
     // Check that user exists
     if (!in_array((int) $arFields["CREATED_BY"], $arCheckedUsers, true)) {
         $rsUser = CUser::GetList($by = 'ID', $order = 'ASC', array('ID' => $arFields["CREATED_BY"]), array('FIELDS' => array('ID')));
         if (!($arUser = $rsUser->Fetch())) {
             return false;
         }
         $arCheckedUsers[] = (int) $arFields["CREATED_BY"];
     }
     if (is_array($arChanges)) {
         if (count($arChanges) == 0) {
             $rsSocNetLogItems = CSocNetLog::GetList(array("ID" => "DESC"), $arLogFilter, false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID"));
             while ($arRes = $rsSocNetLogItems->Fetch()) {
                 $authorUserId = false;
                 if (isset($arFields['CREATED_BY'])) {
                     $authorUserId = (int) $arFields['CREATED_BY'];
                 } elseif (isset($arTask['CREATED_BY'])) {
                     $authorUserId = (int) $arTask['CREATED_BY'];
                 }
                 // Add author to list of users that view log about task in livefeed
                 // But only when some other person change task
                 // or if added FORUM_TOPIC_ID
                 if ($authorUserId !== $effectiveUserId || $arTask['FORUM_TOPIC_ID'] == 0 && isset($arFields['FORUM_TOPIC_ID']) && $arFields['FORUM_TOPIC_ID'] > 0) {
                     $authorGroupCode = 'U' . $authorUserId;
                     $rsRights = CSocNetLogRights::GetList(array(), array('LOG_ID' => $arRes['ID'], 'GROUP_CODE' => $authorGroupCode));
                     // If task's author hasn't rights yet, give them
                     if (!($arRights = $rsRights->fetch())) {
                         CSocNetLogRights::Add($arRes["ID"], array($authorGroupCode));
                     }
                 }
             }
             return null;
         } elseif (count($arChanges) == 1 && isset($arChanges['STATUS'])) {
             return null;
             // if only status changes - don't send message, because it will be sent by SendStatusMessage()
         }
     }
     if ($bSpawnedByAgent === 'Y') {
         $bSpawnedByAgent = true;
     } elseif ($bSpawnedByAgent === 'N') {
         $bSpawnedByAgent = false;
     }
     if (!is_bool($bSpawnedByAgent)) {
         return false;
     }
     $taskId = false;
     if (is_array($arFields) && isset($arFields['ID']) && $arFields['ID'] > 0) {
         $taskId = $arFields['ID'];
     } elseif (is_array($arTask) && isset($arTask['ID']) && $arTask['ID'] > 0) {
         $taskId = $arTask['ID'];
     }
     // We will mark this to false, if we send update message and log item already exists
     $bSocNetAddNewItem = true;
     $logDate = $DB->CurrentTimeFunction();
     $curTimeTimestamp = time() + CTimeZone::GetOffset();
     if (!$bCrmTask) {
         $arSoFields = array('EVENT_ID' => 'tasks', 'TITLE' => $arFields['TITLE'], 'MESSAGE' => '', 'MODULE_ID' => 'tasks');
     } else {
         $arSoFields = array();
     }
     // If changes and task data given => we are prepare "update" message,
     // or "add" message otherwise
     if (is_array($arChanges) && is_array($arTask)) {
         // Prepare "update" message here
         if (strlen($arFields["CHANGED_DATE"]) > 0) {
             $createdDateTimestamp = MakeTimeStamp($arFields["CHANGED_DATE"], $cachedSiteTimeFormat);
             if ($createdDateTimestamp > $curTimeTimestamp) {
                 $logDate = $DB->CharToDateFunction($arFields["CHANGED_DATE"], "FULL", SITE_ID);
             }
         }
         $arChangesFields = array_keys($arChanges);
         $arSoFields['TEXT_MESSAGE'] = str_replace('#CHANGES#', implode(', ', CTaskNotifications::__Fields2Names($arChangesFields)), GetMessage('TASKS_SONET_TASK_CHANGED_MESSAGE'));
         if (!$bCrmTask) {
             if ($arFields["GROUP_ID"] === NULL && $arTask['GROUP_ID'] || $arFields['GROUP_ID']) {
                 $arSoFields["ENTITY_TYPE"] = SONET_ENTITY_GROUP;
                 $arSoFields["ENTITY_ID"] = $arFields["GROUP_ID"] ? $arFields["GROUP_ID"] : $arTask['GROUP_ID'];
             } else {
                 $arSoFields["ENTITY_TYPE"] = SONET_ENTITY_USER;
                 $arSoFields["ENTITY_ID"] = $arFields["CREATED_BY"] ? $arFields["CREATED_BY"] : $arTask["CREATED_BY"];
             }
         }
         $arSoFields['PARAMS'] = serialize(array('TYPE' => 'modify', 'CHANGED_FIELDS' => $arChangesFields, 'CREATED_BY' => $arFields["CREATED_BY"] ? $arFields["CREATED_BY"] : $arTask["CREATED_BY"], 'CHANGED_BY' => $occurAsUserId ? $occurAsUserId : $arFields['CHANGED_BY'], 'PREV_REAL_STATUS' => isset($arTask['REAL_STATUS']) ? $arTask['REAL_STATUS'] : false));
         // Determine, does item exists in sonet log
         $rsSocNetLogItems = CSocNetLog::GetList(array("ID" => "DESC"), $arLogFilter, false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID"));
         if ($rsSocNetLogItems->Fetch()) {
             $bSocNetAddNewItem = false;
             // item already exists, update it, not create.
         }
     } else {
         if (strlen($arFields["CREATED_DATE"]) > 0) {
             $createdDateTimestamp = MakeTimeStamp($arFields["CREATED_DATE"], $cachedSiteTimeFormat);
             if ($createdDateTimestamp > $curTimeTimestamp) {
                 $logDate = $DB->CharToDateFunction($arFields["CREATED_DATE"], "FULL", SITE_ID);
             }
         }
         $arSoFields['TEXT_MESSAGE'] = GetMessage('TASKS_SONET_NEW_TASK_MESSAGE');
         if ($arFields["GROUP_ID"]) {
             $arSoFields["ENTITY_TYPE"] = SONET_ENTITY_GROUP;
             $arSoFields["ENTITY_ID"] = $arFields["GROUP_ID"];
         } else {
             $arSoFields["ENTITY_TYPE"] = SONET_ENTITY_USER;
             $arSoFields["ENTITY_ID"] = $arFields["CREATED_BY"];
         }
         $arParamsLog = array('TYPE' => 'create', 'CREATED_BY' => $arFields["CREATED_BY"] ? $arFields["CREATED_BY"] : $arTask["CREATED_BY"], 'PREV_REAL_STATUS' => isset($arTask['REAL_STATUS']) ? $arTask['REAL_STATUS'] : false);
         if ($occurAsUserId) {
             $arParamsLog["CREATED_BY"] = $occurAsUserId;
         }
         $arSoFields['PARAMS'] = serialize($arParamsLog);
     }
     // rating entity id (ilike)
     $arSoFields["RATING_ENTITY_ID"] = $taskId;
     $arSoFields["RATING_TYPE_ID"] = "TASK";
     // Do we need add new item to socnet?
     // We adds new item, if it is not exists.
     $logID = false;
     if (IsModuleInstalled("webdav") || IsModuleInstalled("disk")) {
         $ufDocID = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFieldValue("TASKS_TASK", "UF_TASK_WEBDAV_FILES", $taskId, LANGUAGE_ID);
         if ($ufDocID) {
             $arSoFields["UF_SONET_LOG_DOC"] = $ufDocID;
         }
     }
     if ($bSocNetAddNewItem) {
         $arSoFields['=LOG_DATE'] = $logDate;
         $arSoFields['CALLBACK_FUNC'] = false;
         $arSoFields['SOURCE_ID'] = $taskId;
         $arSoFields['ENABLE_COMMENTS'] = 'Y';
         $arSoFields['URL'] = CTaskNotifications::GetNotificationPath(array('ID' => (int) $arFields["CREATED_BY"]), $taskId, false);
         $arSoFields['USER_ID'] = $arFields['CREATED_BY'];
         $arSoFields['TITLE_TEMPLATE'] = '#TITLE#';
         // Set all sites because any user from any site may be
         // added to task in future. For example, new auditor, etc.
         $arSoFields['SITE_ID'] = $cachedAllSitesIds;
         $logID = CSocNetLog::Add($arSoFields, false);
         if (intval($logID) > 0) {
             CSocNetLog::Update($logID, array("TMP_ID" => $logID));
             $arTaskParticipant = CTaskNotifications::GetRecipientsIDs($arFields, false);
             // Exclude author
             $arLogCanViewedBy = array_diff($arTaskParticipant, array($arFields['CREATED_BY']));
             $arRights = CTaskNotifications::__UserIDs2Rights($arLogCanViewedBy);
             if (isset($arFields['GROUP_ID'])) {
                 $arRights = array_merge($arRights, self::prepareRightsCodesForViewInGroupLiveFeed($logID, $arFields['GROUP_ID']));
             }
             CSocNetLogRights::Add($logID, $arRights);
             CSocNetLog::SendEvent($logID, "SONET_NEW_EVENT", $logID);
         }
     } else {
         $arSoFields['=LOG_DATE'] = $logDate;
         $arSoFields['=LOG_UPDATE'] = $logDate;
         // All tasks posts in live feed should be from director
         if (isset($arFields['CREATED_BY'])) {
             $arSoFields['USER_ID'] = $arFields['CREATED_BY'];
         } elseif (isset($arTask['CREATED_BY'])) {
             $arSoFields['USER_ID'] = $arTask['CREATED_BY'];
         } elseif ($occurAsUserId) {
             $arSoFields['USER_ID'] = $occurAsUserId;
         } else {
             unset($arSoFields['USER_ID']);
         }
         $rsSocNetLogItems = CSocNetLog::GetList(array("ID" => "DESC"), $arLogFilter, false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID"));
         while ($arRes = $rsSocNetLogItems->Fetch()) {
             CSocNetLog::Update($arRes["ID"], $arSoFields);
             $arTaskParticipant = CTaskNotifications::GetRecipientsIDs($arFields, false, true);
             $bAuthorMustBeExcluded = false;
             $authorUserId = false;
             if (isset($arFields['CREATED_BY'])) {
                 $authorUserId = (int) $arFields['CREATED_BY'];
             } elseif (isset($arTask['CREATED_BY'])) {
                 $authorUserId = (int) $arTask['CREATED_BY'];
             }
             // Get current rights
             $rsRights = CSocNetLogRights::GetList(array(), array('LOG_ID' => $arRes['ID']));
             $arCurrentRights = array();
             while ($arRights = $rsRights->fetch()) {
                 $arCurrentRights[] = $arRights['GROUP_CODE'];
             }
             // If author changes the task and author doesn't have
             // access to task yet, don't give access to him.
             if ($authorUserId === $effectiveUserId) {
                 $authorGroupCode = 'U' . $authorUserId;
                 // If task's author hasn't rights yet, still exclude him
                 if (!in_array($authorGroupCode, $arCurrentRights, true)) {
                     $bAuthorMustBeExcluded = true;
                 }
             }
             if ($bAuthorMustBeExcluded) {
                 $arLogCanViewedBy = array_diff($arTaskParticipant, array($authorUserId));
             } else {
                 $arLogCanViewedBy = $arTaskParticipant;
             }
             $arNewRights = CTaskNotifications::__UserIDs2Rights($arLogCanViewedBy);
             $bGroupChanged = false;
             if (isset($arFields['GROUP_ID'], $arTask['GROUP_ID']) && $arFields['GROUP_ID'] && $arFields['GROUP_ID'] != $arTask['GROUP_ID']) {
                 $bGroupChanged = true;
             }
             // If rights really changed, update them
             if (count(array_diff($arCurrentRights, $arNewRights)) || count(array_diff($arNewRights, $arCurrentRights)) || $bGroupChanged) {
                 if (isset($arFields['GROUP_ID'])) {
                     $arNewRights = array_merge($arNewRights, self::prepareRightsCodesForViewInGroupLiveFeed($logID, $arFields['GROUP_ID']));
                 } elseif (isset($arTask['GROUP_ID'])) {
                     $arNewRights = array_merge($arNewRights, self::prepareRightsCodesForViewInGroupLiveFeed($logID, $arTask['GROUP_ID']));
                 }
                 CSocNetLogRights::DeleteByLogID($arRes["ID"], true);
                 CSocNetLogRights::Add($arRes["ID"], $arNewRights);
             }
         }
     }
     return $logID;
 }
Пример #7
0
 /**
  * This method is deprecated. Use CTaskItem::update() instead.
  * @deprecated
  */
 public function Update($ID, $arFields, $arParams = array())
 {
     global $DB, $USER, $USER_FIELD_MANAGER, $CACHE_MANAGER, $APPLICATION;
     if (isset($arFields['META::EVENT_GUID'])) {
         $eventGUID = $arFields['META::EVENT_GUID'];
         unset($arFields['META::EVENT_GUID']);
     } else {
         $eventGUID = sha1(uniqid('AUTOGUID', true));
     }
     $bWasFatalError = false;
     $ID = intval($ID);
     if ($ID < 1) {
         return false;
     }
     $userID = null;
     $bCheckRightsOnFiles = false;
     // for backward compatibility
     if (is_array($arParams)) {
         if (isset($arParams['USER_ID']) && $arParams['USER_ID'] > 0) {
             $userID = (int) $arParams['USER_ID'];
         }
         if (isset($arParams['CHECK_RIGHTS_ON_FILES'])) {
             if ($arParams['CHECK_RIGHTS_ON_FILES'] === 'Y' || $arParams['CHECK_RIGHTS_ON_FILES'] === true) {
                 $bCheckRightsOnFiles = true;
             } else {
                 $bCheckRightsOnFiles = false;
             }
         }
     }
     if ($userID === null) {
         $userID = is_object($USER) ? intval($USER->GetID()) : 1;
     }
     $rsTask = CTasks::GetByID($ID, false);
     if ($arTask = $rsTask->Fetch()) {
         if ($this->CheckFields($arFields, $ID, $userID)) {
             if ($USER_FIELD_MANAGER->CheckFields("TASKS_TASK", $ID, $arFields)) {
                 unset($arFields["ID"]);
                 $arBinds = array("DESCRIPTION" => $arFields["DESCRIPTION"], "DECLINE_REASON" => $arFields["DECLINE_REASON"]);
                 $time = time() + CTasksTools::getTimeZoneOffset();
                 $arFields["CHANGED_BY"] = $userID;
                 $arFields["CHANGED_DATE"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                 $occurAsUserId = CTasksTools::getOccurAsUserId();
                 if (!$occurAsUserId) {
                     $occurAsUserId = $arFields["CHANGED_BY"] ? $arFields["CHANGED_BY"] : 1;
                 }
                 if (!$arFields["OUTLOOK_VERSION"]) {
                     $arFields["OUTLOOK_VERSION"] = ($arTask["OUTLOOK_VERSION"] ? $arTask["OUTLOOK_VERSION"] : 1) + 1;
                 }
                 // If new status code given AND new status code != current status => than update
                 if (isset($arFields["STATUS"]) && (int) $arTask['STATUS'] !== (int) $arFields['STATUS']) {
                     $arFields["STATUS_CHANGED_BY"] = $userID;
                     $arFields["STATUS_CHANGED_DATE"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                     if ($arFields["STATUS"] == 5 || $arFields["STATUS"] == 4) {
                         $arFields["CLOSED_BY"] = $userID;
                         $arFields["CLOSED_DATE"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                     } else {
                         $arFields["CLOSED_BY"] = false;
                         $arFields["CLOSED_DATE"] = false;
                         if ($arFields["STATUS"] == 3) {
                             $arFields["DATE_START"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                         }
                     }
                 }
                 if ($arFields["REPLICATE"] == "Y") {
                     $arFields["REPLICATE_PARAMS"] = serialize($arFields["REPLICATE_PARAMS"]);
                 }
                 $arTaskCopy = $arTask;
                 // this will allow transfer data by pointer for speed-up
                 foreach (GetModuleEvents('tasks', 'OnBeforeTaskUpdate', true) as $arEvent) {
                     if (ExecuteModuleEventEx($arEvent, array($ID, &$arFields, &$arTaskCopy)) === false) {
                         $errmsg = GetMessage("TASKS_UNKNOWN_UPDATE_ERROR");
                         $errno = 'ERROR_UNKNOWN_UPDATE_TASK_ERROR';
                         if ($ex = $APPLICATION->getException()) {
                             $errmsg = $ex->getString();
                             $errno = $ex->getId();
                         }
                         $this->_errors[] = array('text' => $errmsg, 'id' => $errno);
                         return false;
                     }
                 }
                 $oTaskList = CTaskCountersProcessor::getInstance();
                 $oTaskList->onBeforeTaskUpdate($ID, $arTask, $arFields);
                 $strUpdate = $DB->PrepareUpdate("b_tasks", $arFields, "tasks");
                 $strSql = "UPDATE b_tasks SET " . $strUpdate . " WHERE ID=" . $ID;
                 $result = $DB->QueryBind($strSql, $arBinds, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
                 if ($result) {
                     CTaskCountersProcessor::onAfterTaskUpdate($ID, $arTask, $arFields);
                     $arParticipants = array_merge(array($arTask['CREATED_BY'], $arTask['RESPONSIBLE_ID']), (array) $arTask['ACCOMPLICES'], (array) $arTask['AUDITORS']);
                     if (isset($arFields['CREATED_BY'])) {
                         $arParticipants[] = $arFields['CREATED_BY'];
                     }
                     if (isset($arFields['RESPONSIBLE_ID'])) {
                         $arParticipants[] = $arFields['RESPONSIBLE_ID'];
                     }
                     if (isset($arFields['ACCOMPLICES'])) {
                         $arParticipants = array_merge($arParticipants, (array) $arFields['ACCOMPLICES']);
                     }
                     if (isset($arFields['AUDITORS'])) {
                         $arParticipants = array_merge($arParticipants, (array) $arFields['AUDITORS']);
                     }
                     $arParticipants = array_unique($arParticipants);
                     // Emit pull event
                     try {
                         $arPullRecipients = array();
                         foreach ($arParticipants as $userId) {
                             $arPullRecipients[] = (int) $userId;
                         }
                         $taskGroupId = 0;
                         // no group
                         $taskGroupIdBeforeUpdate = 0;
                         // no group
                         if (isset($arTask['GROUP_ID']) && $arTask['GROUP_ID'] > 0) {
                             $taskGroupId = (int) $arTask['GROUP_ID'];
                         }
                         // if $arFields['GROUP_ID'] not given, than it means,
                         // that group not changed during this update, so
                         // we must take existing group_id (from $arTask)
                         if (!array_key_exists('GROUP_ID', $arFields)) {
                             if (isset($arTask['GROUP_ID']) && $arTask['GROUP_ID'] > 0) {
                                 $taskGroupIdBeforeUpdate = (int) $arTask['GROUP_ID'];
                             } else {
                                 $taskGroupIdBeforeUpdate = 0;
                             }
                             // no group
                         } else {
                             if ($arFields['GROUP_ID'] > 0) {
                                 $taskGroupIdBeforeUpdate = (int) $arFields['GROUP_ID'];
                             } else {
                                 $taskGroupIdBeforeUpdate = 0;
                             }
                             // no group
                         }
                         $arPullData = array('TASK_ID' => (int) $ID, 'BEFORE' => array('GROUP_ID' => $taskGroupId), 'AFTER' => array('GROUP_ID' => $taskGroupIdBeforeUpdate), 'TS' => time(), 'event_GUID' => $eventGUID);
                         self::EmitPullWithTagPrefix($arPullRecipients, 'TASKS_GENERAL_', 'task_update', $arPullData);
                         self::EmitPullWithTag($arPullRecipients, 'TASKS_TASK_' . (int) $ID, 'task_update', $arPullData);
                     } catch (Exception $e) {
                         $bWasFatalError = true;
                         $this->_errors[] = 'at line ' . $e->GetLine() . ', ' . $e->GetMessage();
                     }
                     // changes log
                     $arTmp = array('arTask' => $arTask, 'arFields' => $arFields);
                     if (isset($arFields['DURATION_PLAN']) && isset($arFields['DURATION_TYPE'])) {
                         if ($arFields['DURATION_TYPE'] === 'hours') {
                             $arTmp['arFields']['DURATION_PLAN_SECONDS'] = $arFields['DURATION_PLAN'] * 3600;
                             unset($arTmp['arFields']['DURATION_PLAN']);
                         } elseif ($arFields['DURATION_TYPE'] === 'days') {
                             $arTmp['arFields']['DURATION_PLAN_SECONDS'] = $arFields['DURATION_PLAN'] * 3600 * 24;
                             unset($arTmp['arFields']['DURATION_PLAN']);
                         }
                     }
                     if (isset($arTask['DURATION_PLAN']) && isset($arTask['DURATION_TYPE'])) {
                         if ($arTask['DURATION_TYPE'] === 'hours') {
                             $arTmp['arTask']['DURATION_PLAN_SECONDS'] = $arTask['DURATION_PLAN'] * 3600;
                             unset($arTmp['arTask']['DURATION_PLAN']);
                         } elseif ($arTask['DURATION_TYPE'] === 'days') {
                             $arTmp['arTask']['DURATION_PLAN_SECONDS'] = $arTask['DURATION_PLAN'] * 3600 * 24;
                             unset($arTmp['arTask']['DURATION_PLAN']);
                         }
                     }
                     $arChanges = CTaskLog::GetChanges($arTmp['arTask'], $arTmp['arFields']);
                     unset($arTmp);
                     foreach ($arChanges as $key => $value) {
                         $arLogFields = array("TASK_ID" => $ID, "USER_ID" => $occurAsUserId, "CREATED_DATE" => $arFields["CHANGED_DATE"], "FIELD" => $key, "FROM_VALUE" => $value["FROM_VALUE"], "TO_VALUE" => $value["TO_VALUE"]);
                         $log = new CTaskLog();
                         $log->Add($arLogFields);
                     }
                     if (isset($arFields["ACCOMPLICES"]) && isset($arChanges["ACCOMPLICES"])) {
                         CTaskMembers::DeleteByTaskID($ID, "A");
                         CTasks::AddAccomplices($ID, $arFields["ACCOMPLICES"]);
                     }
                     if (isset($arFields["AUDITORS"]) && isset($arChanges["AUDITORS"])) {
                         CTaskMembers::DeleteByTaskID($ID, "U");
                         CTasks::AddAuditors($ID, $arFields["AUDITORS"]);
                     }
                     if (isset($arFields["FILES"]) && (isset($arChanges["NEW_FILES"]) || isset($arChanges["DELETED_FILES"]))) {
                         $arNotDeleteFiles = $arFields["FILES"];
                         CTaskFiles::DeleteByTaskID($ID, $arNotDeleteFiles);
                         CTasks::AddFiles($ID, $arFields["FILES"], array('USER_ID' => $userID, 'CHECK_RIGHTS_ON_FILES' => $bCheckRightsOnFiles));
                     }
                     if (isset($arFields["TAGS"]) && isset($arChanges["TAGS"])) {
                         CTaskTags::DeleteByTaskID($ID);
                         CTasks::AddTags($ID, $arTask["CREATED_BY"], $arFields["TAGS"], $userID);
                     }
                     if (isset($arFields["DEPENDS_ON"]) && isset($arChanges["DEPENDS_ON"])) {
                         CTaskDependence::DeleteByTaskID($ID);
                         CTasks::AddPrevious($ID, $arFields["DEPENDS_ON"]);
                     }
                     $USER_FIELD_MANAGER->Update("TASKS_TASK", $ID, $arFields, $userID);
                     $notifArFields = array_merge($arFields, array('CHANGED_BY' => $occurAsUserId));
                     if (($status = intval($arFields["STATUS"])) && $status > 0 && $status < 8 && (int) $arTask['STATUS'] !== (int) $arFields['STATUS']) {
                         if ($status == 7) {
                             $arTask["DECLINE_REASON"] = $arFields["DECLINE_REASON"];
                         }
                         CTaskNotifications::SendStatusMessage($arTask, $status, $notifArFields);
                     }
                     CTaskNotifications::SendUpdateMessage($notifArFields, $arTask);
                     CTaskComments::onAfterTaskUpdate($ID, $arTask, $arFields);
                     $arFields["ID"] = $ID;
                     $arMergedFields = array_merge($arTask, $arFields);
                     CTaskSync::UpdateItem($arFields, $arTask);
                     // MS Exchange
                     $arFields['META:PREV_FIELDS'] = $arTask;
                     try {
                         $lastEventName = '';
                         foreach (GetModuleEvents('tasks', 'OnTaskUpdate', true) as $arEvent) {
                             $lastEventName = $arEvent['TO_CLASS'] . '::' . $arEvent['TO_METHOD'] . '()';
                             ExecuteModuleEventEx($arEvent, array($ID, &$arFields, &$arTaskCopy));
                         }
                     } catch (Exception $e) {
                         CTaskAssert::logWarning('[0xee8999a8] exception in module event: ' . $lastEventName . '; at file: ' . $e->getFile() . ':' . $e->getLine() . ";\n");
                     }
                     unset($arFields['META:PREV_FIELDS']);
                     CTasks::Index($arMergedFields, $arFields["TAGS"]);
                     // search index
                     // clear cache
                     if ($arTask["GROUP_ID"]) {
                         $CACHE_MANAGER->ClearByTag("tasks_group_" . $arTask["GROUP_ID"]);
                     }
                     if ($arFields['GROUP_ID'] && $arFields['GROUP_ID'] != $arTask['GROUP_ID']) {
                         $CACHE_MANAGER->ClearByTag('tasks_group_' . $arFields['GROUP_ID']);
                     }
                     foreach ($arParticipants as $userId) {
                         $CACHE_MANAGER->ClearByTag("tasks_user_" . $userId);
                     }
                     if ($bWasFatalError) {
                         soundex('push&pull: bWasFatalError === true');
                     }
                     return true;
                 }
             } else {
                 $e = $APPLICATION->GetException();
                 foreach ($e->messages as $msg) {
                     $this->_errors[] = $msg;
                 }
             }
         }
     }
     if (sizeof($this->_errors) == 0) {
         $this->_errors[] = array("text" => GetMessage("TASKS_UNKNOWN_UPDATE_ERROR"), "id" => "ERROR_UNKNOWN_UPDATE_TASK_ERROR");
     }
     return false;
 }
Пример #8
0
 function SendStatusMessage($arTask, $status, $arFields = array())
 {
     global $USER, $DB;
     $status = intval($status);
     if ($status > 0 && $status < 8) {
         $arRecipientsIDs = CTaskNotifications::GetRecipientsIDs(array_merge($arTask, $arFields));
         if (sizeof($arRecipientsIDs) && (is_object($USER) && $USER->GetID() || $arTask["CREATED_BY"])) {
             // If task was redoed
             if (($status == CTasks::STATE_NEW || $status == CTasks::STATE_PENDING) && $arTask['REAL_STATUS'] == CTasks::STATE_SUPPOSEDLY_COMPLETED) {
                 $message = str_replace("#TASK_TITLE#", self::formatTaskName($arTask['ID'], $arTask['TITLE'], $arTask['GROUP_ID'], true), GetMessage("TASKS_TASK_STATUS_MESSAGE_REDOED"));
                 $message_email = str_replace("#TASK_TITLE#", self::formatTaskName($arTask['ID'], $arTask['TITLE'], $arTask['GROUP_ID']), GetMessage("TASKS_TASK_STATUS_MESSAGE_REDOED") . "\r\n" . GetMessage('TASKS_MESSAGE_LINK') . ': #PATH_TO_TASK#');
             } else {
                 $message = str_replace("#TASK_TITLE#", self::formatTaskName($arTask['ID'], $arTask['TITLE'], $arTask['GROUP_ID'], true), GetMessage("TASKS_TASK_STATUS_MESSAGE_" . $status));
                 $message_email = str_replace("#TASK_TITLE#", self::formatTaskName($arTask['ID'], $arTask['TITLE'], $arTask['GROUP_ID']), GetMessage("TASKS_TASK_STATUS_MESSAGE_" . $status) . "\r\n" . GetMessage('TASKS_MESSAGE_LINK') . ': #PATH_TO_TASK#');
                 if ($status == CTasks::STATE_DECLINED) {
                     $message = str_replace("#TASK_DECLINE_REASON#", $arTask["DECLINE_REASON"], $message);
                     $message_email = str_replace("#TASK_DECLINE_REASON#", $arTask["DECLINE_REASON"], $message_email);
                 }
             }
             $occurAsUserId = CTasksTools::getOccurAsUserId();
             if (!$occurAsUserId) {
                 $occurAsUserId = is_object($USER) && $USER->GetID() ? $USER->GetID() : $arTask["CREATED_BY"];
             }
             CTaskNotifications::SendMessage($occurAsUserId, $arRecipientsIDs, $message, $arTask["ID"], $message_email, array('ACTION' => 'TASK_STATUS_CHANGED_MESSAGE', 'arTask' => $arTask, 'arFields' => $arFields));
         }
     }
     // sonet log
     if (CModule::IncludeModule("socialnetwork")) {
         if ($status == CTasks::STATE_PENDING) {
             $message = GetMessage("TASKS_SONET_TASK_STATUS_MESSAGE_" . CTasks::STATE_NEW);
         } else {
             $message = GetMessage("TASKS_SONET_TASK_STATUS_MESSAGE_" . $status);
         }
         if ($status == CTasks::STATE_DECLINED) {
             $message = str_replace("#TASK_DECLINE_REASON#", $arTask["DECLINE_REASON"], $message);
         }
         $arSoFields = array("TITLE" => $arTask["TITLE"], "=LOG_UPDATE" => strlen($arTask["CHANGED_DATE"]) > 0 ? MakeTimeStamp($arTask["CHANGED_DATE"], CSite::GetDateFormat("FULL", SITE_ID)) > time() + CTimeZone::GetOffset() ? $DB->CharToDateFunction($arTask["CHANGED_DATE"], "FULL", SITE_ID) : $DB->CurrentTimeFunction() : $DB->CurrentTimeFunction(), "MESSAGE" => "", "TEXT_MESSAGE" => $message, "PARAMS" => serialize(array("TYPE" => "status", 'CHANGED_BY' => $arFields['CHANGED_BY'], 'PREV_REAL_STATUS' => isset($arTask['REAL_STATUS']) ? $arTask['REAL_STATUS'] : false)));
         $arSoFields['=LOG_DATE'] = $arSoFields['=LOG_UPDATE'];
         // All tasks posts in live feed should be from director
         if (isset($arFields['CREATED_BY'])) {
             $arSoFields["USER_ID"] = $arFields['CREATED_BY'];
         }
         $loggedInUserId = false;
         if (is_object($USER) && method_exists($USER, 'getId')) {
             $loggedInUserId = (int) $USER->getId();
         }
         $dbRes = CSocNetLog::GetList(array("ID" => "DESC"), array("EVENT_ID" => "tasks", "SOURCE_ID" => $arTask["ID"]), false, false, array("ID", "ENTITY_TYPE", "ENTITY_ID"));
         while ($arRes = $dbRes->Fetch()) {
             CSocNetLog::Update($arRes['ID'], $arSoFields);
             $authorUserId = (int) $arTask['CREATED_BY'];
             // Add author to list of users that view log about task in livefeed
             // But only when some other person change task
             if ($authorUserId !== $loggedInUserId) {
                 $authorGroupCode = 'U' . $authorUserId;
                 $rsRights = CSocNetLogRights::GetList(array(), array('LOG_ID' => $arRes['ID'], 'GROUP_CODE' => $authorGroupCode));
                 // If task's author hasn't rights yet, give them
                 if (!($arRights = $rsRights->fetch())) {
                     CSocNetLogRights::Add($arRes["ID"], array($authorGroupCode));
                 }
             }
         }
     }
 }
Пример #9
0
 /**
  * This method is deprecated. Use CTaskItem::update() instead.
  * @deprecated
  */
 public function Update($ID, $arFields, $arParams = array('CORRECT_DATE_PLAN_DEPENDENT_TASKS' => true, 'CORRECT_DATE_PLAN' => true, 'THROTTLE_MESSAGES' => false))
 {
     global $DB, $USER, $USER_FIELD_MANAGER, $APPLICATION;
     if (!isset($arParams['CORRECT_DATE_PLAN'])) {
         $arParams['CORRECT_DATE_PLAN'] = true;
     }
     if (!isset($arParams['CORRECT_DATE_PLAN_DEPENDENT_TASKS'])) {
         $arParams['CORRECT_DATE_PLAN_DEPENDENT_TASKS'] = true;
     }
     if (!isset($arParams['THROTTLE_MESSAGES'])) {
         $arParams['THROTTLE_MESSAGES'] = false;
     }
     $this->lastOperationResultData = array();
     if (isset($arFields['META::EVENT_GUID'])) {
         $eventGUID = $arFields['META::EVENT_GUID'];
         unset($arFields['META::EVENT_GUID']);
     } else {
         $eventGUID = sha1(uniqid('AUTOGUID', true));
     }
     $bWasFatalError = false;
     $ID = intval($ID);
     if ($ID < 1) {
         return false;
     }
     $userID = null;
     $bCheckRightsOnFiles = false;
     // for backward compatibility
     if (!is_array($arParams)) {
         $arParams = array();
     }
     if (isset($arParams['USER_ID']) && $arParams['USER_ID'] > 0) {
         $userID = (int) $arParams['USER_ID'];
     }
     if (isset($arParams['CHECK_RIGHTS_ON_FILES'])) {
         if ($arParams['CHECK_RIGHTS_ON_FILES'] === 'Y' || $arParams['CHECK_RIGHTS_ON_FILES'] === true) {
             $bCheckRightsOnFiles = true;
         } else {
             $bCheckRightsOnFiles = false;
         }
     }
     if (!isset($arParams['CORRECT_DATE_PLAN_DEPENDENT_TASKS'])) {
         $arParams['CORRECT_DATE_PLAN_DEPENDENT_TASKS'] = true;
     }
     if (!isset($arParams['CORRECT_DATE_PLAN'])) {
         $arParams['CORRECT_DATE_PLAN'] = true;
     }
     if ($userID === null) {
         $userID = is_object($USER) ? intval($USER->GetID()) : 1;
     }
     $rsTask = CTasks::GetByID($ID, false);
     if ($arTask = $rsTask->Fetch()) {
         // check if there are userfields in $arFields
         $hasUfs = false;
         foreach ($arFields as $fld => $value) {
             $fld = trim($fld);
             if (strpos($fld, 'UF_') == 0) {
                 $hasUfs = true;
                 break;
             }
         }
         if ($this->CheckFields($arFields, $ID, $userID)) {
             $okay = $hasUfs ? $USER_FIELD_MANAGER->CheckFields("TASKS_TASK", $ID, $arFields) : true;
             if ($okay) {
                 $scheduler = null;
                 unset($arFields["ID"]);
                 $arBinds = array("DESCRIPTION" => $arFields["DESCRIPTION"], "DECLINE_REASON" => $arFields["DECLINE_REASON"]);
                 $time = time() + CTasksTools::getTimeZoneOffset();
                 $arFields["CHANGED_BY"] = $userID;
                 $arFields["CHANGED_DATE"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                 $occurAsUserId = CTasksTools::getOccurAsUserId();
                 if (!$occurAsUserId) {
                     $occurAsUserId = $arFields["CHANGED_BY"] ? $arFields["CHANGED_BY"] : 1;
                 }
                 if (!$arFields["OUTLOOK_VERSION"]) {
                     $arFields["OUTLOOK_VERSION"] = ($arTask["OUTLOOK_VERSION"] ? $arTask["OUTLOOK_VERSION"] : 1) + 1;
                 }
                 // If new status code given AND new status code != current status => than update
                 if (isset($arFields["STATUS"]) && (int) $arTask['STATUS'] !== (int) $arFields['STATUS']) {
                     $arFields["STATUS_CHANGED_BY"] = $userID;
                     $arFields["STATUS_CHANGED_DATE"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                     if ($arFields["STATUS"] == 5 || $arFields["STATUS"] == 4) {
                         $arFields["CLOSED_BY"] = $userID;
                         $arFields["CLOSED_DATE"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                     } else {
                         $arFields["CLOSED_BY"] = false;
                         $arFields["CLOSED_DATE"] = false;
                         if ($arFields["STATUS"] == 3) {
                             $arFields["DATE_START"] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $time);
                         }
                     }
                 }
                 if ($arFields["REPLICATE"] == "Y") {
                     $arFields["REPLICATE_PARAMS"] = serialize($arFields["REPLICATE_PARAMS"]);
                 }
                 // when updating end or start date plan, we need to be sure the time is correct
                 if ((string) $arFields['START_DATE_PLAN'] != '' || (string) $arFields['END_DATE_PLAN'] != '') {
                     if ($arParams['CORRECT_DATE_PLAN']) {
                         /*
                         print_r('Try to update '.$ID.' to:'.PHP_EOL);
                         print_r($arFields['START_DATE_PLAN']->getInfoGmt().PHP_EOL);
                         print_r($arFields['END_DATE_PLAN']->getInfoGmt().PHP_EOL);
                         */
                         $arTaskDPCopy = $arTask;
                         if ((string) $arFields['START_DATE_PLAN'] == '') {
                             // start date will be dropped, scheduler should be informed about that
                             $arTaskDPCopy['START_DATE_PLAN'] = '';
                         }
                         if ((string) $arFields['END_DATE_PLAN'] == '') {
                             // end date will be dropped, scheduler should be informed about that
                             $arTaskDPCopy['END_DATE_PLAN'] = '';
                         }
                         $scheduler = new Scheduler($userID, $ID, $arTaskDPCopy);
                         $data = $scheduler->reScheduleTask($arFields);
                         /*
                         print_r('Actual moving '.$ID.' to:'.PHP_EOL);
                         print_r($data['START_DATE_PLAN']->getInfoGmt().PHP_EOL);
                         print_r($data['END_DATE_PLAN']->getInfoGmt().PHP_EOL);
                         */
                         // to database:
                         if ($data['START_DATE_PLAN']) {
                             if ($data['START_DATE_PLAN']->toString() != (string) $arTask['CREATED_DATE']) {
                                 $arFields['START_DATE_PLAN'] = $data['START_DATE_PLAN']->toString();
                             }
                             $data['START_DATE_PLAN_STRUCT'] = $data['START_DATE_PLAN']->getTimeStruct();
                             $data['START_DATE_PLAN'] = $data['START_DATE_PLAN']->toString();
                         }
                         if ($data['END_DATE_PLAN']) {
                             $arFields['END_DATE_PLAN'] = $data['END_DATE_PLAN']->toString();
                             $data['END_DATE_PLAN_STRUCT'] = $data['END_DATE_PLAN']->getTimeStruct();
                             $data['END_DATE_PLAN'] = $data['END_DATE_PLAN']->toString();
                         }
                         if (isset($data['DURATION_PLAN_SECONDS'])) {
                             $arFields['DURATION_PLAN_SECONDS'] = $data['DURATION_PLAN_SECONDS'];
                         }
                         unset($data['ID']);
                         unset($data['MATCH_WORK_TIME']);
                         $this->lastOperationResultData['SHIFT_RESULT'][$ID] = $data;
                     }
                 }
                 // END_DATE_PLAN will be dropped
                 if (isset($arFields['END_DATE_PLAN']) && (string) $arFields['END_DATE_PLAN'] == '') {
                     // duration is no longer adequate
                     $arFields['DURATION_PLAN'] = 0;
                 }
                 self::processDurationPlanFields($arFields, (string) $arFields['DURATION_TYPE'] != '' ? $arFields['DURATION_TYPE'] : $arTask['DURATION_TYPE']);
                 $arTaskCopy = $arTask;
                 // this will allow transfer data by pointer for speed-up
                 foreach (GetModuleEvents('tasks', 'OnBeforeTaskUpdate', true) as $arEvent) {
                     if (ExecuteModuleEventEx($arEvent, array($ID, &$arFields, &$arTaskCopy)) === false) {
                         $errmsg = GetMessage("TASKS_UNKNOWN_UPDATE_ERROR");
                         $errno = 'ERROR_UNKNOWN_UPDATE_TASK_ERROR';
                         if ($ex = $APPLICATION->getException()) {
                             $errmsg = $ex->getString();
                             $errno = $ex->getId();
                         }
                         $this->_errors[] = array('text' => $errmsg, 'id' => $errno);
                         return false;
                     }
                 }
                 $oTaskList = CTaskCountersProcessor::getInstance();
                 $oTaskList->onBeforeTaskUpdate($ID, $arTask, $arFields);
                 $strUpdate = $DB->PrepareUpdate("b_tasks", $arFields, "tasks");
                 $strSql = "UPDATE b_tasks SET " . $strUpdate . " WHERE ID=" . $ID;
                 $result = $DB->QueryBind($strSql, $arBinds, false, "File: " . __FILE__ . "<br>Line: " . __LINE__);
                 if ($result) {
                     CTaskCountersProcessor::onAfterTaskUpdate($ID, $arTask, $arFields);
                     $arParticipants = array_merge(array($arTask['CREATED_BY'], $arTask['RESPONSIBLE_ID']), (array) $arTask['ACCOMPLICES'], (array) $arTask['AUDITORS']);
                     if (isset($arFields['CREATED_BY'])) {
                         $arParticipants[] = $arFields['CREATED_BY'];
                     }
                     if (isset($arFields['RESPONSIBLE_ID'])) {
                         $arParticipants[] = $arFields['RESPONSIBLE_ID'];
                     }
                     if (isset($arFields['ACCOMPLICES'])) {
                         $arParticipants = array_merge($arParticipants, (array) $arFields['ACCOMPLICES']);
                     }
                     if (isset($arFields['AUDITORS'])) {
                         $arParticipants = array_merge($arParticipants, (array) $arFields['AUDITORS']);
                     }
                     $arParticipants = array_unique($arParticipants);
                     // Emit pull event
                     try {
                         $arPullRecipients = array();
                         foreach ($arParticipants as $userId) {
                             $arPullRecipients[] = (int) $userId;
                         }
                         $taskGroupId = 0;
                         // no group
                         $taskGroupIdBeforeUpdate = 0;
                         // no group
                         if (isset($arTask['GROUP_ID']) && $arTask['GROUP_ID'] > 0) {
                             $taskGroupId = (int) $arTask['GROUP_ID'];
                         }
                         // if $arFields['GROUP_ID'] not given, than it means,
                         // that group not changed during this update, so
                         // we must take existing group_id (from $arTask)
                         if (!array_key_exists('GROUP_ID', $arFields)) {
                             if (isset($arTask['GROUP_ID']) && $arTask['GROUP_ID'] > 0) {
                                 $taskGroupIdBeforeUpdate = (int) $arTask['GROUP_ID'];
                             } else {
                                 $taskGroupIdBeforeUpdate = 0;
                             }
                             // no group
                         } else {
                             if ($arFields['GROUP_ID'] > 0) {
                                 $taskGroupIdBeforeUpdate = (int) $arFields['GROUP_ID'];
                             } else {
                                 $taskGroupIdBeforeUpdate = 0;
                             }
                             // no group
                         }
                         $arPullData = array('TASK_ID' => (int) $ID, 'BEFORE' => array('GROUP_ID' => $taskGroupId), 'AFTER' => array('GROUP_ID' => $taskGroupIdBeforeUpdate), 'TS' => time(), 'event_GUID' => $eventGUID);
                         self::EmitPullWithTagPrefix($arPullRecipients, 'TASKS_GENERAL_', 'task_update', $arPullData);
                         self::EmitPullWithTag($arPullRecipients, 'TASKS_TASK_' . (int) $ID, 'task_update', $arPullData);
                     } catch (Exception $e) {
                         $bWasFatalError = true;
                         $this->_errors[] = 'at line ' . $e->GetLine() . ', ' . $e->GetMessage();
                     }
                     // changes log
                     $arTmp = array('arTask' => $arTask, 'arFields' => $arFields);
                     if (isset($arTask['DURATION_PLAN'])) {
                         $arTmp['arTask']['DURATION_PLAN_SECONDS'] = $arTask['DURATION_PLAN_SECONDS'];
                         unset($arTmp['arTask']['DURATION_PLAN']);
                     }
                     if (isset($arFields['DURATION_PLAN'])) {
                         // at this point, $arFields['DURATION_PLAN'] in seconds
                         $arTmp['arFields']['DURATION_PLAN_SECONDS'] = $arFields['DURATION_PLAN'];
                         unset($arTmp['arFields']['DURATION_PLAN']);
                     }
                     $arChanges = CTaskLog::GetChanges($arTmp['arTask'], $arTmp['arFields']);
                     unset($arTmp);
                     foreach ($arChanges as $key => $value) {
                         $arLogFields = array("TASK_ID" => $ID, "USER_ID" => $occurAsUserId, "CREATED_DATE" => $arFields["CHANGED_DATE"], "FIELD" => $key, "FROM_VALUE" => $value["FROM_VALUE"], "TO_VALUE" => $value["TO_VALUE"]);
                         $log = new CTaskLog();
                         $log->Add($arLogFields);
                     }
                     if (isset($arFields["ACCOMPLICES"]) && isset($arChanges["ACCOMPLICES"])) {
                         CTaskMembers::DeleteByTaskID($ID, "A");
                         CTasks::AddAccomplices($ID, $arFields["ACCOMPLICES"]);
                     }
                     if (isset($arFields["AUDITORS"]) && isset($arChanges["AUDITORS"])) {
                         CTaskMembers::DeleteByTaskID($ID, "U");
                         CTasks::AddAuditors($ID, $arFields["AUDITORS"]);
                     }
                     if (isset($arFields["FILES"]) && (isset($arChanges["NEW_FILES"]) || isset($arChanges["DELETED_FILES"]))) {
                         $arNotDeleteFiles = $arFields["FILES"];
                         CTaskFiles::DeleteByTaskID($ID, $arNotDeleteFiles);
                         CTasks::AddFiles($ID, $arFields["FILES"], array('USER_ID' => $userID, 'CHECK_RIGHTS_ON_FILES' => $bCheckRightsOnFiles));
                     }
                     if (isset($arFields["TAGS"]) && isset($arChanges["TAGS"])) {
                         CTaskTags::DeleteByTaskID($ID);
                         CTasks::AddTags($ID, $arTask["CREATED_BY"], $arFields["TAGS"], $userID);
                     }
                     if (isset($arFields["DEPENDS_ON"]) && isset($arChanges["DEPENDS_ON"])) {
                         CTaskDependence::DeleteByTaskID($ID);
                         CTasks::AddPrevious($ID, $arFields["DEPENDS_ON"]);
                     }
                     if ($hasUfs) {
                         $USER_FIELD_MANAGER->Update("TASKS_TASK", $ID, $arFields, $userID);
                     }
                     // tasks dependence
                     if ($arParams['CORRECT_DATE_PLAN'] && $arParams['CORRECT_DATE_PLAN_DEPENDENT_TASKS'] && (isset($arFields["START_DATE_PLAN"]) || isset($arFields["END_DATE_PLAN"]))) {
                         if ($scheduler === null) {
                             $scheduler = new Scheduler($userID, $ID, $arTask);
                         }
                         $relatedTaskUpdate = $scheduler->reScheduleRelatedTasks();
                         if (is_array($relatedTaskUpdate)) {
                             $relatedUpdateParams = $arParams;
                             $relatedUpdateParams['CORRECT_DATE_PLAN'] = false;
                             // no self-correction
                             $relatedUpdateParams['CORRECT_DATE_PLAN_DEPENDENT_TASKS'] = false;
                             // no sub-correction
                             foreach ($relatedTaskUpdate as $relatedTaskId => $relatedTaskData) {
                                 $relatedTaskData['START_DATE_PLAN_STRUCT'] = $relatedTaskData['START_DATE_PLAN']->getTimeStruct();
                                 // as struct
                                 $relatedTaskData['END_DATE_PLAN_STRUCT'] = $relatedTaskData['END_DATE_PLAN']->getTimeStruct();
                                 // as struct
                                 $relatedTaskData['START_DATE_PLAN'] = $relatedTaskData['START_DATE_PLAN']->toString();
                                 // as string, not object
                                 $relatedTaskData['END_DATE_PLAN'] = $relatedTaskData['END_DATE_PLAN']->toString();
                                 // as string, not object
                                 $relatedTask = new CTasks();
                                 $relatedTask->update($relatedTaskId, $relatedTaskData, $relatedUpdateParams);
                                 $this->lastOperationResultData['SHIFT_RESULT'][$relatedTaskId] = $relatedTaskData;
                             }
                         }
                     }
                     $notifArFields = array_merge($arFields, array('CHANGED_BY' => $occurAsUserId));
                     if (($status = intval($arFields["STATUS"])) && $status > 0 && $status < 8 && (int) $arTask['STATUS'] !== (int) $arFields['STATUS']) {
                         if ($status == 7) {
                             $arTask["DECLINE_REASON"] = $arFields["DECLINE_REASON"];
                         }
                         CTaskNotifications::SendStatusMessage($arTask, $status, $notifArFields);
                     }
                     CTaskNotifications::SendUpdateMessage($notifArFields, $arTask, false, $arParams);
                     CTaskComments::onAfterTaskUpdate($ID, $arTask, $arFields);
                     $arFields["ID"] = $ID;
                     $arMergedFields = array_merge($arTask, $arFields);
                     CTaskSync::UpdateItem($arFields, $arTask);
                     // MS Exchange
                     $arFields['META:PREV_FIELDS'] = $arTask;
                     try {
                         $lastEventName = '';
                         foreach (GetModuleEvents('tasks', 'OnTaskUpdate', true) as $arEvent) {
                             $lastEventName = $arEvent['TO_CLASS'] . '::' . $arEvent['TO_METHOD'] . '()';
                             ExecuteModuleEventEx($arEvent, array($ID, &$arFields, &$arTaskCopy));
                         }
                     } catch (Exception $e) {
                         CTaskAssert::logWarning('[0xee8999a8] exception in module event: ' . $lastEventName . '; at file: ' . $e->getFile() . ':' . $e->getLine() . ";\n");
                     }
                     unset($arFields['META:PREV_FIELDS']);
                     // clear cache
                     static::addCacheIdToClear("tasks_" . $ID);
                     if ($arTask["GROUP_ID"]) {
                         static::addCacheIdToClear("tasks_group_" . $arTask["GROUP_ID"]);
                     }
                     if ($arFields['GROUP_ID'] && $arFields['GROUP_ID'] != $arTask['GROUP_ID']) {
                         static::addCacheIdToClear("tasks_group_" . $arFields["GROUP_ID"]);
                     }
                     foreach ($arParticipants as $userId) {
                         static::addCacheIdToClear("tasks_user_" . $userId);
                     }
                     static::clearCache();
                     if ($bWasFatalError) {
                         soundex('push&pull: bWasFatalError === true');
                     }
                     $this->previousData = $arTask;
                     return true;
                 }
             } else {
                 $e = $APPLICATION->GetException();
                 foreach ($e->messages as $msg) {
                     $this->_errors[] = $msg;
                 }
             }
         }
     }
     if (sizeof($this->_errors) == 0) {
         $this->_errors[] = array("text" => GetMessage("TASKS_UNKNOWN_UPDATE_ERROR"), "id" => "ERROR_UNKNOWN_UPDATE_TASK_ERROR");
     }
     return false;
 }