Issues (2473)

Branch: master

Security Analysis    no vulnerabilities found

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.

engine/lib/navigation.php (3 issues)

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
 * Elgg navigation library
4
 * Functions for managing menus and other navigational elements
5
 *
6
 * Breadcrumbs
7
 * Elgg uses a breadcrumb stack. The page handlers (controllers in MVC terms)
8
 * push the breadcrumb links onto the stack. @see elgg_push_breadcrumb()
9
 *
10
 *
11
 * Pagination
12
 * Automatically handled by Elgg when using elgg_list_entities* functions.
13
 * @see elgg_list_entities()
14
 *
15
 *
16
 * Tabs
17
 * @see navigation/tabs view
18
 *
19
 *
20
 * Menus
21
 * Elgg uses a single interface to manage its menus. Menu items are added with
22
 * {@link elgg_register_menu_item()}. This is generally used for menus that
23
 * appear only once per page. For dynamic menus (such as the hover
24
 * menu for user's avatar), a plugin hook is emitted when the menu is being
25
 * created. The hook is 'register', 'menu:<menu_name>'. For more details on this,
26
 * @see elgg_view_menu().
27
 *
28
 * Menus supported by the Elgg core
29
 * Standard menus:
30
 *     site   Site navigation shown on every page.
31
 *     page   Page menu usually shown in a sidebar. Uses Elgg's context.
32
 *     topbar Topbar menu shown on every page. The default has two sections.
33
 *     footer Like the topbar but in the footer.
34
 *     extras Links about content on the page. The RSS link is added to this.
35
 *
36
 * Dynamic menus (also called just-in-time menus):
37
 *     user_hover  Avatar hover menu. The user entity is passed as a parameter.
38
 *     entity      The set of links shown in the summary of an entity.
39
 *     river       Links shown on river items.
40
 *     owner_block Links shown for a user or group in their owner block.
41
 *     filter      The tab filter for content (all, mine, friends)
42
 *     title       The buttons shown next to a content title.
43
 *     longtext    The links shown above the input/longtext view.
44
 *     login       Menu of links at bottom of login box
45
 *
46
 * @package    Elgg.Core
47
 * @subpackage Navigation
48
 */
49
50
/**
51
 * Register an item for an Elgg menu
52
 *
53
 * @warning Generally you should not use this in response to the plugin hook:
54
 * 'register', 'menu:<menu_name>'. If you do, you may end up with many incorrect
55
 * links on a dynamic menu.
56
 *
57
 * @warning A menu item's name must be unique per menu. If more than one menu
58
 * item with the same name are registered, the last menu item takes priority.
59
 *
60
 * @see elgg_view_menu() for the plugin hooks available for modifying a menu as
61
 * it is being rendered.
62
 *
63
 * @see ElggMenuItem::factory() is used to turn an array value of $menu_item into an
64
 * ElggMenuItem object.
65
 *
66
 * @param string $menu_name The name of the menu: site, page, userhover,
67
 *                          userprofile, groupprofile, or any custom menu
68
 * @param mixed  $menu_item A \ElggMenuItem object or an array of options in format:
69
 *                          name        => STR  Menu item identifier (required)
70
 *                          text        => STR  Menu item display text as HTML (required)
71
 *                          href        => STR  Menu item URL (required) (false for non-links.
72
 *                                              @warning If you disable the href the <a> tag will
73
 *                                              not appear, so the link_class will not apply. If you
74
 *                                              put <a> tags in manually through the 'text' option
75
 *                                              the default CSS selector .elgg-menu-$menu > li > a
76
 *                                              may affect formatting. Wrap in a <span> if it does.)
77
 *                          contexts    => ARR  Page context strings
78
 *                          section     => STR  Menu section identifier
79
 *                          title       => STR  Menu item tooltip
80
 *                          selected    => BOOL Is this menu item currently selected
81
 *                          parent_name => STR  Identifier of the parent menu item
82
 *                          link_class  => STR  A class or classes for the <a> tag
83
 *                          item_class  => STR  A class or classes for the <li> tag
84
 *
85
 *                          Additional options that the view output/url takes can be
86
 *							passed in the array. Custom options can be added by using
87
 *							the 'data' key with the	value being an associative array.
88
 *
89
 * @return bool False if the item could not be added
90
 * @since 1.8.0
91
 */
92
function elgg_register_menu_item($menu_name, $menu_item) {
93 1
	global $CONFIG;
94
95 1
	if (is_array($menu_item)) {
96 1
		$options = $menu_item;
97 1
		$menu_item = \ElggMenuItem::factory($options);
98 1
		if (!$menu_item) {
99 1
			$menu_item_name = elgg_extract('name', $options, 'MISSING NAME');
100 1
			elgg_log("Unable to add menu item '{$menu_item_name}' to '$menu_name' menu", 'WARNING');
101 1
			return false;
102
		}
103 1
	}
104
105 1
	if (!$menu_item instanceof ElggMenuItem) {
106 1
		elgg_log('Second argument of elgg_register_menu_item() must be an instance of ElggMenuItem or an array of menu item factory options', 'ERROR');
107 1
		return false;
108
	}
109
110 1
	if (!isset($CONFIG->menus[$menu_name])) {
111 1
		$CONFIG->menus[$menu_name] = array();
112 1
	}
113 1
	$CONFIG->menus[$menu_name][] = $menu_item;
114 1
	return true;
115
}
116
117
/**
118
 * Remove an item from a menu
119
 *
120
 * @param string $menu_name The name of the menu
121
 * @param string $item_name The unique identifier for this menu item
122
 *
123
 * @return \ElggMenuItem|null
124
 * @since 1.8.0
125
 */
126
function elgg_unregister_menu_item($menu_name, $item_name) {
127
	global $CONFIG;
128
129
	if (empty($CONFIG->menus[$menu_name])) {
130
		return null;
131
	}
132
133
	foreach ($CONFIG->menus[$menu_name] as $index => $menu_object) {
134
		/* @var \ElggMenuItem $menu_object */
135
		if ($menu_object instanceof ElggMenuItem && $menu_object->getName() == $item_name) {
136
			$item = $CONFIG->menus[$menu_name][$index];
137
			unset($CONFIG->menus[$menu_name][$index]);
138
			return $item;
139
		}
140
	}
141
142
	return null;
143
}
144
145
/**
146
 * Check if a menu item has been registered
147
 *
148
 * @param string $menu_name The name of the menu
149
 * @param string $item_name The unique identifier for this menu item
150
 * 
151
 * @return bool
152
 * @since 1.8.0
153
 */
154
function elgg_is_menu_item_registered($menu_name, $item_name) {
155
	global $CONFIG;
156
157
	if (!isset($CONFIG->menus[$menu_name])) {
158
		return false;
159
	}
160
161
	foreach ($CONFIG->menus[$menu_name] as $menu_object) {
162
		/* @var \ElggMenuItem $menu_object */
163
		if ($menu_object->getName() == $item_name) {
164
			return true;
165
		}
166
	}
167
168
	return false;
169
}
170
171
/**
172
 * Get a menu item registered for a menu
173
 *
174
 * @param string $menu_name The name of the menu
175
 * @param string $item_name The unique identifier for this menu item
176
 *
177
 * @return ElggMenuItem|null
178
 * @since 1.9.0
179
 */
180
function elgg_get_menu_item($menu_name, $item_name) {
181
	global $CONFIG;
182
183
	if (!isset($CONFIG->menus[$menu_name])) {
184
		return null;
185
	}
186
187
	foreach ($CONFIG->menus[$menu_name] as $index => $menu_object) {
188
		/* @var \ElggMenuItem $menu_object */
189
		if ($menu_object->getName() == $item_name) {
190
			return $CONFIG->menus[$menu_name][$index];
191
		}
192
	}
193
194
	return null;
195
}
196
197
/**
198
 * Convenience function for registering a button to the title menu
199
 *
200
 * The URL must be $handler/$name/$guid where $guid is the guid of the page owner.
201
 * The label of the button is "$handler:$name" so that must be defined in a
202
 * language file.
203
 *
204
 * This is used primarily to support adding an add content button
205
 *
206
 * @param string $handler The handler to use or null to autodetect from context
207
 * @param string $name    Name of the button
208
 * @return void
209
 * @since 1.8.0
210
 */
211
function elgg_register_title_button($handler = null, $name = 'add') {
212
	if (elgg_is_logged_in()) {
213
214
		if (!$handler) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $handler of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
215
			$handler = elgg_get_context();
216
		}
217
218
		$owner = elgg_get_page_owner_entity();
219
		if (!$owner) {
220
			// no owns the page so this is probably an all site list page
221
			$owner = elgg_get_logged_in_user_entity();
222
		}
223
		if ($owner && $owner->canWriteToContainer()) {
224
			$guid = $owner->getGUID();
225
			elgg_register_menu_item('title', array(
226
				'name' => $name,
227
				'href' => "$handler/$name/$guid",
228
				'text' => elgg_echo("$handler:$name"),
229
				'link_class' => 'elgg-button elgg-button-action',
230
			));
231
		}
232
	}
233
}
234
235
/**
236
 * Adds a breadcrumb to the breadcrumbs stack.
237
 *
238
 * See elgg_get_breadcrumbs() and the navigation/breadcrumbs view.
239
 *
240
 * @param string $title The title to display. During rendering this is HTML encoded.
241
 * @param string $link  Optional. The link for the title. During rendering links are
242
 *                      normalized via elgg_normalize_url().
243
 *
244
 * @return void
245
 * @since 1.8.0
246
 * @see elgg_get_breadcrumbs
247
 */
