Passed
Push — master ( c2d8e3...289151 )
by Jeroen
06:06
created

engine/lib/widgets.php (7 issues)

1
<?php
2
/**
3
 * Elgg widgets library.
4
 * Contains code for handling widgets.
5
 *
6
 * @package Elgg.Core
7
 * @subpackage Widgets
8
 */
9
10
/**
11
 * Get widgets for a particular context
12
 *
13
 * The widgets are ordered for display and grouped in columns.
14
 * $widgets = elgg_get_widgets(elgg_get_logged_in_user_guid(), 'dashboard');
15
 * $first_column_widgets = $widgets[1];
16
 *
17
 * @param int    $owner_guid The owner GUID of the layout
18
 * @param string $context    The context (profile, dashboard, etc)
19
 *
20
 * @return array An 2D array of \ElggWidget objects
21
 * @since 1.8.0
22
 */
23
function elgg_get_widgets($owner_guid, $context) {
24 6
	return _elgg_services()->widgets->getWidgets($owner_guid, $context);
25
}
26
27
/**
28
 * Create a new widget instance
29
 *
30
 * @param int    $owner_guid GUID of entity that owns this widget
31
 * @param string $handler    The handler for this widget
32
 * @param string $context    The context for this widget
33
 * @param int    $access_id  If not specified, it is set to the default access level
34
 *
35
 * @return int|false Widget GUID or false on failure
36
 * @since 1.8.0
37
 */
38
function elgg_create_widget($owner_guid, $handler, $context, $access_id = null) {
39 9
	return _elgg_services()->widgets->createWidget($owner_guid, $handler, $context, $access_id);
40
}
41
42
/**
43
 * Can the user edit the widget layout
44
 *
45
 * Triggers a 'permissions_check', 'widget_layout' plugin hook
46
 *
47
 * @param string $context   The widget context
48
 * @param int    $user_guid The GUID of the user (0 for logged in user)
49
 *
50
 * @return bool
51
 * @since 1.8.0
52
 */
53
function elgg_can_edit_widget_layout($context, $user_guid = 0) {
54 8
	return _elgg_services()->widgets->canEditLayout($context, $user_guid);
55
}
56
57
/**
58
 * Register a widget type
59
 *
60
 * This should be called by plugins in their init function.
61
 *
62
 * @param string|array $handler     An array of options or the identifier for the widget handler
63
 * @param string       $name        The name of the widget type
64
 * @param string       $description A description for the widget type
65
 * @param array        $context     An array of contexts where this widget is allowed
66
 * @param bool         $multiple    Whether or not multiple instances of this widget
67
 *                                  are allowed in a single layout (default: false)
68
 *
69
 * @return bool
70
 * @since 1.8.0
71
 */
72
function elgg_register_widget_type($handler, $name = null, $description = null, $context = [], $multiple = false) {
73 34
	if (is_array($handler)) {
74 2
		$definition = \Elgg\WidgetDefinition::factory($handler);
75
	} else {
76 32
		$definition = \Elgg\WidgetDefinition::factory([
77 32
			'id' => $handler,
78 32
			'name' => $name,
79 32
			'description' => $description,
80 32
			'context' => $context,
81 32
			'multiple' => $multiple,
82
		]);
83
	}
84
85 34
	return _elgg_services()->widgets->registerType($definition);
86
}
87
88
/**
89
 * Remove a widget type
90
 *
91
 * @param string $handler The identifier for the widget
92
 *
93
 * @return bool true if handler was found as unregistered
94
 * @since 1.8.0
95
 */
96
function elgg_unregister_widget_type($handler) {
97 2
	return _elgg_services()->widgets->unregisterType($handler);
98
}
99
100
/**
101
 * Has a widget type with the specified handler been registered
102
 *
103
 * @param string      $handler   The widget handler identifying string
104
 * @param string      $context   Optional context to check
105
 * @param \ElggEntity $container Optional limit widget definitions to a container
106
 *
107
 * @return bool Whether or not that widget type exists
108
 * @since 1.8.0
109
 */
110
function elgg_is_widget_type($handler, $context = null, \ElggEntity $container = null) {
111 1
	return _elgg_services()->widgets->validateType($handler, $context, $container);
112
}
113
114
/**
115
 * Get the widget types for a context
116
 *
117
 * If passing $context as an associative array you the following can be used:
118
 * array (
119
 *     'context' => string (defaults to ''),
120
 *     'exact'   => bool (defaults to false),
121
 *     'container' => \ElggEntity (defaults to null)
122
 * )
123
 * The contents of the array will be passed to the handlers:widgets hook.
124
 *
125
 * @param array|string $context An associative array of options or the widget context
126
 *
127
 * @return \Elgg\WidgetDefinition[]
128
 * @since 1.8.0
129
 */
