Passed
Push — master ( 609cb6...29f7ac )
by Anton
12:56
created

Std::reverse()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 40
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 7.0031

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 24
c 2
b 0
f 0
dl 0
loc 40
ccs 24
cts 25
cp 0.96
rs 8.6026
cc 7
nc 10
nop 2
crap 7.0031
1
<?php declare(strict_types=1);
2
3
namespace Phact\Router\Reverser;
4
5
use FastRoute\BadRouteException;
6
use Phact\Router\Reverser;
7
use LogicException;
8
9
use function is_string;
10
use function count;
11
use function in_array;
12
use function http_build_query;
13
14
class Std implements Reverser
15
{
16
    /**
17
     * @var array
18
     */
19
    protected $routes;
20
21 34
    public function __construct(array $routes)
22
    {
23 34
        $this->routes = $routes;
24 34
    }
25
26
    /**
27
     * @inheritDoc
28
     */
29 16
    public function reverse(string $routeName, array $variables = []): string
30
    {
31 16
        $this->hasRouteCheck($routeName);
32
33 15
        $route = $this->routes[$routeName];
34
35 15
        $url = '';
36 15
        $counter = -1;
37 15
        $usedParams = [];
38 15
        foreach ($route as $part) {
39 15
            if (is_string($part)) {
40 15
                $url .= $part;
41 15
                continue;
42
            }
43
44 11
            if ($counter === count($variables)) {
45
                throw new LogicException('Not enough parameters given');
46
            }
47
48 11
            $variableName = $part[0];
49 11
            $usedParams[] = $variableName;
50 11
            $counter++;
51
52 11
            if (isset($variables[$variableName])) {
53 8
                $url .= $variables[$variableName];
54 8
                continue;
55
            }
56
57 6
            if (isset($variables[$counter])) {
58 4
                $url .= $variables[$counter];
59 4
                continue;
60
            }
61
62 2
            throw new LogicException('Incorrect parameters given');
63
        }
64
65 13
        $query = $this->buildQuery($variables, $usedParams);
66 13
        $query = $query ? '?' . $query : '';
67
68 13
        return $url . $query;
69
    }
70
71
    /**
72
     * @param string $routeName
73
     */
74 16
    public function hasRouteCheck(string $routeName): void
75
    {
76 16
        if (!isset($this->routes[$routeName])) {
77 1
            throw new BadRouteException(sprintf(
78 1
                'Could not find route with name "%s"',
79 1
                $routeName
80
            ));
81
        }
82 15
    }
83
84
    /**
85
     * Build query string from unused params
86
     *
87
     * @param array $variables
88
     * @param array $usedParams
89
     * @return string
90
     */
91 13
    protected function buildQuery(array $variables, array $usedParams): string
92
    {
93 13
        $query = [];
94 13
        foreach ($variables as $param => $value) {
95 10
            if (is_string($param) && !in_array($param, $usedParams)) {
96 5
                $query[$param] = $value;
97
            }
98
        }
99 13
        if (!$query) {
100 8
            return '';
101
        }
102 5
        return http_build_query($query);
103
    }
104
}
105