Your IP : 3.139.108.124


Current Path : /home/bitrix/ext_www/dev.klimatlend.ua/bitrix/modules/rest/classes/general/
Upload File :
Current File : /home/bitrix/ext_www/dev.klimatlend.ua/bitrix/modules/rest/classes/general/rest_provider.php

<?
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Entity;
use Bitrix\Main\Loader;
use Bitrix\Rest\RestException;
use Bitrix\Rest\AccessException;
use Bitrix\OAuth;

class CRestProvider
	extends \IRestService
{
	const ERROR_BATCH_LENGTH_EXCEEDED = 'ERROR_BATCH_LENGTH_EXCEEDED';
	const ERROR_BATCH_METHOD_NOT_ALLOWED = 'ERROR_BATCH_METHOD_NOT_ALLOWED';

	// default license shown instead of absent or unknown
	const LICENSE_DEFAULT = "project";

	// controller group id => rest license id
	protected static $licenseList = array(
		"project" => "project",
		"corporation" => "corporation",
		"company" => "company",
		"team" => "team",
		"demo" => "demo",
		"nfr" => "nfr",
		"tf" => "tf",
		"crm" => "crm",
	);

	protected static $arApp = null;
	protected static $arScope = null;
	protected static $arMethodsList = null;

	public function getDescription()
	{
		if(!is_array(self::$arMethodsList))
		{
			$globalMethods = array(
				\CRestUtil::GLOBAL_SCOPE => array(
					'batch' => array(__CLASS__, 'methodsBatch'),

					'scope' => array(__CLASS__, 'scopeList'),
					'methods' => array(__CLASS__, 'methodsList'),

					'server.time' => array(__CLASS__, 'getServerTime'),
				),
			);

			$ownMethods = array(
				\CRestUtil::GLOBAL_SCOPE => array(
					'app.info' => array(__CLASS__, 'appInfo'),

					'app.option.get' => array(__CLASS__, 'appOptionGet'),
					'app.option.set' => array(__CLASS__, 'appOptionSet'),
					'user.option.get' => array(__CLASS__, 'userOptionGet'),
					'user.option.set' => array(__CLASS__, 'userOptionSet'),

					\CRestUtil::EVENTS => array(
						'OnAppUninstall' => array(
							'rest',
							'OnRestAppDelete',
							array(__CLASS__, 'OnAppEvent'),
							array(
								"sendAuth" => false,
								"category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT,
							)
						),
						'OnAppInstall' => array(
							'rest',
							'OnRestAppInstall',
							array(__CLASS__, 'OnAppEvent'),
							array(
								"sendRefreshToken" => true,
								"category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT,
							)
						),
						'OnAppUpdate' => array(
							'rest',
							'OnRestAppUpdate',
							array(__CLASS__, 'OnAppEvent'),
							array(
								"sendRefreshToken" => true,
								"category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT,
							)
						),
						'OnAppPayment' => array(
							'bitrix24',
							'OnAfterAppPaid',
							array(__CLASS__, 'OnAppPayment'),
							array(
								"category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT,
							)
						),
						'OnAppTest' => array(
							'rest',
							'OnRestAppTest',
							array(__CLASS__, 'OnAppEvent'),
							array(
								"sendRefreshToken" => true,
							)
						),
						'OnAppMethodConfirm' => array(
							'rest',
							'OnRestAppMethodConfirm',
							array(__CLASS__, 'OnAppEvent'),
							array(
								"sendAuth" => false,
								"category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT,
							)
						),
					),
				),
			);

			$arDescription = array();

			foreach(GetModuleEvents("rest", "OnRestServiceBuildDescription", true) as $arEvent)
			{
				$res = ExecuteModuleEventEx($arEvent);
				if(is_array($res))
				{
					$arDescription = array_merge_recursive($res, $arDescription);
				}
			}

			self::$arMethodsList = array_merge_recursive(
				$globalMethods,
				$ownMethods,
				$arDescription
			);

			if(!array_key_exists('profile', self::$arMethodsList[\CRestUtil::GLOBAL_SCOPE]))
			{
				self::$arMethodsList[\CRestUtil::GLOBAL_SCOPE]['profile'] = array(
					'callback' => array(__CLASS__, 'getProfile'),
					'options' => array(),
				);
			}

			array_change_key_case(self::$arMethodsList, CASE_LOWER);

			foreach (self::$arMethodsList as $scope => $arScopeMethods)
			{
				self::$arMethodsList[$scope] = array_change_key_case(self::$arMethodsList[$scope], CASE_LOWER);
				if(
					array_key_exists(\CRestUtil::EVENTS, self::$arMethodsList[$scope])
					&& is_array(self::$arMethodsList[$scope][\CRestUtil::EVENTS])
				)
				{
					self::$arMethodsList[$scope][\CRestUtil::EVENTS] = array_change_key_case(self::$arMethodsList[$scope][\CRestUtil::EVENTS], CASE_UPPER);
				}
				if(
					array_key_exists(\CRestUtil::PLACEMENTS, self::$arMethodsList[$scope])
					&& is_array(self::$arMethodsList[$scope][\CRestUtil::PLACEMENTS])
				)
				{
					self::$arMethodsList[$scope][\CRestUtil::PLACEMENTS] = array_change_key_case(self::$arMethodsList[$scope][\CRestUtil::PLACEMENTS], CASE_UPPER);
				}
			}
		}

		return self::$arMethodsList;
	}

	public static function getProfile($params, $n, \CRestServer $server)
	{
		global $USER;

		if(!$USER->isAuthorized())
		{
			throw new \Bitrix\Rest\AccessException("User authorization required");
		}

		$dbRes = CUser::getById($USER->getId());
		$userInfo = $dbRes->fetch();

		$result = array();

		if($userInfo['ACTIVE'] == 'Y')
		{
			$result = array(
				'ID' => $userInfo['ID'],
				'ADMIN' => \CRestUtil::isAdmin(),
				'NAME' => $userInfo['NAME'],
				'LAST_NAME' => $userInfo['LAST_NAME'],
				'PERSONAL_GENDER' => $userInfo['PERSONAL_GENDER'],
			);

			if($userInfo['PERSONAL_PHOTO'] > 0)
			{
				$result['PERSONAL_PHOTO'] = \CRestUtil::GetFile($userInfo["PERSONAL_PHOTO"]);
			}

			$result['TIME_ZONE'] = $userInfo['TIME_ZONE'];
			$result['TIME_ZONE_OFFSET'] = $userInfo['TIME_ZONE_OFFSET'] + date('Z');

			$securityState = array(
				"ID" => $result['ID'],
				"NAME" => $result['NAME'],
				"LAST_NAME" => $result['LAST_NAME'],
			);

			$server->setSecurityState($securityState);
		}

		return $result;
	}


	public static function methodsBatch($arQuery, $start, \CRestServer $server)
	{
		$arQuery = array_change_key_case($arQuery, CASE_UPPER);

		$bHalt = (bool)$arQuery['HALT'];

		$arResult = array(
			'result' => array(),
			'next' => array(),
			'total' => array(),
			'time' => array(),
			'error' => array(),
		);
		if(isset($arQuery['CMD']))
		{
			$cnt = 0;

			$authData = $server->getAuth();
			foreach ($arQuery['CMD'] as $key => $call)
			{
				if(($cnt++) < \CRestUtil::BATCH_MAX_LENGTH)
				{
					$queryData = parse_url($call);

					$method = $queryData['path'];
					$query = $queryData['query'];

					$arParams = \CRestUtil::ParseBatchQuery($query, $arResult);

					if($method === \CRestUtil::METHOD_DOWNLOAD || $method === \CRestUtil::METHOD_UPLOAD)
					{
						$res = array('error' => self::ERROR_BATCH_METHOD_NOT_ALLOWED, 'error_description' => 'Method is not allowed for batch usage');
					}
					else
					{
						if(is_array($authData))
						{
							foreach($authData as $authParam => $authValue)
							{
								$arParams[$authParam] = $authValue;
							}
						}

						$pseudoServer = new \CRestServerBatchItem(array(
							'CLASS' => __CLASS__,
							'METHOD' => $method,
							'QUERY' => $arParams
						));
						$pseudoServer->setApplicationId($server->getClientId());
						$pseudoServer->setAuthKeys(array_keys($authData));
						$pseudoServer->setAuthData($server->getAuthData());
						$pseudoServer->setAuthType($server->getAuthType());

						$res = $pseudoServer->process();

						unset($pseudoServer);
					}
				}
				else
				{

					$res = array('error' => self::ERROR_BATCH_LENGTH_EXCEEDED, 'error_description' => 'Max batch length exceeded');
				}

				if(is_array($res))
				{
					if(isset($res['error']))
					{
						$res['error'] = $res;
					}

					foreach ($res as $k=>$v)
					{
						$arResult[$k][$key] = $v;
					}
				}

				if($res['error'] && $bHalt)
				{
					break;
				}
			}
		}

		return array(
			'result' => $arResult['result'],
			'result_error' => $arResult['error'],
			'result_total' => $arResult['total'],
			'result_next' => $arResult['next'],
			'result_time' => $arResult['time'],
		);
	}

	public static function scopeList($arQuery, $n, \CRestServer $server)
	{
		$arQuery = array_change_key_case($arQuery, CASE_UPPER);

		if($arQuery['FULL'] == true)
		{
			$arScope = \CRestUtil::getScopeList(self::getDescription());
		}
		else
		{
			$arScope = self::getScope($server);
		}

		return $arScope;
	}

	public static function methodsList($arQuery, $n, \CRestServer $server)
	{
		$arMethods = self::getDescription();
		$arScope = array(\CRestUtil::GLOBAL_SCOPE);
		$arResult = array();

		$arQuery = array_change_key_case($arQuery, CASE_UPPER);

		if(isset($arQuery['SCOPE']))
		{
			if($arQuery['SCOPE'] != '')
				$arScope = array($arQuery['SCOPE']);
		}
		elseif($arQuery['FULL'] == true)
		{
			$arScope = array_keys($arMethods);
		}
		else
		{
			$arScope = self::getScope($server);
			$arScope[] = \CRestUtil::GLOBAL_SCOPE;
		}

		foreach ($arMethods as $scope => $arScopeMethods)
		{
			if(in_array($scope, $arScope))
			{
				unset($arScopeMethods[\CRestUtil::METHOD_DOWNLOAD]);
				unset($arScopeMethods[\CRestUtil::METHOD_UPLOAD]);
				unset($arScopeMethods[\CRestUtil::EVENTS]);
				unset($arScopeMethods[\CRestUtil::PLACEMENTS]);

				foreach($arScopeMethods as $method => $methodDesc)
				{
					if(isset($methodDesc["options"]) && $methodDesc["options"]["private"] === true)
					{
						unset($arScopeMethods[$method]);
					}
				}

				$arResult = array_merge($arResult, array_keys($arScopeMethods));
			}
		}

		return $arResult;
	}




	public static function appInfo($params, $n, \CRestServer $server)
	{
		if(\Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24'))
		{
			$licenseInfo = COption::GetOptionString("main", "~controller_group_name");

			list($lang, $licenseName, $additional) = explode("_", $licenseInfo, 3);

			if(!array_key_exists($licenseName, static::$licenseList))
			{
				$licenseName = static::LICENSE_DEFAULT;
			}

			if(!$lang)
			{
				$lang = LANGUAGE_ID;
			}

			$license = $lang."_".static::$licenseList[$licenseName];
		}
		else
		{
			$license = LANGUAGE_ID.'_selfhosted';
		}

		if($server->getClientId())
		{
			$arApp = self::getApp($server);

			$info = \Bitrix\Rest\AppTable::getAppStatusInfo($arApp, '');

			$res = array(
				'ID' => $arApp['ID'],
				'CODE' => $arApp['CODE'],
				'VERSION' => intval($arApp['VERSION']),
				'STATUS' => $info['STATUS'],
				'INSTALLED' => $arApp['INSTALLED'] == \Bitrix\Rest\AppTable::INSTALLED,
				'PAYMENT_EXPIRED' => $info['PAYMENT_EXPIRED'],
				'DAYS' => $info['DAYS_LEFT'],
				'LICENSE' => $license,
				'LANGUAGE_ID' => \CRestUtil::getLanguage(),
			);

			$server->setSecurityState($res);
		}
		elseif($server->getPasswordId())
		{
			$res = array(
				'SCOPE' => static::getScope($server),
				'LICENSE' => $license,
			);
		}
		else
		{
			throw new AccessException("Application context required");
		}

		foreach(GetModuleEvents('rest', 'OnRestAppInfo', true) as $event)
		{
			$eventData = ExecuteModuleEventEx($event, array($server, &$res));
			if(is_array($eventData))
			{
				if(!isset($res['ADDITIONAL']))
				{
					$res['ADDITIONAL'] = array();
				}

				$res['ADDITIONAL'] = array_merge($res['ADDITIONAL'], $eventData);
			}
		}

		return $res;
	}

	/**
	 * Gets application option values
	 *
	 * @param array $params array([option => option_name])
	 * @param int $n Standard pagination param
	 * @param CRestServer $server Standard Server object link
	 *
	 * @return array|mixed|null|string
	 *
	 * @throws AccessException
	 * @throws ArgumentNullException
	 */
	public static function appOptionGet($params, $n, \CRestServer $server)
	{
		global $USER;

		if(!$server->getClientId())
		{
			throw new AccessException("Application context required");
		}

		if(!$USER->IsAuthorized())
		{
			throw new AccessException("User authorization required");
		}

		$appOptions = Option::get("rest", "options_".$server->getClientId(), "");

		if(strlen($appOptions) > 0)
		{
			$appOptions = unserialize($appOptions);
		}
		else
		{
			$appOptions = array();
		}

		if(isset($params['option']))
		{
			return isset($appOptions[$params['option']]) ? $appOptions[$params['option']] : null;
		}
		else
		{
			return $appOptions;
		}
	}

	/**
	 * Sets application options values
	 *
	 * @param array $params array(option_name => option_value) || array(options => array(option_name => option_value,....))
	 * @param int $n Standard pagination param
	 * @param CRestServer $server Standard Server object link
	 *
	 * @return true
	 *
	 * @throws AccessException
	 * @throws ArgumentNullException
	 */
	public static function appOptionSet($params, $n, \CRestServer $server)
	{
		if(!$server->getClientId())
		{
			throw new AccessException("Application context required");
		}

		if(!isset($params["options"]))
		{
			$params['options'] = $params;
		}

		if(count($params['options']) <= 0)
		{
			throw new ArgumentNullException('options');
		}

		if(\CRestUtil::isAdmin())
		{
			$appOptions = Option::get("rest", "options_".$server->getClientId(), "");
			if(strlen($appOptions) > 0)
			{
				$appOptions = unserialize($appOptions);
			}
			else
			{
				$appOptions = array();
			}

			foreach($params['options'] as $key => $value)
			{
				$appOptions[$key] = $value;
			}

			Option::set('rest', "options_".$server->getClientId(), serialize($appOptions));
		}
		else
		{
			throw new AccessException("Administrator authorization required");
		}

		return true;
	}

	/**
	 * Gets user option values for application
	 *
	 * @param array $params array([option => option_name])
	 * @param int $n Standard pagination param
	 * @param CRestServer $server Standard Server object link
	 *
	 * @return array|mixed|null|string
	 *
	 * @throws AccessException
	 */
	public static function userOptionGet($params, $n, \CRestServer $server)
	{
		global $USER;

		if(!$server->getClientId())
		{
			throw new AccessException("Application context required");
		}

		if(!$USER->IsAuthorized())
		{
			throw new AccessException("User authorization required");
		}

		$userOptions = \CUserOptions::GetOption("app_options", "options_".$server->getClientId(), array());

		if(isset($params['option']))
		{
			return isset($userOptions[$params['option']]) ? $userOptions[$params['option']] : null;
		}
		else
		{
			return $userOptions;
		}
	}

	/**
	 * Sets user options values for application
	 *
	 * @param array $params array(option_name => option_value) || array(options => array(option_name => option_value,....))
	 * @param int $n Standard pagination param.
	 * @param CRestServer $server Standard Server object link
	 *
	 * @return bool
	 *
	 * @throws AccessException
	 * @throws ArgumentNullException
	 */
	public static function userOptionSet($params, $n, \CRestServer $server)
	{
		global $USER;

		if(!$server->getClientId())
		{
			throw new AccessException("Application context required");
		}

		if(!$USER->IsAuthorized())
		{
			throw new AccessException("User authorization required");
		}

		if(!isset($params["options"]))
		{
			$params['options'] = $params;
		}

		if(count($params['options']) <= 0)
		{
			throw new ArgumentNullException('options');
		}

		$userOptions = \CUserOptions::GetOption("app_options", "options_".$server->getClientId(), array());

		foreach($params['options'] as $key => $value)
		{
			$userOptions[$key] = $value;
		}

		\CUserOptions::SetOption("app_options", "options_".$server->getClientId(), $userOptions);

		return true;
	}

	public static function getServerTime($params)
	{
		return date('c', time());
	}

	public static function OnAppEvent($arParams, $arHandler)
	{
		$arEventFields = $arParams[0];
		if($arEventFields['APP_ID'] == $arHandler['APP_ID'] || $arEventFields['APP_ID'] == $arHandler['APP_CODE'])
		{
			$arEventFields["LANGUAGE_ID"] = \CRestUtil::getLanguage();

			unset($arEventFields['APP_ID']);
			return $arEventFields;
		}
		else
		{
			throw new Exception('Wrong app!');
		}
	}

	public static function OnAppPayment($arParams, $arHandler)
	{
		if($arParams[0] == $arHandler['APP_ID'])
		{
			$app = \Bitrix\Rest\AppTable::getByClientId($arHandler['APP_ID']);
			if($app)
			{
				$info = \Bitrix\Rest\AppTable::getAppStatusInfo($app, '');

				return array(
					'CODE' => $app['CODE'],
					'VERSION' => intval($app['VERSION']),
					'STATUS' => $info['STATUS'],
					'PAYMENT_EXPIRED' => $info['PAYMENT_EXPIRED'],
					'DAYS' => $info['DAYS_LEFT']
				);
			}
		}

		throw new Exception('Wrong app!');
	}

	protected static function getApp(\CRestServer $server)
	{
		if(self::$arApp == null)
		{
			if(CModule::IncludeModule('oauth'))
			{
				$client = OAuth\Base::instance($server->getClientId());

				if($client)
				{
					self::$arApp = $client->getClient();

					if(is_array(self::$arApp) && is_array(self::$arApp['SCOPE']))
					{
						self::$arApp['SCOPE'] = implode(',', self::$arApp['SCOPE']);
					}
				}
			}
			elseif($server->getClientId())
			{
				self::$arApp = \Bitrix\Rest\AppTable::getByClientId($server->getClientId());
			}
			else
			{
				throw new AccessException("Application context required");
			}
		}

		return self::$arApp;
	}

	protected static function getScope(\CRestServer $server)
	{
		return $server->getAuthScope();
	}
}
?>