Completed
Push — master ( d88360...8e8e44 )
by Restu
13:44
created

Router::getRouteByPath()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 4
eloc 5
c 2
b 0
f 2
nc 3
nop 2
dl 0
loc 11
rs 9.2
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
        $method = $this->request->method();
70
        $route = $this->getRouteByPath($path, $method);
71
72
        if (!arr_has_key($route, "action")) {
73
            throw new \Exception("not found action for route id : " . arr_get($route, "id"));
74
        }
75
76
        $action = arr_get($route, "action");
77
78
        if (is_callable($action)) {
79
            // if use callback function
80
            $this->handleCallback($action);
81
        } elseif (arr_has_key($route, "controller") && is_string($action)) {
82
            // if use controller
83
            $this->handleController($route);
84
        } else {
85
            $this->response->setNotFound($path);
86
        }
87
88
        return $this->response;
89
    }
90
91
    private function handleCallback($func)
92
    {
93
        $content = call_user_func($func);
94
        $this->response->setContent($content);
95
    }
96
97
    /**
98
     * Handle Controller
99
     * @param $route
100
     */
101
    private function handleController($route)
102
    {
103
        $controller_class = "App\\Controller\\" . arr_get($route, "controller");
104
105
        if (!class_exists($controller_class)) {
106
            throw new \InvalidArgumentException("controller " . $controller_class . " not found");
107
        }
108
109
        $controller = new $controller_class($this->request, $this->response);
110
111
        $action = arr_get($route, "action");
112
113
        if (!method_exists($controller, $action)) {
114
            throw new \InvalidArgumentException("method " . $action . " not found");
115
        }
116
117
        $content = $controller->$action();
118
        $this->response->setContent($content);
119
    }
120
121
    /**
122
     * @param string $id
123
     * @return array
124
     */
125
    public function getRoute($id = null)
126
    {
127
        if (is_null($id)) {
128
            return $this->routes;
129
        }
130
131
        if (!is_string($id)) {
132
            throw new \InvalidArgumentException("var id must be a string");
133
        }
134
135
        foreach ($this->routes as $route) {
136
            if (arr_has_key($route, "id") && arr_get($route, "id") == $id) {
137
                return $route;
138
            }
139
        }
140
141
        throw new \OutOfBoundsException("not found route with id " . $id);
142
    }
143
144
    /**
145
     * @param string $path
146
     * @param string $method
147
     * @return array
148
     */
149
    public function getRouteByPath($path, $method)
150
    {
151
152
        foreach ($this->routes as $route) {
153
            if (arr_get($route, "path") == $path && arr_get($route, "method", "GET") == $method) {
154
                return $route;
155
            }
156
        }
157
158
        return null;
159
    }
160
161
    /**
162
     * @param array $routes
163
     */
164
    public function setRoutes($routes)
165
    {
166
        $this->routes = $routes;
167
    }
168
}
169