ActiveChecker::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

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