Passed
Pull Request — master (#22)
by Wanderson
02:51
created

Router::redirectToIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Win\Services;
4
5
use Win\Common\Traits\InjectableTrait;
6
use Win\Common\Utils\Input;
7
use Win\HttpException;
8
9
/**
10
 * Rota de URL
11
 *
12
 * Define o Controller@action a ser executado baseado na URL
13
 * @see "config/routes.php"
14
 */
15
class Router
16
{
17
	use InjectableTrait;
18
	const HOME = ['index', 'index'];
19
	const SUFFIX = '/';
20
21
	/** @var string HTTPS/HTTP */
22
	public $protocol;
23
24
	/** @var string URL Base */
25
	public $baseUrl;
26
27
	/** @var string URL Relativa */
28
	public $relativeUrl;
29
30
	/** @var string URL Completa/Absoluta */
31
	public $url;
32
33
	/** @var string[] fragmentos da URL */
34
	public $segments;
35
	public $page;
36
	public $action;
37
38
	/** @var string[] */
39
	protected $routes = [];
40
41
	public function __construct()
42
	{
43
		$this->protocol = Input::protocol();
44
		$this->baseUrl = $this->getBaseUrl();
45
		$this->relativeUrl = $this->getRelativeUrl();
46
		$this->segments = $this->getSegments();
47
		$this->url = $this->baseUrl . $this->relativeUrl;
48
	}
49
50
	/**
51
	 * Adiciona as rotas
52
	 * @param string $namespace
53
	 * @param string[] $routes
54
	 */
55
	public function add($namespace, $routes)
56
	{
57
		foreach ($routes as $request => $destination) {
58
			$this->routes[$request] = $namespace . $destination;
59
		}
60
	}
61
62
	/**
63
	 * Percorre todas as rotas e retorna o destino final
64
	 * @return array Destino
65
	 * @example return [Controller, action, ...$args]
66
	 */
67
	public function getDestination()
68
	{
69
		$url = $this->format($this->relativeUrl);
70
		$args = [];
71
72
		foreach ($this->routes as $request => $destination) {
73
			$pattern = '@^' . $this->format($request) . '$@';
74
			$match = preg_match($pattern, $url, $args);
75
			if ($match) {
76
				return [...explode('@', $destination), ...array_splice($args, 1)];
77
			}
78
		}
79
80
		throw new HttpException('Route not found, check "config/routes;php"', 404);
81
	}
82
83
84
	/**
85
	 * Retorna no formato de URL
86
	 * @param string $url
87
	 * @return string
88
	 */
89
	public function format($url)
90
	{
91
		return rtrim($url, static::SUFFIX) . static::SUFFIX;
92
	}
93
94
	/**
95
	 * Redireciona para a URL escolhida
96
	 * @param string $url URL relativa ou absoluta
97
	 * @codeCoverageIgnore
98
	 */
99
	public function redirect($url = '')
100
	{
101
		if (false === strpos($url, '://')) {
102
			$url = $this->baseUrl . $url;
103
		}
104
		header('location:' . $url);
105
		die();
106
	}
107
108
	/**
109
	 * Volta para o método index da pagina atual
110
	 * @codeCoverageIgnore
111
	 */
112
	public function redirectToIndex()
113
	{
114
		$this->redirect($this->segments[0]);
115
	}
116
117
	/**
118
	 * Atualiza a mesma página
119
	 * @param string $url
120
	 * @codeCoverageIgnore
121
	 */
122
	public function refresh()
123
	{
124
		$this->redirect($this->url);
125
	}
126
127
	/**
128
	 * Retorna a URL base
129
	 * @return string
130
	 */
131
	private function getBaseUrl()
132
	{
133
		$host = Input::server('HTTP_HOST');
134
		if ($host) {
135
			$script = Input::server('SCRIPT_NAME');
136
			$baseUrl = preg_replace('@/+$@', '', dirname($script));
137
			return $this->protocol . '://' . $host . $baseUrl . '/';
138
		}
139
	}
140
141
	/**
142
	 * Define o final da URL
143
	 * @return string
144
	 */
145
	private function getRelativeUrl()
146
	{
147
		$host = Input::server('HTTP_HOST');
148
		if ($host) {
149
			$requestUri = explode('?', Input::server('REQUEST_URI'));
150
			$context = explode($host, $this->baseUrl);
151
			$uri = (explode(end($context), $requestUri[0], 2));
152
			return end($uri);
153
		}
154
	}
155
156
	/**
157
	 * Define os fragmentos da URL
158
	 * @return string[]
159
	 */
160
	private function getSegments()
161
	{
162
		return array_filter(explode('/', $this->relativeUrl)) + static::HOME;
163
	}
164
}
165