- Модуль: tasks
- Путь к файлу: ~/bitrix/modules/tasks/lib/util/replicator/task/fromtemplate.php
- Класс: BitrixTasksUtilReplicatorTaskFromTemplate
- Вызов: FromTemplate::produceSub
public function produceSub($source, $destination, array $parameters = array(), $userId = 0)
{
$result = new Result();
Template::enterBatchState();
$source = $this->getSourceInstance($source, $userId);
$destination = $this->getDestinationInstance($destination, $userId);
$created = new Collection();
$wereErrors = false;
$destinations = array(
$destination // root task
);
// in case of multitasking create several destinations
if($this->isMultitaskSource($source, $parameters))
{
// create duplicates of $destination for each sub-responsible
foreach($source['RESPONSIBLES'] as $responsibleId)
{
if($responsibleId == $destination['CREATED_BY'])
{
continue; // skip creator itself
}
$subResult = $this->saveItemFromSource($source, array(
'PARENT_ID' => $destination->getId(),
'RESPONSIBLE_ID' => $responsibleId,
), $userId);
if($subResult->isSuccess())
{
$destinations[] = $subResult->getInstance();
}
else
{
$wereErrors = true;
}
$created->push($subResult);
}
}
// now for each destination create sub-tasks according to the sub-templates, if any
$data = $this->getSubItemData($source->getId());
if (empty($data))
{
Template::leaveBatchState();
return $result;
}
$order = $this->getCreationOrder($data, $source->getId());
if(!$order)
{
$result->getErrors()->add('ILLEGAL_STRUCTURE.LOOP', Loc::getMessage('TASKS_REPLICATOR_SUBTREE_LOOP'));
}
else
{
// disable copying disk files for each sub-task
// todo: impove this later
$this->getConverter()->setConfig('UF.FILTER', array('!=USER_TYPE_ID' => 'disk_file'));
foreach($destinations as $destination)
{
//////////////////////////////
$src2dstId = array($source->getId() => $destination->getId());
$cTree = $order;
$walkQueue = array($source->getId());
while(!empty($walkQueue)) // walk sub-item tree
{
$topTemplate = array_shift($walkQueue);
if(is_array($cTree[$topTemplate] ?? null))
{
// create all sub template on that tree level
foreach($cTree[$topTemplate] as $template)
{
$dataMixin = array_merge(array(
'PARENT_ID' => $src2dstId[$topTemplate],
), $parameters);
$creationResult = $this->saveItemFromSource($data[$template], $dataMixin, $userId);
if($creationResult->isSuccess())
{
$walkQueue[] = $template; // walk further on that template
$src2dstId[$template] = $creationResult->getInstance()->getId();
}
else
{
$wereErrors = true;
$errors = $creationResult->getErrors();
$neededError = $errors->find(array('CODE' => 'ACCESS_DENIED.RESPONSIBLE_AND_ORIGINATOR_NOT_ALLOWED'));
if ($errors->count() == 1 && !$neededError->isEmpty())
{
$data[$template]['CREATED_BY'] = $userId;
$creationResult->getErrors()->clear();
$creationResult = $this->saveItemFromSource($data[$template], $dataMixin, $userId);
if ($creationResult->isSuccess())
{
$walkQueue[] = $template;
$src2dstId[$template] = $creationResult->getInstance()->getId();
$wereErrors = false;
}
}
}
$created->push($creationResult); // add sub-item creation result
}
}
unset($cTree[$topTemplate]);
}
//////////////////////////////
}
if($wereErrors)
{
$result->addError('SUB_ITEMS_CREATION_FAILURE', 'Some of the sub-tasks was not properly created');
}
$result->setData($created);
}
Template::leaveBatchState();
return $result;
}