Completed
Push — master ( 6c9a0a...d88360 )
by Restu
11:05
created

Router::handle()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 2
Metric Value
cc 5
eloc 13
c 4
b 0
f 2
nc 4
nop 0
dl 0
loc 22
rs 8.6737
1
<?php
2
namespace JayaCode\Framework\Core\Router;
3
4
use JayaCode\Framework\Core\Http\Request;
5
use JayaCode\Framework\Core\Http\Response;
6
7
class Router
8
{
9
    /**
10
     * @var array
11
     */
12
    public $routes = array(
13
        [
14
            "id"    => "home",
15
            "path"  => "/",
16
            "controller"    => "HomeController",
17
            "action"        => "index"
18
        ]
19
    );
20
21
    /**
22
     * @var Request
23
     */
24
    public $request;
25
26
    /**
27
     * @var Response
28
     */
29
    public $response;
30
31
    /**
32
     * Router constructor.
33
     * @param Request $request
34
     * @param Response $response
35
     */
36
    public function __construct(Request &$request = null, Response &$response = null)
37
    {
38
        $this->initialize($request, $response);
39
    }
40
41
    /**
42
     * initialize Router
43
     * @param Request $request
44
     * @param Response $response
45
     */
46
    public function initialize(Request &$request = null, Response &$response = null)
47
    {
48
        $this->request = &$request;
49
        $this->response = &$response;
50
    }
51
52
    /**
53
     * Create Router object from static function
54
     * @param Request $request
55
     * @param Response $response
56
     * @return Router
57
     */
58
    public static function create(Request &$request = null, Response &$response = null)
59
    {
60
        return new Router($request, $response);
61
    }
62
63
    /**
64
     * Handle request
65
     */
66
    public function handle()
67
    {
68
        $path = $this->request->path();
69
        $route = $this->getRouteByPath($path);
70
71
        if (!arr_has_key($route, "action")) {
72
            throw new \Exception("not found action for route id : " . arr_get($route, "id"));
73
        }
74
75
        if (is_callable(arr_get($route, "action"))) {
76
            // if use callback function
77
            $content = call_user_func(arr_get($route, "action"));
78
            $this->response->setContent($content);
79
        } elseif (arr_has_key($route, "controller") && is_string(arr_get($route, "action"))) {
80
            // if use controller
81
            $this->handleController($route);
82
        } else {
83
            $this->response->setNotFound($path);
84
        }
85
86
        return $this->response;
87
    }
88
89
    /**
90
     * @param $route
91
     */
92
    private function handleController($route)
93
    {
94
        $controller_class = "App\\Controller\\" . arr_get($route, "controller");
95
96
        if (!class_exists($controller_class)) {
97
            throw new \InvalidArgumentException("controller " . $controller_class . " not found");
98
        }
99
100
        $controller = new $controller_class($this->request, $this->response);
101
102
        $action = arr_get($route, "action");
103
104
        if (!method_exists($controller, $action)) {
105
            throw new \InvalidArgumentException("method " . $action . " not found");
106
        }
107
108
        $content = $controller->$action();
109
        $this->response->setContent($content);
110
    }
111
112
    /**
113
     * @param string $id
114
     * @return array
115
     */
116
    public function getRoute($id = null)
117
    {
118
        if (is_null($id)) {
119
            return $this->routes;
120
        }
121
122
        if (!is_string($id)) {
123
            throw new \InvalidArgumentException("var id must be a string");
124
        }
125
126
        foreach ($this->routes as $route) {
127
            if (arr_has_key($route, "id") && arr_get($route, "id") == $id) {
128
                return $route;
129
            }
130
        }
131
132
        throw new \OutOfBoundsException("not found route with id " . $id);
133
    }
134
135
    /**
136
     * @param string $path
137
     * @return array
138
     */
139
    public function getRouteByPath($path = null)
140
    {
141
        if (!is_string($path)) {
142
            throw new \InvalidArgumentException("var path must be a string");
143
        }
144
145
        foreach ($this->routes as $route) {
146
            if (arr_has_key($route, "path") && arr_get($route, "path") == $path) {
147
                return $route;
148
            }
149
        }
150
151
        return null;
152
    }
153
154
    /**
155
     * @param array $routes
156
     */
157
    public function setRoutes($routes)
158
    {
159
        $this->routes = $routes;
160
    }
161
}
162