Passed
Push — master ( 2d8943...988cde )
by Florian
03:21
created

ActiveChecker::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1.0019

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 13
ccs 7
cts 8
cp 0.875
crap 1.0019
rs 10
1
<?php
2
3
namespace JeroenNoten\LaravelAdminLte\Menu;
4
5
use Illuminate\Contracts\Routing\UrlGenerator;
6
use Illuminate\Http\Request;
7
use Illuminate\Support\Str;
8
9
class ActiveChecker
10
{
11
    /**
12
     * The request instance.
13
     *
14
     * @var Request
15
     */
16
    private $request;
17
18
    /**
19
     * The url generator instance.
20
     *
21
     * @var UrlGenerator
22
     */
23
    private $url;
24
25
    /**
26
     * Map between menu item properties and their respective test method.
27
     *
28
     * @var array
29
     */
30
    private $tests;
31
32
    /**
33
     * Constructor.
34
     *
35
     * @param UrlGenerator $url
36
     */
37 69
    public function __construct(UrlGenerator $url)
38
    {
39 69
        $this->request = $url->getRequest();
40 69
        $this->url = $url;
41
42
        // Fill the map with tests. These tests will check if a menu item is
43
        // active or not.
44
45
        $this->tests = [
46 69
            'submenu' => [$this, 'containsActive'],
47 69
            'active'  => [$this, 'isExplicitActive'],
48 69
            'href'    => [$this, 'checkPattern'],
49 69
            'url'     => [$this, 'checkPattern'],
50
        ];
51 69
    }
52
53
    /**
54
     * Checks if a menu item is currently active. Active items will be
55
     * highlighted.
56
     *
57
     * @param mixed $item The menu item to check
58
     * @return bool
59
     */
60 67
    public function isActive($item)
61
    {
62
        // Return true if any of the verification tests is met.
63
64 67
        foreach ($this->tests as $prop => $testFunc) {
65 67
            if (isset($item[$prop]) && $testFunc($item[$prop])) {
66 50
                return true;
67
            }
68
        }
69
70
        // Otherwise, returns false.
71
72 46
        return false;
73
    }
74
75
    /**
76
     * Checks if an array of items contains an active item.
77
     *
78
     * @param array $items The items to check
79
     * @return bool
80
     */
81 19
    protected function containsActive($items)
82
    {
83 19
        foreach ($items as $item) {
84 18
            if ($this->isActive($item)) {
85 5
                return true;
86
            }
87
        }
88
89 14
        return false;
90
    }
91
92
    /**
93
     * Checks if an item is active by explicit definition of 'active' state.
94
     *
95
     * @param bool|array $activeDef
96
     * @return bool
97
     */
98 29
    protected function isExplicitActive($activeDef)
99
    {
100
        // If the active definition is a bool, return it.
101
102 29
        if (is_bool($activeDef)) {
103 22
            return $activeDef;
104
        }
105
106
        // Otherwise, check if any of the url patterns that defines the active
107
        // state matches the requested url.
108
109 7
        foreach ($activeDef as $pattern) {
110 7
            if ($this->checkPattern($pattern)) {
111 5
                return true;
112
            }
113
        }
114
115 6
        return false;
116
    }
117
118
    /**
119
     * Checks if an url pattern matches the requested url.
120
     *
121
     * @param string $pattern
122
     * @return bool
123
     */
124 66
    protected function checkPattern($pattern)
125
    {
126
        // First, check if the pattern is a regular expression.
127
128 66
        if (Str::startsWith($pattern, 'regex:')) {
129 1
            $regex = Str::substr($pattern, 6);
130
131 1
            return (bool) preg_match($regex, $this->request->path());
132
        }
133
134
        // If pattern is not a regex, check if the requested url matches the
135
        // absolute path to the given pattern. When the pattern uses query
136
        // parameters, compare with the full url request.
137
138 65
        $pattern = preg_replace('@^https?://@', '*', $this->url->to($pattern));
139 65
        $request = $this->request->url();
140
141 65
        if (isset(parse_url($pattern)['query'])) {
142 2
            $request = $this->request->fullUrl();
143
        }
144
145 65
        return Str::is(trim($pattern), trim($request));
146
    }
147
}
148