Completed
Push — master ( ab9a78...953765 )
by Sinnarasa
02:47
created

Router::addMatcher()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace JetFire\Routing;
4
5
/**
6
 * Class Router
7
 * @package JetFire\Routing
8
 */
9
class Router
10
{
11
12
    /**
13
     * @var Route
14
     */
15
    public $route;
16
    /**
17
     * @var RouteCollection
18
     */
19
    public $collection;
20
    /**
21
     * @var
22
     */
23
    public $middleware;
24
    /**
25
     * @var
26
     */
27
    public $dispatcher;
28
29
    /**
30
     * @var array
31
     */
32
    private $config = [
33
        'matcher'            => ['JetFire\Routing\Match\RoutesMatch', 'JetFire\Routing\Match\SmartMatch'],
34
        'viewExtension'      => ['.html', '.php', '.json', '.xml'],
35
        'viewCallback'       => [],
36
        'di'                 => '',
37
        'generateRoutesPath' => false,
38
    ];
39
40
    /**
41
     * @param RouteCollection $collection
42
     */
43
    public function __construct(RouteCollection $collection)
44
    {
45
        $this->collection = $collection;
46
        $this->route = new Route();
47
        $this->config['di'] = function($class){
48
            return new $class;
49
        };
50
    }
51
52
    /**
53
     * @param array $config
54
     */
55
    public function setConfig($config)
56
    {
57
        $this->config = array_merge($this->config, $config);
58
    }
59
60
    /**
61
     * @return array
62
     */
63
    public function getConfig()
64
    {
65
        return $this->config;
66
    }
67
68
    /**
69
     * @param string $matcher
70
     */
71
    public function addMatcher($matcher){
72
        $this->config['matcher'][] = $matcher;
73
    }
74
75
    /**
76
     * @description main function to execute the router
77
     */
78
    public function run()
79
    {
80
        $this->setUrl();
81
        if ($this->config['generateRoutesPath']) $this->collection->generateRoutesPath();
82
        if ($this->match()) {
83
            $this->handle();
84
            $this->callTarget();
85
        }
86
        $this->callResponse();
87
    }
88
89
    /**
90
     * @param null $url
91
     */
92
    public function setUrl($url = null)
0 ignored issues
show
Coding Style introduced by
setUrl uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
setUrl uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
93
    {
94
        if (is_null($url))
95
            $url = (isset($_GET['url'])) ? $_GET['url'] : substr(str_replace(str_replace('/index.php', '', $_SERVER['SCRIPT_NAME']), '', $_SERVER['REQUEST_URI']), 1);
96
        $this->route->setUrl('/' . trim(explode('?', $url)[0], '/'));
97
    }
98
99
    /**
100
     * @return bool
101
     */
102
    public function match()
103
    {
104
        foreach ($this->config['matcher'] as $matcher) {
105
            $this->config['matcherInstance'][$matcher] = new $matcher($this);
106
            if (call_user_func([$this->config['matcherInstance'][$matcher], 'match']))
107
                return true;
108
        }
109
        return false;
110
    }
111
112
    /**
113
     * @return mixed
114
     */
115
    public function callTarget()
116
    {
117
        $target = $this->route->getTarget('dispatcher');
118
        $this->dispatcher = new $target($this->route);
119
        return call_user_func([$this->dispatcher, 'call']);
120
    }
121
122
    /**
123
     * @description handle middleware
124
     */
125
    private function handle()
126
    {
127
        $this->middleware = new Middleware($this);
128
        $this->middleware->globalMiddleware();
129
        $this->middleware->blockMiddleware();
130
        $this->middleware->classMiddleware();
131
        $this->middleware->routeMiddleware();
132
    }
133
134
    /**
135
     * @param array $responses
136
     */
137
    public function setResponse($responses = [])
138
    {
139
        $this->route->setResponse('templates', $responses);
140
    }
141
142
    /**
143
     * @description set response code
144
     */
145
    public function callResponse()
146
    {
147
        if (isset($this->route->getResponse()['templates']) && isset($this->route->getResponse()['templates'][$this->route->getResponse('code')])) {
148
            $this->route->setCallback($this->route->getResponse()['templates'][$this->route->getResponse('code')]);
149
            foreach($this->config['matcherInstance'] as $matcher) {
150
                foreach (call_user_func([$matcher, 'getMatcher']) as $match)
151
                    if (call_user_func([$matcher, $match])){ $this->callTarget(); break; }
152
            }
153
        }
154
        http_response_code($this->route->getResponse('code'));
155
    }
156
}
157