Your IP : 3.15.140.19


Current Path : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/landing/lib/
Upload File :
Current File : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/landing/lib/publicaction.php

<?php
namespace Bitrix\Landing;

use \Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);

class PublicAction
{
	/**
	 * Scope for REST.
	 */
	const REST_SCOPE = 'landing';

	/**
	 * Get full namespace for public classes.
	 * @return string
	 */
	protected static function getNamespacePublicClasses()
	{
		return __NAMESPACE__ . '\\PublicAction';
	}

	/**
	 * Get info about method - class/method/params.
	 * @param string $action Full name of action (\Namespace\Class::method).
	 * @param array $data Array of data.
	 * @return array
	 */
	protected static function getMethodInfo($action, $data = array())
	{
		$info = array();

		// if action exist and is callable
		if ($action && strpos($action, '::'))
		{
			$action = self::getNamespacePublicClasses() . '\\' . $action;
			if (is_callable(explode('::', $action)))
			{
				list($class, $method) = explode('::', $action);
				$info = array(
					'class' => $class,
					'method' => $method,
					'params_init' => array(),
					'params_missing' => array()
				);
				// parse func params
				$reflection = new \ReflectionMethod($class, $method);
				foreach ($reflection->getParameters() as $param)
				{
					if (isset($data[$param->getName()]))
					{
						$info['params_init'][$param->getName()] = $data[$param->getName()];
					}
					elseif ($param->isDefaultValueAvailable())
					{
						$info['params_init'][$param->getName()] = $param->getDefaultValue();
					}
					else
					{
						$info['params_missing'][] = $param->getName();
					}
				}
			}
		}

		return $info;
	}

	/**
	 * Processing the AJAX/REST action.
	 * @param string $action Action name.
	 * @param mixed $data Data.
	 * @param boolean $isRest Is rest call.
	 * @return array|null
	 */
	protected static function actionProcessing($action, $data, $isRest = false)
	{
		if (!is_array($data))
		{
			$data = array();
		}

		if (!$isRest && (!defined('BX_UTF') || BX_UTF !== true))
		{
			$data = Manager::getApplication()->convertCharsetArray(
				$data, 'UTF-8', SITE_CHARSET
			);
		}

		// if method::action exist in PublicAction, call it
		if (($action = self::getMethodInfo($action, $data)))
		{
			$error = new Error;
			if (!$isRest && !check_bitrix_sessid())
			{
				$error->addError(
					'SESSION_EXPIRED',
					Loc::getMessage('LANDING_SESSION_EXPIRED')
				);
			}
			if (!empty($action['params_missing']))
			{
				$error->addError(
					'MISSING_PARAMS',
					Loc::getMessage('LANDING_MISSING_PARAMS', array(
						'#MISSING#' => implode(', ', $action['params_missing'])
					))
				);
			}
			// all right - execute
			if ($error->isEmpty())
			{
				$result = call_user_func_array(
					array($action['class'], $action['method']),
					$action['params_init']
				);
				$error->copyError($result->getError());
			}
			// return error or answer
			if (!$error->isEmpty())
			{
				$errors = array();
				foreach ($error->getErrors() as $error)
				{
					$errors[] = array(
						'error' => $error->getCode(),
						'error_description' => $error->getMessage()
					);
				}
				return array(
					'type' => 'error',
					'result' => $errors
				);
			}
			if ($result->isSuccess())
			{
				return array(
					'type' => 'success',
					'result' => $result->getResult()
				);
			}
		}
	}

	/**
	 * Listen commands from ajax.
	 * @return array|null
	 */
	public static function ajaxProcessing()
	{
		$context = \Bitrix\Main\Application::getInstance()->getContext();
		$request = $context->getRequest();
		$action = $request->get('action');
		$data = $request->get('data');

		foreach ($request->getFileList() as $code => $file)
		{
			$data[$code] = $file;
		}

		return self::actionProcessing($action, $data);
	}

	/**
	 * Register methods in REST.
	 * @return array
	 */
	public static function restBase()
	{
		static $restMethods = array();

		if (empty($restMethods))
		{
			$classes = array('site', 'landing', 'block', 'repo', 'utils');

			// then methods list for each class
			foreach ($classes as $className)
			{
				$fullClassName = self::getNamespacePublicClasses() . '\\' . $className;
				$class = new \ReflectionClass($fullClassName);
				$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
				foreach ($methods as $method)
				{
					$command = self::REST_SCOPE . '.' .
									strtolower($className) . '.' .
									strtolower($method->getName());
					$restMethods[$command] = array(
						__CLASS__, 'restGateway'
					);
				}
			}
		}

		return array(
			self::REST_SCOPE => $restMethods
		);
	}

	/**
	 * Gateway between REST and publicaction.
	 * @params array $fields Rest fields.
	 * @params mixed $t
	 * @param \CRestServer $server Server instance.
	 * @return mixed
	 */
	public static function restGateway($fields, $t, $server)
	{
		// prepare method and call action
		$method = $server->getMethod();
		$method = substr($method, strlen(self::REST_SCOPE) + 1);// delete module-prefix
		$method = preg_replace('/\./', '\\', $method, substr_count($method, '.') - 1);
		$method = str_replace('.', '::', $method);
		$result = self::actionProcessing(
			$method,
			$fields,
			true
		);
		// prepare answer
		if ($result['type'] == 'error')
		{
			foreach ($result['result'] as $error)
			{
				throw new \Bitrix\Rest\RestException(
					$error['error_description'],
					$error['error']
				);
			}
		}
		else
		{
			return $result['result'];
		}
	}
}