Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
30 / 30
Router
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
7 / 7
15
100.00% covered (success)
100.00%
30 / 30
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
6 / 6
 getDestination
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
8 / 8
 isHomePage
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 format
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 redirect
n/a
0 / 0
2
n/a
0 / 0
 redirectToIndex
n/a
0 / 0
1
n/a
0 / 0
 refresh
n/a
0 / 0
1
n/a
0 / 0
 getBaseUrl
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
6 / 6
 getRelativeUrl
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
7 / 7
 getSegments
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
<?php
namespace Win\Services;
use Win\InjectableTrait;
use Win\Utils\Input;
use Win\HttpException;
/**
 * Rota de URL
 *
 * Define o [Controller, action] a ser executado baseado na URL
 * "/config/routes.php"
 */
class Router
{
    use InjectableTrait;
    const HOME = ['index', 'index'];
    const SUFFIX = '/';
    /** @var string HTTPS/HTTP */
    public $protocol;
    /** @var string URL Base */
    public $baseUrl;
    /** @var string URL Relativa */
    public $relativeUrl;
    /** @var string URL Completa/Absoluta */
    public $url;
    /** @var string[] fragmentos da URL */
    public $segments;
    /** @var string Nome do Controller */
    public $page;
    /** @var string Nome do action */
    public $action;
    /** @var string[][] url => [Controller, action] */
    public $routes = [];
    public function __construct()
    {
        $this->protocol = Input::protocol();
        $this->baseUrl = $this->getBaseUrl();
        $this->relativeUrl = $this->getRelativeUrl();
        $this->segments = $this->getSegments();
        $this->url = $this->baseUrl . $this->relativeUrl;
    }
    /**
     * Percorre todas as rotas e retorna o destino final
     * @return array Destino
     * @example return [Controller, action, ...$args]
     */
    public function getDestination()
    {
        $url = $this->format($this->relativeUrl);
        $args = [];
        foreach ($this->routes as $request => $destination) {
            $pattern = '@^' . $this->format($request) . '$@';
            $match = preg_match($pattern, $url, $args);
            if ($match) {
                return [...$destination, ...array_splice($args, 1)];
            }
        }
        throw new HttpException('Route não encontrada, verifique: "config/routes.php"', 404);
    }
    /**
     * Retorna TRUE se está na página inicial
     * @return bool
     */
    public function isHomePage()
    {
        return $this->segments == static::HOME;
    }
    /**
     * Retorna no formato de URL
     * @param string $url
     * @return string
     */
    public function format($url)
    {
        return rtrim($url, static::SUFFIX) . static::SUFFIX;
    }
    /**
     * Redireciona para a URL escolhida
     * @param string $url URL relativa ou absoluta
     * @codeCoverageIgnore
     */
    public function redirect($url = '')
    {
        if (false === strpos($url, '://')) {
            $url = $this->baseUrl . $url;
        }
        header('location:' . $url);
        die();
    }
    /**
     * Volta para o método index da pagina atual
     * @codeCoverageIgnore
     */
    public function redirectToIndex()
    {
        $this->redirect($this->segments[0]);
    }
    /**
     * Atualiza a mesma página
     * @param string $url
     * @codeCoverageIgnore
     */
    public function refresh()
    {
        $this->redirect($this->url);
    }
    /**
     * Retorna a URL base
     * @return string
     */
    private function getBaseUrl()
    {
        $host = Input::server('HTTP_HOST');
        if ($host) {
            $script = Input::server('SCRIPT_NAME');
            $baseUrl = preg_replace('@/+$@', '', dirname($script));
            return $this->protocol . '://' . $host . $baseUrl . '/';
        }
    }
    /**
     * Define o final da URL
     * @return string
     */
    private function getRelativeUrl()
    {
        $host = Input::server('HTTP_HOST');
        if ($host) {
            $requestUri = explode('?', Input::server('REQUEST_URI'));
            $context = explode($host, $this->baseUrl);
            $uri = (explode(end($context), $requestUri[0], 2));
            return end($uri);
        }
    }
    /**
     * Define os fragmentos da URL
     * @return string[]
     */
    private function getSegments()
    {
        return array_filter(explode('/', $this->relativeUrl)) + static::HOME;
    }
}