248
function elgg_push_breadcrumb($title, $link = null) {
249 3
	global $CONFIG;
250 3
	if (!isset($CONFIG->breadcrumbs)) {
251 3
		$CONFIG->breadcrumbs = array();
252 3
	}
253
254 3
	$CONFIG->breadcrumbs[] = array('title' => $title, 'link' => $link);
255 3
}
256
257
/**
258
 * Removes last breadcrumb entry.
259
 *
260
 * @return array popped breadcrumb array or empty array
261
 * @since 1.8.0
262
 */
263
function elgg_pop_breadcrumb() {
264 1
	global $CONFIG;
265
266 1
	if (empty($CONFIG->breadcrumbs) || !is_array($CONFIG->breadcrumbs)) {
267
		return array();
268
	}
269 1
	return array_pop($CONFIG->breadcrumbs);
270
}
271
272
/**
273
 * Returns all breadcrumbs as an array of array('title' => 'Title', 'link' => 'URL')
274
 *
275
 * Since 1.11, breadcrumbs are filtered through the plugin hook [prepare, breadcrumbs] before
276
 * being returned.
277
 *
278
 * @return array Breadcrumbs
279
 * @since 1.8.0
280
 * @see elgg_prepare_breadcrumbs
281
 */
282
function elgg_get_breadcrumbs() {
283 3
	global $CONFIG;
284
285
	// if no crumbs set, still allow hook to populate it
286 3
	if (isset($CONFIG->breadcrumbs) && is_array($CONFIG->breadcrumbs)) {
287 3
		$breadcrumbs = $CONFIG->breadcrumbs;
288 3
	} else {
289
		$breadcrumbs = array();
290
	}
291
292
	$params = array(
293 3
		'breadcrumbs' => $breadcrumbs,
294 3
	);
295 3
	$breadcrumbs = elgg_trigger_plugin_hook('prepare', 'breadcrumbs', $params, $breadcrumbs);
296 3
	if (!is_array($breadcrumbs)) {
297
		return array();
298
	}
299
300 3
	return $breadcrumbs;
301
}
302
303
/**
304
 * Hook handler to turn titles into 100-character excerpts. To remove this behavior, unregister this
305
 * function from the [prepare, breadcrumbs] hook.
306
 *
307
 * @param string $hook        "prepare"
308
 * @param string $type        "breadcrumbs"
309
 * @param array  $breadcrumbs Breadcrumbs to be altered
310
 * @param array  $params      Hook parameters
311
 *
312
 * @return array
313
 * @since 1.11
314
 */
