• Модуль: rest
  • Путь к файлу: ~/bitrix/modules/rest/lib/api/placement.php
  • Класс: BitrixRestApiPlacement
  • Вызов: Placement::bind
static function bind($params, $n, CRestServer $server)
{
	static::checkPermission($server);

	$params = array_change_key_case($params, CASE_UPPER);

	$placement = toUpper($params['PLACEMENT']);
	$placementHandler = $params['HANDLER'];

	if($placement == '')
	{
		throw new ArgumentNullException("PLACEMENT");
	}

	if($placement == PlacementTable::PLACEMENT_DEFAULT)
	{
		throw new ArgumentException("Wrong value", "PLACEMENT");
	}

	if($placementHandler == '')
	{
		throw new ArgumentNullException("HANDLER");
	}

	$appInfo = static::getApplicationInfo($server);
	HandlerHelper::checkCallback($placementHandler, $appInfo);

	$scopeList = static::getScope($server);
	$scopeList[] = CRestUtil::GLOBAL_SCOPE;

	$placementList = static::getPlacementList($server, $scopeList);
	$placementInfo = $placementList[$placement];

	if (is_array($placementInfo) && (!isset($placementInfo['private']) || !$placementInfo['private']))
	{
		$placementLangList = [];
		$paramsOptions = $params['OPTIONS'] ?? [];
		$placementInfoOptions = $placementInfo['options'] ?? [];

		$placementBind = array(
			'APP_ID' => $appInfo['ID'],
			'USER_ID' => (isset($params['USER_ID']) && (int)$params['USER_ID'] > 0) ? (int)$params['USER_ID'] : PlacementTable::DEFAULT_USER_ID_VALUE,
			'PLACEMENT' => $placement,
			'PLACEMENT_HANDLER' => $placementHandler,
			'OPTIONS' => static::prepareOptions($paramsOptions, $placementInfoOptions),
		);

		if (
			$placementBind['USER_ID'] !== PlacementTable::DEFAULT_USER_ID_VALUE
			&& $placementInfo['user_mode'] !== true
		)
		{
			throw new RestException(
				'User mode is not available.',
				PlacementTable::ERROR_PLACEMENT_USER_MODE
			);
		}

		$langList = Lang::listLanguage();
		$langDefault = reset($langList);

		if (empty($params['LANG_ALL']))
		{
			if (!empty($params['TITLE']))
			{
				$placementLangList[$langDefault]['TITLE'] = trim($params['TITLE']);
			}

			if (!empty($params['DESCRIPTION']))
			{
				$placementLangList[$langDefault]['DESCRIPTION'] = trim($params['DESCRIPTION']);
			}

			if (!empty($params['GROUP_NAME']))
			{
				$placementLangList[$langDefault]['GROUP_NAME'] = trim($params['GROUP_NAME']);
			}
		}
		else
		{
			$fieldList = [
				'TITLE',
				'DESCRIPTION',
				'GROUP_NAME',
			];
			foreach ($params['LANG_ALL'] as $langCode => $langItem)
			{
				foreach ($fieldList as $field)
				{
					$placementLangList[$langCode][$field] = trim($langItem[$field] ?? '');
				}
			}
		}

		$placementBind['LANG_ALL'] = $placementLangList;
		$placementBind = Lang::mergeFromLangAll($placementBind);
		unset($placementBind['LANG_ALL']);

		if ($placementInfo['max_count'] > 0)
		{
			$filter = [
				'=APP_ID' => $placementBind['APP_ID'],
				'=PLACEMENT' => $placementBind['PLACEMENT'],
			];
			if ($placementInfo['user_mode'] === true)
			{
				$filter['=USER_ID'] = [
					PlacementTable::DEFAULT_USER_ID_VALUE,
					(int)$placementBind['USER_ID'],
				];
			}

			$res = PlacementTable::getList(
				[
					'filter' => $filter,
					'select' => [
						'COUNT',
					],
					'runtime' => [
						new ExpressionField('COUNT', 'COUNT(*)'),
					]
				]
			);

			if ($result = $res->fetch())
			{
				if ($result['COUNT'] >= $placementInfo['max_count'])
				{
					throw new RestException(
						'Placement max count: ' . $placementInfo['max_count'],
						PlacementTable::ERROR_PLACEMENT_MAX_COUNT
					);
				}
			}
		}

		if (
			array_key_exists('ICON', $params)
			&& is_array($params['ICON'])
			&& $params['ICON']['fileData']
			&& ($file = CRestUtil::saveFile($params['ICON']['fileData']))
		)
		{
			$placementBind['ICON'] = $file;
		}
		if (!empty($placementInfo['registerCallback']['callback']))
		{
			if (
				$placementInfo['registerCallback']['moduleId']
				&& Loader::includeModule($placementInfo['registerCallback']['moduleId'])
				&& is_callable($placementInfo['registerCallback']['callback'])
			)
			{
				$resultCallback = call_user_func(
					$placementInfo['registerCallback']['callback'],
					$placementBind,
					$placementInfo
				);
				if (!empty($resultCallback['error']) && !empty($resultCallback['error_description']))
				{
					return $resultCallback;
				}
			}
		}

		$result = PlacementTable::add($placementBind);
		if ($result->isSuccess())
		{
			$placementId = $result->getId();
			if (empty($placementLangList))
			{
				$app = AppTable::getByClientId($placementBind['APP_ID']);
				if (!empty($app['APP_NAME']))
				{
					$placementLangList[$langDefault] = [
						'TITLE' => $app['APP_NAME']
					];
				}
			}
			foreach ($placementLangList as $langId => $data)
			{
				$data['PLACEMENT_ID'] = $placementId;
				$data['LANGUAGE_ID'] = $langId;
				$res = PlacementLangTable::add($data);
				if (!$res->isSuccess())
				{
					$errorMessage = $res->getErrorMessages();
					throw new RestException(
						'Unable to set placements language: ' . implode(', ', $errorMessage),
						RestException::ERROR_CORE
					);
				}
			}
		}
		else
		{
			$errorMessage = $result->getErrorMessages();
			throw new RestException(
				'Unable to set placement handler: ' . implode(', ', $errorMessage),
				RestException::ERROR_CORE
			);
		}

		return true;
	}

	throw new RestException(
		'Placement not found',
		PlacementTable::ERROR_PLACEMENT_NOT_FOUND
	);
}