130
function elgg_get_widget_types($context = "") {
131 5
	if (is_array($context)) {
132 4
		$params = $context;
133
	} else {
134
		$params = [
135 1
			'context' => $context,
136
			'container' => null,
137
		];
138
	}
139 5
	return _elgg_services()->widgets->getTypes($params);
140
}
141
142
/**
143
 * Returns widget URLS used in widget titles
144
 *
145
 * @param string $hook   Hook name
146
 * @param string $type   Hook type
147
 * @param string $result URL
148
 * @param array  $params Parameters
149
 * @return string|null
150
 * @access private
151
 */
152
function _elgg_widgets_widget_urls($hook, $type, $result, $params) {
3 ignored issues
show
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

152
function _elgg_widgets_widget_urls($hook, /** @scrutinizer ignore-unused */ $type, $result, $params) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $hook is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

152
function _elgg_widgets_widget_urls(/** @scrutinizer ignore-unused */ $hook, $type, $result, $params) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $result is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

152
function _elgg_widgets_widget_urls($hook, $type, /** @scrutinizer ignore-unused */ $result, $params) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
153 3
	$widget = elgg_extract('entity', $params);
154 3
	if (!($widget instanceof \ElggWidget)) {
155 3
		return;
156
	}
157
	
158
	switch ($widget->handler) {
159
		case 'content_stats':
160
			return 'admin/statistics/numentities';
161
		case 'cron_status':
162
			return 'admin/cron';
163
		case 'new_users':
164
			return 'admin/users/newest';
165
		case 'online_users':
166
			return 'admin/users/online';
167
	}
168
}
169
170
/**
171
 * Function to initialize widgets functionality
172
 *
173
 * @return void
174
 * @access private
175
 */
176
function _elgg_widgets_init() {
177
	elgg_register_action('widgets/save');
178
	elgg_register_action('widgets/add');
179
	elgg_register_action('widgets/move');
180
	elgg_register_action('widgets/delete');
181
182
	elgg_register_plugin_hook_handler('entity:url', 'object', '_elgg_widgets_widget_urls');
183
}
184
185
/**
186
 * Gets a list of events to create default widgets for and
187
 * register menu items for default widgets with the admin section.
188
 *
189
 * A plugin that wants to register a new context for default widgets should
190
 * register for the plugin hook 'get_list', 'default_widgets'. The handler
191
 * can register the new type of default widgets by adding an associate array to
192
 * the return value array like this:
193
 * array(
194
 *     'name' => elgg_echo('profile'),
195
 *     'widget_context' => 'profile',
196
 *     'widget_columns' => 3,
197
 *
198
 *     'event' => 'create',
199
 *     'entity_type' => 'user',
200
 *     'entity_subtype' => ELGG_ENTITIES_ANY_VALUE,
201
 * );
202
 *
203
 * The first set of keys define information about the new type of default
204
 * widgets and the second set determine what event triggers the creation of the
205
 * new widgets.
206
 *
207
 * @return void
208 31
 * @access private
209 31
 */
210 31
function _elgg_default_widgets_init() {
211 31
	$default_widgets = elgg_trigger_plugin_hook('get_list', 'default_widgets', null, []);
212
213 31
	_elgg_config()->default_widget_info = $default_widgets;
214
215 31
	if (empty($default_widgets)) {
216 31
		return;
217
	}
218
219
	elgg_register_menu_item('page', [
220
		'name' => 'default_widgets',
221
		'text' => elgg_echo('admin:configure_utilities:default_widgets'),
222
		'href' => 'admin/configure_utilities/default_widgets',
223
		'section' => 'configure',
224
		'parent_name' => 'configure_utilities',
225
		'context' => 'admin',
226
	]);
227
228
	// override permissions for creating widget on logged out / just created entities
229
	elgg_register_plugin_hook_handler('container_permissions_check', 'object', '_elgg_default_widgets_permissions_override');
230
231
	// only register the callback once per event
232
	$events = [];
233
	foreach ($default_widgets as $info) {
234
		if (!is_array($info)) {
235
			continue;
236
		}
237
		$event = elgg_extract('event', $info);
238
		$entity_type = elgg_extract('entity_type', $info);
239
		if (!$event || !$entity_type) {
240
			continue;
241
		}
242
		if (!isset($events[$event][$entity_type])) {
243
			elgg_register_event_handler($event, $entity_type, '_elgg_create_default_widgets');
244 18
			$events[$event][$entity_type] = true;
245
		}
246 18
	}
247
}
248 18
249
/**
250
 * Creates default widgets
251
 *
252 18
 * This plugin hook handler is registered for events based on what kinds of
253 18
 * default widgets have been registered. See elgg_default_widgets_init() for
254 18
 * information on registering new default widget contexts.
255 18
 *
256 18
 * @param string      $event  The event
257 18
 * @param string      $type   The type of object
258 18
 * @param \ElggEntity $entity The entity being created
259
 * @return void
260
 * @access private
261
 */
