• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/util/replicator/task/fromtemplate.php
  • Класс: BitrixTasksUtilReplicatorTaskFromTemplate
  • Вызов: FromTemplate::getNextTime
static function getNextTime(array $templateData, $agentTime = false, $nowTime = false)
{
	$result = new UtilResult();

	if (!is_array($templateData['REPLICATE_PARAMS']))
	{
		$templateData['REPLICATE_PARAMS'] = array();
	}
	$arParams = CTaskTemplates::parseReplicationParams($templateData['REPLICATE_PARAMS']); // todo: replace with just $template['REPLICATE_PARAMS']

	// get users and their time zone offsets
	$currentTimeZoneOffset = User::getTimeZoneOffsetCurrentUser(); // set 0 to imitate working on agent

	if (isset($arParams['TIMEZONE_OFFSET']))
	{
		$creatorTimeZoneOffset = $arParams['TIMEZONE_OFFSET'];
	}
	else
	{
		$creatorTimeZoneOffset = User::getTimeZoneOffset($templateData['CREATED_BY']);
	}

	// prepare time to be forced to
	$creatorPreferredTime = UI::parseTimeAmount(date("H:i", strtotime($arParams["TIME"]) - $creatorTimeZoneOffset), 'HH:MI');

	// prepare base time
	$baseTime = time(); // server time
	if ($nowTime)
	{
		$nowTime = MakeTimeStamp($nowTime); // from string to stamp
		if ($nowTime) // time parsed normally
		{
			// $agentTime is in current user`s time, but we want server time here
			$nowTime -= $currentTimeZoneOffset;
			$baseTime = $nowTime;
		}
	}

	if ($agentTime) // agent were found and had legal next_time
	{
		$agentTime = MakeTimeStamp($agentTime); // from string to stamp
		if ($agentTime) // time parsed normally
		{
			// $agentTime is in current user`s time, but we want server time here
			$agentTime -= $currentTimeZoneOffset;
			$baseTime = $agentTime;
		}
	}

	// prepare time limits
	$startTime = 0;
	if ($arParams["START_DATE"])
	{
		$startTime = MakeTimeStamp($arParams["START_DATE"]); // from string to stamp
		$startTime -= $creatorTimeZoneOffset;
	}

	$endTime = PHP_INT_MAX; // never ending
	if ($arParams["END_DATE"])
	{
		$endTime = MakeTimeStamp($arParams["END_DATE"]); // from string to stamp
		$endTime -= $creatorTimeZoneOffset;
	}

	// now get max of dates and add time
	$baseTime = max($baseTime, $startTime);

	// now calculate next time based on current $baseTime

	$arPeriods = array("daily", "weekly", "monthly", "yearly");
	$arOrdinals = array("first", "second", "third", "fourth", "last");
	$arWeekDays = array("mon", "tue", "wed", "thu", "fri", "sat", "sun");
	$type = in_array($arParams["PERIOD"], $arPeriods) ? $arParams["PERIOD"] : "daily";

	$nextTime = 0;
	switch ($type)
	{
		case "daily":
			$nextTime = static::getDailyDate($baseTime, $arParams, $creatorPreferredTime);
			break;

		case "weekly":
			$nextTime = static::getWeeklyDate($baseTime, $arParams, $creatorPreferredTime);
			break;

		case "monthly":
			$nextTime = static::getMonthlyDate($baseTime, $arParams, $creatorPreferredTime, $arOrdinals, $arWeekDays);
			break;

		case "yearly":
			$nextTime = static::getYearlyDate($baseTime, $arParams, $creatorPreferredTime, $arOrdinals, $arWeekDays);
			break;
	}

	// now check if we can proceed
	$proceed = false;

	if ($nextTime)
	{
		$proceed = true;

		// about end date
		if (array_key_exists("REPEAT_TILL", $arParams) && $arParams['REPEAT_TILL'] != 'endless')
		{
			if ($arParams['REPEAT_TILL'] == 'date')
			{
				$proceed = !($endTime && $nextTime > $endTime);

				if (!$proceed)
				{
					$result->addError('STOP_CONDITION.END_DATE_REACHED', Loc::getMessage('TASKS_REPLICATOR_END_DATE_REACHED'));
				}
			}
			elseif ($arParams['REPEAT_TILL'] == 'times' && $templateData)
			{
				$proceed = intval($templateData['TPARAM_REPLICATION_COUNT']) < intval($arParams['TIMES']);

				if (!$proceed)
				{
					$result->addError('STOP_CONDITION.LIMIT_REACHED', Loc::getMessage('TASKS_REPLICATOR_LIMIT_REACHED'));
				}
			}
		}
	}
	else // $nextTime was not calculated
	{
		if ($result->getErrors()->isEmpty())
		{
			$result->addError('STOP_CONDITION.ILLEGAL_NEXT_TIME', Loc::getMessage('TASKS_REPLICATOR_ILLEGAL_NEXT_TIME'));
		}
	}

	// to current time zone if we can proceed
	if ($proceed)
	{
		$nextTime += $currentTimeZoneOffset;
	}
	else
	{
		$nextTime = 0;
	}

	$result->setData(array(
		'TIME' => ($nextTime? UI::formatDateTime($nextTime) : '')
	));

	return $result;
}