315
function elgg_prepare_breadcrumbs($hook, $type, $breadcrumbs, $params) {
316
	foreach (array_keys($breadcrumbs) as $i) {
317
		$breadcrumbs[$i]['title'] = elgg_get_excerpt($breadcrumbs[$i]['title'], 100);
318
	}
319
	return $breadcrumbs;
320
}
321
322
/**
323
 * Set up the site menu
324
 *
325
 * Handles default, featured, and custom menu items
326
 *
327
 * @access private
328
 */
329
function _elgg_site_menu_setup($hook, $type, $return, $params) {
330
331
	$featured_menu_names = elgg_get_config('site_featured_menu_names');
332
	$custom_menu_items = elgg_get_config('site_custom_menu_items');
333
	if ($featured_menu_names || $custom_menu_items) {
334
		// we have featured or custom menu items
335
336
		$registered = $return['default'];
337
		/* @var \ElggMenuItem[] $registered */
338
339
		// set up featured menu items
340
		$featured = array();
341
		foreach ($featured_menu_names as $name) {
342
			foreach ($registered as $index => $item) {
343
				if ($item->getName() == $name) {
344
					$featured[] = $item;
345
					unset($registered[$index]);
346
				}
347
			}
348
		}
349
350
		// add custom menu items
351
		$n = 1;
352
		foreach ($custom_menu_items as $title => $url) {
353
			$item = new \ElggMenuItem("custom$n", $title, $url);
354
			$featured[] = $item;
355
			$n++;
356
		}
357
358
		$return['default'] = $featured;
359
		if (count($registered) > 0) {
360
			$return['more'] = $registered;
361
		}
362
	} else {
363
		// no featured menu items set
364
		$max_display_items = 5;
365
366
		// the first n are shown, rest added to more list
367
		// if only one item on more menu, stick it with the rest
368
		$num_menu_items = count($return['default']);
369
		if ($num_menu_items > ($max_display_items + 1)) {
370
			$return['more'] = array_splice($return['default'], $max_display_items);
371
		}
372
	}
373
	
374
	// check if we have anything selected
375
	$selected = false;
376
	foreach ($return as $section) {
377
		/* @var \ElggMenuItem[] $section */
378
379
		foreach ($section as $item) {
380
			if ($item->getSelected()) {
381
				$selected = true;
382
				break 2;
383
			}
384
		}
385
	}
386
	
387
	if (!$selected) {
388
		// nothing selected, match name to context or match url
389
		$current_url = current_page_url();
390
		foreach ($return as $section_name => $section) {
391
			foreach ($section as $key => $item) {
392
				// only highlight internal links
393
				if (strpos($item->getHref(), elgg_get_site_url()) === 0) {
394
					if ($item->getName() == elgg_get_context()) {
395
						$return[$section_name][$key]->setSelected(true);
396
						break 2;
397
					}
398
					if ($item->getHref() == $current_url) {
399
						$return[$section_name][$key]->setSelected(true);
400
						break 2;
401
					}
402
				}
403
			}
404
		}
405
	}
406
407
	return $return;
408
}
409
410
/**
411
 * Add the comment and like links to river actions menu
412
 * @access private
413
 */
