Файл: Neiron/Kernel/Routing.php
Строк: 101
<?php
/**
* PHP 5x framework с открытым иходным кодом
*/
namespace NeironKernel;
use NeironAPIKernelRoutingInterface;
use NeironAPIKernelRequestInterface;
/**
* Обработчик роутов
* @author KpuTuK
* @version 1.0.0
* @package Neiron framework
* @category Kernel
* @link
*/
class Routing implements RoutingInterface
{
/**
* Массив роутов
* @var array
*/
private $routes = array(
'GET' => array(),
'POST' => array(),
'PUT' => array(),
'DELET' => array()
);
/**
* Массив паттернов и обработчиков
* @var array
*/
private $patterns = array(
'GET' => array(),
'POST' => array(),
'PUT' => array(),
'DELET' => array()
);
/**
* Конструктор класса
* @param array $routes Массив роутов
*/
public function __construct(array $routes = array())
{
$this->addRoutes($routes);
}
/**
* Добавляет роут в обработчик
* @param string $name Имя роута
* @param string $pattern Паттерн обработки
* @param mixed $handler Анонимная функция или строка вида "пространство имен контроллера@экшен"
* @param string $method Метод запроса
*/
public function addRoute($name, $pattern, $handler, $method = RequestInterface::METH_GET)
{
$regex = $this->compilePattern(rtrim($pattern, '/'));
$this->routes[$method][$name] = array(
'handler' => $handler,
'pattern' => $regex
);
$this->patterns[$method][$regex] = $handler;
}
/**
* Компилирует паттерн из условного выражения
* @param string $pattern Компилируемый паттерн
* @return string Скомпилированный паттерн
*/
private function compilePattern($pattern)
{
if (false === strpos($pattern, '{')) {
return $pattern;
}
return preg_replace_callback('#{(w+):(w+)}#', function ($match) {
$patterns = array(
'i' => '[0-9]+',
's' => '[a-zA-Z.-_%]+',
'x' => '[a-zA-Z0-9.-_%]+',
);
list(, $name, $prce) = $match;
return '(?<' . $name . '>' . strtr($prce, $patterns) . ')';
}, $pattern);
}
/**
* Добавляет массив роутов в обработчик
* @param array $routes Массив роутов
*/
public function addRoutes(array $routes = array())
{
foreach ($routes as $route) {
$this->addRoute(
$route['name'], $route['pattern'], $route['handler'], $route['method']
);
}
}
/**
* Обрабатывает uri по роуту
* @param string $uri Обрабатываемый uri
* @param string $method Метод запроса
* @throws ErrorException Исключение выбрасываемое при отсутствии роутов
* @return array Массив с даныыми контролера
*/
public function match($uri = null, $method = RequestInterface::METH_GET)
{
if (
(count($this->patterns[$method]) === 0) &&
(count($this->routes[$method]) === 0)
) {
throw new ErrorException('Не указан ни один роут!');
}
if (array_key_exists($uri, $this->patterns[$method])) {
return array(
'handler' => $this->patterns[$method][$uri],
'params' => array()
);
}
$matches = array();
foreach ($this->routes[$method] as $route) {
if (preg_match('#^' . $route['pattern'] . '$#s', $uri, $matches)) {
return array(
'handler' => $route['handler'],
'params' => $this->getParams($matches)
);
}
}
return array(
'handler' => 'NeironKernelController@pageNotFound',
'params' => array()
);
}
/**
* Фильтрует и возвращает параметры запроса
* @param array $params Паараметры запроса
* @return array Параметры запроса
*/
private function getParams($params)
{
foreach ($params as $key => $value) {
if (is_int($key)) {
unset($params[$key]);
}
}
return $params;
}
}