Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

engine/lib/widgets.php (1 issue)

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) {
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
 * Handle widgets pages.
172
 *
173
 * @param array $page Array of pages
174
 *
175
 * @return bool
176
 * @access private
177
 */
178
function _elgg_widgets_page_handler($page) {
179
	$segment = elgg_extract(0, $page);
180
	if ($segment !== 'add_panel') {
181
		return;
182
	}
183
	elgg_ajax_gatekeeper();
184
	
185
	$owner_guid = (int) get_input('owner_guid');
186
	elgg_set_page_owner_guid($owner_guid);
187
188
	// restoring context stack
189
	$context_stack = get_input('context_stack');
190
	if (!empty($context_stack) && is_array($context_stack)) {
191
		elgg_set_context_stack($context_stack);
192
	}
193
	
194
	echo elgg_view_resource('widgets/add_panel', [
195
		'owner_guid' => $owner_guid,
196
		'context' => get_input('context'),
197
	]);
198
	return true;
199
}
200
201
/**
202
 * Function to initialize widgets functionality
203
 *
204
 * @return void
205
 * @access private
206
 */
207
function _elgg_widgets_init() {
208 31
	elgg_register_action('widgets/save');
209 31
	elgg_register_action('widgets/add');
210 31
	elgg_register_action('widgets/move');
211 31
	elgg_register_action('widgets/delete');
212
	
213 31
	elgg_register_page_handler('widgets', '_elgg_widgets_page_handler');
0 ignored issues
show
Deprecated Code introduced by
The function elgg_register_page_handler() has been deprecated: 3.0 ( Ignorable by Annotation )

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

213
	/** @scrutinizer ignore-deprecated */ elgg_register_page_handler('widgets', '_elgg_widgets_page_handler');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
214
215 31
	elgg_register_plugin_hook_handler('entity:url', 'object', '_elgg_widgets_widget_urls');
216 31
}
217
218
/**
219
 * Gets a list of events to create default widgets for and
220
 * register menu items for default widgets with the admin section.
221
 *
222
 * A plugin that wants to register a new context for default widgets should
223
 * register for the plugin hook 'get_list', 'default_widgets'. The handler
224
 * can register the new type of default widgets by adding an associate array to
225
 * the return value array like this:
226
 * array(
227
 *     'name' => elgg_echo('profile'),
228
 *     'widget_context' => 'profile',
229
 *     'widget_columns' => 3,
230
 *
231
 *     'event' => 'create',
232
 *     'entity_type' => 'user',
233
 *     'entity_subtype' => ELGG_ENTITIES_ANY_VALUE,
234
 * );
235
 *
236
 * The first set of keys define information about the new type of default
237
 * widgets and the second set determine what event triggers the creation of the
238
 * new widgets.
239
 *
240
 * @return void
241
 * @access private
242
 */
243
function _elgg_default_widgets_init() {
244 18
	$default_widgets = elgg_trigger_plugin_hook('get_list', 'default_widgets', null, []);
245
246 18
	_elgg_config()->default_widget_info = $default_widgets;
247
248 18
	if (empty($default_widgets)) {
249
		return;
250
	}
251
252 18
	elgg_register_menu_item('page', [
253 18
		'name' => 'default_widgets',
254 18
		'text' => elgg_echo('admin:configure_utilities:default_widgets'),
255 18
		'href' => 'admin/configure_utilities/default_widgets',
256 18
		'section' => 'configure',
257 18
		'parent_name' => 'configure_utilities',
258 18
		'context' => 'admin',
259
	]);
260
261
	// override permissions for creating widget on logged out / just created entities
262 18
	elgg_register_plugin_hook_handler('container_permissions_check', 'object', '_elgg_default_widgets_permissions_override');
263
264
	// only register the callback once per event
265 18
	$events = [];
266 18
	foreach ($default_widgets as $info) {
267 18
		if (!is_array($info)) {
268
			continue;
269
		}
270 18
		$event = elgg_extract('event', $info);
271 18
		$entity_type = elgg_extract('entity_type', $info);
272 18
		if (!$event || !$entity_type) {
273
			continue;
274
		}
275 18
		if (!isset($events[$event][$entity_type])) {
276 18
			elgg_register_event_handler($event, $entity_type, '_elgg_create_default_widgets');
277 18
			$events[$event][$entity_type] = true;
278
		}
279
	}
280 18
}
281
282
/**
283
 * Creates default widgets
284
 *
285
 * This plugin hook handler is registered for events based on what kinds of
286
 * default widgets have been registered. See elgg_default_widgets_init() for
287
 * information on registering new default widget contexts.
288
 *
289
 * @param string      $event  The event
290
 * @param string      $type   The type of object
291
 * @param \ElggEntity $entity The entity being created
292
 * @return void
293
 * @access private
294
 */
295
function _elgg_create_default_widgets($event, $type, $entity) {
296 61
	$default_widget_info = _elgg_config()->default_widget_info;
297
298 61
	if (empty($default_widget_info) || !$entity) {
299
		return;
300
	}
301
302 61
	$type = $entity->getType();
303 61
	$subtype = $entity->getSubtype();
304
305
	// event is already guaranteed by the hook registration.
306
	// need to check subtype and type.
307 61
	foreach ($default_widget_info as $info) {
308 61
		if (elgg_extract('entity_type', $info) !== $type) {
309
			continue;
310
		}
311
312 61
		$entity_subtype = elgg_extract('entity_subtype', $info);
313 61
		if ($entity_subtype !== ELGG_ENTITIES_ANY_VALUE && $entity_subtype !== $subtype) {
314
			continue;
315
		}
316
317
		// need to be able to access everything
318 61
		$old_ia = elgg_set_ignore_access(true);
319 61
		elgg_push_context('create_default_widgets');
320
321
		// pull in by widget context with widget owners as the site
322
		// not using elgg_get_widgets() because it sorts by columns and we don't care right now.
323 61
		$widgets = elgg_get_entities([
324 61
			'type' => 'object',
325 61
			'subtype' => 'widget',
326 61
			'owner_guid' => elgg_get_site_entity()->guid,
327 61
			'private_setting_name' => 'context',
328 61
			'private_setting_value' => elgg_extract('widget_context', $info),
329 61
			'limit' => 0,
330
			'batch' => true,
331
		]);
332
		/* @var \ElggWidget[] $widgets */
333
334 61
		foreach ($widgets as $widget) {
335
			// change the container and owner
336
			$new_widget = clone $widget;
337
			$new_widget->container_guid = $entity->guid;
338
			$new_widget->owner_guid = $entity->guid;
339
340
			// pull in settings
341
			$settings = get_all_private_settings($widget->guid);
342
343
			foreach ($settings as $name => $value) {
344
				$new_widget->$name = $value;
345
			}
346
347
			$new_widget->save();
348
		}
349
350 61
		elgg_set_ignore_access($old_ia);
351 61
		elgg_pop_context();
352
	}
353 61
}
354
355
/**
356
 * Overrides permissions checks when creating widgets for logged out users.
357
 *
358
 * @param string $hook   The permissions hook.
359
 * @param string $type   The type of entity being created.
360
 * @param string $return Value
361
 * @param mixed  $params Params
362
 * @return true|null
363
 * @access private
364
 */
365
function _elgg_default_widgets_permissions_override($hook, $type, $return, $params) {
366 8
	if ($type == 'object' && $params['subtype'] == 'widget') {
367
		return elgg_in_context('create_default_widgets') ? true : null;
368
	}
369
370 8
	return null;
371
}
372
373
/**
374
 * @see \Elgg\Application::loadCore Do not do work here. Just register for events.
375
 */
376
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
377 18
	$events->registerHandler('init', 'system', '_elgg_widgets_init');
378 18
	$events->registerHandler('ready', 'system', '_elgg_default_widgets_init');
379
};
380