414
function _elgg_river_menu_setup($hook, $type, $return, $params) {
415
	if (elgg_is_logged_in()) {
416
		$item = $params['item'];
417
		/* @var \ElggRiverItem $item */
418
		$object = $item->getObjectEntity();
419
		// add comment link but annotations cannot be commented on
420
		if ($item->annotation_id == 0) {
421
			if ($object->canComment()) {
422
				$options = array(
423
					'name' => 'comment',
424
					'href' => "#comments-add-$object->guid",
425
					'text' => elgg_view_icon('speech-bubble'),
426
					'title' => elgg_echo('comment:this'),
427
					'rel' => 'toggle',
428
					'priority' => 50,
429
				);
430
				$return[] = \ElggMenuItem::factory($options);
431
			}
432
		}
433
		
434
		if (elgg_is_admin_logged_in()) {
435
			$options = array(
436
				'name' => 'delete',
437
				'href' => elgg_add_action_tokens_to_url("action/river/delete?id=$item->id"),
438
				'text' => elgg_view_icon('delete'),
439
				'title' => elgg_echo('river:delete'),
440
				'confirm' => elgg_echo('deleteconfirm'),
441
				'priority' => 200,
442
			);
443
			$return[] = \ElggMenuItem::factory($options);
444
		}
445
	}
446
447
	return $return;
448
}
449
450
/**
451
 * Entity menu is list of links and info on any entity
452
 * @access private
453
 */
