• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/classes/general/taskitem.php
  • Класс: CTaskItem
  • Вызов: CTaskItem::addByTemplate
static function addByTemplate($templateId, $executiveUserId, $overrideTaskData = array(), $parameters = array(
	'TEMPLATE_DATA' => array(),
	'CREATE_CHILD_TASKS' => true,
	'CREATE_MULTITASK' => true,

	'BEFORE_ADD_CALLBACK' => null,
	'SPAWNED_BY_AGENT' => false
))
{
	CTaskAssert::assertLaxIntegers($executiveUserId);
	CTaskAssert::assert($executiveUserId > 0);

	$templateId = (int) $templateId;
	if ( ! $templateId )
	{
		return array();	// template id not set
	}

	if(!is_array($overrideTaskData))
		$overrideTaskData = array();

	if(!is_array($parameters))
		$parameters = array();
	if(!isset($parameters['CREATE_CHILD_TASKS']))
		$parameters['CREATE_CHILD_TASKS'] = true;
	if(!isset($parameters['CREATE_MULTITASK']))
		$parameters['CREATE_MULTITASK'] = true;
	if(!isset($parameters['BEFORE_ADD_CALLBACK']))
		$parameters['BEFORE_ADD_CALLBACK'] = null;
	if(!isset($parameters['SPAWNED_BY_AGENT']))
		$parameters['SPAWNED_BY_AGENT'] = false;

	// read template data

	if(is_array($parameters['TEMPLATE_DATA']) && !empty($parameters['TEMPLATE_DATA']))
	{
		$arTemplate = $parameters['TEMPLATE_DATA'];
	}
	else
	{
		$arFilter   = array('ID' => $templateId);
		$rsTemplate = CTaskTemplates::GetList(array(), $arFilter, array(), array(), array('*', 'UF_*'));
		$arTemplate = $rsTemplate->Fetch();

		if ( ! $arTemplate )
		{
			return array();	// nothing to do
		}
	}

	$arTemplate = array_merge($arTemplate, $overrideTaskData);

	$checkListItems = TemplateCheckListFacade::getByEntityId($templateId);
	$arTemplate['CHECK_LIST'] = array_map(
		static function($item)
		{
			$item['COPIED_ID'] = $item['ID'];
			unset($item['ID']);
			return $item;
		},
		$checkListItems
	);

	//////////////////////////////////////////////
	//////////////////////////////////////////////
	//////////////////////////////////////////////

	unset($arTemplate['STATUS'], $arTemplate['SCENARIO']);

	$userTime = BitrixTasksUtilUser::getTime();

	$arFields = $arTemplate;

	$arFields['CREATED_DATE'] = BitrixTasksUI::formatDateTime($userTime);
	$arFields['ACCOMPLICES'] = unserialize($arFields['ACCOMPLICES'], ['allowed_classes' => false]);
	$arFields['AUDITORS'] = unserialize($arFields['AUDITORS'], ['allowed_classes' => false]);
	$arFields['TAGS'] = unserialize($arFields['TAGS'], ['allowed_classes' => false]);
	$arFields['FILES'] = unserialize($arFields['FILES'], ['allowed_classes' => false]);
	$arFields['DEPENDS_ON'] = unserialize($arFields['DEPENDS_ON'], ['allowed_classes' => false]);
	$arFields['REPLICATE'] = 'N';
	$arFields['CHANGED_BY'] = $arFields['CREATED_BY'];
	$arFields['CHANGED_DATE'] = $arFields['CREATED_DATE'];
	$arFields['ACTIVITY_DATE'] = $arFields['CREATED_DATE'];

	if ( ! $arFields['ACCOMPLICES'] )
	{
		$arFields['ACCOMPLICES'] = array();
	}

	if ( ! $arFields['AUDITORS'] )
	{
		$arFields['AUDITORS'] = array();
	}

	unset($arFields['ID'], $arFields['REPLICATE'], $arFields['REPLICATE_PARAMS']);

	$datePlanValues = array('DEADLINE', 'START_DATE_PLAN', 'END_DATE_PLAN');
	foreach ($datePlanValues as $value)
	{
		if ($arTemplate[$value.'_AFTER'])
		{
			$newValue = $userTime + $arTemplate[$value.'_AFTER'];
			$arFields[$value] = BitrixTasksUI::formatDateTime($newValue);
		}
	}

	$multitaskMode = false;
	if($parameters['CREATE_MULTITASK'])
	{
		$arFields['RESPONSIBLES'] = unserialize($arFields['RESPONSIBLES'], ['allowed_classes' => false]);

		// copy task to multiple responsibles
		if ($arFields['MULTITASK'] == 'Y' && !empty($arFields['RESPONSIBLES']))
		{
			$arFields['RESPONSIBLE_ID'] = $arFields['CREATED_BY'];
			$multitaskMode = true;
		}
		else
		{
			$arFields['RESPONSIBLES'] = array();
		}
	}
	else
	{
		$arFields['MULTITASK'] = 'N';
		$arFields['RESPONSIBLES'] = array();
	}

	$arFields['FORKED_BY_TEMPLATE_ID'] = $templateId;

	// add main task to the create list
	$tasksToCreate = array(
		$arFields
	);

	// if MULTITASK where set to Y, create a duplicate task for each of RESPONSIBLES
	if (!empty($arFields['RESPONSIBLES']))
	{
		$arFields['MULTITASK'] = 'N';

		foreach ($arFields['RESPONSIBLES'] as $responsible)
		{
			$arFields['RESPONSIBLE_ID'] = $responsible;
			$tasksToCreate[] = $arFields;
		}
	}

	// get sub-templates
	$subTasksToCreate = array();
	if($parameters['CREATE_CHILD_TASKS'] !== false)
	{
		$subTasksToCreate = static::getChildTemplateData($templateId);
	}

	$created = array();

	// first, create ROOT tasks
	$multitaskTaskId = false;
	$i = 0;
	foreach($tasksToCreate as $arFields)
	{
		if($multitaskMode && $i > 0) // assign parent
		{
			if($multitaskTaskId)
			{
				// all following tasks will be subtasks of a base task in case of MULTITASK was turned on
				$arFields['PARENT_ID'] = $multitaskTaskId;
			}
			else
			{
				break; // no child tasks will be created, because parent task failed to be created
			}
		}

		$add = true;
		if(is_callable($parameters['BEFORE_ADD_CALLBACK']))
		{
			$result = call_user_func_array($parameters['BEFORE_ADD_CALLBACK'], array(&$arFields));
			if($result === false)
			{
				$add = false;
			}
		}

		if($add)
		{
			$taskId = 0;
			try
			{
				$task = static::add($arFields, $executiveUserId, array(
					'SPAWNED_BY_AGENT' => !!$parameters['SPAWNED_BY_AGENT'],
					'CLONE_DISK_FILE_ATTACHMENT' => true
				));
				$taskId = $task->getId();
			}
			catch(Exception $e)
			{
			}

			if ($taskId)
			{
				$commentPoster = CommentPoster::getInstance($taskId, $executiveUserId);
				$commentPoster->enableDeferredPostMode();
				$commentPoster->clearComments();

				// increase replication count of our template
				if ($i === 0 && (bool)$parameters['SPAWNED_BY_AGENT'])
				{
					$templateInstance = new CTaskTemplates();
					$templateInstance->update($templateId, [
						'TPARAM_REPLICATION_COUNT' => (int)$arTemplate['TPARAM_REPLICATION_COUNT'] + 1,
					]);
				}

				// the first task should be mom in case of multitasking
				if ($i === 0 && $multitaskMode)
				{
					$multitaskTaskId = $taskId;
				}

				$checkListRoots = TaskCheckListFacade::getObjectStructuredRoots(
					$arTemplate['CHECK_LIST'],
					$taskId,
					$executiveUserId
				);
				foreach ($checkListRoots as $root)
				{
					/** @var CheckList $root */
					$root->save();
				}

				$taskInstance = static::getInstance($taskId, $executiveUserId);
				$created[$taskId] = $taskInstance;

				if(!empty($subTasksToCreate))
				{
					$notifADWasDisabled = CTaskNotifications::disableAutoDeliver();

					$createdSubtasks = $taskInstance->addChildTasksByTemplate($templateId, array(
						'CHILD_TEMPLATE_DATA' =>	$subTasksToCreate,

						// transfer some parameters
						'BEFORE_ADD_CALLBACK' =>	$parameters['BEFORE_ADD_CALLBACK'],
						'SPAWNED_BY_AGENT' =>		$parameters['SPAWNED_BY_AGENT'],
					));

					if($notifADWasDisabled)
					{
						CTaskNotifications::enableAutoDeliver();
					}

					if(is_array($createdSubtasks) && !empty($createdSubtasks))
					{
						foreach($createdSubtasks as $ctId => $ctInst)
						{
							$created[$ctId] = $ctInst;
						}
					}
				}
			}
		}

		$i++;
	}

	return $created;
}