private function proceedAction($actionId, $arActionArguments = null) { $actionId = (int) $actionId; if ($actionId == self::ACTION_ADD_FAVORITE || $actionId == self::ACTION_DELETE_FAVORITE || $actionId == self::ACTION_TOGGLE_FAVORITE) { if (!is_array($arActionArguments)) { $arActionArguments = array(); } $addChildren = true; if (array_key_exists('AFFECT_CHILDREN', $arActionArguments)) { $addChildren = $arActionArguments['AFFECT_CHILDREN'] == 'Y' || $arActionArguments['AFFECT_CHILDREN'] === true; } $tellSocnet = true; if (array_key_exists('TELL_SOCNET', $arActionArguments)) { $tellSocnet = $arActionArguments['TELL_SOCNET'] == 'Y' || $arActionArguments['TELL_SOCNET'] === true; } switch ($actionId) { case self::ACTION_ADD_FAVORITE: $f = 'add'; break; case self::ACTION_DELETE_FAVORITE: $f = 'delete'; break; default: $f = 'toggle'; break; } // ensure we have access to the task $this->checkCanReadThrowException(); // drop cache $this->markCacheAsDirty(); // here could be trouble: socnet doesn`t know anything aboult child tasks // in case of a ticket came, get all child tasks IDs here, pass ID list to \Bitrix\Tasks\Integration\Socialnetwork\Task::toggleFavorites() // and also pass ID list as a cache to FavoriteTable::$f to avoid calling same query twice $res = FavoriteTable::$f(array('TASK_ID' => $this->getId(), 'USER_ID' => $this->executiveUserId), array('AFFECT_CHILDREN' => $addChildren)); if (!$res->isSuccess()) { static::throwExceptionVerbose($res->getErrors()); } if ($actionId == self::ACTION_TOGGLE_FAVORITE) { $result = $res instanceof \Bitrix\Main\Entity\AddResult; $add = $result; } else { $result = true; $add = $actionId == self::ACTION_ADD_FAVORITE; } foreach (GetModuleEvents('tasks', 'OnTaskToggleFavorite', true) as $arEvent) { ExecuteModuleEventEx($arEvent, array($this->getId(), $this->executiveUserId, $add)); } if ($tellSocnet) { \Bitrix\Tasks\Integration\Socialnetwork\Task::toggleFavorites(array('TASK_ID' => $this->getId(), 'USER_ID' => $this->executiveUserId, 'OPERATION' => $add ? 'ADD' : 'DELETE')); } return $result; } $arTaskData = $this->getData($bSpecialChars = false); $arNewFields = null; if ($actionId == self::ACTION_REMOVE) { if (!$this->isActionAllowed(self::ACTION_REMOVE)) { throw new TasksException('', TasksException::TE_ACTION_NOT_ALLOWED | TasksException::TE_ACCESS_DENIED); } $this->markCacheAsDirty(); /** @noinspection PhpDeprecationInspection */ if (CTasks::Delete($this->taskId) !== true) { throw new TasksException('Cannot delete task ' . $this->taskId, TasksException::TE_ACTION_FAILED_TO_BE_PROCESSED); } return; } elseif ($actionId == self::ACTION_EDIT) { $this->lastOperationResultData['UPDATE'] = array(); $arFields = $arActionArguments['FIELDS']; $arParams = $arActionArguments['PARAMETERS']; if (!is_array($arParams)) { $arParams = array(); } if (isset($arFields['ID'])) { unset($arFields['ID']); } $arParams = array_merge($arParams, array('USER_ID' => $this->executiveUserId, 'CHECK_RIGHTS_ON_FILES' => true)); $actionChangeDeadlineFields = array('DEADLINE', 'START_DATE_PLAN', 'END_DATE_PLAN'); $arGivenFieldsNames = array_keys($arFields); if (array_key_exists('STATUS', $arFields) && !in_array((int) $arFields['STATUS'], array(CTasks::STATE_NEW, CTasks::STATE_PENDING, CTasks::STATE_IN_PROGRESS, CTasks::STATE_SUPPOSEDLY_COMPLETED, CTasks::STATE_COMPLETED, CTasks::STATE_DEFERRED, CTasks::STATE_DECLINED), true)) { throw new TasksException('Invalid status given', TasksException::TE_WRONG_ARGUMENTS); } if (array_key_exists('PRIORITY', $arFields) && !in_array((int) $arFields['PRIORITY'], array(CTasks::PRIORITY_LOW, CTasks::PRIORITY_AVERAGE, CTasks::PRIORITY_HIGH), true)) { throw new TasksException('Invalid priority given', TasksException::TE_WRONG_ARGUMENTS); } if (array_key_exists('CREATED_BY', $arFields) && !$this->isActionAllowed(self::ACTION_CHANGE_DIRECTOR)) { throw new TasksException('Access denied for field CREATED_BY to be updated', TasksException::TE_ACTION_NOT_ALLOWED); } if (array_diff($actionChangeDeadlineFields, $arGivenFieldsNames) && !$this->isActionAllowed(self::ACTION_CHANGE_DEADLINE)) { throw new TasksException('Access denied for field CREATED_BY to be updated', TasksException::TE_ACTION_NOT_ALLOWED); } // Get list of fields, except just checked above $arGeneralFields = array_diff($arGivenFieldsNames, array_merge($actionChangeDeadlineFields, array('CREATED_BY'))); // Is there is something more for update? if (!empty($arGeneralFields)) { if (!$this->isActionAllowed(self::ACTION_EDIT)) { throw new TasksException('Access denied for field CREATED_BY to be updated', TasksException::TE_ACTION_NOT_ALLOWED); } } $this->markCacheAsDirty(); $o = new CTasks(); /** @noinspection PhpDeprecationInspection */ if ($o->update($this->taskId, $arFields, $arParams) !== true) { $this->markCacheAsDirty(); static::throwExceptionVerbose($o->GetErrors()); } $this->markCacheAsDirty(); $this->lastOperationResultData['UPDATE'] = $o->getLastOperationResultData(); $prevData = $o->getPreviousData(); if ($arActionArguments['SUBTASKS_CHANGE_GROUP'] !== false && intval($prevData['GROUP_ID']) != intval($arFields['GROUP_ID'])) { $this->moveSubTasksToGroup($arFields['GROUP_ID']); } return; } switch ($actionId) { case self::ACTION_ACCEPT: $arNewFields['STATUS'] = CTasks::STATE_PENDING; break; case self::ACTION_DECLINE: $arNewFields['STATUS'] = CTasks::STATE_DECLINED; if (isset($arActionArguments['DECLINE_REASON'])) { $arNewFields['DECLINE_REASON'] = $arActionArguments['DECLINE_REASON']; } else { $arNewFields['DECLINE_REASON'] = ''; } break; case self::ACTION_COMPLETE: if ($arTaskData['TASK_CONTROL'] === 'N' || $arTaskData['CREATED_BY'] == $this->executiveUserId) { $arNewFields['STATUS'] = CTasks::STATE_COMPLETED; } else { $arNewFields['STATUS'] = CTasks::STATE_SUPPOSEDLY_COMPLETED; } break; case self::ACTION_APPROVE: $arNewFields['STATUS'] = CTasks::STATE_COMPLETED; break; case self::ACTION_START: $arNewFields['STATUS'] = CTasks::STATE_IN_PROGRESS; break; case self::ACTION_PAUSE: $arNewFields['STATUS'] = CTasks::STATE_PENDING; break; case self::ACTION_DELEGATE: $arNewFields['STATUS'] = CTasks::STATE_PENDING; if (!isset($arActionArguments['RESPONSIBLE_ID'])) { throw new TasksException('Expected $arActionArguments[\'RESPONSIBLE_ID\']', TasksException::TE_WRONG_ARGUMENTS); } $arNewFields['RESPONSIBLE_ID'] = $arActionArguments['RESPONSIBLE_ID']; if (isset($arTaskData['AUDITORS']) && count($arTaskData['AUDITORS'])) { if (!in_array($this->executiveUserId, $arTaskData['AUDITORS'])) { $arNewFields['AUDITORS'] = $arTaskData['AUDITORS']; $arNewFields['AUDITORS'][] = $this->executiveUserId; } } else { $arNewFields['AUDITORS'] = array($this->executiveUserId); } break; case self::ACTION_DEFER: $arNewFields['STATUS'] = CTasks::STATE_DEFERRED; break; case self::ACTION_DISAPPROVE: case self::ACTION_RENEW: $arNewFields['STATUS'] = CTasks::STATE_PENDING; break; default: break; } if ($arNewFields === null) { throw new TasksException(); } // Don't update task, if nothing changed $bNeedUpdate = false; foreach ($arNewFields as $fieldName => $newValue) { $curValue = $arTaskData[$fieldName]; // Convert task data arrays to strings, for comparing if (is_array($curValue)) { sort($curValue); sort($newValue); $curValue = implode('|', $curValue); $newValue = implode('|', $newValue); } if ($curValue != $newValue) { $bNeedUpdate = true; break; } } if ($bNeedUpdate) { if (!$this->isActionAllowed($actionId)) { throw new TasksException('', TasksException::TE_ACTION_NOT_ALLOWED | TasksException::TE_ACCESS_DENIED); } $arParams = array('USER_ID' => $this->executiveUserId); $this->markCacheAsDirty(); $o = new CTasks(); /** @noinspection PhpDeprecationInspection */ if ($o->Update($this->taskId, $arNewFields, $arParams) !== true) { throw new TasksException('', TasksException::TE_ACTION_FAILED_TO_BE_PROCESSED); } } }