Completed
Push — master ( 29f7ac...56fa27 )
by Anton
01:47
created

Std::buildQuery()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.6111
cc 5
nc 6
nop 2
crap 5
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 = 0;
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 1
                throw new LogicException('Not enough parameters given');
46
            }
47
48 11
            $variableName = $part[0];
49 11
            $usedParams[] = $variableName;
50
51 11
            $url .= $this->retrieveVariable($variables, $counter, $variableName);
52 10
            $counter++;
53
        }
54
55 13
        $query = $this->buildQuery($variables, $usedParams);
56 13
        $query = $query ? '?' . $query : '';
57
58 13
        return $url . $query;
59
    }
60
61
    /**
62
     * Get variables from variables by name or by index
63
     *
64
     * @param array $variables
65
     * @param int $index
66
     * @param string $variableName
67
     * @return string
68
     */
69 11
    public function retrieveVariable(array $variables, int $index, string $variableName): string
70
    {
71 11
        if (isset($variables[$variableName])) {
72 8
            return $variables[$variableName];
73
        }
74
75 5
        if (isset($variables[$index])) {
76 4
            return $variables[$index];
77
        }
78 1
        throw new LogicException('Incorrect parameters given');
79
    }
80
81
    /**
82
     * Check that route with given name exists
83
     *
84
     * @param string $routeName
85
     */
86 16
    public function hasRouteCheck(string $routeName): void
87
    {
88 16
        if (!isset($this->routes[$routeName])) {
89 1
            throw new BadRouteException(sprintf(
90 1
                'Could not find route with name "%s"',
91 1
                $routeName
92
            ));
93
        }
94 15
    }
95
96
    /**
97
     * Build query string from unused params
98
     *
99
     * @param array $variables
100
     * @param array $usedParams
101
     * @return string
102
     */
103 13
    protected function buildQuery(array $variables, array $usedParams): string
104
    {
105 13
        $query = [];
106 13
        foreach ($variables as $param => $value) {
107 10
            if (is_string($param) && !in_array($param, $usedParams)) {
108 5
                $query[$param] = $value;
109
            }
110
        }
111 13
        if (!$query) {
112 8
            return '';
113
        }
114 5
        return http_build_query($query);
115
    }
116
}
117