From bec87b6811e644214522451200550d9a127d87ff Mon Sep 17 00:00:00 2001 From: Karel Wintersky Date: Mon, 7 Aug 2023 18:03:16 +0300 Subject: [PATCH] 2.6.0 * [-] removed AppRouter and AppLogger from Arris core package --- {sources/File => _in_work}/FileCSV.php | 0 {sources/Core => _legacy}/Option.php | 0 interfaces/AppLoggerConstants.php | 100 --- interfaces/AppLoggerInterface.php | 64 -- interfaces/AppRouterInterface.php | 134 ---- sources/AppLogger.php | 359 ---------- sources/AppRouter.php | 628 ------------------ sources/Exceptions/AppRouterException.php | 41 -- sources/Exceptions/AppRouterHandlerError.php | 49 -- .../AppRouterMethodNotAllowedException.php | 48 -- .../Exceptions/AppRouterNotFoundException.php | 48 -- sources/{ => Helpers}/Dataset.php | 2 +- 12 files changed, 1 insertion(+), 1472 deletions(-) rename {sources/File => _in_work}/FileCSV.php (100%) rename {sources/Core => _legacy}/Option.php (100%) delete mode 100644 interfaces/AppLoggerConstants.php delete mode 100644 interfaces/AppLoggerInterface.php delete mode 100644 interfaces/AppRouterInterface.php delete mode 100644 sources/AppLogger.php delete mode 100644 sources/AppRouter.php delete mode 100644 sources/Exceptions/AppRouterException.php delete mode 100644 sources/Exceptions/AppRouterHandlerError.php delete mode 100644 sources/Exceptions/AppRouterMethodNotAllowedException.php delete mode 100644 sources/Exceptions/AppRouterNotFoundException.php rename sources/{ => Helpers}/Dataset.php (99%) diff --git a/sources/File/FileCSV.php b/_in_work/FileCSV.php similarity index 100% rename from sources/File/FileCSV.php rename to _in_work/FileCSV.php diff --git a/sources/Core/Option.php b/_legacy/Option.php similarity index 100% rename from sources/Core/Option.php rename to _legacy/Option.php diff --git a/interfaces/AppLoggerConstants.php b/interfaces/AppLoggerConstants.php deleted file mode 100644 index 0203856..0000000 --- a/interfaces/AppLoggerConstants.php +++ /dev/null @@ -1,100 +0,0 @@ - false, 'enable' => true, 'handler' => StreamHandler::class], - [ '200-info.log', self::INFO, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class], - [ '250-notice.log', self::NOTICE, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class], - [ '300-warning.log', self::WARNING, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class], - [ '400-error.log', self::ERROR, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class], - [ '500-critical.log', self::CRITICAL, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class], - [ '550-alert.log', self::ALERT, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class], - [ '600-emergency.log', self::EMERGENCY, 'bubbling' => false, 'enable' => true, 'handler' => StreamHandler::class] - ]; - - /** - * Порядок опций в параметре $options метода addScope() - */ - const addScope_OPTION_FILENAME = 0; - const addScope_OPTION_LOGLEVEL = 1; - const addScope_OPTION_OPTIONS = 2; - - const addScope_OPTION_BUBBLING = 'bubbling'; - const addScope_OPTION_ENABLE = 'enable'; - const addScope_OPTION_HANDLER = 'handler'; -} \ No newline at end of file diff --git a/interfaces/AppLoggerInterface.php b/interfaces/AppLoggerInterface.php deleted file mode 100644 index f50ba6f..0000000 --- a/interfaces/AppLoggerInterface.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - bubbling - [FALSE] - всплывает ли логгируемое сообщение?
- * - * - default_log_level - [DEBUG] - уровень логгирования по умолчанию
- * - default_logfile_path - [''] - путь к файлам логов по умолчанию
- * - default_logfile_prefix - [''] - префикc файла лога по умолчанию
- * - default_log_file - ['_.log'] имя файла лога по умолчанию, применяется если для имени файла передан NULL
- * - default_handler - [NULL] - хэндлер, реализующий \Monolog\Handler\HandlerInterface как логгер по умолчанию для этого скоупа - * - * - add_scope_to_log - [FALSE] - добавлять ли имя скоупа к имени логгера в файле лога?
- * - deferred_scope_creation - [TRUE] - разрешать ли отложенную инициализацию скоупов
- * - deferred_scope_separate_files - [TRUE] - использовать ли разные файлы для deferred-скоупов (на основе имени скоупа) - * - */ - public static function init($application, $instance, $options = []); - - /** - * Добавляет скоуп - * - * @param null $scope - имя скоупа - * @param array $scope_levels - массив кортежей: - * [ filename , logging_level, <опции> ], где: - * - filename - имя файла лога - * - logging_level - уровень логгирования - уровень логгирования (переменные Logger::DEBUG etc) - * А опции - возможные ключи: - * - enabled - [TRUE], разрешен ли уровень логгирования - * - bubbling - [FALSE], всплывает ли сообщение логгирования на следующий уровень - * - handler - NULL либо инстанс Хэндлера, реализующего интерфейс Monolog\Handler\HandlerInterface - * - * Если передается пустой массив - загружаются опции по умолчанию, а скоуп считается DEFERRED и к нему применяются - * правила создания Deferred-скоупов. - * - * @param bool $scope_logging_enabled - разрешен ли скоуп вообще для логгирования? - * @return mixed - */ - public static function addScope($scope = null, $scope_levels = [], $scope_logging_enabled = true); - - /** - * Получает скоуп - * - * @param null $scope - * @return Logger - */ - public static function scope($scope = null):Logger; - - /** - * Добавляет null-logger - * @return mixed Logger - */ - public static function addNullLogger(); -} \ No newline at end of file diff --git a/interfaces/AppRouterInterface.php b/interfaces/AppRouterInterface.php deleted file mode 100644 index 0c4a980..0000000 --- a/interfaces/AppRouterInterface.php +++ /dev/null @@ -1,134 +0,0 @@ - [ handler, namespace, name ] - * - * @return array - */ - public static function getRoutingRules(); - -} \ No newline at end of file diff --git a/sources/AppLogger.php b/sources/AppLogger.php deleted file mode 100644 index fd60e96..0000000 --- a/sources/AppLogger.php +++ /dev/null @@ -1,359 +0,0 @@ - false, - 'default_logfile_path' => '', - 'default_log_level' => Logger::DEBUG, - 'default_logfile_prefix' => '', - 'default_log_file' => self::DEFAULT_LOG_FILENAME, - 'default_handler' => StreamHandler::class, - 'add_scope_to_log' => false, - 'deferred_scope_creation' => true, - 'deferred_scope_separate_files' => true - ]; - - /** - * @var string - */ - private static $application; - - /** - * @var string - */ - private static $instance; - - /** - * @var array - */ - private static $_configs = []; - - public static function init($application, $instance, $options = []) - { - self::$application = $application; - self::$instance = $instance; - - // Всплывание лога - self::$_global_config['bubbling'] - = setOption($options, 'bubbling', false); - - // Уровень логгирования по умолчанию - self::$_global_config['default_log_level'] - = setOption($options, 'default_log_level', Logger::DEBUG); - - // дефолтные значения для всего AppLogger - self::$_global_config['default_logfile_path'] - = setOption($options, 'default_logfile_path', ''); - - if (!empty(self::$_global_config['default_logfile_path'])) { - self::$_global_config['default_logfile_path'] - = rtrim(self::$_global_config['default_logfile_path'], DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR ; - } - - self::$_global_config['default_logfile_prefix'] - = setOption($options, 'default_logfile_prefix', ''); - - self::$_global_config['default_log_file'] - = setOption($options, 'default_log_file', self::DEFAULT_LOG_FILENAME); - - self::$_global_config['default_handler'] - = setOption($options, 'handler', StreamHandler::class); - - // добавлять ли скоуп к имени логгера в файле лога - self::$_global_config['add_scope_to_log'] - = setOption($options, 'add_scope_to_log', false); - - // опции Deferred-скоупов - self::$_global_config['deferred_scope_creation'] - = setOption($options, 'deferred_scope_creation', true); - - self::$_global_config['deferred_scope_separate_files'] - = setOption($options, 'deferred_scope_separate_files', true); - } - - public static function addScope($scope = null, $scope_levels = [], $scope_logging_enabled = true, $is_deferred_scope = false) - { - if (empty($scope_levels)) { - $scope_levels = self::DEFAULT_SCOPE_OPTIONS; - $is_deferred_scope = true; - } - - try { - $logger_name = self::getLoggerName($scope); - $internal_key = self::getScopeKey($scope); - - $logger = new Logger($logger_name); - - // $level - параметры логгера для разных уровней - foreach ($scope_levels as $level) { - $loglevel = $level[ self::addScope_OPTION_LOGLEVEL ] ?? self::$_global_config['default_log_level']; - - $filename - = $level[ self::addScope_OPTION_FILENAME ] === 'php://stdout' - ? 'php://stdout' - : self::createLoggerFilename($scope, $level, $is_deferred_scope); - - $options = array_key_exists(self::addScope_OPTION_OPTIONS, $level) ? $level[ self::addScope_OPTION_OPTIONS ] : []; - - $level_options = [ - 'enable' => array_key_exists('enable', $options) ? $options['enable'] : $scope_logging_enabled, - 'bubbling' => array_key_exists('bubbling', $options) ? $options['bubbling'] : self::$_global_config['bubbling'], - 'handler' => array_key_exists('handler', $options) ? $options['handler'] : StreamHandler::class - ]; - - self::$_declared_loggers[ $scope ][] = [ - 'file' => $filename, - 'level' => $loglevel, - 'options' => $level_options - ]; - - /*$level_options = array( - 'enable' => setOption($level, 'enable', $scope_logging_enabled), - 'bubbling' => setOption($level, 'bubbling', self::$_global_config['bubbling']), - 'handler' => setOption($level, 'handler', StreamHandler::class) - );*/ - - // NullHandler если логгер так или иначе отключен - if ($level_options['enable'] === false) { - $level_options['handler'] = \Monolog\Handler\NullHandler::class; - } - - if ( $level_options['enable'] == false || $scope_logging_enabled == false ) - { - // NULL Handler - $level_options['enable'] = false; - $logger->pushHandler( new \Monolog\Handler\NullHandler($loglevel) ); - } - elseif ( is_callable($level_options['handler']) ) - { - // у коллбэка не будет параметров, поэтому мы их не передаем - $logger->pushHandler( call_user_func_array($level_options['handler'], []) ); - - } - elseif ( $level_options['handler'] == StreamHandler::class || $level_options['handler'] === null ) - { - // Default stream Handler - $logger->pushHandler( new StreamHandler($filename, $loglevel, $level_options['bubbling']) ); - } - elseif ( in_array('Monolog\Handler\HandlerInterface', class_implements($level_options['handler'])) ) - { - // via HandlerInterface (не тестировалось нормально) - /** - * @param \Monolog\Handler\HandlerInterface $level_options[] - */ - $logger->pushHandler( /** @param \Monolog\Handler\HandlerInterface */ $level_options['handler'] ); - } - else - { - // NULL Handler - $logger->pushHandler( new \Monolog\Handler\NullHandler($loglevel) ); - } - - self::$_configs[ $internal_key ][ $loglevel ] = $level_options; - - } //foreach - self::$_instances[ $internal_key ] = $logger; - unset($logger); - - } catch (Exception $e) { - die(__METHOD__ . ' died at line ' .$e->getLine() . ' With exception ' . $e->getMessage() . ' code = ' . $e->getCode() ); - } - } - - public static function addNullLogger() - { - return (new Logger('null'))->pushHandler(new \Monolog\Handler\NullHandler()); - } - - public static function scope($scope = null):Logger - { - try { - $internal_key = self::getScopeKey( $scope ); - - if (!self::checkInstance($internal_key) and self::$_global_config['deferred_scope_creation']) { - self::addDeferredScope($scope); - } - - return self::$_instances[ $internal_key ]; - - } catch (Exception $e) { - die(__METHOD__ . ' died at line ' .$e->getLine() . ' With exception ' . $e->getMessage() . ' code = ' . $e->getCode() ); - } - } - - /** - * Возвращает глобальный конфиг - * - * @return array - */ - public static function getAppLoggerConfig(): array - { - return self::$_global_config; - } - - /** - * Возвращает вычисленные параметры логгера по имени скоупа и уровню логгирования (int) - * - * @param null $scope - * @param null $level - * @return array - */ - public static function getScopeConfig($scope = null, $level = null):array - { - $data = is_null($scope) - ? self::$_declared_loggers - : ( - array_key_exists( $scope, self::$_declared_loggers) ? self::$_declared_loggers[$scope] : [] - ); - /*if (is_null($level)) { - return $data; - } else { - return current(array_filter($data, static function ($v) use ($level) { - return $v['level'] == $level; - })); - }*/ - return is_null($level) - ? $data - : current(array_filter($data, static function ($v) use ($level) - { - return $v['level'] == $level; - })); - } - - /** - * Возвращает опции логгер-скоупа - * @param null $scope - * @return mixed - */ - public static function getLoggerConfig($scope = null) - { - return self::$_configs[ self::getScopeKey( $scope ) ]; - } - - /** - * Поздняя инициализация скоупа со значениями по умолчанию. - * - * @param null $scope - */ - private static function addDeferredScope($scope = null) - { - self::addScope($scope, self::DEFAULT_SCOPE_OPTIONS, true, true); - } - - /** - * Проверяет существование инстанса логгера ПО internal_key (!!!), не по имени скоупа! - * - * @param $key - * @return bool - */ - private static function checkInstance($key):bool - { - return ( array_key_exists($key, self::$_instances) && self::$_instances[$key] !== NULL ); - } - - /** - * Получает внутренний ключ логгера - * - * @param null $scope - * @return string - */ - private static function getScopeKey($scope = null): string - { - $scope = $scope ? (self::SCOPE_DELIMETER . (string)$scope) : ''; - return self::$application . self::$instance . $scope; - } - - /** - * Проверяет существование скоупа по имени - * - * @param null $scope - * @return bool - */ - private static function checkScopeExist($scope = null): bool - { - $key = self::getScopeKey($scope); - return self::checkInstance($key); - } - - /** - * Генерирует имя логгера - * - * @param null $scope - * @return string - */ - private static function getLoggerName($scope = null): string - { - $scope = (string)$scope; - - return - self::$_global_config['add_scope_to_log'] - ? self::$application . self::SCOPE_DELIMETER . self::$instance . self::SCOPE_DELIMETER . $scope - : self::$application . self::SCOPE_DELIMETER . self::$instance; - } - - /** - * Генерирует имя файла для логгера/скоупа - * - * @param $scope - * @param $level - * @param bool $is_deferred - * @return string - */ - private static function createLoggerFilename($scope, $level, bool $is_deferred = false): string - { - $filename - = empty($level[ self::addScope_OPTION_FILENAME ]) - ? self::$_global_config['default_log_file'] - : $level[ self::addScope_OPTION_FILENAME ]; - - $filepath = self::$_global_config['default_logfile_path'] . self::$_global_config['default_logfile_prefix']; - - // если мы генерим имя файла для DeferredScope - префикс имени файла = scope, иначе '' - // определить это мы вызовом метода не можем, придется передавать параметром - - // вообще, проверим, пишется ли deferred-лог в разные файлы? - $is_deferred = $is_deferred && self::$_global_config['deferred_scope_separate_files']; - - $file_prefix = $is_deferred ? $scope . self::SCOPE_DELIMETER : ''; - - return $filepath . $file_prefix . $filename; - } - -} - -# -eof- diff --git a/sources/AppRouter.php b/sources/AppRouter.php deleted file mode 100644 index a439ad5..0000000 --- a/sources/AppRouter.php +++ /dev/null @@ -1,628 +0,0 @@ - 'GET', - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - public static function post($route, $handler, $name = null) - { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => 'POST', - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - public static function put($route, $handler, $name = null) - { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => 'PUT', - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - public static function patch($route, $handler, $name = null) - { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => 'PATCH', - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - public static function delete($route, $handler, $name = null) - { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => 'DELETE', - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - public static function head($route, $handler, $name = null) - { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => 'HEAD', - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - - public static function any($route, $handler, $name = null) - { - foreach (self::ALL_HTTP_METHODS as $method) { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => $method, - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - - - self::$rules[] = [ - 'httpMethod' => $method, - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name - ]; - } - - /*self::$rules[] = [ - 'httpMethod' => self::ALL_HTTP_METHODS, - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name - ];*/ - - /*self::$rules[] = [ - 'httpMethod' => '*', - 'route' => $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name - ];*/ - } - - - public static function addRoute($httpMethod, $route, $handler, $name = null) - { - foreach ((array) $httpMethod as $method) { - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - - self::$rules[] = [ - 'httpMethod' => $method, - 'route' => self::$current_prefix . $route, - 'handler' => $handler, - 'namespace' => self::$current_namespace, - 'name' => $name, - 'middlewares' => [ - 'before' => self::$current_middleware_before, - 'after' => self::$current_middleware_after - ] - ]; - } - - - if (!is_null($name)) { - self::$route_names[$name] = self::$current_prefix . $route; - } - } - - /** - * @param array $options [
- * string 'prefix' => '',
- * string 'namespace' => '',
- * callable 'before' = null,
- * callable 'after' => null
- * ] - * @param callable|null $callback - * @param string $name - * @return mixed|void - */ - public static function group(array $options = [], callable $callback = null) - { - $_setPrefix = array_key_exists('prefix', $options); - $_setNamespace = array_key_exists('namespace', $options); - - if ($_setPrefix) { - self::$stack_prefix->push($options['prefix']); - self::$current_prefix = self::$stack_prefix->implode(); - } - - if ($_setNamespace) { - self::$stack_namespace->push($options['namespace']); - self::$current_namespace = self::$stack_namespace->implode('\\'); - } - - if (array_key_exists('before', $options) && self::is_handler($options['before'])) { - self::$stack_middlewares_before->push($options['before']); - self::$current_middleware_before = $options['before']; - - self::$stack_middlewares_after->push($options['after']); - self::$current_middleware_after = $options['after']; - } - - $callback(); - - if (array_key_exists('after', $options) && self::is_handler($options['after'])) { - self::$current_middleware_after = self::$stack_middlewares_after->pop(); - self::$current_middleware_before = self::$stack_middlewares_before->pop(); - } - - if ($_setNamespace) { - self::$stack_namespace->pop(); - self::$current_namespace = self::$stack_namespace->implode('\\'); - } - - if ($_setPrefix) { - self::$stack_prefix->pop(); - self::$current_prefix = self::$stack_prefix->implode(); - } - } - - /** - * Возвращает информацию о роуте по имени - * - * @param string $name - * @return string|array - */ - public static function getRouter($name = '') - { - if ($name === '*') { - return self::$route_names; - } - - if ($name === '') { - return '/'; - } - - if (array_key_exists($name, self::$route_names)) { - return self::$route_names[ $name ]; - } - - return '/'; - } - - /** - * @return array - */ - public static function getRoutersNames() - { - return self::$route_names; - } - - public static function dispatch() - { - self::$dispatcher = FastRoute\simpleDispatcher(function (RouteCollector $r) { - foreach (self::$rules as $rule) { - $handler - = (is_string($rule['handler']) && !empty($rule['namespace'])) - ? "{$rule['namespace']}\\{$rule['handler']}" - : $rule['handler']; - - // Чтобы передавать доп.параметры в правило - нужно расширять метод addRoute - $r->addRoute($rule['httpMethod'], $rule['route'], $handler); - } - }); - - // Fetch method and URI from somewhere - self::$routeInfo = $routeInfo = (self::$dispatcher)->dispatch(self::$httpMethod, self::$uri); - - list($state, $handler, $method_parameters) = $routeInfo; - - //@todo: никак невозможно выяснить, какому правилу сопоставлен обработанный URL. Имеет ли смысл создать issue для пакета, который не обновлялся много лет? - - // dispatch errors - if ($state === FastRoute\Dispatcher::NOT_FOUND) { - // URL or URI? https://ru.wikipedia.org/wiki/URI - throw new AppRouterNotFoundException("URL not found", 404, null, [ - 'method' => self::$httpMethod, - 'uri' => self::$uri - ]); - } - - if ($state === FastRoute\Dispatcher::METHOD_NOT_ALLOWED) { - throw new AppRouterMethodNotAllowedException("Method " . self::$httpMethod . " not allowed for URI " . self::$uri, 405, null, [ - 'uri' => self::$uri, - 'method' => self::$httpMethod, - 'info' => self::$routeInfo - ]); - } - - // нужно получить параметры правила для обработанного роута! (к сожалению, не получится получить именно для ОБРАБОТАННОГО, только для объявленного) - // т.е., если в роуте есть опциональные части или плейсхолдеры - роут работать не будет. - - $rules = self::getRoutingRules(); - $rules_key = self::$httpMethod . ' ' . self::$uri; - $rule = array_key_exists($rules_key, $rules) ? $rules[$rules_key] : []; - - $actor = self::compileHandler($handler); - - if (self::is_handler($rule['middlewares']['before'])){ - $before = self::compileHandler($rule['middlewares']['before']); - $before(); - unset($before); - } - - call_user_func_array($actor, $method_parameters); - - if (self::is_handler($rule['middlewares']['after'])){ - $after = self::compileHandler($rule['middlewares']['after']); - $after(); - unset($after); - } - - unset($state, $rules, $rules_key, $rule); - } - - /** - * @inheritDoc - * - * @return array - */ - public static function getRoutingInfo(): array - { - return self::$routeInfo; - } - - /** - * Возвращает список объявленных роутов: [ 'method route' => [ handler, namespace, name ] - * - * @return array - */ - public static function getRoutingRules(): array - { - $rules = []; - foreach (self::$rules as $record) { - $key = is_array($record['httpMethod']) ? "ANY {$record['route']}" : "{$record['httpMethod']} {$record['route']}"; - - if (array_key_exists($key, $rules)) { - $key .= " [ DUPLICATE ROUTE " . microtime(false) . ' ]'; - } - - $rules[ $key ] = [ - 'handler' => is_callable($record['handler']) ? "Closure" : $record['handler'], - 'namespace' => $record['namespace'], - 'name' => $record['name'], - 'middlewares' => [ - 'before' => $record['middlewares']['before'], - 'after' => $record['middlewares']['after'] - ] - ]; - } - - return $rules; - } - - /** - * @throws \JsonException - */ - private static function jsonize($data) - { - return json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR); - } - - /** - * Выясняет, является ли передаваемый аргумент допустимым хэндлером - * - * @param $handler - * @param bool $validate_handlers - * - * @return bool - */ - public static function is_handler($handler = null, $validate_handlers = false) - { - if (is_null($handler)) { - return false; - } elseif ($handler instanceof \Closure) { - return true; - } elseif (strpos($handler, '@') > 0) { - // dynamic method - list($class, $method) = explode('@', $handler, 2); - - if ($validate_handlers && !class_exists($class)) { - return false; - } - - if ($validate_handlers && !method_exists($class, $method)) { - return false; - } - - return true; - } elseif (strpos($handler, '::')) { - // static method - list($class, $method) = explode('::', $handler, 2); - - if ($validate_handlers && !class_exists($class)){ - return false; - } - - if ($validate_handlers && !method_exists($class, $method)){ - return false; - } - - return true; - } else { - // function - if ($validate_handlers && !function_exists($handler)){ - return false; - } - - return true; - } - } // is_handler() - - private static function compileHandler($handler) - { - if ($handler instanceof \Closure) { - $actor = $handler; - } elseif (strpos($handler, '@') > 0) { - // dynamic method - list($class, $method) = explode('@', $handler, 2); - - if (!class_exists($class)) { - self::$logger->error("Class {$class} not defined.", [ self::$uri, self::$httpMethod, $class ]); - throw new AppRouterHandlerError("Class {$class} not defined", 500, null, [ - 'uri' => self::$uri, - 'method' => self::$httpMethod, - 'info' => self::$routeInfo - ]); - } - - if (!method_exists($class, $method)) { - self::$logger->error("Method {$method} not declared at {$class} class.", [ self::$uri, self::$httpMethod, $class ]); - throw new AppRouterHandlerError("Method {$method} not declared at class {$class}", 500, null, [ - 'uri' => self::$uri, - 'method' => self::$httpMethod, - 'info' => self::$routeInfo - ]); - } - - $actor = [ new $class, $method ]; - - } elseif (strpos($handler, '::')) { - // static method - list($class, $method) = explode('::', $handler, 2); - - if (!class_exists($class)){ - self::$logger->error("Class {$class} not defined.", [ self::$uri, self::$httpMethod, $class ]); - throw new AppRouterHandlerError("Static class {$class} not defined", 500, null, [ - 'uri' => self::$uri, - 'method' => self::$httpMethod, - 'info' => self::$routeInfo - ]); - } - - if (!method_exists($class, $method)){ - self::$logger->error("Method {$method} not declared at {$class} class", [ self::$uri, self::$httpMethod, $class ]); - throw new AppRouterHandlerError("Method {$method} not declared at static class {$class}", 500, null, [ - 'uri' => self::$uri, - 'method' => self::$httpMethod, - 'info' => self::$routeInfo - ]); - } - - $actor = [ $class, $method ]; - - } else { - // function - if (!function_exists($handler)){ - self::$logger->error("Handler function {$handler} not found", [ self::$uri, self::$httpMethod, $handler ]); - throw new AppRouterHandlerError("Handler function {$handler} not found", 500, null, [ - 'uri' => self::$uri, - 'method' => self::$httpMethod, - 'info' => self::$routeInfo - ]); - } - - $actor = $handler; - } - - return $actor; - } - -} - -# -eof- diff --git a/sources/Exceptions/AppRouterException.php b/sources/Exceptions/AppRouterException.php deleted file mode 100644 index 9d107f1..0000000 --- a/sources/Exceptions/AppRouterException.php +++ /dev/null @@ -1,41 +0,0 @@ -_info = $info; - - parent::__construct($message, $code, $previous); - } - - /** - * Get custom field - * - * @param $key - * @return array|mixed|null - */ - public function getInfo($key = null) - { - return is_null($key) ? $this->_info : (array_key_exists($key, $this->_info) ? $this->_info[$key] : null); - } -} \ No newline at end of file diff --git a/sources/Exceptions/AppRouterHandlerError.php b/sources/Exceptions/AppRouterHandlerError.php deleted file mode 100644 index 84d224c..0000000 --- a/sources/Exceptions/AppRouterHandlerError.php +++ /dev/null @@ -1,49 +0,0 @@ -_info = $info; - - parent::__construct($message, $code, $previous, $info); - } - - /** - * Get custom field - * - * @param $key - * @return array|mixed|null - */ - public function getInfo($key = null) - { - return is_null($key) ? $this->_info : (array_key_exists($key, $this->_info) ? $this->_info[$key] : null); - } - -} diff --git a/sources/Exceptions/AppRouterMethodNotAllowedException.php b/sources/Exceptions/AppRouterMethodNotAllowedException.php deleted file mode 100644 index 0949988..0000000 --- a/sources/Exceptions/AppRouterMethodNotAllowedException.php +++ /dev/null @@ -1,48 +0,0 @@ -_info = $info; - - parent::__construct($message, $code, $previous, $info); - } - - /** - * Get custom field - * - * @param $key - * @return array|mixed|null - */ - public function getInfo($key = null) - { - return is_null($key) ? $this->_info : (array_key_exists($key, $this->_info) ? $this->_info[$key] : null); - } -} diff --git a/sources/Exceptions/AppRouterNotFoundException.php b/sources/Exceptions/AppRouterNotFoundException.php deleted file mode 100644 index 27e62f3..0000000 --- a/sources/Exceptions/AppRouterNotFoundException.php +++ /dev/null @@ -1,48 +0,0 @@ -_info = $info; - - parent::__construct($message, $code, $previous, $info); - } - - /** - * Get custom field - * - * @param $key - * @return array|mixed|null - */ - public function getInfo($key = null) - { - return is_null($key) ? $this->_info : (array_key_exists($key, $this->_info) ? $this->_info[$key] : null); - } -} \ No newline at end of file diff --git a/sources/Dataset.php b/sources/Helpers/Dataset.php similarity index 99% rename from sources/Dataset.php rename to sources/Helpers/Dataset.php index 8ac5afe..3f1c0bd 100644 --- a/sources/Dataset.php +++ b/sources/Helpers/Dataset.php @@ -1,6 +1,6 @@