These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * WP Bootstrap Navwalker |
||
4 | * |
||
5 | * @package WP-Bootstrap-Navwalker |
||
6 | */ |
||
7 | |||
8 | /* |
||
9 | * Class Name: WP_Bootstrap_Navwalker |
||
10 | * Plugin Name: WP Bootstrap Navwalker |
||
11 | * Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker |
||
12 | * Description: A custom WordPress nav walker class to implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager. |
||
13 | * Author: Edward McIntyre - @twittem, WP Bootstrap, William Patton - @pattonwebz |
||
14 | * Version: 4.0.0 |
||
15 | * Author URI: https://github.com/wp-bootstrap |
||
16 | * GitHub Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker |
||
17 | * GitHub Branch: master |
||
18 | * License: GPL-3.0+ |
||
19 | * License URI: http://www.gnu.org/licenses/gpl-3.0.txt |
||
20 | */ |
||
21 | |||
22 | /* Check if Class Exists. */ |
||
23 | if ( ! class_exists( 'WP_Bootstrap_Navwalker' ) ) { |
||
24 | /** |
||
25 | * WP_Bootstrap_Navwalker class. |
||
26 | * |
||
27 | * @extends Walker_Nav_Menu |
||
28 | */ |
||
29 | class WP_Bootstrap_Navwalker extends Walker_Nav_Menu { |
||
30 | |||
31 | /** |
||
32 | * Starts the list before the elements are added. |
||
33 | * |
||
34 | * @since WP 3.0.0 |
||
35 | * |
||
36 | * @see Walker_Nav_Menu::start_lvl() |
||
37 | * |
||
38 | * @param string $output Used to append additional content (passed by reference). |
||
39 | * @param int $depth Depth of menu item. Used for padding. |
||
40 | * @param stdClass $args An object of wp_nav_menu() arguments. |
||
41 | */ |
||
42 | public function start_lvl( &$output, $depth = 0, $args = array() ) { |
||
43 | View Code Duplication | if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { |
|
0 ignored issues
–
show
|
|||
44 | $t = ''; |
||
45 | $n = ''; |
||
46 | } else { |
||
47 | $t = "\t"; |
||
48 | $n = "\n"; |
||
49 | } |
||
50 | $indent = str_repeat( $t, $depth ); |
||
51 | // Default class. |
||
52 | $classes = array( 'dropdown-menu' ); |
||
53 | /** |
||
54 | * Filters the CSS class(es) applied to a menu list element. |
||
55 | * |
||
56 | * @since WP 4.8.0 |
||
57 | * |
||
58 | * @param array $classes The CSS classes that are applied to the menu `<ul>` element. |
||
59 | * @param stdClass $args An object of `wp_nav_menu()` arguments. |
||
60 | * @param int $depth Depth of menu item. Used for padding. |
||
61 | */ |
||
62 | $class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) ); |
||
63 | $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; |
||
64 | /** |
||
65 | * The `.dropdown-menu` container needs to have a labelledby |
||
66 | * attribute which points to it's trigger link. |
||
67 | * |
||
68 | * Form a string for the labelledby attribute from the the latest |
||
69 | * link with an id that was added to the $output. |
||
70 | */ |
||
71 | // find all links with an id in the output. |
||
72 | preg_match_all( '/(<a.*?id=\"|\')(.*?)\"|\'.*?>/im', $output, $matches ); |
||
73 | // with pointer at end of array check if we got an ID match. |
||
74 | if ( end( $matches[2] ) ) { |
||
75 | // build a string to use as aria-labelledby. |
||
76 | $lablledby = 'aria-labelledby="' . end( $matches[2] ) . '"'; |
||
77 | } |
||
78 | $output .= "{$n}{$indent}<ul$class_names $lablledby role=\"menu\">{$n}"; |
||
0 ignored issues
–
show
The variable
$lablledby does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
79 | } |
||
80 | |||
81 | /** |
||
82 | * Starts the element output. |
||
83 | * |
||
84 | * @since WP 3.0.0 |
||
85 | * @since WP 4.4.0 The {@see 'nav_menu_item_args'} filter was added. |
||
86 | * |
||
87 | * @see Walker_Nav_Menu::start_el() |
||
88 | * |
||
89 | * @param string $output Used to append additional content (passed by reference). |
||
90 | * @param WP_Post $item Menu item data object. |
||
91 | * @param int $depth Depth of menu item. Used for padding. |
||
92 | * @param stdClass $args An object of wp_nav_menu() arguments. |
||
93 | * @param int $id Current item ID. |
||
94 | */ |
||
95 | public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { |
||
96 | View Code Duplication | if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
97 | $t = ''; |
||
98 | $n = ''; |
||
0 ignored issues
–
show
$n is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
99 | } else { |
||
100 | $t = "\t"; |
||
101 | $n = "\n"; |
||
0 ignored issues
–
show
$n is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
102 | } |
||
103 | $indent = ( $depth ) ? str_repeat( $t, $depth ) : ''; |
||
104 | |||
105 | $value = ''; |
||
106 | $class_names = $value; |
||
107 | $classes = empty( $item->classes ) ? array() : (array) $item->classes; |
||
108 | |||
109 | // Initialize some holder variables to store specially handled item |
||
110 | // wrappers and icons. |
||
111 | $extra_link_classes = array(); |
||
112 | $icon_classes = array(); |
||
113 | $icon_class_string = ''; |
||
0 ignored issues
–
show
$icon_class_string is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
114 | |||
115 | // Loop and begin handling any special linkmod or icon classes. |
||
116 | foreach ( $classes as $key => $class ) { |
||
117 | /** |
||
118 | * Find any custom link mods or icons, store in their holder |
||
119 | * arrays and remove them from the classes array. |
||
120 | * |
||
121 | * Supported linkmods: .disabled, .dropdown-header, .dropdown-divider |
||
122 | * Supported iconsets: Font Awesome 4/5, Glypicons |
||
123 | */ |
||
124 | if ( preg_match( '/disabled/', $class ) ) { |
||
125 | // Test for .disabled. |
||
126 | $extra_link_classes[] = $class; |
||
127 | unset( $classes[ $key ] ); |
||
128 | } elseif ( preg_match( '/dropdown-header|dropdown-divider/', $class ) && $depth > 0 ) { |
||
129 | // Test for .dropdown-header or .dropdown-divider and a |
||
130 | // depth greater than 0 - IE inside a dropdown. |
||
131 | $extra_link_classes[] = $class; |
||
132 | unset( $classes[ $key ] ); |
||
133 | } elseif ( preg_match( '/fa-(\S*)?|fas(\s?)|fa(\s?)/', $class ) ) { |
||
134 | // Font Awesome. |
||
135 | $icon_classes[] = $class; |
||
136 | unset( $classes[ $key ] ); |
||
137 | } elseif ( preg_match( '/glyphicons-(\S*)?|glyphicons(\s?)/', $class ) ) { |
||
138 | // Glyphicons. |
||
139 | $icon_classes[] = $class; |
||
140 | unset( $classes[ $key ] ); |
||
141 | } |
||
142 | } // End foreach(). |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
143 | |||
144 | // Join any icon classes plucked from $classes into a string. |
||
145 | $icon_class_string = join( ' ', $icon_classes ); |
||
146 | |||
147 | /** |
||
148 | * Filters the arguments for a single nav menu item. |
||
149 | * |
||
150 | * WP 4.4.0 |
||
151 | * |
||
152 | * @param stdClass $args An object of wp_nav_menu() arguments. |
||
153 | * @param WP_Post $item Menu item data object. |
||
154 | * @param int $depth Depth of menu item. Used for padding. |
||
155 | */ |
||
156 | $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth ); |
||
157 | |||
158 | $classes[] = 'menu-item-' . $item->ID; |
||
159 | $classes[] = 'nav-item'; |
||
160 | |||
161 | // Add .dropdown or .active classes where they are needed. |
||
162 | if ( $args->has_children ) { |
||
163 | $classes[] = 'dropdown'; |
||
164 | } |
||
165 | if ( in_array( 'current-menu-item', $classes, true ) || in_array( 'current-menu-parent', $classes, true ) ) { |
||
166 | $classes = 'active'; |
||
167 | } |
||
168 | |||
169 | // Allow filtering the classes. |
||
170 | $classes = apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ); |
||
171 | |||
172 | // Form a string of classes in format: class="class_names". |
||
173 | $class_names = join( ' ', $classes ); |
||
174 | $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; |
||
175 | |||
176 | /** |
||
177 | * Filters the ID applied to a menu item's list item element. |
||
178 | * |
||
179 | * @since WP 3.0.1 |
||
180 | * @since WP 4.1.0 The `$depth` parameter was added. |
||
181 | * |
||
182 | * @param string $menu_id The ID that is applied to the menu item's `<li>` element. |
||
183 | * @param WP_Post $item The current menu item. |
||
184 | * @param stdClass $args An object of wp_nav_menu() arguments. |
||
185 | * @param int $depth Depth of menu item. Used for padding. |
||
186 | */ |
||
187 | $id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth ); |
||
188 | $id = $id ? ' id="' . esc_attr( $id ) . '"' : ''; |
||
189 | |||
190 | $output .= $indent . '<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement"' . $id . $value . $class_names . '>'; |
||
191 | |||
192 | // initialize array for holding the $atts for the link item. |
||
193 | $atts = array(); |
||
194 | |||
195 | // Set title from item to the $atts array - if title is empty then |
||
196 | // default to item title. |
||
197 | if ( empty( $item->attr_title ) ) { |
||
198 | $atts['title'] = ! empty( $item->title ) ? strip_tags( $item->title ) : ''; |
||
199 | } else { |
||
200 | $atts['title'] = $item->attr_title; |
||
201 | } |
||
202 | |||
203 | $atts['target'] = ! empty( $item->target ) ? $item->target : ''; |
||
204 | $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : ''; |
||
205 | // If item has_children add atts to <a>. |
||
206 | if ( $args->has_children && 0 === $depth && $args->depth > 1 ) { |
||
207 | $atts['href'] = '#'; |
||
208 | $atts['data-toggle'] = 'dropdown'; |
||
209 | $atts['aria-haspopup'] = 'true'; |
||
210 | $atts['aria-expanded'] = 'false'; |
||
211 | $atts['class'] = 'dropdown-toggle nav-link'; |
||
212 | $atts['id'] = 'menu-item-dropdown-' . $item->ID; |
||
213 | } else { |
||
214 | $atts['href'] = ! empty( $item->url ) ? $item->url : ''; |
||
215 | // Items in dropdowns use .dropdown-item instead of .nav-link. |
||
216 | if ( $depth > 0 ) { |
||
217 | $atts['class'] = 'dropdown-item'; |
||
218 | } else { |
||
219 | $atts['class'] = 'nav-link'; |
||
220 | } |
||
221 | } |
||
222 | |||
223 | // Set this as an indetifier flag to ease identifying special item |
||
224 | // types later in the processing. Default will be '' or 'link'. |
||
225 | $type_flag = ''; |
||
226 | // Loop through the array of extra link classes plucked from the |
||
227 | // parent <li>s classes array. |
||
228 | if ( ! empty( $extra_link_classes ) ) { |
||
229 | foreach ( $extra_link_classes as $link_class ) { |
||
230 | if ( ! empty( $link_class ) ) { |
||
231 | // update $atts with the extra classname. |
||
232 | $atts['class'] .= ' ' . esc_attr( $link_class ); |
||
233 | |||
234 | // check for special class types we need additional handling for. |
||
235 | if ( 'disabled' === $link_class ) { |
||
236 | // Convert link to '#' and unset open targets. |
||
237 | $atts['href'] = '#'; |
||
238 | unset( $atts['target'] ); |
||
239 | } elseif ( 'dropdown-header' === $link_class ) { |
||
240 | // Store a type flag and unset href and target. |
||
241 | $type_flag = 'dropdown-header'; |
||
242 | unset( $atts['href'] ); |
||
243 | unset( $atts['target'] ); |
||
244 | } elseif ( 'dropdown-divider' === $link_class ) { |
||
245 | // Store a type flag and unset href and target. |
||
246 | $type_flag = 'dropdown-divider'; |
||
247 | unset( $atts['href'] ); |
||
248 | unset( $atts['target'] ); |
||
249 | } |
||
250 | } |
||
251 | } |
||
252 | } |
||
253 | |||
254 | // Allow filtering of the $atts array before using it. |
||
255 | $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args ); |
||
256 | |||
257 | // Build a string of html containing all the atts for the item. |
||
258 | $attributes = ''; |
||
259 | foreach ( $atts as $attr => $value ) { |
||
260 | if ( ! empty( $value ) ) { |
||
261 | $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); |
||
262 | $attributes .= ' ' . $attr . '="' . $value . '"'; |
||
263 | } |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * START appending the internal item contents to the output. |
||
268 | */ |
||
269 | $item_output = $args->before; |
||
270 | |||
271 | /** |
||
272 | * This is the start of the internal nav item. Depending on what |
||
273 | * kind of link mod we have we need different wrapper elements. |
||
274 | */ |
||
275 | if ( 'dropdown-header' === $type_flag ) { |
||
276 | // For a header use a span with the .h6 class instead of a real |
||
277 | // header tag so that it doesn't confuse screen readers. |
||
278 | $item_output .= '<span class="dropdown-header h6"' . $attributes . '>'; |
||
279 | } elseif ( 'dropdown-divider' === $type_flag ) { |
||
280 | // this is a divider. |
||
281 | $item_output .= '<div class="dropdown-divider"' . $attributes . '>'; |
||
282 | } else { |
||
283 | // With no link mod type set this must be a standard <a> tag. |
||
284 | $item_output .= '<a' . $attributes . '>'; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Initiate empty icon var, then if we have a string containing any |
||
289 | * icon classes form the icon markup with an <i> element. This is |
||
290 | * output inside of the item before the $title (the link text). |
||
291 | */ |
||
292 | $icon_html = ''; |
||
293 | if ( ! empty( $icon_class_string ) ) { |
||
294 | // append an <i> with the icon classes to what is output before links. |
||
295 | $icon_html = '<i class="' . esc_attr( $icon_class_string ) . '" aria-hidden="true"></i> '; |
||
296 | } |
||
297 | |||
298 | /** This filter is documented in wp-includes/post-template.php */ |
||
299 | $title = apply_filters( 'the_title', $item->title, $item->ID ); |
||
300 | /** |
||
301 | * Filters a menu item's title. |
||
302 | * |
||
303 | * @since 4.4.0 |
||
304 | * |
||
305 | * @param string $title The menu item's title. |
||
306 | * @param WP_Post $item The current menu item. |
||
307 | * @param stdClass $args An object of wp_nav_menu() arguments. |
||
308 | * @param int $depth Depth of menu item. Used for padding. |
||
309 | */ |
||
310 | $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth ); |
||
311 | |||
312 | // Put the item contents into $output. |
||
313 | $item_output .= $args->link_before . $icon_html . $title . $args->link_after; |
||
314 | |||
315 | /** |
||
316 | * This is the end of the internal nav item. We need to close the |
||
317 | * correct element depending on the type of link or link mod. |
||
318 | */ |
||
319 | if ( 'dropdown-header' === $type_flag ) { |
||
320 | // this is a header. |
||
321 | $item_output .= '</span>'; |
||
322 | } elseif ( 'dropdown-divider' === $type_flag ) { |
||
323 | // this is a divider. |
||
324 | $item_output .= '</div>'; |
||
325 | } else { |
||
326 | // it's most likely a link at this point. |
||
327 | $item_output .= '</a>'; |
||
328 | } |
||
329 | |||
330 | $item_output .= $args->after; |
||
331 | /** |
||
332 | * END appending the internal item contents to the output. |
||
333 | */ |
||
334 | |||
335 | $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); |
||
336 | |||
337 | } |
||
338 | |||
339 | /** |
||
340 | * Traverse elements to create list from elements. |
||
341 | * |
||
342 | * Display one element if the element doesn't have any children otherwise, |
||
343 | * display the element and its children. Will only traverse up to the max |
||
344 | * depth and no ignore elements under that depth. It is possible to set the |
||
345 | * max depth to include all depths, see walk() method. |
||
346 | * |
||
347 | * This method should not be called directly, use the walk() method instead. |
||
348 | * |
||
349 | * @since WP 2.5.0 |
||
350 | * |
||
351 | * @see Walker::start_lvl() |
||
352 | * |
||
353 | * @param object $element Data object. |
||
354 | * @param array $children_elements List of elements to continue traversing (passed by reference). |
||
355 | * @param int $max_depth Max depth to traverse. |
||
356 | * @param int $depth Depth of current element. |
||
357 | * @param array $args An array of arguments. |
||
358 | * @param string $output Used to append additional content (passed by reference). |
||
359 | */ |
||
360 | public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) { |
||
361 | if ( ! $element ) { |
||
362 | return; } |
||
363 | $id_field = $this->db_fields['id']; |
||
364 | // Display this element. |
||
365 | if ( is_object( $args[0] ) ) { |
||
366 | $args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] ); } |
||
367 | parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * Menu Fallback |
||
372 | * ============= |
||
373 | * If this function is assigned to the wp_nav_menu's fallback_cb variable |
||
374 | * and a menu has not been assigned to the theme location in the WordPress |
||
375 | * menu manager the function with display nothing to a non-logged in user, |
||
376 | * and will add a link to the WordPress menu manager if logged in as an admin. |
||
377 | * |
||
378 | * @param array $args passed from the wp_nav_menu function. |
||
379 | */ |
||
380 | public static function fallback( $args ) { |
||
381 | if ( current_user_can( 'edit_theme_options' ) ) { |
||
382 | |||
383 | /* Get Arguments. */ |
||
384 | $container = $args['container']; |
||
385 | $container_id = $args['container_id']; |
||
386 | $container_class = $args['container_class']; |
||
387 | $menu_class = $args['menu_class']; |
||
388 | $menu_id = $args['menu_id']; |
||
389 | |||
390 | // initialize var to store fallback html. |
||
391 | $fallback_output = ''; |
||
392 | |||
393 | if ( $container ) { |
||
394 | $fallback_output .= '<' . esc_attr( $container ); |
||
395 | if ( $container_id ) { |
||
396 | $fallback_output .= ' id="' . esc_attr( $container_id ) . '"'; |
||
397 | } |
||
398 | if ( $container_class ) { |
||
399 | $fallback_output .= ' class="' . esc_attr( $container_class ) . '"'; |
||
400 | } |
||
401 | $fallback_output .= '>'; |
||
402 | } |
||
403 | $fallback_output .= '<ul'; |
||
404 | if ( $menu_id ) { |
||
405 | $fallback_output .= ' id="' . esc_attr( $menu_id ) . '"'; } |
||
406 | if ( $menu_class ) { |
||
407 | $fallback_output .= ' class="' . esc_attr( $menu_class ) . '"'; } |
||
408 | $fallback_output .= '>'; |
||
409 | $fallback_output .= '<li><a href="' . esc_url( admin_url( 'nav-menus.php' ) ) . '" title="">' . esc_attr( 'Add a menu', '' ) . '</a></li>'; |
||
410 | $fallback_output .= '</ul>'; |
||
411 | if ( $container ) { |
||
412 | $fallback_output .= '</' . esc_attr( $container ) . '>'; |
||
413 | } |
||
414 | |||
415 | // if $args has 'echo' key and it's true echo, otherwise return. |
||
416 | if ( array_key_exists( 'echo', $args ) && $args['echo'] ) { |
||
417 | echo $fallback_output; // WPCS: XSS OK. |
||
418 | } else { |
||
419 | return $fallback_output; |
||
420 | } |
||
421 | } // End if(). |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
422 | } |
||
423 | } |
||
424 | } // End if(). |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
425 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.