Issues (10)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Menus/Menu.php (4 issues)

Labels

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Larabros\Laranav\Menus;
4
5
use Illuminate\Contracts\Routing\UrlGenerator;
6
use Illuminate\Contracts\View\Factory;
7
use Illuminate\Http\Request;
8
use Illuminate\Support\Collection;
9
10
class Menu
11
{
12
    /**
13
     * The unique name used to identify a `Menu` instance.
14
     *
15
     * @var string
16
     */
17
    protected $name;
18
19
    /**
20
     * The menu's items.
21
     *
22
     * @var Collection
23
     */
24
    protected $items;
25
26
    /**
27
     * Any configuration options for the menu.
28
     *
29
     * @var array
30
     */
31
    protected $config;
32
33
    /**
34
     * The incoming `Request` object.
35
     *
36
     * @var Request
37
     */
38
    protected $request;
39
40
    /**
41
     * An instance of `UrlGenerator` used to generate any URLs for the menu items.
42
     *
43
     * @var UrlGenerator
44
     */
45
    protected $generator;
46
47
    /**
48
     * The `Factory` instance used to generate the views.
49
     *
50
     * @var Factory
51
     */
52
    protected $viewFactory;
53
54
    /**
55
     * Create a new `Menu` instance.
56
     *
57
     * @param string       $name
58
     * @param array        $items
59
     * @param array        $config
60
     * @param UrlGenerator $generator
61
     * @param Factory      $viewFactory
62
     */
63 24
    public function __construct(
64
        $name,
65
        array $items,
66
        array $config,
67
        UrlGenerator $generator,
68
        Factory $viewFactory
69
    ) {
70 24
        $this->name        = $name;
71 24
        $this->config      = $config;
72 24
        $this->request     = $generator->getRequest();
0 ignored issues
show
The method getRequest() does not seem to exist on object<Illuminate\Contracts\Routing\UrlGenerator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
73 24
        $this->generator   = $generator;
74 24
        $this->viewFactory = $viewFactory;
75
76
        // Has to be done after other dependencies are set
77 24
        $this->items       = new Collection($this->createItems($items));
78 24
    }
79
80
    /**
81
     * Return name of `Menu` instance.
82
     *
83
     * @return string
84
     */
85 4
    public function getName()
86
    {
87 4
        return $this->name;
88
    }
89
90
    /**
91
     * Returns `Collection` of `Item` objects.
92
     *
93
     * @return Collection
94
     */
95 12
    public function getItems()
96
    {
97 12
        return $this->items;
98
    }
99
100
    /**
101
     * Adds multiple items to the menu.
102
     *
103
     * @param array $items
104
     */
105 16
    public function addItems(array $items)
106
    {
107 16
        $this->items = $this->items->merge($this->createItems($items));
108 16
    }
109
110
    /**
111
     * Adds an item to the menu.
112
     *
113
     * @param string       $title
114
     * @param array|string $item
115
     */
116 4
    public function addItem($title, $item)
117
    {
118 4
        $this->items->push($this->createItem($title, $item));
119 4
    }
120
121
    /**
122
     * Renders the menu as a HTML string and returns it.
123
     *
124
     * @return string
125
     */
126 8
    public function toHtml()
127
    {
128 8
        return $this->viewFactory
129 8
            ->make($this->config['view'], ['menuItems' => $this->items->all()])
130 8
            ->render();
131
    }
132
133
    /**
134
     * Creates and returns a `Collection` of `Items`.
135
     *
136
     * @param  array $items
137
     *
138
     * @return Collection
139
     */
140 16
    protected function createItems(array $items)
141
    {
142 16
        $itemCollection = [];
143 16
        foreach ($items as $title => $item) {
144 16
            $itemCollection[] = $this->createItem($title, $item);
145 16
        }
146 16
        return new Collection($itemCollection);
147
    }
148
149
    /**
150
     * Creates and returns a new instance of `Item`.
151
     *
152
     * @param  string        $title
153
     * @param  array|string  $item
154
     *
155
     * @return Item
156
     */
157 12
    protected function createItem($title, $item)
158
    {
159
        // The best way to be ;)
160 12
        $children = null;
161 12
        $url      = $item;
162
163
        // If `$item` is an array, then attempt to generate a URL from the
164
        // provided parameters.
165 12
        if ($this->isItemArray($item) && !$this->hasNestedItems($item)) {
166 6
            $url = $this->generateItemUrl($item);
167 6
        }
168
169
        // If `$item` is an array and has a `default` key, then it has children.
170 12
        if ($this->hasNestedItems($item)) {
171
            // Get `default` item URL
172 4
            $url = $this->generateItemUrl($item['default']);
173
174
            // Create a `Collection` of the children items
175 4
            $children = $this->createItems(array_except($item, 'default'));
0 ignored issues
show
It seems like $item defined by parameter $item on line 157 can also be of type string; however, array_except() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
176 4
        }
177
178 12
        return new Item(
179 12
            $title,
180 12
            $url,
0 ignored issues
show
It seems like $url defined by $item on line 161 can also be of type array; however, Larabros\Laranav\Menus\Item::__construct() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
181 12
            $this->isUrlActive($url),
0 ignored issues
show
It seems like $url defined by $item on line 161 can also be of type array; however, Larabros\Laranav\Menus\Menu::isUrlActive() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
182 12
            $children,
183 12
            $this->config['active_class'],
184 12
            $this->config['children_class']
185 12
        );
186
    }
187
188
    /**
189
     * Checks whether an item is an array and contains one of the following keys:
190
     *
191
     * - `to`
192
     * - `secure`
193
     * - `asset`
194
     * - `route`
195
     * - `action`
196
     *
197
     * @param  array|string  $item
198
     *
199
     * @return boolean
200
     */
201 20
    protected function isItemArray($item)
202
    {
203 20
        return is_array($item)
204 20
            && in_array(key($item), ['to', 'secure', 'asset', 'route', 'action']);
205
    }
206
207
    /**
208
     * Checks whether an item has a `default` key.
209
     *
210
     * @param  array|string  $item
211
     *
212
     * @return boolean
213
     */
214 20
    protected function hasNestedItems($item)
215
    {
216 20
        return is_array($item) && in_array('default', array_keys($item));
217
    }
218
219
    /**
220
     * Checks if a provided URL is active or not.
221
     *
222
     * @param  string  $url
223
     *
224
     * @return boolean
225
     */
226 20
    protected function isUrlActive($url)
227
    {
228 20
        $path = trim(str_replace($this->request->root(), '', $url), '/');
229 20
        return $this->request->is($path);
230
    }
231
232
    /**
233
     * Generates a URL using `UrlGenerator`. If `$item` is a string, then it is
234
     * returned unchanged. If `$item` is an array, the key of the array
235
     * corresponds to a method on the `UrlGenerator` instance, and the value is
236
     * passed as a parameter.
237
     *
238
     * @param  array|string $item
239
     *
240
     * @return string
241
     */
242 14
    protected function generateItemUrl($item)
243
    {
244 14
        if ($this->isItemArray($item)) {
245 10
            $type = key($item);
246 10
            return $this->generator->$type($item[$type]);
247
        }
248 4
        return $item;
249
    }
250
}
251