454
function _elgg_entity_menu_setup($hook, $type, $return, $params) {
455
	if (elgg_in_context('widgets')) {
456
		return $return;
457
	}
458
	
459
	$entity = $params['entity'];
460
	/* @var \ElggEntity $entity */
461
	$handler = elgg_extract('handler', $params, false);
462
463
	// access
464
	if (elgg_is_logged_in()) {
465
		$access = elgg_view('output/access', array('entity' => $entity));
466
		$options = array(
467
			'name' => 'access',
468
			'text' => $access,
469
			'href' => false,
470
			'priority' => 100,
471
		);
472
		$return[] = \ElggMenuItem::factory($options);
473
	}
474
	
475
	if ($entity->canEdit() && $handler) {
476
477
			// edit link
478
		$user = elgg_get_logged_in_user_entity();
479
        $page_owner = elgg_get_page_owner_entity();
480
            if($entity->getSubtype() == 'discussion_reply' ){
481
				if($page_owner!=''||$page_owner!=null){
482
                if($entity->owner_guid == $user['guid'] || elgg_is_admin_logged_in() || ($page_owner instanceof ElggGroup && $page_owner->getOwnerGUID() == $user['guid']) || $page_owner->canEdit()){
483
					$options = array(
484
						'name' => 'edit',
485
						'text' => elgg_echo('edit'),
486
						'title' => elgg_echo('edit:this'),
487
						'href' => "$handler/edit/{$entity->getGUID()}",
488
						'priority' => 200,
489
					);
490
					$return[] = \ElggMenuItem::factory($options);
491
492 View Code Duplication
					if(elgg_is_logged_in()){
493
494
						// delete link
495
						$options = array(
496
							'name' => 'delete',
497
							'text' => elgg_view_icon('delete'),
498
							'title' => elgg_echo('delete:this'),
499
							'href' => "action/$handler/delete?guid={$entity->getGUID()}",
500
							'confirm' => elgg_echo('deleteconfirm'),
501
							'priority' => 300,
502
						);
503
						$return[] = \ElggMenuItem::factory($options);
504
					}
505
				}
506
			}
507
			}else{
508
509
				$options = array(
510
					'name' => 'edit',
511
					'text' => elgg_echo('edit'),
512
					'title' => elgg_echo('edit:this'),
513
					'href' => "$handler/edit/{$entity->getGUID()}",
514
					'priority' => 200,
515
				);
516
				$return[] = \ElggMenuItem::factory($options);
517
518 View Code Duplication
				if(elgg_is_logged_in()){
519
520
					// delete link
521
					$options = array(
522
						'name' => 'delete',
523
						'text' => elgg_view_icon('delete'),
524
						'title' => elgg_echo('delete:this'),
525
						'href' => "action/$handler/delete?guid={$entity->getGUID()}",
526
						'confirm' => elgg_echo('deleteconfirm'),
527
						'priority' => 300,
528
					);
529
					$return[] = \ElggMenuItem::factory($options);
530
				}
531
			}
532
		}
533
534
	return $return;
535
}
536
537
function widget_check_collapsed_state($widget_guid, $state) {
538
	static $collapsed_widgets_state;
539
	$user_guid = elgg_get_logged_in_user_guid();
540
	//return $widget_guid;
541
	if (empty($user_guid)) {
542
		return false;
543
	}
544
	
545
	if (!isset($collapsed_widgets_state)) {
546
		$collapsed_widgets_state = array();
547
		$dbprefix = elgg_get_config("dbprefix");
548
		
549
		$query = "SELECT * FROM {$dbprefix}entity_relationships WHERE guid_one = $user_guid AND relationship IN ('widget_state_collapsed', 'widget_state_open')";
550
		$result = get_data($query);
551
		$i=0;
552
		if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
553
			foreach ($result as $row) {
554
				if (!isset($collapsed_widgets_state[$row->guid_two])) {
555
					$collapsed_widgets_state[$row->guid_two] = array();
556
				}
557
				$collapsed_widgets_state[$row->guid_two][] = $row->relationship;
558
				$ids[$i++] = $row->guid_two;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ids was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ids = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
559
			}
560
		}
561
	}
562
	
563
	if (!array_key_exists($widget_guid, $collapsed_widgets_state)) {
564
		return -1;
565
	}
566
	
567
	if (in_array($state, $collapsed_widgets_state[$widget_guid])) {
568
		return true;
569
	}
570
	
571
	return false;
572
}
573
574
/**
575
 * Widget menu is a set of widget controls
576
 * @access private
577
 */