262 18
function _elgg_create_default_widgets($event, $type, $entity) {
2 ignored issues
show
The parameter $event is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

262
function _elgg_create_default_widgets(/** @scrutinizer ignore-unused */ $event, $type, $entity) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

262
function _elgg_create_default_widgets($event, /** @scrutinizer ignore-unused */ $type, $entity) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
263
	$default_widget_info = _elgg_config()->default_widget_info;
264
265 18
	if (empty($default_widget_info) || !$entity) {
266 18
		return;
267 18
	}
268
269
	$type = $entity->getType();
270 18
	$subtype = $entity->getSubtype();
271 18
272 18
	// event is already guaranteed by the hook registration.
273
	// need to check subtype and type.
274
	foreach ($default_widget_info as $info) {
275 18
		if (elgg_extract('entity_type', $info) !== $type) {
276 18
			continue;
277 18
		}
278
279
		$entity_subtype = elgg_extract('entity_subtype', $info);
280 18
		if ($entity_subtype !== ELGG_ENTITIES_ANY_VALUE && $entity_subtype !== $subtype) {
281
			continue;
282
		}
283
284
		// need to be able to access everything
285
		$old_ia = elgg_set_ignore_access(true);
286
		elgg_push_context('create_default_widgets');
287
288
		// pull in by widget context with widget owners as the site
289
		// not using elgg_get_widgets() because it sorts by columns and we don't care right now.
290
		$widgets = elgg_get_entities([
291
			'type' => 'object',
292
			'subtype' => 'widget',
293
			'owner_guid' => elgg_get_site_entity()->guid,
294
			'private_setting_name' => 'context',
295
			'private_setting_value' => elgg_extract('widget_context', $info),
296 61
			'limit' => 0,
297
			'batch' => true,
298 61
		]);
299
		/* @var \ElggWidget[] $widgets */
300
301
		foreach ($widgets as $widget) {
302 61
			// change the container and owner
303 61
			$new_widget = clone $widget;
304
			$new_widget->container_guid = $entity->guid;
305
			$new_widget->owner_guid = $entity->guid;
306
307 61
			// pull in settings
308 61
			$settings = get_all_private_settings($widget->guid);
309
310
			foreach ($settings as $name => $value) {
311
				$new_widget->$name = $value;
312 61
			}
313 61
314
			$new_widget->save();
315
		}
316
317
		elgg_set_ignore_access($old_ia);
318 61
		elgg_pop_context();
319 61
	}
320
}
321
322
/**
323 61
 * Overrides permissions checks when creating widgets for logged out users.
324 61
 *
325 61
 * @param string $hook   The permissions hook.
326 61
 * @param string $type   The type of entity being created.
327 61
 * @param string $return Value
328 61
 * @param mixed  $params Params
329 61
 * @return true|null
330
 * @access private
331
 */
332
function _elgg_default_widgets_permissions_override($hook, $type, $return, $params) {
2 ignored issues
show
The parameter $return is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

332
function _elgg_default_widgets_permissions_override($hook, $type, /** @scrutinizer ignore-unused */ $return, $params) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $hook is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

332
function _elgg_default_widgets_permissions_override(/** @scrutinizer ignore-unused */ $hook, $type, $return, $params) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
333
	if ($type == 'object' && $params['subtype'] == 'widget') {
334 61
		return elgg_in_context('create_default_widgets') ? true : null;
335
	}
336
337
	return null;
338
}
339
340
/**
341
 * @see \Elgg\Application::loadCore Do not do work here. Just register for events.
342
 */
343
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
344
	$events->registerHandler('init', 'system', '_elgg_widgets_init');
345
	$events->registerHandler('ready', 'system', '_elgg_default_widgets_init');
346
};
347