/controllers/core/Route.php
PHP | 294 lines | 219 code | 24 blank | 51 comment | 15 complexity | e617c2a621382cfef534491e61cf7c50 MD5 | raw file
- <?php
- /**
- * OYiEngine 6.x
- * Company Otakoyi.com
- * Author wmgodyak mailto:wmgodyak@gmail.com
- * Date: 07.05.14 21:56
- */
- namespace controllers\core;
- if ( !defined('SYSPATH') ) die();
- class Route {
- const HEADER_404 = 'HTTP/1.0 404 Not Found';
- const HEADER_301 = 'HTTP/1.1 301 Moved Permanently';
- /**
- * Local storage
- * */
- private $storage;
- /**
- * The URI pattern the route responds to.
- *
- * @var string
- */
- protected $uri;
- protected $placeholder=array(
- '/:module' =>'/([a-zA-Z]+)',
- '/:controller' => '/([a-zA-Z]+)',
- '/:action' =>'/([a-zA-Z]+)',
- ':params' =>'(.*)',
- '/:namespace' =>'([a-zA-Z]+)',
- '/:int' =>'/([0-9]+)',
- // '(' => '(?:',
- // '/)' => '/)?',
- '~|' => '(?:',
- '|~' => '/)?'
- );
- /**
- * тут будуть записуватись правила маршрутизації
- * @var array
- * */
- private $rules;
- public function __construct($uri)
- {
- // clear globals
- $this->uri = self::protect($uri);
- }
- public function add($pattern,$rule)
- {
- if (strpos($pattern, '(') !== FALSE) {
- $pattern = strtr($pattern,$this->placeholder);
- }
- $this->rules[] = array($pattern,$rule);
- }
- /**
- * Додає роутер
- * @param string $regex
- * @param string $namespace
- * @param string $params
- * @return $this
- */
- public function set($regex, $namespace , $params ='')
- {
- $this->rules[] = array(
- 'params' => $params,
- 'regex' => $regex,
- 'namespace' => $namespace
- );
- return $this;
- }
- public function get(){
- return $this->rules;
- }
- /**
- * Setter method
- * @param string $index
- * @param mixed $value
- */
- public function __set($index, $value)
- {
- $this->storage[$index] = $value;
- }
- /**
- * Getter method
- * @param string $index
- * @return array
- */
- public function __get($index)
- {
- return isset($this->storage[$index]) ? $this->storage[$index] : null;
- }
- public function run()
- {
- $request = Request::instance();
- $routes = $this->get();
- // echo '<pre>';
- // print_r($routes);
- // echo '<pre>';
- // die;
- // echo '<pre>URI: '; echo $this->uri, '<br>';
- if(strpos($this->uri, '?')){
- $a = explode('?', $this->uri);
- $this->uri=$a[0];
- foreach ($_GET as $k=>$v) {
- $request->param($k,$v);
- }
- }
- foreach ($routes as $route) {
- if(preg_match("@^" . $route['regex'] . "$@u",$this->uri,$matches)){
- // echo '<pre>FOUND:'; print_r($route);die;
- // echo 'Matches: '; print_r($matches);
- if(empty($route['params'])) {
- // вирізаю з неймспейсу :controller :action
- if(strpos($route['namespace'], ':controller') !== false) {
- $s = explode(':', $route['namespace']);
- // echo '<b>NS String:</b> ';
- // print_r($s);
- $this->namespace = $s[0];
- if(isset($s[1]) && $s[1] == 'controller') {
- $this->controller = $matches[1];
- }
- if(isset($s[2]) && $s[2] == 'action') {
- $this->action = $matches[2];
- }
- if(isset($matches[3]) && !empty($matches[3])) {
- // echo '----------';
- $this->params = explode('/', trim($matches[3],'/'));
- }
- // var_dump($this->params);
- } else {
- // задано виклик конкретного контрола
- $this->controller = substr(strrchr($route['namespace'], '\\'), 1);
- $this->namespace = str_replace($this->controller, '', $route['namespace']);
- }
- } else {
- // echo '---<br>Чітко задана назва і послідовнсть параметрів: ';
- // чітко задана послідовність параметрів і назви
- $this->namespace = $route['namespace'];
- $request = Request::instance();
- $s = explode('/', $route['params']);
- // echo 'Params: '; print_r($s);
- foreach ($s as $k=>$param) {
- // echo $k, ':', $param,'<br>';
- $k++;
- if(!isset($matches[$k])) continue;
- $request->param($param, $matches[$k]);
- }
- }
- // echo '<br><b>Storage</b>: ';
- // print_r($this->storage);
- break;
- }
- }
- // save data to request storage
- $request->setStorage($this->storage);
- $this->route();
- }
- private final function route()
- {
- try{
- if(empty($this->storage)) return;
- $namespace = $this->namespace;
- $controller = ucfirst($this->controller);
- $action = $this->action == '' ? 'index' : $this->action;
- $action = rtrim($action,'/');
- $params = $this->params;
- // echo '<pre>'; print_r($this->storage); echo '<br>';
- $c = $namespace . $controller;
- $path= str_replace("\\", "/", $c);
- if(!file_exists(DOCROOT . $path . '.php')) {
- die('file not exist:' . DOCROOT . $path . '.php');
- }
- $controller = new $c;
- if(!is_callable(array($controller,$action))){
- die('File not is_callable: ' . DOCROOT . $path . '.php');
- }
- // $action = (is_callable(array($controller,$action))) ? $action : 'index';
- if(!empty($params)){
- $res = call_user_func_array(array($controller,$action),$params);
- } else{
- $res = call_user_func(array($controller,$action));
- }
- // save data to request storage
- $request = Request::instance();
- if($res) $request->body = $res;
- } catch (Exceptions $e){
- echo $e->showError();
- }
- }
- private static function protect($uri)
- {
- // '@<script[^>]*\?\>.*?</script>@si',
- $tags = array (
- '@\'@si',
- '@\[\[(.*?)\]\]@si',
- '@\[!(.*?)!\]@si',
- '@\[\~(.*?)\~\]@si',
- '@\[\((.*?)\)\]@si',
- '@{{(.*?)}}@si',
- '@\[\+(.*?)\+\]@si',
- '@\[\*(.*?)\*\]@si'
- );
- // Null is eval
- if (isset($_SERVER['QUERY_STRING']) && strpos(urldecode($_SERVER['QUERY_STRING']), chr(0)) !== false)
- die();
- // Unregister globals
- if (@ ini_get('register_globals')) {
- foreach ($_REQUEST as $key => $value) {
- $$key = null; // This is NOT paranoid because
- unset ($$key); // unset may not work.
- }
- }
- $uri = preg_replace($tags, "", $uri);
- $_GET = self::sanitize_gpc($_GET, $tags);
- $_POST = self::sanitize_gpc($_POST, $tags);
- $_COOKIE = self::sanitize_gpc($_COOKIE, $tags);
- $_REQUEST = self::sanitize_gpc($_REQUEST, $tags);
- unset($tags,$key,$value);
- return $uri;
- }
- private static function sanitize_gpc($target, $tags, $limit = 4)
- {
- foreach ($target as $key => $value) {
- if (is_array($value) && $limit > 0) {
- self::sanitize_gpc($value, $tags, $limit - 1);
- } else {
- $target[$key] = preg_replace($tags, "", $value);
- }
- }
- return $target;
- }
- /**
- * redirect to url vs headers
- * @param $url
- * @param string $header
- */
- public static function redirect($url, $header = '')
- {
- if(!empty($header)) {
- header ($header);
- }
- header("Location: {$url}"); die;
- }
- }