578
function _elgg_widget_menu_setup($hook, $type, $return, $params) {
579
580
	$widget = $params['entity'];
581
	/* @var \ElggWidget $widget */
582
	$show_edit = elgg_extract('show_edit', $params, true);
583
584
	$collapse = array(
585
		'name' => 'collapse',
586
		'text' => ' ',
587
		'href' => "#elgg-widget-content-$widget->guid",
588
		'link_class' => 'elgg-widget-collapse-button',
589
		'rel' => 'toggle',
590
		'priority' => 1,
591
	);
592
	$return[] = \ElggMenuItem::factory($collapse);
593
594
	if ($widget->canEdit()) {
595
		$delete = array(
596
			'name' => 'delete',
597
			'text' => elgg_view_icon('delete-alt'),
598
			'title' => elgg_echo('widget:delete', array($widget->getTitle())),
599
			'href' => "action/widgets/delete?widget_guid=$widget->guid",
600
			'is_action' => true,
601
			'link_class' => 'elgg-widget-delete-button',
602
			'id' => "elgg-widget-delete-button-$widget->guid",
603
			'data-elgg-widget-type' => $widget->handler,
604
			'priority' => 900,
605
		);
606
		$return[] = \ElggMenuItem::factory($delete);
607
608
		if ($show_edit) {
609
			$edit = array(
610
				'name' => 'settings',
611
				'text' => elgg_view_icon('settings-alt'),
612
				'title' => elgg_echo('widget:edit'),
613
				'href' => "#widget-edit-$widget->guid",
614
				'link_class' => "elgg-widget-edit-button",
615
				'rel' => 'toggle',
616
				'priority' => 800,
617
			);
618
			$return[] = \ElggMenuItem::factory($edit);
619
		}
620
	}
621
622
	return $return;
623
}
624
625
/**
626
 * Add the register and forgot password links to login menu
627
 * @access private
628
 */
629
function _elgg_login_menu_setup($hook, $type, $return, $params) {
630
631
	if (elgg_get_config('allow_registration')) {
632
		$return[] = \ElggMenuItem::factory(array(
633
			'name' => 'register',
634
			'href' => 'register',
635
			'text' => elgg_echo('register'),
636
			'link_class' => 'registration_link',
637
		));
638
	}
639
640
	$return[] = \ElggMenuItem::factory(array(
641
		'name' => 'forgotpassword',
642
		'href' => 'forgotpassword',
643
		'text' => elgg_echo('user:password:lost'),
644
		'link_class' => 'forgot_link',
645
	));
646
647
	return $return;
648
}
649
650
651
/**
652
 * Navigation initialization
653
 * @access private
654
 */
655
function _elgg_nav_init() {
656
	elgg_register_plugin_hook_handler('prepare', 'breadcrumbs', 'elgg_prepare_breadcrumbs');
657
658
	elgg_register_plugin_hook_handler('prepare', 'menu:site', '_elgg_site_menu_setup');
659
	elgg_register_plugin_hook_handler('register', 'menu:river', '_elgg_river_menu_setup');
660
	elgg_register_plugin_hook_handler('register', 'menu:entity', '_elgg_entity_menu_setup');
661
	elgg_register_plugin_hook_handler('register', 'menu:widget', '_elgg_widget_menu_setup');
662
	elgg_register_plugin_hook_handler('register', 'menu:login', '_elgg_login_menu_setup');
663
664
	elgg_register_plugin_hook_handler('public_pages', 'walled_garden', '_elgg_nav_public_pages');
665
666
	elgg_register_menu_item('footer', \ElggMenuItem::factory(array(
667
		'name' => 'powered',
668
		'text' => elgg_echo("elgg:powered"),
669
		'href' => 'http://elgg.org',
670
		'title' => 'Elgg ' . elgg_get_version(true),
671
		'section' => 'meta',
672
	)));
673
674
	elgg_register_ajax_view('navigation/menu/user_hover/contents');
675
}
676
677
/**
678
 * Extend public pages
679
 *
680
 * @param string   $hook_name    "public_pages"
681
 * @param string   $entity_type  "walled_garden"
682
 * @param string[] $return_value Paths accessible outside the "walled garden"
683
 * @param mixed    $params       unused
684
 *
685
 * @return string[]
686
 * @access private
687
 * @since 1.11.0
688
 */
689
function _elgg_nav_public_pages($hook_name, $entity_type, $return_value, $params) {
690
	if (is_array($return_value)) {
691
		$return_value[] = 'navigation/menu/user_hover/contents';
692
	}
693
694
	return $return_value;
695
}
696
697
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
698
	$events->registerHandler('init', 'system', '_elgg_nav_init');
699
};
700