1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Elgg's view system. |
4
|
|
|
* |
5
|
|
|
* The view system is the primary templating engine in Elgg and renders |
6
|
|
|
* all output. Views are short, parameterised PHP scripts for displaying |
7
|
|
|
* output that can be regsitered, overridden, or extended. The view type |
8
|
|
|
* determines the output format and location of the files that renders the view. |
9
|
|
|
* |
10
|
|
|
* Elgg uses a two step process to render full output: first |
11
|
|
|
* content-specific elements are rendered, then the resulting |
12
|
|
|
* content is inserted into a layout and displayed. This makes it |
13
|
|
|
* easy to maintain a consistent look on all pages. |
14
|
|
|
* |
15
|
|
|
* A view corresponds to a single file on the filesystem and the views |
16
|
|
|
* name is its directory structure. A file in |
17
|
|
|
* <code>mod/plugins/views/default/myplugin/example.php</code> |
18
|
|
|
* is called by saying (with the default viewtype): |
19
|
|
|
* <code>echo elgg_view('myplugin/example');</code> |
20
|
|
|
* |
21
|
|
|
* View names that are registered later override those that are |
22
|
|
|
* registered earlier. For plugins this corresponds directly |
23
|
|
|
* to their load order: views in plugins lower in the list override |
24
|
|
|
* those higher in the list. |
25
|
|
|
* |
26
|
|
|
* Plugin views belong in the views/ directory under an appropriate |
27
|
|
|
* viewtype. Views are automatically registered. |
28
|
|
|
* |
29
|
|
|
* Views can be embedded-you can call a view from within a view. |
30
|
|
|
* Views can also be prepended or extended by any other view. |
31
|
|
|
* |
32
|
|
|
* Any view can extend any other view if registered with |
33
|
|
|
* {@link elgg_extend_view()}. |
34
|
|
|
* |
35
|
|
|
* Viewtypes are set by passing $_REQUEST['view']. The viewtype |
36
|
|
|
* 'default' is a standard HTML view. Types can be defined on the fly |
37
|
|
|
* and you can get the current viewtype with {@link elgg_get_viewtype()}. |
38
|
|
|
* |
39
|
|
|
* @note Internal: Plugin views are autoregistered before their init functions |
40
|
|
|
* are called, so the init order doesn't affect views. |
41
|
|
|
* |
42
|
|
|
* @note Internal: The file that determines the output of the view is the last |
43
|
|
|
* registered by {@link elgg_set_view_location()}. |
44
|
|
|
* |
45
|
|
|
* @package Elgg.Core |
46
|
|
|
* @subpackage Views |
47
|
|
|
*/ |
48
|
|
|
|
49
|
|
|
use Elgg\Menu\Menu; |
50
|
|
|
use Elgg\Menu\UnpreparedMenu; |
51
|
|
|
use Elgg\Project\Paths; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Manually set the viewtype. |
55
|
|
|
* |
56
|
|
|
* View types are detected automatically. This function allows |
57
|
|
|
* you to force subsequent views to use a different viewtype. |
58
|
|
|
* |
59
|
|
|
* @tip Call elgg_set_viewtype() with no parameter to reset. |
60
|
|
|
* |
61
|
|
|
* @param string $viewtype The view type, e.g. 'rss', or 'default'. |
62
|
|
|
* |
63
|
|
|
* @return bool |
64
|
|
|
*/ |
65
|
|
|
function elgg_set_viewtype($viewtype = '') { |
66
|
36 |
|
return _elgg_services()->views->setViewtype($viewtype); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Return the current view type. |
71
|
|
|
* |
72
|
|
|
* Viewtypes are automatically detected and can be set with $_REQUEST['view'] |
73
|
|
|
* or {@link elgg_set_viewtype()}. |
74
|
|
|
* |
75
|
|
|
* @return string The viewtype |
76
|
|
|
* @see elgg_set_viewtype() |
77
|
|
|
*/ |
78
|
|
|
function elgg_get_viewtype() { |
79
|
320 |
|
return _elgg_services()->views->getViewtype(); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Checks if $viewtype is a string suitable for use as a viewtype name |
84
|
|
|
* |
85
|
|
|
* @param string $viewtype Potential viewtype name. Alphanumeric chars plus _ allowed. |
86
|
|
|
* |
87
|
|
|
* @return bool |
88
|
|
|
* @internal |
89
|
|
|
* @since 1.9 |
90
|
|
|
*/ |
91
|
|
|
function _elgg_is_valid_viewtype($viewtype) { |
92
|
1 |
|
return _elgg_services()->views->isValidViewtype($viewtype); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Register a viewtype to fall back to a default view if a view isn't |
97
|
|
|
* found for that viewtype. |
98
|
|
|
* |
99
|
|
|
* @tip This is useful for alternate html viewtypes (such as for mobile devices). |
100
|
|
|
* |
101
|
|
|
* @param string $viewtype The viewtype to register |
102
|
|
|
* |
103
|
|
|
* @return void |
104
|
|
|
* @since 1.7.2 |
105
|
|
|
*/ |
106
|
|
|
function elgg_register_viewtype_fallback($viewtype) { |
107
|
|
|
_elgg_services()->views->registerViewtypeFallback($viewtype); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Checks if a viewtype falls back to default. |
112
|
|
|
* |
113
|
|
|
* @param string $viewtype Viewtype |
114
|
|
|
* |
115
|
|
|
* @return boolean |
116
|
|
|
* @since 1.7.2 |
117
|
|
|
*/ |
118
|
|
|
function elgg_does_viewtype_fallback($viewtype) { |
119
|
|
|
return _elgg_services()->views->doesViewtypeFallback($viewtype); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Register a view to be available for ajax calls |
124
|
|
|
* |
125
|
|
|
* @warning Only views that begin with 'js/' and 'css/' have their content |
126
|
|
|
* type set to 'text/javascript' and 'text/css'. Other views are served as |
127
|
|
|
* 'text/html'. |
128
|
|
|
* |
129
|
|
|
* @param string $view The view name |
130
|
|
|
* @return void |
131
|
|
|
* @since 1.8.3 |
132
|
|
|
*/ |
133
|
|
|
function elgg_register_ajax_view($view) { |
134
|
94 |
|
elgg_register_external_view($view, false); |
135
|
94 |
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Unregister a view for ajax calls |
139
|
|
|
* |
140
|
|
|
* @param string $view The view name |
141
|
|
|
* @return void |
142
|
|
|
* @since 1.8.3 |
143
|
|
|
*/ |
144
|
|
|
function elgg_unregister_ajax_view($view) { |
145
|
|
|
elgg_unregister_external_view($view); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Registers a view as being available externally (i.e. via URL). |
150
|
|
|
* |
151
|
|
|
* @param string $view The name of the view. |
152
|
|
|
* @param boolean $cacheable Whether this view can be cached. |
153
|
|
|
* @return void |
154
|
|
|
* @since 1.9.0 |
155
|
|
|
*/ |
156
|
|
|
function elgg_register_external_view($view, $cacheable = false) { |
157
|
|
|
|
158
|
94 |
|
_elgg_services()->ajax->registerView($view); |
159
|
|
|
|
160
|
94 |
|
if ($cacheable) { |
161
|
|
|
_elgg_services()->views->registerCacheableView($view); |
162
|
|
|
} |
163
|
94 |
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Unregister a view for ajax calls |
167
|
|
|
* |
168
|
|
|
* @param string $view The view name |
169
|
|
|
* @return void |
170
|
|
|
* @since 1.9.0 |
171
|
|
|
*/ |
172
|
|
|
function elgg_unregister_external_view($view) { |
173
|
|
|
_elgg_services()->ajax->unregisterView($view); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Set an alternative base location for a view. |
178
|
|
|
* |
179
|
|
|
* Views are expected to be in plugin_name/views/. This function can |
180
|
|
|
* be used to change that location. |
181
|
|
|
* |
182
|
|
|
* @tip This is useful to optionally register views in a plugin. |
183
|
|
|
* |
184
|
|
|
* @param string $view The name of the view |
185
|
|
|
* @param string $location The full path to the view |
186
|
|
|
* @param string $viewtype The view type |
187
|
|
|
* |
188
|
|
|
* @return void |
189
|
|
|
*/ |
190
|
|
|
function elgg_set_view_location($view, $location, $viewtype = '') { |
191
|
|
|
_elgg_services()->views->setViewDir($view, $location, $viewtype); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Returns whether the specified view exists |
196
|
|
|
* |
197
|
|
|
* @note If $recurse is true, also checks if a view exists only as an extension. |
198
|
|
|
* |
199
|
|
|
* @param string $view The view name |
200
|
|
|
* @param string $viewtype If set, forces the viewtype |
201
|
|
|
* @param bool $recurse If false, do not check extensions |
202
|
|
|
* |
203
|
|
|
* @return bool |
204
|
|
|
*/ |
205
|
|
|
function elgg_view_exists($view, $viewtype = '', $recurse = true) { |
206
|
275 |
|
return _elgg_services()->views->viewExists($view, $viewtype, $recurse); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* List all views in a viewtype |
211
|
|
|
* |
212
|
|
|
* @param string $viewtype Viewtype |
213
|
|
|
* |
214
|
|
|
* @return string[] |
215
|
|
|
* |
216
|
|
|
* @since 2.0 |
217
|
|
|
*/ |
218
|
|
|
function elgg_list_views($viewtype = 'default') { |
219
|
|
|
return _elgg_services()->views->listViews($viewtype); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Return a parsed view. |
224
|
|
|
* |
225
|
|
|
* Views are rendered by a template handler and returned as strings. |
226
|
|
|
* |
227
|
|
|
* Views are called with a special $vars variable set, |
228
|
|
|
* which includes any variables passed as the second parameter. |
229
|
|
|
* |
230
|
|
|
* The input of views can be intercepted by registering for the |
231
|
|
|
* view_vars, $view_name plugin hook. |
232
|
|
|
* |
233
|
|
|
* If the input contains the key "__view_output", the view will output this value as a string. |
234
|
|
|
* No extensions are used, and the "view" hook is not triggered). |
235
|
|
|
* |
236
|
|
|
* The output of views can be intercepted by registering for the |
237
|
|
|
* view, $view_name plugin hook. |
238
|
|
|
* |
239
|
|
|
* @param string $view The name and location of the view to use |
240
|
|
|
* @param array $vars Variables to pass to the view. |
241
|
|
|
* @param string $viewtype If set, forces the viewtype for the elgg_view call to be |
242
|
|
|
* this value (default: standard detection) |
243
|
|
|
* |
244
|
|
|
* @return string The parsed view |
245
|
|
|
*/ |
246
|
|
|
function elgg_view($view, $vars = [], $viewtype = '') { |
247
|
420 |
|
if (func_num_args() == 5) { |
248
|
|
|
elgg_log(__FUNCTION__ . ' now has only 3 arguments. Update your usage.', 'ERROR'); |
249
|
|
|
$viewtype = func_get_arg(4); |
250
|
|
|
} |
251
|
420 |
|
return _elgg_services()->views->renderView($view, $vars, $viewtype); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Display a view with a deprecation notice. No missing view NOTICE is logged |
256
|
|
|
* |
257
|
|
|
* @param string $view The name and location of the view to use |
258
|
|
|
* @param array $vars Variables to pass to the view |
259
|
|
|
* @param string $suggestion Suggestion with the deprecation message |
260
|
|
|
* @param string $version Human-readable *release* version: 1.7, 1.8, ... |
261
|
|
|
* |
262
|
|
|
* @return string The parsed view |
263
|
|
|
* |
264
|
|
|
* @see elgg_view() |
265
|
|
|
*/ |
266
|
|
|
function elgg_view_deprecated($view, array $vars, $suggestion, $version) { |
267
|
|
|
return _elgg_services()->views->renderDeprecatedView($view, $vars, $suggestion, $version); |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Extends a view with another view. |
272
|
|
|
* |
273
|
|
|
* The output of any view can be prepended or appended to any other view. |
274
|
|
|
* |
275
|
|
|
* The default action is to append a view. If the priority is less than 500, |
276
|
|
|
* the output of the extended view will be appended to the original view. |
277
|
|
|
* |
278
|
|
|
* Views can be extended multiple times, and extensions are not checked for |
279
|
|
|
* uniqueness. Use {@link elgg_unextend_view()} to help manage duplicates. |
280
|
|
|
* |
281
|
|
|
* Priority can be specified and affects the order in which extensions |
282
|
|
|
* are appended or prepended. |
283
|
|
|
* |
284
|
|
|
* @see elgg_prepend_css_urls() If the extension is CSS, you may need to use this to fix relative URLs. |
285
|
|
|
* |
286
|
|
|
* @param string $view The view to extend. |
287
|
|
|
* @param string $view_extension This view is added to $view |
288
|
|
|
* @param int $priority The priority, from 0 to 1000, to add at (lowest numbers displayed first) |
289
|
|
|
* |
290
|
|
|
* @return void |
291
|
|
|
* @since 1.7.0 |
292
|
|
|
*/ |
293
|
|
|
function elgg_extend_view($view, $view_extension, $priority = 501) { |
294
|
86 |
|
_elgg_services()->views->extendView($view, $view_extension, $priority); |
295
|
86 |
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* Unextends a view. |
299
|
|
|
* |
300
|
|
|
* @param string $view The view that was extended. |
301
|
|
|
* @param string $view_extension This view that was added to $view |
302
|
|
|
* |
303
|
|
|
* @return bool |
304
|
|
|
* @since 1.7.2 |
305
|
|
|
*/ |
306
|
|
|
function elgg_unextend_view($view, $view_extension) { |
307
|
43 |
|
return _elgg_services()->views->unextendView($view, $view_extension); |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* Get the views (and priorities) that extend a view. |
312
|
|
|
* |
313
|
|
|
* @note extensions may change anytime, especially during the [init, system] event |
314
|
|
|
* |
315
|
|
|
* @param string $view View name |
316
|
|
|
* |
317
|
|
|
* @return string[] Keys returned are view priorities. |
318
|
|
|
* @since 2.3 |
319
|
|
|
*/ |
320
|
|
|
function elgg_get_view_extensions($view) { |
321
|
|
|
$list = _elgg_services()->views->getViewList($view); |
322
|
|
|
unset($list[500]); |
323
|
|
|
return $list; |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* In CSS content, prepend a path to relative URLs. |
328
|
|
|
* |
329
|
|
|
* This is useful to process a CSS view being used as an extension. |
330
|
|
|
* |
331
|
|
|
* @param string $css CSS |
332
|
|
|
* @param string $path Path to prepend. E.g. "foo/bar/" or "../" |
333
|
|
|
* |
334
|
|
|
* @return string |
335
|
|
|
* @since 2.2 |
336
|
|
|
*/ |
337
|
|
|
function elgg_prepend_css_urls($css, $path) { |
338
|
1 |
|
return Minify_CSS_UriRewriter::prepend($css, $path); |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Assembles and outputs a full page. |
343
|
|
|
* |
344
|
|
|
* A "page" in Elgg is determined by the current view type and |
345
|
|
|
* can be HTML for a browser, RSS for a feed reader, or |
346
|
|
|
* Javascript, PHP and a number of other formats. |
347
|
|
|
* |
348
|
|
|
* For HTML pages, use the 'head', 'page' plugin hook for setting meta elements |
349
|
|
|
* and links. |
350
|
|
|
* |
351
|
|
|
* @param string $title Title |
352
|
|
|
* @param string $body Body |
353
|
|
|
* @param string $page_shell Optional page shell to use. See page/shells view directory |
354
|
|
|
* @param array $vars Optional vars array to pass to the page |
355
|
|
|
* shell. Automatically adds title, body, head, and sysmessages |
356
|
|
|
* |
357
|
|
|
* @return string The contents of the page |
358
|
|
|
* @since 1.8 |
359
|
|
|
*/ |
360
|
|
|
function elgg_view_page($title, $body, $page_shell = 'default', $vars = []) { |
361
|
52 |
|
$timer = _elgg_services()->timer; |
362
|
52 |
|
if (!$timer->hasEnded(['build page'])) { |
363
|
9 |
|
$timer->end(['build page']); |
364
|
|
|
} |
365
|
52 |
|
$timer->begin([__FUNCTION__]); |
366
|
|
|
|
367
|
52 |
|
$params = []; |
368
|
52 |
|
$params['identifier'] = _elgg_services()->request->getFirstUrlSegment(); |
369
|
52 |
|
$params['segments'] = _elgg_services()->request->getUrlSegments(); |
370
|
52 |
|
array_shift($params['segments']); |
371
|
52 |
|
$page_shell = elgg_trigger_plugin_hook('shell', 'page', $params, $page_shell); |
372
|
|
|
|
373
|
|
|
|
374
|
52 |
|
$system_messages = _elgg_services()->systemMessages; |
375
|
|
|
|
376
|
52 |
|
$messages = null; |
377
|
52 |
|
if ($system_messages->count()) { |
378
|
|
|
$messages = $system_messages->dumpRegister(); |
379
|
|
|
|
380
|
|
|
if (isset($messages['error'])) { |
381
|
|
|
// always make sure error is the first type |
382
|
|
|
$errors = [ |
383
|
|
|
'error' => $messages['error'] |
384
|
|
|
]; |
385
|
|
|
|
386
|
|
|
unset($messages['error']); |
387
|
|
|
$messages = array_merge($errors, $messages); |
388
|
|
|
} |
389
|
|
|
} |
390
|
|
|
|
391
|
52 |
|
$vars['title'] = $title; |
392
|
52 |
|
$vars['body'] = $body; |
393
|
52 |
|
$vars['sysmessages'] = $messages; |
394
|
52 |
|
$vars['page_shell'] = $page_shell; |
395
|
|
|
|
396
|
|
|
// head has keys 'title', 'metas', 'links' |
397
|
52 |
|
$head_params = _elgg_views_prepare_head($title); |
398
|
|
|
|
399
|
52 |
|
$vars['head'] = elgg_trigger_plugin_hook('head', 'page', $vars, $head_params); |
400
|
|
|
|
401
|
52 |
|
$vars = elgg_trigger_plugin_hook('output:before', 'page', null, $vars); |
402
|
|
|
|
403
|
52 |
|
$output = elgg_view("page/$page_shell", $vars); |
404
|
|
|
|
405
|
|
|
|
406
|
|
|
// Allow plugins to modify the output |
407
|
52 |
|
$output = elgg_trigger_plugin_hook('output', 'page', $vars, $output); |
408
|
|
|
|
409
|
52 |
|
$timer->end([__FUNCTION__]); |
410
|
52 |
|
return $output; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* Render a resource view. Use this in your page handler to hand off page rendering to |
415
|
|
|
* a view in "resources/". If not found in the current viewtype, we try the "default" viewtype. |
416
|
|
|
* |
417
|
|
|
* @param string $name The view name without the leading "resources/" |
418
|
|
|
* @param array $vars Arguments passed to the view |
419
|
|
|
* |
420
|
|
|
* @return string |
421
|
|
|
* @throws \Elgg\PageNotFoundException |
422
|
|
|
*/ |
423
|
|
|
function elgg_view_resource($name, array $vars = []) { |
424
|
70 |
|
$view = "resources/$name"; |
425
|
|
|
|
426
|
70 |
|
if (elgg_view_exists($view)) { |
427
|
70 |
|
return _elgg_services()->views->renderView($view, $vars); |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
if (elgg_get_viewtype() !== 'default' && elgg_view_exists($view, 'default')) { |
431
|
|
|
return _elgg_services()->views->renderView($view, $vars, 'default'); |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
_elgg_services()->logger->error("The view $view is missing."); |
435
|
|
|
|
436
|
|
|
// only works for default viewtype |
437
|
|
|
throw new \Elgg\PageNotFoundException(); |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
/** |
441
|
|
|
* Prepare the variables for the html head |
442
|
|
|
* |
443
|
|
|
* @param string $title Page title for <head> |
444
|
|
|
* @return array |
445
|
|
|
* @internal |
446
|
|
|
*/ |
447
|
|
|
function _elgg_views_prepare_head($title) { |
448
|
|
|
$params = [ |
449
|
52 |
|
'links' => [], |
450
|
|
|
'metas' => [], |
451
|
|
|
]; |
452
|
|
|
|
453
|
52 |
|
if (empty($title)) { |
454
|
5 |
|
$params['title'] = _elgg_config()->sitename; |
455
|
|
|
} else { |
456
|
47 |
|
$params['title'] = $title . ' : ' . _elgg_config()->sitename; |
457
|
|
|
} |
458
|
|
|
|
459
|
52 |
|
$params['metas']['content-type'] = [ |
460
|
|
|
'http-equiv' => 'Content-Type', |
461
|
|
|
'content' => 'text/html; charset=utf-8', |
462
|
|
|
]; |
463
|
|
|
|
464
|
52 |
|
$params['metas']['description'] = [ |
465
|
52 |
|
'name' => 'description', |
466
|
52 |
|
'content' => _elgg_config()->sitedescription |
467
|
|
|
]; |
468
|
|
|
|
469
|
|
|
// https://developer.chrome.com/multidevice/android/installtohomescreen |
470
|
52 |
|
$params['metas']['viewport'] = [ |
471
|
|
|
'name' => 'viewport', |
472
|
|
|
'content' => 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0', |
473
|
|
|
]; |
474
|
52 |
|
$params['metas']['mobile-web-app-capable'] = [ |
475
|
|
|
'name' => 'mobile-web-app-capable', |
476
|
|
|
'content' => 'yes', |
477
|
|
|
]; |
478
|
52 |
|
$params['metas']['apple-mobile-web-app-capable'] = [ |
479
|
|
|
'name' => 'apple-mobile-web-app-capable', |
480
|
|
|
'content' => 'yes', |
481
|
|
|
]; |
482
|
|
|
|
483
|
|
|
// RSS feed link |
484
|
52 |
|
if (_elgg_has_rss_link()) { |
485
|
27 |
|
$url = current_page_url(); |
486
|
27 |
|
if (substr_count($url, '?')) { |
487
|
1 |
|
$url .= "&view=rss"; |
488
|
|
|
} else { |
489
|
26 |
|
$url .= "?view=rss"; |
490
|
|
|
} |
491
|
27 |
|
$params['links']['rss'] = [ |
492
|
27 |
|
'rel' => 'alternative', |
493
|
27 |
|
'type' => 'application/rss+xml', |
494
|
27 |
|
'title' => 'RSS', |
495
|
27 |
|
'href' => $url, |
496
|
|
|
]; |
497
|
|
|
} |
498
|
|
|
|
499
|
52 |
|
return $params; |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
|
503
|
|
|
/** |
504
|
|
|
* Add favicon link tags to HTML head |
505
|
|
|
* |
506
|
|
|
* @param string $hook "head" |
507
|
|
|
* @param string $type "page" |
508
|
|
|
* @param array $head_params Head params |
509
|
|
|
* <code> |
510
|
|
|
* [ |
511
|
|
|
* 'title' => '', |
512
|
|
|
* 'metas' => [], |
513
|
|
|
* 'links' => [], |
514
|
|
|
* ] |
515
|
|
|
* </code> |
516
|
|
|
* @param array $params Hook params |
517
|
|
|
* @return array |
518
|
|
|
*/ |
519
|
|
|
function _elgg_views_prepare_favicon_links($hook, $type, $head_params, $params) { |
520
|
|
|
|
521
|
10 |
|
$head_params['links']['apple-touch-icon'] = [ |
522
|
10 |
|
'rel' => 'apple-touch-icon', |
523
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-128.png'), |
524
|
|
|
]; |
525
|
|
|
|
526
|
|
|
// favicons |
527
|
10 |
|
$head_params['links']['icon-ico'] = [ |
528
|
10 |
|
'rel' => 'icon', |
529
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon.ico'), |
530
|
|
|
]; |
531
|
10 |
|
$head_params['links']['icon-vector'] = [ |
532
|
10 |
|
'rel' => 'icon', |
533
|
10 |
|
'sizes' => '16x16 32x32 48x48 64x64 128x128', |
534
|
10 |
|
'type' => 'image/svg+xml', |
535
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon.svg'), |
536
|
|
|
]; |
537
|
10 |
|
$head_params['links']['icon-16'] = [ |
538
|
10 |
|
'rel' => 'icon', |
539
|
10 |
|
'sizes' => '16x16', |
540
|
10 |
|
'type' => 'image/png', |
541
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-16.png'), |
542
|
|
|
]; |
543
|
10 |
|
$head_params['links']['icon-32'] = [ |
544
|
10 |
|
'rel' => 'icon', |
545
|
10 |
|
'sizes' => '32x32', |
546
|
10 |
|
'type' => 'image/png', |
547
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-32.png'), |
548
|
|
|
]; |
549
|
10 |
|
$head_params['links']['icon-64'] = [ |
550
|
10 |
|
'rel' => 'icon', |
551
|
10 |
|
'sizes' => '64x64', |
552
|
10 |
|
'type' => 'image/png', |
553
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-64.png'), |
554
|
|
|
]; |
555
|
10 |
|
$head_params['links']['icon-128'] = [ |
556
|
10 |
|
'rel' => 'icon', |
557
|
10 |
|
'sizes' => '128x128', |
558
|
10 |
|
'type' => 'image/png', |
559
|
10 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-128.png'), |
560
|
|
|
]; |
561
|
|
|
|
562
|
10 |
|
return $head_params; |
563
|
|
|
} |
564
|
|
|
|
565
|
|
|
/** |
566
|
|
|
* Displays a layout with optional parameters. |
567
|
|
|
* |
568
|
|
|
* Layouts are templates provide consistency by organizing blocks of content on the page. |
569
|
|
|
* |
570
|
|
|
* Plugins should use one of the core layouts: |
571
|
|
|
* - default Primary template with one, two or no sidebars |
572
|
|
|
* - admin Admin page template |
573
|
|
|
* - error Error page template |
574
|
|
|
* - widgets Widgets canvas |
575
|
|
|
* |
576
|
|
|
* Plugins can create and use custom layouts by placing a layout view |
577
|
|
|
* in "page/layouts/<layout_name>" and calling elgg_view_layout(<layout_name>). |
578
|
|
|
* |
579
|
|
|
* For a full list of parameters supported by each of these layouts see |
580
|
|
|
* corresponding layout views. |
581
|
|
|
* |
582
|
|
|
* @param string $layout_name Layout name |
583
|
|
|
* Corresponds to a view in "page/layouts/<layout_name>". |
584
|
|
|
* @param array $vars Layout parameters |
585
|
|
|
* An associative array of parameters to pass to |
586
|
|
|
* the layout hooks and views. |
587
|
|
|
* Route 'identifier' and 'segments' of the page being |
588
|
|
|
* rendered will be added to this array automatially, |
589
|
|
|
* allowing plugins to alter layout views and subviews |
590
|
|
|
* based on the current route. |
591
|
|
|
* @return string |
592
|
|
|
*/ |
593
|
|
|
function elgg_view_layout($layout_name, $vars = []) { |
594
|
43 |
|
$timer = _elgg_services()->timer; |
595
|
43 |
|
if (!$timer->hasEnded(['build page'])) { |
596
|
42 |
|
$timer->end(['build page']); |
597
|
|
|
} |
598
|
43 |
|
$timer->begin([__FUNCTION__]); |
599
|
|
|
|
600
|
|
|
// Help plugins transition without breaking them |
601
|
43 |
|
switch ($layout_name) { |
602
|
43 |
|
case 'content' : |
603
|
12 |
|
$layout_name = 'default'; |
604
|
12 |
|
$vars = _elgg_normalize_content_layout_vars($vars); |
605
|
12 |
|
break; |
606
|
|
|
|
607
|
31 |
|
case 'one_sidebar' : |
608
|
1 |
|
$layout_name = 'default'; |
609
|
1 |
|
$vars['sidebar'] = elgg_extract('sidebar', $vars, '', false); |
610
|
1 |
|
$vars['sidebar_alt'] = false; |
611
|
1 |
|
break; |
612
|
|
|
|
613
|
30 |
|
case 'one_column' : |
614
|
|
|
$layout_name = 'default'; |
615
|
|
|
$vars['sidebar'] = false; |
616
|
|
|
$vars['sidebar_alt'] = false; |
617
|
|
|
break; |
618
|
|
|
|
619
|
30 |
|
case 'two_sidebar' : |
620
|
|
|
$layout_name = 'default'; |
621
|
|
|
$vars['sidebar'] = elgg_extract('sidebar', $vars, '', false); |
622
|
|
|
$vars['sidebar_alt'] = elgg_extract('sidebar_alt', $vars, '', false); |
623
|
|
|
break; |
624
|
|
|
|
625
|
30 |
|
case 'default' : |
626
|
23 |
|
$filter_id = elgg_extract('filter_id', $vars, 'filter'); |
627
|
23 |
|
$filter_context = elgg_extract('filter_value', $vars); |
628
|
23 |
|
if (isset($filter_context) && $filter_id === 'filter') { |
629
|
11 |
|
$context = elgg_extract('context', $vars, elgg_get_context()); |
630
|
11 |
|
$vars['filter'] = elgg_get_filter_tabs($context, $filter_context, null, $vars); |
631
|
11 |
|
$vars['filter_id'] = $filter_id; |
632
|
11 |
|
$vars['filter_value'] = $filter_context; |
633
|
|
|
} |
634
|
23 |
|
break; |
635
|
|
|
} |
636
|
|
|
|
637
|
43 |
|
if (isset($vars['nav'])) { |
638
|
|
|
// Temporary helper until all core views are updated |
639
|
|
|
$vars['breadcrumbs'] = $vars['nav']; |
640
|
|
|
unset($vars['nav']); |
641
|
|
|
} |
642
|
|
|
|
643
|
43 |
|
$vars['identifier'] = _elgg_services()->request->getFirstUrlSegment(); |
644
|
43 |
|
$vars['segments'] = _elgg_services()->request->getUrlSegments(); |
645
|
43 |
|
array_shift($vars['segments']); |
646
|
|
|
|
647
|
43 |
|
$layout_name = elgg_trigger_plugin_hook('layout', 'page', $vars, $layout_name); |
648
|
|
|
|
649
|
43 |
|
$vars['layout'] = $layout_name; |
650
|
|
|
|
651
|
|
|
$layout_views = [ |
652
|
43 |
|
"page/layouts/$layout_name", |
653
|
43 |
|
"page/layouts/default", |
654
|
|
|
]; |
655
|
|
|
|
656
|
43 |
|
$output = ''; |
657
|
43 |
|
foreach ($layout_views as $layout_view) { |
658
|
43 |
|
if (elgg_view_exists($layout_view)) { |
659
|
10 |
|
$output = elgg_view($layout_view, $vars); |
660
|
43 |
|
break; |
661
|
|
|
} |
662
|
|
|
} |
663
|
|
|
|
664
|
43 |
|
$timer->end([__FUNCTION__]); |
665
|
43 |
|
return $output; |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
/** |
669
|
|
|
* Normalizes deprecated content layout $vars for use in default layout |
670
|
|
|
* Helper function to assist plugins transitioning to 3.0 |
671
|
|
|
* |
672
|
|
|
* @param array $vars Vars |
673
|
|
|
* @return array |
674
|
|
|
* @internal |
675
|
|
|
*/ |
676
|
|
|
function _elgg_normalize_content_layout_vars(array $vars = []) { |
677
|
|
|
|
678
|
12 |
|
$context = elgg_extract('context', $vars, elgg_get_context()); |
679
|
|
|
|
680
|
12 |
|
$vars['title'] = elgg_extract('title', $vars, ''); |
681
|
12 |
|
if (!$vars['title'] && $vars['title'] !== false) { |
682
|
1 |
|
$vars['title'] = elgg_echo($context); |
683
|
|
|
} |
684
|
|
|
|
685
|
|
|
// 1.8 supported 'filter_override' |
686
|
12 |
|
if (isset($vars['filter_override'])) { |
687
|
|
|
$vars['filter'] = $vars['filter_override']; |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
// register the default content filters |
691
|
12 |
|
if (!isset($vars['filter']) && $context) { |
692
|
|
|
$selected = elgg_extract('filter_context', $vars); |
693
|
|
|
$vars['filter'] = elgg_get_filter_tabs($context, $selected, null, $vars); |
694
|
|
|
$vars['filter_id'] = $context; |
695
|
|
|
$vars['filter_value'] = $selected; |
696
|
|
|
} |
697
|
|
|
|
698
|
12 |
|
return $vars; |
699
|
|
|
} |
700
|
|
|
|
701
|
|
|
/** |
702
|
|
|
* Render a menu |
703
|
|
|
* |
704
|
|
|
* @see elgg_register_menu_item() for documentation on adding menu items and |
705
|
|
|
* navigation.php for information on the different menus available. |
706
|
|
|
* |
707
|
|
|
* This function triggers a 'register', 'menu:<menu name>' plugin hook that enables |
708
|
|
|
* plugins to add menu items just before a menu is rendered. This is used by |
709
|
|
|
* dynamic menus (menus that change based on some input such as the user hover |
710
|
|
|
* menu). Using elgg_register_menu_item() in response to the hook can cause |
711
|
|
|
* incorrect links to show up. See the blog plugin's blog_owner_block_menu() |
712
|
|
|
* for an example of using this plugin hook. |
713
|
|
|
* |
714
|
|
|
* An additional hook is the 'prepare', 'menu:<menu name>' which enables plugins |
715
|
|
|
* to modify the structure of the menu (sort it, remove items, set variables on |
716
|
|
|
* the menu items). |
717
|
|
|
* |
718
|
|
|
* Preset (unprepared) menu items passed to the this function with the $vars |
719
|
|
|
* argument, will be merged with the registered items (registered with |
720
|
|
|
* elgg_register_menu_item()). The combined set of menu items will be passed |
721
|
|
|
* to 'register', 'menu:<menu_name>' hook. |
722
|
|
|
* |
723
|
|
|
* Plugins that pass preset menu items to this function and do not wish to be |
724
|
|
|
* affected by plugin hooks (e.g. if you are displaying multiple menus with |
725
|
|
|
* the same name on the page) should instead choose a unqie menu name |
726
|
|
|
* and define a menu_view argument to render menus consistently. |
727
|
|
|
* For example, if you have multiple 'filter' menus on the page: |
728
|
|
|
* <code> |
729
|
|
|
* elgg_view_menu("filter:$uid", [ |
730
|
|
|
* 'items' => $items, |
731
|
|
|
* 'menu_view' => 'navigation/menu/filter', |
732
|
|
|
* ]); |
733
|
|
|
* </code> |
734
|
|
|
* |
735
|
|
|
* elgg_view_menu() uses views in navigation/menu |
736
|
|
|
* |
737
|
|
|
* @param string|Menu|UnpreparedMenu $menu Menu name (or object) |
738
|
|
|
* @param array $vars An associative array of display options for the menu. |
739
|
|
|
* |
740
|
|
|
* Options include: |
741
|
|
|
* items => an array of unprepared menu items |
742
|
|
|
* as ElggMenuItem or menu item factory options |
743
|
|
|
* sort_by => string or php callback |
744
|
|
|
* string options: 'name', 'priority' (default), 'text' |
745
|
|
|
* or a php callback (a compare function for usort) |
746
|
|
|
* handler: string the page handler to build action URLs |
747
|
|
|
* entity: \ElggEntity to use to build action URLs |
748
|
|
|
* class: string the class for the entire menu. |
749
|
|
|
* menu_view: name of the view to be used to render the menu |
750
|
|
|
* show_section_headers: bool show headers before menu sections. |
751
|
|
|
* |
752
|
|
|
* @return string |
753
|
|
|
* @since 1.8.0 |
754
|
|
|
*/ |
755
|
|
|
function elgg_view_menu($menu, array $vars = []) { |
756
|
|
|
|
757
|
54 |
|
$menu_view = elgg_extract('menu_view', $vars); |
758
|
54 |
|
unset($vars['menu_view']); |
759
|
|
|
|
760
|
54 |
|
if (is_string($menu)) { |
761
|
54 |
|
$menu = _elgg_services()->menus->getMenu($menu, $vars); |
762
|
|
|
} elseif ($menu instanceof UnpreparedMenu) { |
763
|
|
|
$menu = _elgg_services()->menus->prepareMenu($menu); |
764
|
|
|
} |
765
|
|
|
|
766
|
54 |
|
if (!$menu instanceof Menu) { |
|
|
|
|
767
|
|
|
throw new \InvalidArgumentException('$menu must be a menu name, a Menu, or UnpreparedMenu'); |
768
|
|
|
} |
769
|
|
|
|
770
|
54 |
|
$name = $menu->getName(); |
771
|
54 |
|
$params = $menu->getParams(); |
772
|
|
|
|
773
|
|
|
$views = [ |
774
|
54 |
|
$menu_view, |
775
|
54 |
|
"navigation/menu/$name", |
776
|
54 |
|
'navigation/menu/default', |
777
|
|
|
]; |
778
|
|
|
|
779
|
54 |
|
foreach ($views as $view) { |
780
|
54 |
|
if (elgg_view_exists($view)) { |
781
|
54 |
|
return elgg_view($view, $params); |
782
|
|
|
} |
783
|
|
|
} |
784
|
30 |
|
} |
785
|
|
|
|
786
|
|
|
/** |
787
|
|
|
* Render a menu item (usually as a link) |
788
|
|
|
* |
789
|
|
|
* @param \ElggMenuItem $item The menu item |
790
|
|
|
* @param array $vars Options to pass to output/url if a link |
791
|
|
|
* @return string |
792
|
|
|
* @since 1.9.0 |
793
|
|
|
*/ |
794
|
|
|
function elgg_view_menu_item(\ElggMenuItem $item, array $vars = []) { |
795
|
|
|
|
796
|
21 |
|
$vars = array_merge($item->getValues(), $vars); |
797
|
21 |
|
$vars['class'] = elgg_extract_class($vars, ['elgg-menu-content']); |
798
|
|
|
|
799
|
21 |
|
if ($item->getLinkClass()) { |
800
|
11 |
|
$vars['class'][] = $item->getLinkClass(); |
801
|
|
|
} |
802
|
|
|
|
803
|
21 |
|
if ($item->getHref() === false || $item->getHref() === null) { |
804
|
6 |
|
$vars['class'][] = 'elgg-non-link'; |
805
|
|
|
} |
806
|
|
|
|
807
|
21 |
|
if (!isset($vars['rel']) && !isset($vars['is_trusted'])) { |
808
|
21 |
|
$vars['is_trusted'] = true; |
809
|
|
|
} |
810
|
|
|
|
811
|
21 |
|
if ($item->getConfirmText()) { |
812
|
|
|
$vars['confirm'] = $item->getConfirmText(); |
813
|
|
|
} |
814
|
|
|
|
815
|
21 |
|
return elgg_view('output/url', $vars); |
816
|
|
|
} |
817
|
|
|
|
818
|
|
|
/** |
819
|
|
|
* Returns a string of a rendered entity. |
820
|
|
|
* |
821
|
|
|
* Entity views are either determined by setting the view property on the entity |
822
|
|
|
* or by having a view named after the entity $type/$subtype. Entities that have |
823
|
|
|
* neither a view property nor a defined $type/$subtype view will fall back to |
824
|
|
|
* using the $type/default view. |
825
|
|
|
* |
826
|
|
|
* The entity view is called with the following in $vars: |
827
|
|
|
* - \ElggEntity 'entity' The entity being viewed |
828
|
|
|
* |
829
|
|
|
* @tip This function can automatically appends annotations to entities if in full |
830
|
|
|
* view and a handler is registered for the entity:annotate. See https://github.com/Elgg/Elgg/issues/964 and |
831
|
|
|
* {@link elgg_view_entity_annotations()}. |
832
|
|
|
* |
833
|
|
|
* @param \ElggEntity $entity The entity to display |
834
|
|
|
* @param array $vars Array of variables to pass to the entity view. |
835
|
|
|
* 'full_view' Whether to show a full or condensed view. (Default: true) |
836
|
|
|
* 'item_view' Alternative view used to render this entity |
837
|
|
|
* 'register_rss_link' Register the rss link availability (default: depending on full_view) |
838
|
|
|
* |
839
|
|
|
* @return false|string HTML to display or false |
840
|
|
|
* @todo The annotation hook might be better as a generic plugin hook to append content. |
841
|
|
|
*/ |
842
|
|
|
function elgg_view_entity(\ElggEntity $entity, array $vars = []) { |
843
|
|
|
|
844
|
|
|
$defaults = [ |
845
|
13 |
|
'full_view' => true, |
846
|
|
|
]; |
847
|
|
|
|
848
|
13 |
|
$vars = array_merge($defaults, $vars); |
849
|
|
|
|
850
|
13 |
|
if (elgg_extract('register_rss_link', $vars, elgg_extract('full_view', $vars))) { |
851
|
11 |
|
elgg_register_rss_link(); |
852
|
|
|
} |
853
|
|
|
|
854
|
13 |
|
$vars['entity'] = $entity; |
855
|
|
|
|
856
|
13 |
|
$entity_type = $entity->getType(); |
857
|
13 |
|
$entity_subtype = $entity->getSubtype(); |
858
|
|
|
|
859
|
|
|
$entity_views = [ |
860
|
13 |
|
elgg_extract('item_view', $vars, ''), |
861
|
13 |
|
"$entity_type/$entity_subtype", |
862
|
13 |
|
"$entity_type/default", |
863
|
|
|
]; |
864
|
|
|
|
865
|
13 |
|
$contents = ''; |
866
|
13 |
|
foreach ($entity_views as $view) { |
867
|
13 |
|
if (elgg_view_exists($view)) { |
868
|
13 |
|
$contents = elgg_view($view, $vars); |
869
|
13 |
|
break; |
870
|
|
|
} |
871
|
|
|
} |
872
|
|
|
|
873
|
|
|
// Marcus Povey 20090616 : Speculative and low impact approach for fixing #964 |
874
|
13 |
|
if ($vars['full_view']) { |
875
|
11 |
|
$annotations = elgg_view_entity_annotations($entity, $vars['full_view']); |
876
|
|
|
|
877
|
11 |
|
if ($annotations) { |
878
|
|
|
$contents .= $annotations; |
879
|
|
|
} |
880
|
|
|
} |
881
|
13 |
|
return $contents; |
882
|
|
|
} |
883
|
|
|
|
884
|
|
|
/** |
885
|
|
|
* View the icon of an entity |
886
|
|
|
* |
887
|
|
|
* Entity views are determined by having a view named after the entity $type/$subtype. |
888
|
|
|
* Entities that do not have a defined icon/$type/$subtype view will fall back to using |
889
|
|
|
* the icon/$type/default view. |
890
|
|
|
* |
891
|
|
|
* @param \ElggEntity $entity The entity to display |
892
|
|
|
* @param string $size The size: tiny, small, medium, large |
893
|
|
|
* @param array $vars An array of variables to pass to the view. Some possible |
894
|
|
|
* variables are img_class and link_class. See the |
895
|
|
|
* specific icon view for more parameters. |
896
|
|
|
* |
897
|
|
|
* @return string HTML to display or false |
898
|
|
|
*/ |
899
|
|
|
function elgg_view_entity_icon(\ElggEntity $entity, $size = 'medium', $vars = []) { |
900
|
|
|
|
901
|
6 |
|
$vars['entity'] = $entity; |
902
|
6 |
|
$vars['size'] = $size; |
903
|
|
|
|
904
|
6 |
|
$entity_type = $entity->getType(); |
905
|
|
|
|
906
|
6 |
|
$subtype = $entity->getSubtype(); |
907
|
|
|
|
908
|
6 |
|
$contents = ''; |
909
|
6 |
|
if (elgg_view_exists("icon/$entity_type/$subtype")) { |
910
|
|
|
$contents = elgg_view("icon/$entity_type/$subtype", $vars); |
911
|
|
|
} |
912
|
6 |
|
if (empty($contents) && elgg_view_exists("icon/$entity_type/default")) { |
913
|
1 |
|
$contents = elgg_view("icon/$entity_type/default", $vars); |
914
|
|
|
} |
915
|
6 |
|
if (empty($contents)) { |
916
|
5 |
|
$contents = elgg_view("icon/default", $vars); |
917
|
|
|
} |
918
|
|
|
|
919
|
6 |
|
return $contents; |
920
|
|
|
} |
921
|
|
|
|
922
|
|
|
/** |
923
|
|
|
* Returns a string of a rendered annotation. |
924
|
|
|
* |
925
|
|
|
* Annotation views are expected to be in annotation/$annotation_name. |
926
|
|
|
* If a view is not found for $annotation_name, the default annotation/default |
927
|
|
|
* will be used. |
928
|
|
|
* |
929
|
|
|
* @warning annotation/default is not currently defined in core. |
930
|
|
|
* |
931
|
|
|
* The annotation view is called with the following in $vars: |
932
|
|
|
* - \ElggEntity 'annotation' The annotation being viewed. |
933
|
|
|
* |
934
|
|
|
* @param \ElggAnnotation $annotation The annotation to display |
935
|
|
|
* @param array $vars Variable array for view. |
936
|
|
|
* 'item_view' Alternative view used to render an annotation |
937
|
|
|
* |
938
|
|
|
* @return string|false Rendered annotation |
939
|
|
|
*/ |
940
|
|
|
function elgg_view_annotation(\ElggAnnotation $annotation, array $vars = []) { |
941
|
|
|
$defaults = [ |
942
|
|
|
'full_view' => true, |
943
|
|
|
]; |
944
|
|
|
|
945
|
|
|
$vars = array_merge($defaults, $vars); |
946
|
|
|
$vars['annotation'] = $annotation; |
947
|
|
|
|
948
|
|
|
$name = $annotation->name; |
949
|
|
|
if (empty($name)) { |
950
|
|
|
return false; |
951
|
|
|
} |
952
|
|
|
|
953
|
|
|
$annotation_views = [ |
954
|
|
|
elgg_extract('item_view', $vars, ''), |
955
|
|
|
"annotation/$name", |
956
|
|
|
"annotation/default", |
957
|
|
|
]; |
958
|
|
|
|
959
|
|
|
$contents = ''; |
960
|
|
|
foreach ($annotation_views as $view) { |
961
|
|
|
if (elgg_view_exists($view)) { |
962
|
|
|
$contents = elgg_view($view, $vars); |
963
|
|
|
break; |
964
|
|
|
} |
965
|
|
|
} |
966
|
|
|
|
967
|
|
|
return $contents; |
968
|
|
|
} |
969
|
|
|
|
970
|
|
|
/** |
971
|
|
|
* Returns a rendered list of entities with pagination. This function should be |
972
|
|
|
* called by wrapper functions. |
973
|
|
|
* |
974
|
|
|
* @see elgg_list_entities() |
975
|
|
|
* |
976
|
|
|
* @param array $entities Array of entities |
977
|
|
|
* @param array $vars Display variables |
978
|
|
|
* 'count' The total number of entities across all pages |
979
|
|
|
* 'offset' The current indexing offset |
980
|
|
|
* 'limit' The number of entities to display per page (default from settings) |
981
|
|
|
* 'full_view' Display the full view of the entities? |
982
|
|
|
* 'list_class' CSS class applied to the list |
983
|
|
|
* 'item_class' CSS class applied to the list items |
984
|
|
|
* 'item_view' Alternative view to render list items content |
985
|
|
|
* 'list_item_view' Alternative view to render list items |
986
|
|
|
* 'pagination' Display pagination? |
987
|
|
|
* 'base_url' Base URL of list (optional) |
988
|
|
|
* 'url_fragment' URL fragment to add to links if not present in base_url (optional) |
989
|
|
|
* 'position' Position of the pagination: before, after, or both |
990
|
|
|
* 'list_type' List type: 'list' (default), 'gallery' |
991
|
|
|
* 'list_type_toggle' Display the list type toggle? |
992
|
|
|
* 'no_results' Message to display if no results (string|true|Closure) |
993
|
|
|
* |
994
|
|
|
* @return string The rendered list of entities |
995
|
|
|
*/ |
996
|
|
|
function elgg_view_entity_list($entities, array $vars = []) { |
997
|
24 |
|
$offset = (int) get_input('offset', 0); |
998
|
|
|
|
999
|
|
|
// list type can be passed as request parameter |
1000
|
24 |
|
$list_type = get_input('list_type', 'list'); |
1001
|
|
|
|
1002
|
|
|
$defaults = [ |
1003
|
24 |
|
'items' => $entities, |
1004
|
24 |
|
'list_class' => 'elgg-list-entity', |
1005
|
|
|
'full_view' => true, |
1006
|
|
|
'pagination' => true, |
1007
|
24 |
|
'list_type' => $list_type, |
1008
|
|
|
'list_type_toggle' => false, |
1009
|
24 |
|
'offset' => $offset, |
1010
|
|
|
'limit' => null, |
1011
|
|
|
]; |
1012
|
|
|
|
1013
|
24 |
|
$vars = array_merge($defaults, $vars); |
1014
|
|
|
|
1015
|
24 |
|
if (!$vars["limit"] && !$vars["offset"]) { |
1016
|
|
|
// no need for pagination if listing is unlimited |
1017
|
|
|
$vars["pagination"] = false; |
1018
|
|
|
} |
1019
|
|
|
|
1020
|
24 |
|
$view = "page/components/{$vars['list_type']}"; |
1021
|
24 |
|
if (!elgg_view_exists($view)) { |
1022
|
20 |
|
$view = 'page/components/list'; |
1023
|
|
|
} |
1024
|
|
|
|
1025
|
24 |
|
return elgg_view($view, $vars); |
1026
|
|
|
} |
1027
|
|
|
|
1028
|
|
|
/** |
1029
|
|
|
* Returns a rendered list of annotations, plus pagination. This function |
1030
|
|
|
* should be called by wrapper functions. |
1031
|
|
|
* |
1032
|
|
|
* @param array $annotations Array of annotations |
1033
|
|
|
* @param array $vars Display variables |
1034
|
|
|
* 'count' The total number of annotations across all pages |
1035
|
|
|
* 'offset' The current indexing offset |
1036
|
|
|
* 'limit' The number of annotations to display per page |
1037
|
|
|
* 'full_view' Display the full view of the annotation? |
1038
|
|
|
* 'list_class' CSS Class applied to the list |
1039
|
|
|
* 'item_view' Alternative view to render list items |
1040
|
|
|
* 'offset_key' The url parameter key used for offset |
1041
|
|
|
* 'no_results' Message to display if no results (string|true|Closure) |
1042
|
|
|
* |
1043
|
|
|
* @return string The list of annotations |
1044
|
|
|
* @internal |
1045
|
|
|
*/ |
1046
|
|
|
function elgg_view_annotation_list($annotations, array $vars = []) { |
1047
|
|
|
$defaults = [ |
1048
|
|
|
'items' => $annotations, |
1049
|
|
|
'offset' => null, |
1050
|
|
|
'limit' => null, |
1051
|
|
|
'list_class' => 'elgg-list-annotation elgg-annotation-list', // @todo remove elgg-annotation-list in Elgg 1.9 |
1052
|
|
|
'full_view' => true, |
1053
|
|
|
'offset_key' => 'annoff', |
1054
|
|
|
]; |
1055
|
|
|
|
1056
|
|
|
$vars = array_merge($defaults, $vars); |
1057
|
|
|
|
1058
|
|
|
if (!$vars["limit"] && !$vars["offset"]) { |
1059
|
|
|
// no need for pagination if listing is unlimited |
1060
|
|
|
$vars["pagination"] = false; |
1061
|
|
|
} |
1062
|
|
|
|
1063
|
|
|
return elgg_view('page/components/list', $vars); |
1064
|
|
|
} |
1065
|
|
|
|
1066
|
|
|
/** |
1067
|
|
|
* Display a plugin-specified rendered list of annotations for an entity. |
1068
|
|
|
* |
1069
|
|
|
* This displays the output of functions registered to the entity:annotation, |
1070
|
|
|
* $entity_type plugin hook. |
1071
|
|
|
* |
1072
|
|
|
* This is called automatically by the framework from {@link elgg_view_entity()} |
1073
|
|
|
* |
1074
|
|
|
* @param \ElggEntity $entity Entity |
1075
|
|
|
* @param bool $full_view Display full view? |
1076
|
|
|
* |
1077
|
|
|
* @return mixed string or false on failure |
1078
|
|
|
* @todo Change the hook name. |
1079
|
|
|
*/ |
1080
|
|
|
function elgg_view_entity_annotations(\ElggEntity $entity, $full_view = true) { |
1081
|
|
|
|
1082
|
11 |
|
$entity_type = $entity->getType(); |
1083
|
|
|
|
1084
|
11 |
|
$annotations = elgg_trigger_plugin_hook('entity:annotate', $entity_type, |
1085
|
|
|
[ |
1086
|
11 |
|
'entity' => $entity, |
1087
|
11 |
|
'full_view' => $full_view, |
1088
|
|
|
] |
1089
|
|
|
); |
1090
|
|
|
|
1091
|
11 |
|
return $annotations; |
1092
|
|
|
} |
1093
|
|
|
|
1094
|
|
|
/** |
1095
|
|
|
* Renders a title. |
1096
|
|
|
* |
1097
|
|
|
* This is a shortcut for {@elgg_view page/elements/title}. |
1098
|
|
|
* |
1099
|
|
|
* @param string $title The page title |
1100
|
|
|
* @param array $vars View variables (was submenu be displayed? (deprecated)) |
1101
|
|
|
* |
1102
|
|
|
* @return string The HTML (etc) |
1103
|
|
|
*/ |
1104
|
|
|
function elgg_view_title($title, array $vars = []) { |
1105
|
8 |
|
$vars['title'] = $title; |
1106
|
|
|
|
1107
|
8 |
|
return elgg_view('page/elements/title', $vars); |
1108
|
|
|
} |
1109
|
|
|
|
1110
|
|
|
/** |
1111
|
|
|
* Displays a UNIX timestamp in a friendly way |
1112
|
|
|
* |
1113
|
|
|
* @see elgg_get_friendly_time() |
1114
|
|
|
* |
1115
|
|
|
* @param int $time A UNIX epoch timestamp |
1116
|
|
|
* |
1117
|
|
|
* @return string The friendly time HTML |
1118
|
|
|
* @since 1.7.2 |
1119
|
|
|
*/ |
1120
|
|
|
function elgg_view_friendly_time($time) { |
1121
|
3 |
|
$view = 'output/friendlytime'; |
1122
|
3 |
|
$vars = ['time' => $time]; |
1123
|
3 |
|
$viewtype = elgg_view_exists($view) ? '' : 'default'; |
1124
|
|
|
|
1125
|
3 |
|
return _elgg_view_under_viewtype($view, $vars, $viewtype); |
1126
|
|
|
} |
1127
|
|
|
|
1128
|
|
|
/** |
1129
|
|
|
* Returns rendered comments and a comment form for an entity. |
1130
|
|
|
* |
1131
|
|
|
* @tip Plugins can override the output by registering a handler |
1132
|
|
|
* for the comments, $entity_type hook. The handler is responsible |
1133
|
|
|
* for formatting the comments and the add comment form. |
1134
|
|
|
* |
1135
|
|
|
* @param \ElggEntity $entity The entity to view comments of |
1136
|
|
|
* @param bool $add_comment Include a form to add comments? |
1137
|
|
|
* @param array $vars Variables to pass to comment view |
1138
|
|
|
* |
1139
|
|
|
* @return string|false Rendered comments or false on failure |
1140
|
|
|
*/ |
1141
|
|
|
function elgg_view_comments($entity, $add_comment = true, array $vars = []) { |
1142
|
|
|
|
1143
|
1 |
|
if (!$entity instanceof \ElggEntity) { |
1144
|
|
|
return false; |
1145
|
|
|
} |
1146
|
|
|
|
1147
|
1 |
|
$vars['entity'] = $entity; |
1148
|
1 |
|
$vars['show_add_form'] = $add_comment; |
1149
|
1 |
|
$vars['class'] = elgg_extract('class', $vars, "{$entity->getSubtype()}-comments"); |
1150
|
|
|
|
1151
|
1 |
|
$output = elgg_trigger_plugin_hook('comments', $entity->getType(), $vars, false); |
1152
|
1 |
|
if ($output !== false) { |
1153
|
|
|
return $output; |
1154
|
|
|
} |
1155
|
|
|
|
1156
|
1 |
|
return elgg_view('page/elements/comments', $vars); |
1157
|
|
|
} |
1158
|
|
|
|
1159
|
|
|
/** |
1160
|
|
|
* Wrapper function for the image block display pattern. |
1161
|
|
|
* |
1162
|
|
|
* Fixed width media on the side (image, icon, flash, etc.). |
1163
|
|
|
* Descriptive content filling the rest of the column. |
1164
|
|
|
* |
1165
|
|
|
* @note Use the $vars "image_alt" key to set an image on the right. If you do, you may pass |
1166
|
|
|
* in an empty string for $image to have only the right image. |
1167
|
|
|
* |
1168
|
|
|
* This is a shortcut for {@elgg_view page/components/image_block}. |
1169
|
|
|
* |
1170
|
|
|
* @param string $image The icon and other information |
1171
|
|
|
* @param string $body Description content |
1172
|
|
|
* @param array $vars Additional parameters for the view |
1173
|
|
|
* |
1174
|
|
|
* @return string |
1175
|
|
|
* @since 1.8.0 |
1176
|
|
|
*/ |
1177
|
|
|
function elgg_view_image_block($image, $body, $vars = []) { |
1178
|
5 |
|
$vars['image'] = $image; |
1179
|
5 |
|
$vars['body'] = $body; |
1180
|
5 |
|
return elgg_view('page/components/image_block', $vars); |
1181
|
|
|
} |
1182
|
|
|
|
1183
|
|
|
/** |
1184
|
|
|
* Wrapper function for the module display pattern. |
1185
|
|
|
* |
1186
|
|
|
* Box with header, body, footer |
1187
|
|
|
* |
1188
|
|
|
* This is a shortcut for {@elgg_view page/components/module}. |
1189
|
|
|
* |
1190
|
|
|
* @param string $type The type of module (main, info, popup, aside, etc.) |
1191
|
|
|
* @param string $title A title to put in the header |
1192
|
|
|
* @param string $body Content of the module |
1193
|
|
|
* @param array $vars Additional parameters for the module |
1194
|
|
|
* |
1195
|
|
|
* @return string |
1196
|
|
|
* @since 1.8.0 |
1197
|
|
|
*/ |
1198
|
|
|
function elgg_view_module($type, $title, $body, array $vars = []) { |
1199
|
21 |
|
$vars['type'] = $type; |
1200
|
21 |
|
$vars['title'] = $title; |
1201
|
21 |
|
$vars['body'] = $body; |
1202
|
21 |
|
return elgg_view('page/components/module', $vars); |
1203
|
|
|
} |
1204
|
|
|
|
1205
|
|
|
/** |
1206
|
|
|
* Wrapper function for the message display pattern. |
1207
|
|
|
* |
1208
|
|
|
* Box with header, body |
1209
|
|
|
* |
1210
|
|
|
* This is a shortcut for {@elgg_view page/components/message}. |
1211
|
|
|
* |
1212
|
|
|
* @param string $type The type of message (error, success, warning, help, notice) |
1213
|
|
|
* @param string $body Content of the message |
1214
|
|
|
* @param array $vars Additional parameters for the message |
1215
|
|
|
* |
1216
|
|
|
* @return string |
1217
|
|
|
* @since 3.0.0 |
1218
|
|
|
*/ |
1219
|
|
|
function elgg_view_message($type, $body, array $vars = []) { |
1220
|
16 |
|
$vars['type'] = $type; |
1221
|
16 |
|
$vars['body'] = $body; |
1222
|
16 |
|
return elgg_view('page/components/message', $vars); |
1223
|
|
|
} |
1224
|
|
|
|
1225
|
|
|
/** |
1226
|
|
|
* Renders a human-readable representation of a river item |
1227
|
|
|
* |
1228
|
|
|
* @param \ElggRiverItem $item A river item object |
1229
|
|
|
* @param array $vars An array of variables for the view |
1230
|
|
|
* 'item_view' Alternative view to render the item |
1231
|
|
|
* 'register_rss_link' Register the rss link availability (default: false) |
1232
|
|
|
* @return string returns empty string if could not be rendered |
1233
|
|
|
*/ |
1234
|
|
|
function elgg_view_river_item($item, array $vars = []) { |
1235
|
|
|
|
1236
|
|
|
if (!($item instanceof \ElggRiverItem)) { |
1237
|
|
|
return ''; |
1238
|
|
|
} |
1239
|
|
|
|
1240
|
|
|
// checking default viewtype since some viewtypes do not have unique views per item (rss) |
1241
|
|
|
$view = $item->getView(); |
1242
|
|
|
|
1243
|
|
|
$subject = $item->getSubjectEntity(); |
1244
|
|
|
$object = $item->getObjectEntity(); |
1245
|
|
|
if (!$subject || !$object) { |
1246
|
|
|
// subject is disabled or subject/object deleted |
1247
|
|
|
return ''; |
1248
|
|
|
} |
1249
|
|
|
|
1250
|
|
|
if (elgg_extract('register_rss_link', $vars)) { |
1251
|
|
|
elgg_register_rss_link(); |
1252
|
|
|
} |
1253
|
|
|
|
1254
|
|
|
$vars['item'] = $item; |
1255
|
|
|
|
1256
|
|
|
// create river view logic |
1257
|
|
|
$type = $object->getType(); |
1258
|
|
|
$subtype = $object->getSubtype(); |
1259
|
|
|
$action = $item->action_type; |
1260
|
|
|
|
1261
|
|
|
$river_views = [ |
1262
|
|
|
elgg_extract('item_view', $vars, ''), |
1263
|
|
|
'river/item', // important for other viewtypes, e.g. "rss" |
1264
|
|
|
$view, |
1265
|
|
|
"river/{$type}/{$subtype}/{$action}", |
1266
|
|
|
"river/{$type}/{$subtype}/default", |
1267
|
|
|
"river/{$type}/{$action}", |
1268
|
|
|
"river/{$type}/default", |
1269
|
|
|
'river/elements/layout', |
1270
|
|
|
]; |
1271
|
|
|
|
1272
|
|
|
$contents = ''; |
1273
|
|
|
foreach ($river_views as $view) { |
1274
|
|
|
if (elgg_view_exists($view)) { |
1275
|
|
|
$contents = elgg_view($view, $vars); |
1276
|
|
|
break; |
1277
|
|
|
} |
1278
|
|
|
} |
1279
|
|
|
|
1280
|
|
|
return $contents; |
1281
|
|
|
} |
1282
|
|
|
|
1283
|
|
|
/** |
1284
|
|
|
* Convenience function for generating a form from a view in a standard location. |
1285
|
|
|
* |
1286
|
|
|
* This function assumes that the body of the form is located at "forms/$action" and |
1287
|
|
|
* sets the action by default to "action/$action". Automatically wraps the forms/$action |
1288
|
|
|
* view with a <form> tag and inserts the anti-csrf security tokens. |
1289
|
|
|
* |
1290
|
|
|
* @tip This automatically appends elgg-form-action-name to the form's class. It replaces any |
1291
|
|
|
* slashes with dashes (blog/save becomes elgg-form-blog-save) |
1292
|
|
|
* |
1293
|
|
|
* @example |
1294
|
|
|
* <code>echo elgg_view_form('login');</code> |
1295
|
|
|
* |
1296
|
|
|
* This would assume a "login" form body to be at "forms/login" and would set the action |
1297
|
|
|
* of the form to "http://yoursite.com/action/login". |
1298
|
|
|
* |
1299
|
|
|
* If elgg_view('forms/login') is: |
1300
|
|
|
* <input type="text" name="username" /> |
1301
|
|
|
* <input type="password" name="password" /> |
1302
|
|
|
* |
1303
|
|
|
* Then elgg_view_form('login') generates: |
1304
|
|
|
* <form action="http://yoursite.com/action/login" method="post"> |
1305
|
|
|
* ...security tokens... |
1306
|
|
|
* <input type="text" name="username" /> |
1307
|
|
|
* <input type="password" name="password" /> |
1308
|
|
|
* </form> |
1309
|
|
|
* |
1310
|
|
|
* @param string $action The name of the action. An action name does not include |
1311
|
|
|
* the leading "action/". For example, "login" is an action name. |
1312
|
|
|
* @param array $form_vars $vars environment passed to the "input/form" view |
1313
|
|
|
* - 'ajax' bool If true, the form will be submitted with an Ajax request |
1314
|
|
|
* @param array $body_vars $vars environment passed to the "forms/$action" view |
1315
|
|
|
* |
1316
|
|
|
* @return string The complete form |
1317
|
|
|
*/ |
1318
|
|
|
function elgg_view_form($action, $form_vars = [], $body_vars = []) { |
1319
|
31 |
|
return _elgg_services()->forms->render($action, $form_vars, $body_vars); |
1320
|
|
|
} |
1321
|
|
|
|
1322
|
|
|
/** |
1323
|
|
|
* Sets form footer and defers its rendering until the form view and extensions have been rendered. |
1324
|
|
|
* Deferring footer rendering allows plugins to extend the form view while maintaining |
1325
|
|
|
* logical DOM structure. |
1326
|
|
|
* Footer will be rendered using 'elements/forms/footer' view after form body has finished rendering |
1327
|
|
|
* |
1328
|
|
|
* @param string $footer Footer |
1329
|
|
|
* @return bool |
1330
|
|
|
*/ |
1331
|
|
|
function elgg_set_form_footer($footer = '') { |
1332
|
22 |
|
return _elgg_services()->forms->setFooter($footer); |
1333
|
|
|
} |
1334
|
|
|
|
1335
|
|
|
/** |
1336
|
|
|
* Returns currently set footer, or false if not in the form rendering stack |
1337
|
|
|
* @return string|false |
1338
|
|
|
*/ |
1339
|
|
|
function elgg_get_form_footer() { |
1340
|
|
|
return _elgg_services()->forms->getFooter(); |
1341
|
|
|
} |
1342
|
|
|
|
1343
|
|
|
/** |
1344
|
|
|
* Split array of vars into subarrays based on property prefixes |
1345
|
|
|
* |
1346
|
|
|
* @see elgg_view_field() |
1347
|
|
|
* |
1348
|
|
|
* @param array $vars Vars to split |
1349
|
|
|
* @param array $prefixes Prefixes to split |
1350
|
|
|
* |
1351
|
|
|
* @return array |
1352
|
|
|
*/ |
1353
|
|
|
function _elgg_split_vars(array $vars = [], array $prefixes = null) { |
1354
|
|
|
|
1355
|
9 |
|
if (!isset($prefixes)) { |
1356
|
9 |
|
$prefixes = ['#']; |
1357
|
|
|
} |
1358
|
|
|
|
1359
|
9 |
|
$return = []; |
1360
|
|
|
|
1361
|
9 |
|
foreach ($vars as $key => $value) { |
1362
|
9 |
|
foreach ($prefixes as $prefix) { |
1363
|
9 |
|
if (substr($key, 0, 1) === $prefix) { |
1364
|
9 |
|
$key = substr($key, 1); |
1365
|
9 |
|
$return[$prefix][$key] = $value; |
1366
|
9 |
|
break; |
1367
|
|
|
} else { |
1368
|
9 |
|
$return[''][$key] = $value; |
1369
|
|
|
} |
1370
|
|
|
} |
1371
|
|
|
} |
1372
|
|
|
|
1373
|
9 |
|
return $return; |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
/** |
1377
|
|
|
* Renders a form field, usually with a wrapper element, a label, help text, etc. |
1378
|
|
|
* |
1379
|
|
|
* @param array $params Field parameters and variables for the input view. |
1380
|
|
|
* Keys not prefixed with hash (#) are passed to the input view as $vars. |
1381
|
|
|
* Keys prefixed with a hash specify the field wrapper (.elgg-view-field) output. |
1382
|
|
|
* - #type: specifies input view. E.g. "text" uses the view "input/text". |
1383
|
|
|
* - #label: field label HTML |
1384
|
|
|
* - #help: field help HTML |
1385
|
|
|
* - #class: field class name |
1386
|
|
|
* - #view: custom view to use to render the field |
1387
|
|
|
* - #html: can be used to render custom HTML instead of in put field, helpful when you need to add a help paragraph or similar |
1388
|
|
|
* Note: Both #label and #help are printed unescaped within their wrapper element. |
1389
|
|
|
* Note: Some fields (like input/checkbox) need special attention because #label and label serve different purposes |
1390
|
|
|
* "#label" will be used as a label in the field wrapper but "label" will be used in the input view |
1391
|
|
|
* |
1392
|
|
|
* @return string |
1393
|
|
|
* @since 2.3 |
1394
|
|
|
*/ |
1395
|
|
|
function elgg_view_field(array $params = []) { |
1396
|
|
|
|
1397
|
26 |
|
if (!empty($params['#html'])) { |
1398
|
|
|
return $params['#html']; |
1399
|
|
|
} |
1400
|
|
|
|
1401
|
26 |
|
if (empty($params['#type'])) { |
1402
|
|
|
_elgg_services()->logger->error(__FUNCTION__ . '(): $params["#type"] is required.'); |
1403
|
|
|
return ''; |
1404
|
|
|
} |
1405
|
|
|
|
1406
|
26 |
|
$input_type = $params['#type']; |
1407
|
26 |
|
if (!elgg_view_exists("input/$input_type")) { |
1408
|
17 |
|
return ''; |
1409
|
|
|
} |
1410
|
|
|
|
1411
|
9 |
|
$hidden_types = ['hidden', 'securitytoken']; |
1412
|
9 |
|
if (in_array($input_type, $hidden_types)) { |
1413
|
9 |
|
$params = _elgg_split_vars($params); |
1414
|
9 |
|
return elgg_view("input/$input_type", $params['']); |
1415
|
|
|
} |
1416
|
|
|
|
1417
|
9 |
|
$id = elgg_extract('id', $params); |
1418
|
9 |
|
if (!$id) { |
1419
|
9 |
|
$id = "elgg-field-" . base_convert(mt_rand(), 10, 36); |
1420
|
9 |
|
$params['id'] = $id; |
1421
|
|
|
} |
1422
|
|
|
|
1423
|
9 |
|
$make_special_checkbox_label = false; |
1424
|
9 |
|
if ($input_type == 'checkbox' && (isset($params['label']) || isset($params['#label']))) { |
1425
|
|
|
if (isset($params['#label']) && isset($params['label'])) { |
1426
|
|
|
$params['label_tag'] = 'div'; |
1427
|
|
|
} else { |
1428
|
|
|
$label = elgg_extract('label', $params); |
1429
|
|
|
$label = elgg_extract('#label', $params, $label); |
1430
|
|
|
|
1431
|
|
|
$params['#label'] = $label; |
1432
|
|
|
unset($params['label']); |
1433
|
|
|
|
1434
|
|
|
// Single checkbox input view gets special treatment |
1435
|
|
|
// We don't want the field label to appear a checkbox without a label |
1436
|
|
|
$make_special_checkbox_label = true; |
1437
|
|
|
} |
1438
|
|
|
} |
1439
|
|
|
|
1440
|
|
|
// Need to set defaults to prevent input keys with same name ending up in element vars if not provided |
1441
|
|
|
$defaults = [ |
1442
|
9 |
|
'#class' => ELGG_ENTITIES_ANY_VALUE, |
1443
|
|
|
'#help' => ELGG_ENTITIES_ANY_VALUE, |
1444
|
|
|
'#label' => ELGG_ENTITIES_ANY_VALUE, |
1445
|
|
|
'#view' => ELGG_ENTITIES_ANY_VALUE, |
1446
|
|
|
]; |
1447
|
9 |
|
$params = array_merge($defaults, $params); |
1448
|
|
|
|
1449
|
|
|
// first pass non-hash keys into both |
1450
|
9 |
|
$split_params = _elgg_split_vars($params); |
1451
|
|
|
|
1452
|
|
|
// $vars passed to input/$input_name |
1453
|
9 |
|
$input_vars = $split_params['']; |
1454
|
|
|
|
1455
|
|
|
// $vars passed to label, help and field wrapper views |
1456
|
9 |
|
$element_vars = array_merge($split_params[''], $split_params['#']); |
1457
|
|
|
|
1458
|
|
|
// field input view needs this |
1459
|
9 |
|
$input_vars['input_type'] = $input_type; |
1460
|
|
|
|
1461
|
|
|
// field views get more data |
1462
|
9 |
|
$element_vars['input_type'] = $input_type; |
1463
|
|
|
|
1464
|
|
|
// wrap if present |
1465
|
9 |
|
$element_vars['label'] = elgg_view('elements/forms/label', $element_vars); |
1466
|
9 |
|
$element_vars['help'] = elgg_view('elements/forms/help', $element_vars); |
1467
|
|
|
|
1468
|
9 |
|
if ($make_special_checkbox_label) { |
1469
|
|
|
$input_vars['label'] = $element_vars['label']; |
1470
|
|
|
$input_vars['label_tag'] = 'div'; |
1471
|
|
|
unset($element_vars['label']); |
1472
|
|
|
} |
1473
|
9 |
|
$element_vars['input'] = elgg_view("elements/forms/input", $input_vars); |
1474
|
|
|
|
1475
|
9 |
|
return elgg_view('elements/forms/field', $element_vars); |
1476
|
|
|
} |
1477
|
|
|
|
1478
|
|
|
/** |
1479
|
|
|
* Create a tagcloud for viewing |
1480
|
|
|
* |
1481
|
|
|
* |
1482
|
|
|
* @param array $options Any elgg_get_tags() options except: |
1483
|
|
|
* |
1484
|
|
|
* type => must be single entity type |
1485
|
|
|
* |
1486
|
|
|
* subtype => must be single entity subtype |
1487
|
|
|
* |
1488
|
|
|
* @return string |
1489
|
|
|
* |
1490
|
|
|
* @see elgg_get_tags() |
1491
|
|
|
* @since 1.7.1 |
1492
|
|
|
*/ |
1493
|
|
|
function elgg_view_tagcloud(array $options = []) { |
1494
|
|
|
|
1495
|
|
|
$type = $subtype = ''; |
1496
|
|
|
if (isset($options['type'])) { |
1497
|
|
|
$type = $options['type']; |
1498
|
|
|
} |
1499
|
|
|
if (isset($options['subtype'])) { |
1500
|
|
|
$subtype = $options['subtype']; |
1501
|
|
|
} |
1502
|
|
|
|
1503
|
|
|
$tag_data = elgg_get_tags($options); |
1504
|
|
|
return elgg_view("output/tagcloud", [ |
1505
|
|
|
'value' => $tag_data, |
1506
|
|
|
'type' => $type, |
1507
|
|
|
'subtype' => $subtype, |
1508
|
|
|
]); |
1509
|
|
|
} |
1510
|
|
|
|
1511
|
|
|
/** |
1512
|
|
|
* View an item in a list |
1513
|
|
|
* |
1514
|
|
|
* @param mixed $item Entity, annotation, river item, or other data |
1515
|
|
|
* @param array $vars Additional parameters for the rendering |
1516
|
|
|
* 'item_view' - Alternative view used to render list items |
1517
|
|
|
* This parameter is required if rendering |
1518
|
|
|
* list items that are not entity, annotation or river |
1519
|
|
|
* @return false|string |
1520
|
|
|
* @since 1.8.0 |
1521
|
|
|
* @internal |
1522
|
|
|
*/ |
1523
|
|
|
function elgg_view_list_item($item, array $vars = []) { |
1524
|
|
|
|
1525
|
6 |
|
if ($item instanceof \ElggEntity) { |
1526
|
6 |
|
return elgg_view_entity($item, $vars); |
1527
|
|
|
} else if ($item instanceof \ElggAnnotation) { |
1528
|
|
|
return elgg_view_annotation($item, $vars); |
1529
|
|
|
} else if ($item instanceof \ElggRiverItem) { |
1530
|
|
|
return elgg_view_river_item($item, $vars); |
1531
|
|
|
} |
1532
|
|
|
|
1533
|
|
|
$view = elgg_extract('item_view', $vars); |
1534
|
|
|
if ($view && elgg_view_exists($view)) { |
1535
|
|
|
$vars['item'] = $item; |
1536
|
|
|
return elgg_view($view, $vars); |
1537
|
|
|
} |
1538
|
|
|
|
1539
|
|
|
return ''; |
1540
|
|
|
} |
1541
|
|
|
|
1542
|
|
|
/** |
1543
|
|
|
* View an icon glyph |
1544
|
|
|
* |
1545
|
|
|
* @param string $name The specific icon to display |
1546
|
|
|
* @param mixed $vars The additional classname as a string ('float', 'float-alt' or a custom class) |
1547
|
|
|
* or an array of variables (array('class' => 'float')) to pass to the icon view. |
1548
|
|
|
* |
1549
|
|
|
* @return string The html for displaying an icon |
1550
|
|
|
* @throws InvalidArgumentException |
1551
|
|
|
*/ |
1552
|
|
|
function elgg_view_icon($name, $vars = []) { |
1553
|
20 |
|
if (empty($vars)) { |
1554
|
12 |
|
$vars = []; |
1555
|
|
|
} |
1556
|
|
|
|
1557
|
20 |
|
if (is_string($vars)) { |
1558
|
1 |
|
$vars = ['class' => $vars]; |
1559
|
|
|
} |
1560
|
|
|
|
1561
|
20 |
|
if (!is_array($vars)) { |
1562
|
|
|
throw new \InvalidArgumentException('$vars needs to be a string or an array'); |
1563
|
|
|
} |
1564
|
|
|
|
1565
|
20 |
|
$vars['class'] = elgg_extract_class($vars, "elgg-icon-$name"); |
1566
|
|
|
|
1567
|
20 |
|
return elgg_view("output/icon", $vars); |
1568
|
|
|
} |
1569
|
|
|
|
1570
|
|
|
/** |
1571
|
|
|
* Include the RSS icon link and link element in the head |
1572
|
|
|
* |
1573
|
|
|
* @return void |
1574
|
|
|
*/ |
1575
|
|
|
function elgg_register_rss_link() { |
1576
|
33 |
|
_elgg_config()->_elgg_autofeed = true; |
1577
|
33 |
|
} |
1578
|
|
|
|
1579
|
|
|
/** |
1580
|
|
|
* Remove the RSS icon link and link element from the head |
1581
|
|
|
* |
1582
|
|
|
* @return void |
1583
|
|
|
*/ |
1584
|
|
|
function elgg_unregister_rss_link() { |
1585
|
|
|
_elgg_config()->_elgg_autofeed = false; |
1586
|
|
|
} |
1587
|
|
|
|
1588
|
|
|
/** |
1589
|
|
|
* Should the RSS view of this URL be linked to? |
1590
|
|
|
* |
1591
|
|
|
* @return bool |
1592
|
|
|
* @internal |
1593
|
|
|
*/ |
1594
|
|
|
function _elgg_has_rss_link() { |
1595
|
52 |
|
if (_elgg_config()->disable_rss) { |
1596
|
|
|
return false; |
1597
|
|
|
} |
1598
|
|
|
|
1599
|
52 |
|
return (bool) _elgg_config()->_elgg_autofeed; |
1600
|
|
|
} |
1601
|
|
|
|
1602
|
|
|
/** |
1603
|
|
|
* Auto-registers views from a location. |
1604
|
|
|
* |
1605
|
|
|
* @note Views in plugin/views/ are automatically registered for active plugins. |
1606
|
|
|
* Plugin authors would only need to call this if optionally including |
1607
|
|
|
* an entire views structure. |
1608
|
|
|
* |
1609
|
|
|
* @param string $view_base Optional The base of the view name without the view type. |
1610
|
|
|
* @param string $folder Required The folder to begin looking in |
1611
|
|
|
* @param string $ignored This argument is ignored |
1612
|
|
|
* @param string $viewtype The type of view we're looking at (default, rss, etc) |
1613
|
|
|
* |
1614
|
|
|
* @return bool returns false if folder can't be read |
1615
|
|
|
* @since 1.7.0 |
1616
|
|
|
* @see elgg_set_view_location() |
1617
|
|
|
* @internal |
1618
|
|
|
*/ |
1619
|
|
|
function autoregister_views($view_base, $folder, $ignored, $viewtype) { |
1620
|
|
|
return _elgg_services()->views->autoregisterViews($view_base, $folder, $viewtype); |
1621
|
|
|
} |
1622
|
|
|
|
1623
|
|
|
/** |
1624
|
|
|
* Minifies simplecache CSS and JS views by handling the "simplecache:generate" hook |
1625
|
|
|
* |
1626
|
|
|
* @param string $hook The name of the hook |
1627
|
|
|
* @param string $type View type (css, js, or unknown) |
1628
|
|
|
* @param string $content Content of the view |
1629
|
|
|
* @param array $params Array of parameters |
1630
|
|
|
* |
1631
|
|
|
* @return string|null View content minified (if css/js type) |
1632
|
|
|
* @internal |
1633
|
|
|
*/ |
1634
|
|
|
function _elgg_views_minify($hook, $type, $content, $params) { |
1635
|
|
|
if (preg_match('~[\.-]min\.~', $params['view'])) { |
1636
|
|
|
// bypass minification |
1637
|
|
|
return; |
1638
|
|
|
} |
1639
|
|
|
|
1640
|
|
|
if ($type == 'js') { |
1641
|
|
|
if (_elgg_config()->simplecache_minify_js) { |
1642
|
|
|
return JSMin::minify($content); |
1643
|
|
|
} |
1644
|
|
|
} elseif ($type == 'css') { |
1645
|
|
|
if (_elgg_config()->simplecache_minify_css) { |
1646
|
|
|
$cssmin = new CSSmin(); |
1647
|
|
|
return $cssmin->run($content); |
1648
|
|
|
} |
1649
|
|
|
} |
1650
|
|
|
} |
1651
|
|
|
|
1652
|
|
|
/** |
1653
|
|
|
* Preprocesses CSS views sent by /cache URLs |
1654
|
|
|
* |
1655
|
|
|
* @param string $hook The name of the hook "simplecache:generate" or "cache:generate" |
1656
|
|
|
* @param string $type "css" |
1657
|
|
|
* @param string $content Content of the view |
1658
|
|
|
* @param array $params Array of parameters |
1659
|
|
|
* |
1660
|
|
|
* @return string|null View content |
1661
|
|
|
* @internal |
1662
|
|
|
*/ |
1663
|
|
|
function _elgg_views_preprocess_css($hook, $type, $content, $params) { |
1664
|
6 |
|
$options = elgg_extract('compiler_options', $params, []); |
1665
|
6 |
|
return _elgg_services()->cssCompiler->compile($content, $options); |
1666
|
|
|
} |
1667
|
|
|
|
1668
|
|
|
/** |
1669
|
|
|
* Inserts module names into anonymous modules by handling the "simplecache:generate" and "cache:generate" hook. |
1670
|
|
|
* |
1671
|
|
|
* @param string $hook The name of the hook |
1672
|
|
|
* @param string $type View type (css, js, or unknown) |
1673
|
|
|
* @param string $content Content of the view |
1674
|
|
|
* @param array $params Array of parameters |
1675
|
|
|
* |
1676
|
|
|
* @return string|null View content minified (if css/js type) |
1677
|
|
|
* @internal |
1678
|
|
|
*/ |
1679
|
|
|
function _elgg_views_amd($hook, $type, $content, $params) { |
1680
|
|
|
$filter = new \Elgg\Amd\ViewFilter(); |
1681
|
|
|
return $filter->filter($params['view'], $content); |
1682
|
|
|
} |
1683
|
|
|
|
1684
|
|
|
/** |
1685
|
|
|
* Sends X-Frame-Options header on page requests |
1686
|
|
|
* |
1687
|
|
|
* @return void |
1688
|
|
|
* |
1689
|
|
|
* @internal |
1690
|
|
|
*/ |
1691
|
|
|
function _elgg_views_send_header_x_frame_options() { |
1692
|
10 |
|
elgg_set_http_header('X-Frame-Options: SAMEORIGIN'); |
1693
|
10 |
|
} |
1694
|
|
|
|
1695
|
|
|
/** |
1696
|
|
|
* Is there a chance a plugin is altering this view? |
1697
|
|
|
* |
1698
|
|
|
* @note Must be called after the [init, system] event, ideally as late as possible. |
1699
|
|
|
* |
1700
|
|
|
* @note Always returns true if the view's location is set in /engine/views.php. Elgg does not keep |
1701
|
|
|
* track of the defaults for those locations. |
1702
|
|
|
* |
1703
|
|
|
* <code> |
1704
|
|
|
* // check a view in core |
1705
|
|
|
* if (_elgg_view_may_be_altered('foo/bar', 'foo/bar.php')) { |
1706
|
|
|
* // use the view for BC |
1707
|
|
|
* } |
1708
|
|
|
* |
1709
|
|
|
* // check a view in a bundled plugin |
1710
|
|
|
* $dir = __DIR__ . "/views/" . elgg_get_viewtype(); |
1711
|
|
|
* if (_elgg_view_may_be_altered('foo.css', "$dir/foo.css.php")) { |
1712
|
|
|
* // use the view for BC |
1713
|
|
|
* } |
1714
|
|
|
* </code> |
1715
|
|
|
* |
1716
|
|
|
* @param string $view View name. E.g. "elgg/init.js" |
1717
|
|
|
* @param string $path Absolute file path, or path relative to the viewtype directory. E.g. "elgg/init.js.php" |
1718
|
|
|
* |
1719
|
|
|
* @return bool |
1720
|
|
|
* @internal |
1721
|
|
|
*/ |
1722
|
|
|
function _elgg_view_may_be_altered($view, $path) { |
1723
|
|
|
$views = _elgg_services()->views; |
1724
|
|
|
|
1725
|
|
|
if ($views->viewIsExtended($view) || $views->viewHasHookHandlers($view)) { |
1726
|
|
|
return true; |
1727
|
|
|
} |
1728
|
|
|
|
1729
|
|
|
$viewtype = elgg_get_viewtype(); |
1730
|
|
|
|
1731
|
|
|
// check location |
1732
|
|
|
if (0 === strpos($path, '/') || preg_match('~^([A-Za-z]\:)?\\\\~', $path)) { |
1733
|
|
|
// absolute path |
1734
|
|
|
$expected_path = $path; |
1735
|
|
|
} else { |
1736
|
|
|
// relative path |
1737
|
|
|
$expected_path = Paths::elgg() . "views/$viewtype/" . ltrim($path, '/\\'); |
1738
|
|
|
} |
1739
|
|
|
|
1740
|
|
|
$view_path = $views->findViewFile($view, $viewtype); |
1741
|
|
|
|
1742
|
|
|
return realpath($view_path) !== realpath($expected_path); |
1743
|
|
|
} |
1744
|
|
|
|
1745
|
|
|
/** |
1746
|
|
|
* Initialize viewtypes on system boot event |
1747
|
|
|
* This ensures simplecache is cleared during upgrades. See #2252 |
1748
|
|
|
* |
1749
|
|
|
* @return void |
1750
|
|
|
* @internal |
1751
|
|
|
* @elgg_event_handler boot system |
1752
|
|
|
*/ |
1753
|
|
|
function elgg_views_boot() { |
1754
|
72 |
|
_elgg_services()->viewCacher->registerCoreViews(); |
1755
|
|
|
|
1756
|
|
|
// jQuery and UI must come before require. See #9024 |
1757
|
72 |
|
elgg_register_js('jquery', elgg_get_simplecache_url('jquery.js'), 'head'); |
1758
|
72 |
|
elgg_load_js('jquery'); |
1759
|
|
|
|
1760
|
72 |
|
elgg_register_js('jquery-ui', elgg_get_simplecache_url('jquery-ui.js'), 'head'); |
1761
|
72 |
|
elgg_load_js('jquery-ui'); |
1762
|
|
|
|
1763
|
72 |
|
elgg_register_js('elgg.require_config', elgg_get_simplecache_url('elgg/require_config.js'), 'head'); |
1764
|
72 |
|
elgg_load_js('elgg.require_config'); |
1765
|
|
|
|
1766
|
72 |
|
elgg_register_js('require', elgg_get_simplecache_url('require.js'), 'head'); |
1767
|
72 |
|
elgg_load_js('require'); |
1768
|
|
|
|
1769
|
72 |
|
elgg_register_js('elgg', elgg_get_simplecache_url('elgg.js'), 'head'); |
1770
|
72 |
|
elgg_load_js('elgg'); |
1771
|
|
|
|
1772
|
72 |
|
elgg_register_css('font-awesome', elgg_get_simplecache_url('font-awesome/css/all.min.css')); |
1773
|
72 |
|
elgg_load_css('font-awesome'); |
1774
|
|
|
|
1775
|
72 |
|
elgg_register_css('elgg', elgg_get_simplecache_url('elgg.css')); |
1776
|
72 |
|
elgg_load_css('elgg'); |
1777
|
|
|
|
1778
|
72 |
|
elgg_register_simplecache_view('elgg/init.js'); |
1779
|
|
|
|
1780
|
72 |
|
elgg_extend_view('elgg.css', 'lightbox/elgg-colorbox-theme/colorbox.css'); |
1781
|
|
|
|
1782
|
72 |
|
elgg_define_js('jquery.ui.autocomplete.html', [ |
1783
|
72 |
|
'deps' => ['jquery-ui'], |
1784
|
|
|
]); |
1785
|
|
|
|
1786
|
72 |
|
elgg_register_js('elgg.avatar_cropper', elgg_get_simplecache_url('elgg/ui.avatar_cropper.js')); |
1787
|
|
|
|
1788
|
|
|
// @deprecated 2.2 |
1789
|
72 |
|
elgg_register_js('elgg.ui.river', elgg_get_simplecache_url('elgg/ui.river.js')); |
1790
|
|
|
|
1791
|
72 |
|
elgg_register_js('jquery.imgareaselect', elgg_get_simplecache_url('jquery.imgareaselect.js')); |
1792
|
72 |
|
elgg_register_css('jquery.imgareaselect', elgg_get_simplecache_url('jquery.imgareaselect.css')); |
1793
|
|
|
|
1794
|
72 |
|
elgg_register_css('jquery.treeview', elgg_get_simplecache_url('jquery-treeview/jquery.treeview.css')); |
1795
|
72 |
|
elgg_define_js('jquery.treeview', [ |
1796
|
72 |
|
'src' => elgg_get_simplecache_url('jquery-treeview/jquery.treeview.js'), |
1797
|
72 |
|
'exports' => 'jQuery.fn.treeview', |
1798
|
|
|
'deps' => ['jquery'], |
1799
|
|
|
]); |
1800
|
|
|
|
1801
|
72 |
|
elgg_register_ajax_view('languages.js'); |
1802
|
|
|
|
1803
|
|
|
// pre-process CSS regardless of simplecache |
1804
|
72 |
|
elgg_register_plugin_hook_handler('cache:generate', 'css', '_elgg_views_preprocess_css'); |
1805
|
72 |
|
elgg_register_plugin_hook_handler('simplecache:generate', 'css', '_elgg_views_preprocess_css'); |
1806
|
|
|
|
1807
|
72 |
|
elgg_register_plugin_hook_handler('simplecache:generate', 'js', '_elgg_views_amd'); |
1808
|
72 |
|
elgg_register_plugin_hook_handler('cache:generate', 'js', '_elgg_views_amd'); |
1809
|
72 |
|
elgg_register_plugin_hook_handler('simplecache:generate', 'css', '_elgg_views_minify'); |
1810
|
72 |
|
elgg_register_plugin_hook_handler('simplecache:generate', 'js', '_elgg_views_minify'); |
1811
|
|
|
|
1812
|
72 |
|
elgg_register_plugin_hook_handler('output:before', 'page', '_elgg_views_send_header_x_frame_options'); |
1813
|
|
|
|
1814
|
72 |
|
elgg_register_plugin_hook_handler('view_vars', 'elements/forms/help', '_elgg_views_file_help_upload_limit'); |
1815
|
|
|
|
1816
|
|
|
// registered with high priority for BC |
1817
|
|
|
// prior to 2.2 registration used to take place in _elgg_views_prepare_head() before the hook was triggered |
1818
|
72 |
|
elgg_register_plugin_hook_handler('head', 'page', '_elgg_views_prepare_favicon_links', 1); |
1819
|
|
|
|
1820
|
|
|
// set default icon sizes - can be overridden with plugin |
1821
|
72 |
|
if (!_elgg_config()->hasValue('icon_sizes')) { |
1822
|
|
|
$icon_sizes = [ |
1823
|
5 |
|
'topbar' => ['w' => 16, 'h' => 16, 'square' => true, 'upscale' => true], |
1824
|
|
|
'tiny' => ['w' => 25, 'h' => 25, 'square' => true, 'upscale' => true], |
1825
|
|
|
'small' => ['w' => 40, 'h' => 40, 'square' => true, 'upscale' => true], |
1826
|
|
|
'medium' => ['w' => 100, 'h' => 100, 'square' => true, 'upscale' => true], |
1827
|
|
|
'large' => ['w' => 200, 'h' => 200, 'square' => true, 'upscale' => true], |
1828
|
|
|
'master' => ['w' => 10240, 'h' => 10240, 'square' => false, 'upscale' => false, 'crop' => false], |
1829
|
|
|
]; |
1830
|
5 |
|
elgg_set_config('icon_sizes', $icon_sizes); |
1831
|
|
|
} |
1832
|
|
|
|
1833
|
|
|
// Configure lightbox |
1834
|
72 |
|
elgg_register_plugin_hook_handler('elgg.data', 'site', '_elgg_set_lightbox_config'); |
1835
|
72 |
|
} |
1836
|
|
|
|
1837
|
|
|
/** |
1838
|
|
|
* Get the site data to be merged into "elgg" in elgg.js. |
1839
|
|
|
* |
1840
|
|
|
* Unlike _elgg_get_js_page_data(), the keys returned are literal expressions. |
1841
|
|
|
* |
1842
|
|
|
* @return array |
1843
|
|
|
* @internal |
1844
|
|
|
*/ |
1845
|
|
|
function _elgg_get_js_site_data() { |
1846
|
|
|
$language = _elgg_config()->language; |
1847
|
|
|
if (!$language) { |
1848
|
|
|
$language = 'en'; |
1849
|
|
|
} |
1850
|
|
|
|
1851
|
|
|
return [ |
1852
|
|
|
'elgg.data' => (object) elgg_trigger_plugin_hook('elgg.data', 'site', null, []), |
1853
|
|
|
'elgg.version' => elgg_get_version(), |
1854
|
|
|
'elgg.release' => elgg_get_version(true), |
1855
|
|
|
'elgg.config.wwwroot' => elgg_get_site_url(), |
1856
|
|
|
|
1857
|
|
|
// refresh token 3 times during its lifetime (in microseconds 1000 * 1/3) |
1858
|
|
|
'elgg.security.interval' => (int) elgg()->csrf->getActionTokenTimeout() * 333, |
1859
|
|
|
'elgg.config.language' => $language, |
1860
|
|
|
]; |
1861
|
|
|
} |
1862
|
|
|
|
1863
|
|
|
/** |
1864
|
|
|
* Get the initial contents of "elgg" client side. Will be extended by elgg.js. |
1865
|
|
|
* |
1866
|
|
|
* @return array |
1867
|
|
|
* @internal |
1868
|
|
|
*/ |
1869
|
|
|
function _elgg_get_js_page_data() { |
1870
|
8 |
|
$data = elgg_trigger_plugin_hook('elgg.data', 'page', null, []); |
1871
|
8 |
|
if (!is_array($data)) { |
1872
|
|
|
elgg_log('"elgg.data" plugin hook handlers must return an array. Returned ' . gettype($data) . '.', 'ERROR'); |
1873
|
|
|
$data = []; |
1874
|
|
|
} |
1875
|
|
|
|
1876
|
|
|
$elgg = [ |
1877
|
8 |
|
'config' => [ |
1878
|
8 |
|
'lastcache' => (int) _elgg_config()->lastcache, |
1879
|
8 |
|
'viewtype' => elgg_get_viewtype(), |
1880
|
8 |
|
'simplecache_enabled' => (int) elgg_is_simplecache_enabled(), |
1881
|
8 |
|
'current_language' => get_current_language(), |
1882
|
|
|
], |
1883
|
|
|
'security' => [ |
1884
|
|
|
'token' => [ |
1885
|
8 |
|
'__elgg_ts' => $ts = time(), |
1886
|
8 |
|
'__elgg_token' => generate_action_token($ts), |
1887
|
|
|
], |
1888
|
|
|
], |
1889
|
|
|
'session' => [ |
1890
|
|
|
'user' => null, |
1891
|
8 |
|
'token' => _elgg_services()->session->get('__elgg_session'), |
1892
|
|
|
], |
1893
|
8 |
|
'_data' => (object) $data, |
1894
|
|
|
]; |
1895
|
|
|
|
1896
|
8 |
|
if (_elgg_config()->elgg_load_sync_code) { |
1897
|
|
|
$elgg['config']['load_sync_code'] = true; |
1898
|
|
|
} |
1899
|
|
|
|
1900
|
8 |
|
$page_owner = elgg_get_page_owner_entity(); |
1901
|
8 |
|
if ($page_owner instanceof ElggEntity) { |
1902
|
|
|
$elgg['page_owner'] = $page_owner->toObject(); |
1903
|
|
|
} |
1904
|
|
|
|
1905
|
8 |
|
$user = elgg_get_logged_in_user_entity(); |
1906
|
8 |
|
if ($user instanceof ElggUser) { |
1907
|
|
|
$user_object = $user->toObject(); |
1908
|
|
|
$user_object->admin = $user->isAdmin(); |
1909
|
|
|
$elgg['session']['user'] = $user_object; |
1910
|
|
|
} |
1911
|
|
|
|
1912
|
8 |
|
return $elgg; |
1913
|
|
|
} |
1914
|
|
|
|
1915
|
|
|
/** |
1916
|
|
|
* Render a view while the global viewtype is temporarily changed. This makes sure that |
1917
|
|
|
* nested views use the same viewtype. |
1918
|
|
|
* |
1919
|
|
|
* @param string $view View name |
1920
|
|
|
* @param array $vars View vars |
1921
|
|
|
* @param string $viewtype Temporary viewtype ('' to leave current) |
1922
|
|
|
* |
1923
|
|
|
* @return mixed |
1924
|
|
|
* @internal |
1925
|
|
|
*/ |
1926
|
|
|
function _elgg_view_under_viewtype($view, $vars, $viewtype) { |
1927
|
27 |
|
$current_view_type = null; |
1928
|
27 |
|
if ($viewtype) { |
1929
|
21 |
|
$current_view_type = elgg_get_viewtype(); |
1930
|
21 |
|
elgg_set_viewtype($viewtype); |
1931
|
|
|
} |
1932
|
|
|
|
1933
|
27 |
|
$ret = elgg_view($view, $vars); |
1934
|
|
|
|
1935
|
27 |
|
if (isset($current_view_type)) { |
1936
|
21 |
|
elgg_set_viewtype($current_view_type); |
1937
|
|
|
} |
1938
|
|
|
|
1939
|
27 |
|
return $ret; |
1940
|
|
|
} |
1941
|
|
|
|
1942
|
|
|
/** |
1943
|
|
|
* Set lightbox config |
1944
|
|
|
* |
1945
|
|
|
* @param string $hook "elgg.data" |
1946
|
|
|
* @param string $type "site" |
1947
|
|
|
* @param array $return Data |
1948
|
|
|
* @param array $params Hook params |
1949
|
|
|
* @return array |
1950
|
|
|
* @internal |
1951
|
|
|
*/ |
1952
|
|
|
function _elgg_set_lightbox_config($hook, $type, $return, $params) { |
1953
|
|
|
|
1954
|
|
|
$return['lightbox'] = [ |
1955
|
|
|
'current' => elgg_echo('js:lightbox:current', ['{current}', '{total}']), |
1956
|
|
|
'previous' => elgg_view_icon('caret-left'), |
1957
|
|
|
'next' => elgg_view_icon('caret-right'), |
1958
|
|
|
'close' => elgg_view_icon('times'), |
1959
|
|
|
'opacity' => 0.5, |
1960
|
|
|
'maxWidth' => '990px', |
1961
|
|
|
'maxHeight' => '990px', |
1962
|
|
|
'initialWidth' => '300px', |
1963
|
|
|
'initialHeight' => '300px', |
1964
|
|
|
]; |
1965
|
|
|
|
1966
|
|
|
return $return; |
1967
|
|
|
} |
1968
|
|
|
|
1969
|
|
|
/** |
1970
|
|
|
* Add a help text to input/file about upload limit |
1971
|
|
|
* |
1972
|
|
|
* In order to not show the help text supply 'show_upload_limit' => false to elgg_view_field() |
1973
|
|
|
* |
1974
|
|
|
* @param \Elgg\Hook $hook 'view_vars' 'elements/forms/help' |
1975
|
|
|
* |
1976
|
|
|
* @return void|array |
1977
|
|
|
* @internal |
1978
|
|
|
*/ |
1979
|
|
|
function _elgg_views_file_help_upload_limit(\Elgg\Hook $hook) { |
1980
|
|
|
|
1981
|
8 |
|
$return = $hook->getValue(); |
1982
|
8 |
|
if (elgg_extract('input_type', $return) !== 'file') { |
1983
|
8 |
|
return; |
1984
|
|
|
} |
1985
|
|
|
|
1986
|
|
|
if (!elgg_extract('show_upload_limit', $return, true)) { |
1987
|
|
|
return; |
1988
|
|
|
} |
1989
|
|
|
|
1990
|
|
|
$help = elgg_extract('help', $return, ''); |
1991
|
|
|
|
1992
|
|
|
// Get post_max_size and upload_max_filesize |
1993
|
|
|
$post_max_size = elgg_get_ini_setting_in_bytes('post_max_size'); |
1994
|
|
|
$upload_max_filesize = elgg_get_ini_setting_in_bytes('upload_max_filesize'); |
1995
|
|
|
|
1996
|
|
|
// Determine the correct value |
1997
|
|
|
$max_upload = $upload_max_filesize > $post_max_size ? $post_max_size : $upload_max_filesize; |
1998
|
|
|
|
1999
|
|
|
$help .= ' ' . elgg_echo('input:file:upload_limit', [elgg_format_bytes($max_upload)]); |
2000
|
|
|
|
2001
|
|
|
$return['help'] = trim($help); |
2002
|
|
|
|
2003
|
|
|
return $return; |
2004
|
|
|
} |
2005
|
|
|
|
2006
|
|
|
/** |
2007
|
|
|
* Maps legacy sprite classes and FontAwesome 4 classes to FontAwesome 5 classes |
2008
|
|
|
* |
2009
|
|
|
* @param array $classes Icon classes |
2010
|
|
|
* @param bool $map_sprites Map legacy Elgg sprites |
2011
|
|
|
* |
2012
|
|
|
* @return array |
2013
|
|
|
* @internal |
2014
|
|
|
*/ |
2015
|
|
|
function _elgg_map_icon_glyph_class(array $classes, $map_sprites = true) { |
2016
|
|
|
|
2017
|
|
|
// these 'old' Elgg 1.x sprite icons will be converted to the FontAwesome version |
2018
|
|
|
$legacy_sprites = [ |
2019
|
17 |
|
"arrow-two-head" => "arrows-h", |
2020
|
|
|
"attention" => "exclamation-triangle", |
2021
|
|
|
"cell-phone" => "mobile", |
2022
|
|
|
"checkmark" => "check", |
2023
|
|
|
"clip" => "paperclip", |
2024
|
|
|
"cursor-drag-arrow" => "arrows", |
2025
|
|
|
"drag-arrow" => "arrows", // 'old' admin sprite |
2026
|
|
|
"delete-alt" => "times-circle", |
2027
|
|
|
"delete" => "times", |
2028
|
|
|
"facebook" => "facebook-square", |
2029
|
|
|
"grid" => "th", |
2030
|
|
|
"hover-menu" => "caret-down", |
2031
|
|
|
"info" => "info-circle", |
2032
|
|
|
"lock-closed" => "lock", |
2033
|
|
|
"lock-open" => "unlock", |
2034
|
|
|
"mail" => "envelope-o", |
2035
|
|
|
"mail-alt" => "envelope", |
2036
|
|
|
"print-alt" => "print", |
2037
|
|
|
"push-pin" => "thumb-tack", |
2038
|
|
|
"push-pin-alt" => "thumb-tack", |
2039
|
|
|
"redo" => "share", |
2040
|
|
|
"round-arrow-left" => "arrow-circle-left", |
2041
|
|
|
"round-arrow-right" => "arrow-circle-right", |
2042
|
|
|
"round-checkmark" => "check-circle", |
2043
|
|
|
"round-minus" => "minus-circle", |
2044
|
|
|
"round-plus" => "plus-circle", |
2045
|
|
|
"rss" => "rss-square", |
2046
|
|
|
"search-focus" => "search", |
2047
|
|
|
"settings" => "wrench", |
2048
|
|
|
"settings-alt" => "cog", |
2049
|
|
|
"share" => "share-alt-square", |
2050
|
|
|
"shop-cart" => "shopping-cart", |
2051
|
|
|
"speech-bubble" => "comment", |
2052
|
|
|
"speech-bubble-alt" => "comments", |
2053
|
|
|
"star-alt" => "star", |
2054
|
|
|
"star-empty" => "star-o", |
2055
|
|
|
"thumbs-down-alt" => "thumbs-down", |
2056
|
|
|
"thumbs-up-alt" => "thumbs-up", |
2057
|
|
|
"trash" => "trash-o", |
2058
|
|
|
"twitter" => "twitter-square", |
2059
|
|
|
"undo" => "reply", |
2060
|
|
|
"video" => "film" |
2061
|
|
|
]; |
2062
|
|
|
|
2063
|
|
|
$fa5 = [ |
2064
|
17 |
|
'address-book-o' => ['address-book', 'far'], |
2065
|
|
|
'address-card-o' => ['address-card', 'far'], |
2066
|
|
|
'area-chart' => ['chart-area', 'fas'], |
2067
|
|
|
'arrow-circle-o-down' => ['arrow-alt-circle-down', 'far'], |
2068
|
|
|
'arrow-circle-o-left' => ['arrow-alt-circle-left', 'far'], |
2069
|
|
|
'arrow-circle-o-right' => ['arrow-alt-circle-right', 'far'], |
2070
|
|
|
'arrow-circle-o-up' => ['arrow-alt-circle-up', 'far'], |
2071
|
|
|
'arrows-alt' => ['expand-arrows-alt', 'fas'], |
2072
|
|
|
'arrows-h' => ['arrows-alt-h', 'fas'], |
2073
|
|
|
'arrows-v' => ['arrows-alt-v', 'fas'], |
2074
|
|
|
'arrows' => ['arrows-alt', 'fas'], |
2075
|
|
|
'asl-interpreting' => ['american-sign-language-interpreting', 'fas'], |
2076
|
|
|
'automobile' => ['car', 'fas'], |
2077
|
|
|
'bank' => ['university', 'fas'], |
2078
|
|
|
'bar-chart-o' => ['chart-bar', 'far'], |
2079
|
|
|
'bar-chart' => ['chart-bar', 'far'], |
2080
|
|
|
'bathtub' => ['bath', 'fas'], |
2081
|
|
|
'battery-0' => ['battery-empty', 'fas'], |
2082
|
|
|
'battery-1' => ['battery-quarter', 'fas'], |
2083
|
|
|
'battery-2' => ['battery-half', 'fas'], |
2084
|
|
|
'battery-3' => ['battery-three-quarters', 'fas'], |
2085
|
|
|
'battery-4' => ['battery-full', 'fas'], |
2086
|
|
|
'battery' => ['battery-full', 'fas'], |
2087
|
|
|
'bell-o' => ['bell', 'far'], |
2088
|
|
|
'bell-slash-o' => ['bell-slash', 'far'], |
2089
|
|
|
'bitbucket-square' => ['bitbucket', 'fab'], |
2090
|
|
|
'bitcoin' => ['btc', 'fab'], |
2091
|
|
|
'bookmark-o' => ['bookmark', 'far'], |
2092
|
|
|
'building-o' => ['building', 'far'], |
2093
|
|
|
'cab' => ['taxi', 'fas'], |
2094
|
|
|
'calendar-check-o' => ['calendar-check', 'far'], |
2095
|
|
|
'calendar-minus-o' => ['calendar-minus', 'far'], |
2096
|
|
|
'calendar-o' => ['calendar', 'far'], |
2097
|
|
|
'calendar-plus-o' => ['calendar-plus', 'far'], |
2098
|
|
|
'calendar-times-o' => ['calendar-times', 'far'], |
2099
|
|
|
'calendar' => ['calendar-alt', 'fas'], |
2100
|
|
|
'caret-square-o-down' => ['caret-square-down', 'far'], |
2101
|
|
|
'caret-square-o-left' => ['caret-square-left', 'far'], |
2102
|
|
|
'caret-square-o-right' => ['caret-square-right', 'far'], |
2103
|
|
|
'caret-square-o-up' => ['caret-square-up', 'far'], |
2104
|
|
|
'cc' => ['closed-captioning', 'far'], |
2105
|
|
|
'chain-broken' => ['unlink', 'fas'], |
2106
|
|
|
'chain' => ['link', 'fas'], |
2107
|
|
|
'check-circle-o' => ['check-circle', 'far'], |
2108
|
|
|
'check-square-o' => ['check-square', 'far'], |
2109
|
|
|
'circle-o-notch' => ['circle-notch', 'fas'], |
2110
|
|
|
'circle-o' => ['circle', 'far'], |
2111
|
|
|
'circle-thin' => ['circle', 'far'], |
2112
|
|
|
'clock-o' => ['clock', 'far'], |
2113
|
|
|
'close' => ['times', 'fas'], |
2114
|
|
|
'cloud-download' => ['cloud-download-alt', 'fas'], |
2115
|
|
|
'cloud-upload' => ['cloud-upload-alt', 'fas'], |
2116
|
|
|
'cny' => ['yen-sign', 'fas'], |
2117
|
|
|
'code-fork' => ['code-branch', 'fas'], |
2118
|
|
|
'comment-o' => ['comment', 'far'], |
2119
|
|
|
'commenting-o' => ['comment-alt', 'far'], |
2120
|
|
|
'commenting' => ['comment-alt', 'fas'], |
2121
|
|
|
'comments-o' => ['comments', 'far'], |
2122
|
|
|
'credit-card-alt' => ['credit-card', 'fas'], |
2123
|
|
|
'cutlery' => ['utensils', 'fas'], |
2124
|
|
|
'dashboard' => ['tachometer-alt', 'fas'], |
2125
|
|
|
'deafness' => ['deaf', 'fas'], |
2126
|
|
|
'dedent' => ['outdent', 'fas'], |
2127
|
|
|
'diamond' => ['gem', 'far'], |
2128
|
|
|
'dollar' => ['dollar-sign', 'fas'], |
2129
|
|
|
'dot-circle-o' => ['dot-circle', 'far'], |
2130
|
|
|
'drivers-license-o' => ['id-card', 'far'], |
2131
|
|
|
'drivers-license' => ['id-card', 'fas'], |
2132
|
|
|
'eercast' => ['sellcast', 'fab'], |
2133
|
|
|
'envelope-o' => ['envelope', 'far'], |
2134
|
|
|
'envelope-open-o' => ['envelope-open', 'far'], |
2135
|
|
|
'eur' => ['euro-sign', 'fas'], |
2136
|
|
|
'euro' => ['euro-sign', 'fas'], |
2137
|
|
|
'exchange' => ['exchange-alt', 'fas'], |
2138
|
|
|
'external-link-square' => ['external-link-square-alt', 'fas'], |
2139
|
|
|
'external-link' => ['external-link-alt', 'fas'], |
2140
|
|
|
'eyedropper' => ['eye-dropper', 'fas'], |
2141
|
|
|
'fa' => ['font-awesome', 'fab'], |
2142
|
|
|
'facebook-f' => ['facebook-f', 'fab'], |
2143
|
|
|
'facebook-official' => ['facebook', 'fab'], |
2144
|
|
|
'facebook' => ['facebook-f', 'fab'], |
2145
|
|
|
'feed' => ['rss', 'fas'], |
2146
|
|
|
'file-archive-o' => ['file-archive', 'far'], |
2147
|
|
|
'file-audio-o' => ['file-audio', 'far'], |
2148
|
|
|
'file-code-o' => ['file-code', 'far'], |
2149
|
|
|
'file-excel-o' => ['file-excel', 'far'], |
2150
|
|
|
'file-image-o' => ['file-image', 'far'], |
2151
|
|
|
'file-movie-o' => ['file-video', 'far'], |
2152
|
|
|
'file-o' => ['file', 'far'], |
2153
|
|
|
'file-pdf-o' => ['file-pdf', 'far'], |
2154
|
|
|
'file-photo-o' => ['file-image', 'far'], |
2155
|
|
|
'file-picture-o' => ['file-image', 'far'], |
2156
|
|
|
'file-powerpoint-o' => ['file-powerpoint', 'far'], |
2157
|
|
|
'file-sound-o' => ['file-audio', 'far'], |
2158
|
|
|
'file-text-o' => ['file-alt', 'far'], |
2159
|
|
|
'file-text' => ['file-alt', 'fas'], |
2160
|
|
|
'file-video-o' => ['file-video', 'far'], |
2161
|
|
|
'file-word-o' => ['file-word', 'far'], |
2162
|
|
|
'file-zip-o' => ['file-archive', 'far'], |
2163
|
|
|
'files-o' => ['copy', 'far'], |
2164
|
|
|
'flag-o' => ['flag', 'far'], |
2165
|
|
|
'flash' => ['bolt', 'fas'], |
2166
|
|
|
'floppy-o' => ['save', 'far'], |
2167
|
|
|
'folder-o' => ['folder', 'far'], |
2168
|
|
|
'folder-open-o' => ['folder-open', 'far'], |
2169
|
|
|
'frown-o' => ['frown', 'far'], |
2170
|
|
|
'futbol-o' => ['futbol', 'far'], |
2171
|
|
|
'gbp' => ['pound-sign', 'fas'], |
2172
|
|
|
'ge' => ['empire', 'fab'], |
2173
|
|
|
'gear' => ['cog', 'fas'], |
2174
|
|
|
'gears' => ['cogs', 'fas'], |
2175
|
|
|
'gittip' => ['gratipay', 'fab'], |
2176
|
|
|
'glass' => ['glass-martini', 'fas'], |
2177
|
|
|
'google-plus-circle' => ['google-plus', 'fab'], |
2178
|
|
|
'google-plus-official' => ['google-plus', 'fab'], |
2179
|
|
|
'google-plus' => ['google-plus-g', 'fab'], |
2180
|
|
|
'group' => ['users', 'fas'], |
2181
|
|
|
'hand-grab-o' => ['hand-rock', 'far'], |
2182
|
|
|
'hand-lizard-o' => ['hand-lizard', 'far'], |
2183
|
|
|
'hand-o-down' => ['hand-point-down', 'far'], |
2184
|
|
|
'hand-o-left' => ['hand-point-left', 'far'], |
2185
|
|
|
'hand-o-right' => ['hand-point-right', 'far'], |
2186
|
|
|
'hand-o-up' => ['hand-point-up', 'far'], |
2187
|
|
|
'hand-paper-o' => ['hand-paper', 'far'], |
2188
|
|
|
'hand-peace-o' => ['hand-peace', 'far'], |
2189
|
|
|
'hand-pointer-o' => ['hand-pointer', 'far'], |
2190
|
|
|
'hand-rock-o' => ['hand-rock', 'far'], |
2191
|
|
|
'hand-scissors-o' => ['hand-scissors', 'far'], |
2192
|
|
|
'hand-spock-o' => ['hand-spock', 'far'], |
2193
|
|
|
'hand-stop-o' => ['hand-paper', 'far'], |
2194
|
|
|
'handshake-o' => ['handshake', 'far'], |
2195
|
|
|
'hard-of-hearing' => ['deaf', 'fas'], |
2196
|
|
|
'hdd-o' => ['hdd', 'far'], |
2197
|
|
|
'header' => ['heading', 'fas'], |
2198
|
|
|
'heart-o' => ['heart', 'far'], |
2199
|
|
|
'hospital-o' => ['hospital', 'far'], |
2200
|
|
|
'hotel' => ['bed', 'fas'], |
2201
|
|
|
'hourglass-1' => ['hourglass-start', 'fas'], |
2202
|
|
|
'hourglass-2' => ['hourglass-half', 'fas'], |
2203
|
|
|
'hourglass-3' => ['hourglass-end', 'fas'], |
2204
|
|
|
'hourglass-o' => ['hourglass', 'far'], |
2205
|
|
|
'id-card-o' => ['id-card', 'far'], |
2206
|
|
|
'ils' => ['shekel-sign', 'fas'], |
2207
|
|
|
'image' => ['image', 'far'], |
2208
|
|
|
'inr' => ['rupee-sign', 'fas'], |
2209
|
|
|
'institution' => ['university', 'fas'], |
2210
|
|
|
'intersex' => ['transgender', 'fas'], |
2211
|
|
|
'jpy' => ['yen-sign', 'fas'], |
2212
|
|
|
'keyboard-o' => ['keyboard', 'far'], |
2213
|
|
|
'krw' => ['won-sign', 'fas'], |
2214
|
|
|
'legal' => ['gavel', 'fas'], |
2215
|
|
|
'lemon-o' => ['lemon', 'far'], |
2216
|
|
|
'level-down' => ['level-down-alt', 'fas'], |
2217
|
|
|
'level-up' => ['level-up-alt', 'fas'], |
2218
|
|
|
'life-bouy' => ['life-ring', 'far'], |
2219
|
|
|
'life-buoy' => ['life-ring', 'far'], |
2220
|
|
|
'life-saver' => ['life-ring', 'far'], |
2221
|
|
|
'lightbulb-o' => ['lightbulb', 'far'], |
2222
|
|
|
'line-chart' => ['chart-line', 'fas'], |
2223
|
|
|
'linkedin-square' => ['linkedin', 'fab'], |
2224
|
|
|
'linkedin' => ['linkedin-in', 'fab'], |
2225
|
|
|
'long-arrow-down' => ['long-arrow-alt-down', 'fas'], |
2226
|
|
|
'long-arrow-left' => ['long-arrow-alt-left', 'fas'], |
2227
|
|
|
'long-arrow-right' => ['long-arrow-alt-right', 'fas'], |
2228
|
|
|
'long-arrow-up' => ['long-arrow-alt-up', 'fas'], |
2229
|
|
|
'mail-forward' => ['share', 'fas'], |
2230
|
|
|
'mail-reply-all' => ['reply-all', 'fas'], |
2231
|
|
|
'mail-reply' => ['reply', 'fas'], |
2232
|
|
|
'map-marker' => ['map-marker-alt', 'fas'], |
2233
|
|
|
'map-o' => ['map', 'far'], |
2234
|
|
|
'meanpath' => ['font-awesome', 'fab'], |
2235
|
|
|
'meh-o' => ['meh', 'far'], |
2236
|
|
|
'minus-square-o' => ['minus-square', 'far'], |
2237
|
|
|
'mobile-phone' => ['mobile-alt', 'fas'], |
2238
|
|
|
'mobile' => ['mobile-alt', 'fas'], |
2239
|
|
|
'money' => ['money-bill-alt', 'far'], |
2240
|
|
|
'moon-o' => ['moon', 'far'], |
2241
|
|
|
'mortar-board' => ['graduation-cap', 'fas'], |
2242
|
|
|
'navicon' => ['bars', 'fas'], |
2243
|
|
|
'newspaper-o' => ['newspaper', 'far'], |
2244
|
|
|
'paper-plane-o' => ['paper-plane', 'far'], |
2245
|
|
|
'paste' => ['clipboard', 'far'], |
2246
|
|
|
'pause-circle-o' => ['pause-circle', 'far'], |
2247
|
|
|
'pencil-square-o' => ['edit', 'far'], |
2248
|
|
|
'pencil-square' => ['pen-square', 'fas'], |
2249
|
|
|
'pencil' => ['pencil-alt', 'fas'], |
2250
|
|
|
'photo' => ['image', 'far'], |
2251
|
|
|
'picture-o' => ['image', 'far'], |
2252
|
|
|
'pie-chart' => ['chart-pie', 'fas'], |
2253
|
|
|
'play-circle-o' => ['play-circle', 'far'], |
2254
|
|
|
'plus-square-o' => ['plus-square', 'far'], |
2255
|
|
|
'question-circle-o' => ['question-circle', 'far'], |
2256
|
|
|
'ra' => ['rebel', 'fab'], |
2257
|
|
|
'refresh' => ['sync', 'fas'], |
2258
|
|
|
'remove' => ['times', 'fas'], |
2259
|
|
|
'reorder' => ['bars', 'fas'], |
2260
|
|
|
'repeat' => ['redo', 'fas'], |
2261
|
|
|
'resistance' => ['rebel', 'fab'], |
2262
|
|
|
'rmb' => ['yen-sign', 'fas'], |
2263
|
|
|
'rotate-left' => ['undo', 'fas'], |
2264
|
|
|
'rotate-right' => ['redo', 'fas'], |
2265
|
|
|
'rouble' => ['ruble-sign', 'fas'], |
2266
|
|
|
'rub' => ['ruble-sign', 'fas'], |
2267
|
|
|
'ruble' => ['ruble-sign', 'fas'], |
2268
|
|
|
'rupee' => ['rupee-sign', 'fas'], |
2269
|
|
|
's15' => ['bath', 'fas'], |
2270
|
|
|
'scissors' => ['cut', 'fas'], |
2271
|
|
|
'send-o' => ['paper-plane', 'far'], |
2272
|
|
|
'send' => ['paper-plane', 'fas'], |
2273
|
|
|
'share-square-o' => ['share-square', 'far'], |
2274
|
|
|
'shekel' => ['shekel-sign', 'fas'], |
2275
|
|
|
'sheqel' => ['shekel-sign', 'fas'], |
2276
|
|
|
'shield' => ['shield-alt', 'fas'], |
2277
|
|
|
'sign-in' => ['sign-in-alt', 'fas'], |
2278
|
|
|
'sign-out' => ['sign-out-alt', 'fas'], |
2279
|
|
|
'signing' => ['sign-language', 'fas'], |
2280
|
|
|
'sliders' => ['sliders-h', 'fas'], |
2281
|
|
|
'smile-o' => ['smile', 'far'], |
2282
|
|
|
'snowflake-o' => ['snowflake', 'far'], |
2283
|
|
|
'soccer-ball-o' => ['futbol', 'far'], |
2284
|
|
|
'sort-alpha-asc' => ['sort-alpha-down', 'fas'], |
2285
|
|
|
'sort-alpha-desc' => ['sort-alpha-up', 'fas'], |
2286
|
|
|
'sort-amount-asc' => ['sort-amount-down', 'fas'], |
2287
|
|
|
'sort-amount-desc' => ['sort-amount-up', 'fas'], |
2288
|
|
|
'sort-asc' => ['sort-up', 'fas'], |
2289
|
|
|
'sort-desc' => ['sort-down', 'fas'], |
2290
|
|
|
'sort-numeric-asc' => ['sort-numeric-down', 'fas'], |
2291
|
|
|
'sort-numeric-desc' => ['sort-numeric-up', 'fas'], |
2292
|
|
|
'spoon' => ['utensil-spoon', 'fas'], |
2293
|
|
|
'square-o' => ['square', 'far'], |
2294
|
|
|
'star-half-empty' => ['star-half', 'far'], |
2295
|
|
|
'star-half-full' => ['star-half', 'far'], |
2296
|
|
|
'star-half-o' => ['star-half', 'far'], |
2297
|
|
|
'star-o' => ['star', 'far'], |
2298
|
|
|
'sticky-note-o' => ['sticky-note', 'far'], |
2299
|
|
|
'stop-circle-o' => ['stop-circle', 'far'], |
2300
|
|
|
'sun-o' => ['sun', 'far'], |
2301
|
|
|
'support' => ['life-ring', 'far'], |
2302
|
|
|
'tablet' => ['tablet-alt', 'fas'], |
2303
|
|
|
'tachometer' => ['tachometer-alt', 'fas'], |
2304
|
|
|
'television' => ['tv', 'fas'], |
2305
|
|
|
'thermometer-0' => ['thermometer-empty', 'fas'], |
2306
|
|
|
'thermometer-1' => ['thermometer-quarter', 'fas'], |
2307
|
|
|
'thermometer-2' => ['thermometer-half', 'fas'], |
2308
|
|
|
'thermometer-3' => ['thermometer-three-quarters', 'fas'], |
2309
|
|
|
'thermometer-4' => ['thermometer-full', 'fas'], |
2310
|
|
|
'thermometer' => ['thermometer-full', 'fas'], |
2311
|
|
|
'thumb-tack' => ['thumbtack', 'fas'], |
2312
|
|
|
'thumbs-o-down' => ['thumbs-down', 'far'], |
2313
|
|
|
'thumbs-o-up' => ['thumbs-up', 'far'], |
2314
|
|
|
'ticket' => ['ticket-alt', 'fas'], |
2315
|
|
|
'times-circle-o' => ['times-circle', 'far'], |
2316
|
|
|
'times-rectangle-o' => ['window-close', 'far'], |
2317
|
|
|
'times-rectangle' => ['window-close', 'fas'], |
2318
|
|
|
'toggle-down' => ['caret-square-down', 'far'], |
2319
|
|
|
'toggle-left' => ['caret-square-left', 'far'], |
2320
|
|
|
'toggle-right' => ['caret-square-right', 'far'], |
2321
|
|
|
'toggle-up' => ['caret-square-up', 'far'], |
2322
|
|
|
'trash-o' => ['trash-alt', 'far'], |
2323
|
|
|
'trash' => ['trash-alt', 'fas'], |
2324
|
|
|
'try' => ['lira-sign', 'fas'], |
2325
|
|
|
'turkish-lira' => ['lira-sign', 'fas'], |
2326
|
|
|
'unsorted' => ['sort', 'fas'], |
2327
|
|
|
'usd' => ['dollar-sign', 'fas'], |
2328
|
|
|
'user-circle-o' => ['user-circle', 'far'], |
2329
|
|
|
'user-o' => ['user', 'far'], |
2330
|
|
|
'vcard-o' => ['address-card', 'far'], |
2331
|
|
|
'vcard' => ['address-card', 'fas'], |
2332
|
|
|
'video-camera' => ['video', 'fas'], |
2333
|
|
|
'vimeo' => ['vimeo-v', 'fab'], |
2334
|
|
|
'volume-control-phone' => ['phone-volume', 'fas'], |
2335
|
|
|
'warning' => ['exclamation-triangle', 'fas'], |
2336
|
|
|
'wechat' => ['weixin', 'fab'], |
2337
|
|
|
'wheelchair-alt' => ['accessible-icon', 'fab'], |
2338
|
|
|
'window-close-o' => ['window-close', 'far'], |
2339
|
|
|
'won' => ['won-sign', 'fas'], |
2340
|
|
|
'y-combinator-square' => ['hacker-news', 'fab'], |
2341
|
|
|
'yc-square' => ['hacker-news', 'fab'], |
2342
|
|
|
'yc' => ['y-combinator', 'fab'], |
2343
|
|
|
'yen' => ['yen-sign', 'fas'], |
2344
|
|
|
'youtube-play' => ['youtube', 'fab'], |
2345
|
|
|
'youtube-square' => ['youtube', 'fab'], |
2346
|
|
|
]; |
2347
|
|
|
|
2348
|
|
|
$brands = [ |
2349
|
17 |
|
'500px', |
2350
|
|
|
'accessible-icon', |
2351
|
|
|
'accusoft', |
2352
|
|
|
'adn', |
2353
|
|
|
'adversal', |
2354
|
|
|
'affiliatetheme', |
2355
|
|
|
'algolia', |
2356
|
|
|
'amazon', |
2357
|
|
|
'amazon-pay', |
2358
|
|
|
'amilia', |
2359
|
|
|
'android', |
2360
|
|
|
'angellist', |
2361
|
|
|
'angrycreative', |
2362
|
|
|
'angular', |
2363
|
|
|
'app-store', |
2364
|
|
|
'app-store-ios', |
2365
|
|
|
'apper', |
2366
|
|
|
'apple', |
2367
|
|
|
'apple-pay', |
2368
|
|
|
'asymmetrik', |
2369
|
|
|
'audible', |
2370
|
|
|
'autoprefixer', |
2371
|
|
|
'avianex', |
2372
|
|
|
'aviato', |
2373
|
|
|
'aws', |
2374
|
|
|
'bandcamp', |
2375
|
|
|
'behance', |
2376
|
|
|
'behance-square', |
2377
|
|
|
'bimobject', |
2378
|
|
|
'bitbucket', |
2379
|
|
|
'bitcoin', |
2380
|
|
|
'bity', |
2381
|
|
|
'black-tie', |
2382
|
|
|
'blackberry', |
2383
|
|
|
'blogger', |
2384
|
|
|
'blogger-b', |
2385
|
|
|
'bluetooth', |
2386
|
|
|
'bluetooth-b', |
2387
|
|
|
'btc', |
2388
|
|
|
'buromobelexperte', |
2389
|
|
|
'buysellads', |
2390
|
|
|
'cc-amazon-pay', |
2391
|
|
|
'cc-amex', |
2392
|
|
|
'cc-apple-pay', |
2393
|
|
|
'cc-diners-club', |
2394
|
|
|
'cc-discover', |
2395
|
|
|
'cc-jcb', |
2396
|
|
|
'cc-mastercard', |
2397
|
|
|
'cc-paypal', |
2398
|
|
|
'cc-stripe', |
2399
|
|
|
'cc-visa', |
2400
|
|
|
'centercode', |
2401
|
|
|
'chrome', |
2402
|
|
|
'cloudscale', |
2403
|
|
|
'cloudsmith', |
2404
|
|
|
'cloudversify', |
2405
|
|
|
'codepen', |
2406
|
|
|
'codiepie', |
2407
|
|
|
'connectdevelop', |
2408
|
|
|
'contao', |
2409
|
|
|
'cpanel', |
2410
|
|
|
'creative-commons', |
2411
|
|
|
'css3', |
2412
|
|
|
'css3-alt', |
2413
|
|
|
'cuttlefish', |
2414
|
|
|
'd-and-d', |
2415
|
|
|
'dashcube', |
2416
|
|
|
'delicious', |
2417
|
|
|
'deploydog', |
2418
|
|
|
'deskpro', |
2419
|
|
|
'deviantart', |
2420
|
|
|
'digg', |
2421
|
|
|
'digital-ocean', |
2422
|
|
|
'discord', |
2423
|
|
|
'discourse', |
2424
|
|
|
'dochub', |
2425
|
|
|
'docker', |
2426
|
|
|
'draft2digital', |
2427
|
|
|
'dribbble', |
2428
|
|
|
'dribbble-square', |
2429
|
|
|
'dropbox', |
2430
|
|
|
'drupal', |
2431
|
|
|
'dyalog', |
2432
|
|
|
'earlybirds', |
2433
|
|
|
'edge', |
2434
|
|
|
'elementor', |
2435
|
|
|
'ember', |
2436
|
|
|
'empire', |
2437
|
|
|
'envira', |
2438
|
|
|
'erlang', |
2439
|
|
|
'ethereum', |
2440
|
|
|
'etsy', |
2441
|
|
|
'expeditedssl', |
2442
|
|
|
'facebook', |
2443
|
|
|
'facebook-f', |
2444
|
|
|
'facebook-messenger', |
2445
|
|
|
'facebook-square', |
2446
|
|
|
'firefox', |
2447
|
|
|
'first-order', |
2448
|
|
|
'firstdraft', |
2449
|
|
|
'flickr', |
2450
|
|
|
'flipboard', |
2451
|
|
|
'fly', |
2452
|
|
|
'font-awesome', |
2453
|
|
|
'font-awesome-alt', |
2454
|
|
|
'font-awesome-flag', |
2455
|
|
|
'fonticons', |
2456
|
|
|
'fonticons-fi', |
2457
|
|
|
'fort-awesome', |
2458
|
|
|
'fort-awesome-alt', |
2459
|
|
|
'forumbee', |
2460
|
|
|
'foursquare', |
2461
|
|
|
'free-code-camp', |
2462
|
|
|
'freebsd', |
2463
|
|
|
'get-pocket', |
2464
|
|
|
'gg', |
2465
|
|
|
'gg-circle', |
2466
|
|
|
'git', |
2467
|
|
|
'git-square', |
2468
|
|
|
'github', |
2469
|
|
|
'github-alt', |
2470
|
|
|
'github-square', |
2471
|
|
|
'gitkraken', |
2472
|
|
|
'gitlab', |
2473
|
|
|
'gitter', |
2474
|
|
|
'glide', |
2475
|
|
|
'glide-g', |
2476
|
|
|
'gofore', |
2477
|
|
|
'goodreads', |
2478
|
|
|
'goodreads-g', |
2479
|
|
|
'google', |
2480
|
|
|
'google-drive', |
2481
|
|
|
'google-play', |
2482
|
|
|
'google-plus', |
2483
|
|
|
'google-plus-g', |
2484
|
|
|
'google-plus-square', |
2485
|
|
|
'google-wallet', |
2486
|
|
|
'gratipay', |
2487
|
|
|
'grav', |
2488
|
|
|
'gripfire', |
2489
|
|
|
'grunt', |
2490
|
|
|
'gulp', |
2491
|
|
|
'hacker-news', |
2492
|
|
|
'hacker-news-square', |
2493
|
|
|
'hips', |
2494
|
|
|
'hire-a-helper', |
2495
|
|
|
'hooli', |
2496
|
|
|
'hotjar', |
2497
|
|
|
'houzz', |
2498
|
|
|
'html5', |
2499
|
|
|
'hubspot', |
2500
|
|
|
'imdb', |
2501
|
|
|
'instagram', |
2502
|
|
|
'internet-explorer', |
2503
|
|
|
'ioxhost', |
2504
|
|
|
'itunes', |
2505
|
|
|
'itunes-note', |
2506
|
|
|
'jenkins', |
2507
|
|
|
'joget', |
2508
|
|
|
'joomla', |
2509
|
|
|
'js', |
2510
|
|
|
'js-square', |
2511
|
|
|
'jsfiddle', |
2512
|
|
|
'keycdn', |
2513
|
|
|
'kickstarter', |
2514
|
|
|
'kickstarter-k', |
2515
|
|
|
'korvue', |
2516
|
|
|
'laravel', |
2517
|
|
|
'lastfm', |
2518
|
|
|
'lastfm-square', |
2519
|
|
|
'leanpub', |
2520
|
|
|
'less', |
2521
|
|
|
'line', |
2522
|
|
|
'linkedin', |
2523
|
|
|
'linkedin-in', |
2524
|
|
|
'linode', |
2525
|
|
|
'linux', |
2526
|
|
|
'lyft', |
2527
|
|
|
'magento', |
2528
|
|
|
'maxcdn', |
2529
|
|
|
'medapps', |
2530
|
|
|
'medium', |
2531
|
|
|
'medium-m', |
2532
|
|
|
'medrt', |
2533
|
|
|
'meetup', |
2534
|
|
|
'microsoft', |
2535
|
|
|
'mix', |
2536
|
|
|
'mixcloud', |
2537
|
|
|
'mizuni', |
2538
|
|
|
'modx', |
2539
|
|
|
'monero', |
2540
|
|
|
'napster', |
2541
|
|
|
'nintendo-switch', |
2542
|
|
|
'node', |
2543
|
|
|
'node-js', |
2544
|
|
|
'npm', |
2545
|
|
|
'ns8', |
2546
|
|
|
'nutritionix', |
2547
|
|
|
'odnoklassniki', |
2548
|
|
|
'odnoklassniki-square', |
2549
|
|
|
'opencart', |
2550
|
|
|
'openid', |
2551
|
|
|
'opera', |
2552
|
|
|
'optin-monster', |
2553
|
|
|
'osi', |
2554
|
|
|
'page4', |
2555
|
|
|
'pagelines', |
2556
|
|
|
'palfed', |
2557
|
|
|
'patreon', |
2558
|
|
|
'paypal', |
2559
|
|
|
'periscope', |
2560
|
|
|
'phabricator', |
2561
|
|
|
'phoenix-framework', |
2562
|
|
|
'php', |
2563
|
|
|
'pied-piper', |
2564
|
|
|
'pied-piper-alt', |
2565
|
|
|
'pied-piper-pp', |
2566
|
|
|
'pinterest', |
2567
|
|
|
'pinterest-p', |
2568
|
|
|
'pinterest-square', |
2569
|
|
|
'playstation', |
2570
|
|
|
'product-hunt', |
2571
|
|
|
'pushed', |
2572
|
|
|
'python', |
2573
|
|
|
'qq', |
2574
|
|
|
'quinscape', |
2575
|
|
|
'quora', |
2576
|
|
|
'ravelry', |
2577
|
|
|
'react', |
2578
|
|
|
'rebel', |
2579
|
|
|
'red-river', |
2580
|
|
|
'reddit', |
2581
|
|
|
'reddit-alien', |
2582
|
|
|
'reddit-square', |
2583
|
|
|
'rendact', |
2584
|
|
|
'renren', |
2585
|
|
|
'replyd', |
2586
|
|
|
'resolving', |
2587
|
|
|
'rocketchat', |
2588
|
|
|
'rockrms', |
2589
|
|
|
'safari', |
2590
|
|
|
'sass', |
2591
|
|
|
'schlix', |
2592
|
|
|
'scribd', |
2593
|
|
|
'searchengin', |
2594
|
|
|
'sellcast', |
2595
|
|
|
'sellsy', |
2596
|
|
|
'servicestack', |
2597
|
|
|
'shirtsinbulk', |
2598
|
|
|
'simplybuilt', |
2599
|
|
|
'sistrix', |
2600
|
|
|
'skyatlas', |
2601
|
|
|
'skype', |
2602
|
|
|
'slack', |
2603
|
|
|
'slack-hash', |
2604
|
|
|
'slideshare', |
2605
|
|
|
'snapchat', |
2606
|
|
|
'snapchat-ghost', |
2607
|
|
|
'snapchat-square', |
2608
|
|
|
'soundcloud', |
2609
|
|
|
'speakap', |
2610
|
|
|
'spotify', |
2611
|
|
|
'stack-exchange', |
2612
|
|
|
'stack-overflow', |
2613
|
|
|
'staylinked', |
2614
|
|
|
'steam', |
2615
|
|
|
'steam-square', |
2616
|
|
|
'steam-symbol', |
2617
|
|
|
'sticker-mule', |
2618
|
|
|
'strava', |
2619
|
|
|
'stripe', |
2620
|
|
|
'stripe-s', |
2621
|
|
|
'studiovinari', |
2622
|
|
|
'stumbleupon', |
2623
|
|
|
'stumbleupon-circle', |
2624
|
|
|
'superpowers', |
2625
|
|
|
'supple', |
2626
|
|
|
'telegram', |
2627
|
|
|
'telegram-plane', |
2628
|
|
|
'tencent-weibo', |
2629
|
|
|
'themeisle', |
2630
|
|
|
'trello', |
2631
|
|
|
'tripadvisor', |
2632
|
|
|
'tumblr', |
2633
|
|
|
'tumblr-square', |
2634
|
|
|
'twitch', |
2635
|
|
|
'twitter', |
2636
|
|
|
'twitter-square', |
2637
|
|
|
'typo3', |
2638
|
|
|
'uber', |
2639
|
|
|
'uikit', |
2640
|
|
|
'uniregistry', |
2641
|
|
|
'untappd', |
2642
|
|
|
'usb', |
2643
|
|
|
'ussunnah', |
2644
|
|
|
'vaadin', |
2645
|
|
|
'viacoin', |
2646
|
|
|
'viadeo', |
2647
|
|
|
'viadeo-square', |
2648
|
|
|
'viber', |
2649
|
|
|
'vimeo', |
2650
|
|
|
'vimeo-square', |
2651
|
|
|
'vimeo-v', |
2652
|
|
|
'vine', |
2653
|
|
|
'vk', |
2654
|
|
|
'vnv', |
2655
|
|
|
'vuejs', |
2656
|
|
|
'weibo', |
2657
|
|
|
'weixin', |
2658
|
|
|
'whatsapp', |
2659
|
|
|
'whatsapp-square', |
2660
|
|
|
'whmcs', |
2661
|
|
|
'wikipedia-w', |
2662
|
|
|
'windows', |
2663
|
|
|
'wordpress', |
2664
|
|
|
'wordpress-simple', |
2665
|
|
|
'wpbeginner', |
2666
|
|
|
'wpexplorer', |
2667
|
|
|
'wpforms', |
2668
|
|
|
'xbox', |
2669
|
|
|
'xing', |
2670
|
|
|
'xing-square', |
2671
|
|
|
'y-combinator', |
2672
|
|
|
'yahoo', |
2673
|
|
|
'yandex', |
2674
|
|
|
'yandex-international', |
2675
|
|
|
'yelp', |
2676
|
|
|
'yoast', |
2677
|
|
|
'youtube', |
2678
|
|
|
'youtube-square', |
2679
|
|
|
]; |
2680
|
|
|
|
2681
|
17 |
|
foreach ($classes as $index => $c) { |
2682
|
17 |
|
if ($c === 'fa') { |
2683
|
|
|
// FontAwesome 5 deprecated the use of fa prefix in favour of fas, far and fab |
2684
|
|
|
unset($classes[$index]); |
2685
|
|
|
continue; |
2686
|
|
|
} |
2687
|
|
|
|
2688
|
17 |
|
if (preg_match_all('/^elgg-icon-(.+)/i', $c)) { |
2689
|
|
|
// convert |
2690
|
16 |
|
$base_icon = preg_replace('/^elgg-icon-(.+)/i', '$1', $c); |
2691
|
|
|
|
2692
|
16 |
|
if ($map_sprites) { |
2693
|
16 |
|
if (strpos($base_icon, '-hover') !== false) { |
2694
|
|
|
$base_icon = str_replace('-hover', '', $base_icon); |
2695
|
|
|
$classes[] = 'elgg-state'; |
2696
|
|
|
$classes[] = 'elgg-state-notice'; |
2697
|
|
|
} |
2698
|
|
|
|
2699
|
16 |
|
$base_icon = elgg_extract($base_icon, $legacy_sprites, $base_icon); |
2700
|
|
|
} |
2701
|
|
|
|
2702
|
|
|
// map solid/regular/light iconnames to correct classes |
2703
|
16 |
|
if (preg_match('/.*-solid$/', $base_icon)) { |
2704
|
|
|
$base_icon = preg_replace('/(.*)-solid$/', '$1', $base_icon); |
2705
|
|
|
$classes[] = 'fas'; |
2706
|
16 |
|
} elseif (preg_match('/.*-regular$/', $base_icon)) { |
2707
|
|
|
$base_icon = preg_replace('/(.*)-regular$/', '$1', $base_icon); |
2708
|
|
|
$classes[] = 'far'; |
2709
|
16 |
|
} elseif (preg_match('/.*-light$/', $base_icon)) { |
2710
|
|
|
// currently light is only available in FontAwesome 5 Pro |
2711
|
|
|
$base_icon = preg_replace('/(.*)-light$/', '$1', $base_icon); |
2712
|
|
|
$classes[] = 'fal'; |
2713
|
|
|
} else { |
2714
|
16 |
|
if (array_key_exists($base_icon, $fa5)) { |
2715
|
6 |
|
$classes[] = $fa5[$base_icon][1]; |
2716
|
6 |
|
$base_icon = $fa5[$base_icon][0]; |
2717
|
14 |
|
} else if (in_array($base_icon, $brands)) { |
2718
|
|
|
$classes[] = 'fab'; |
2719
|
|
|
} else { |
2720
|
14 |
|
$classes[] = 'fas'; |
2721
|
|
|
} |
2722
|
|
|
} |
2723
|
|
|
|
2724
|
17 |
|
$classes[] = "fa-{$base_icon}"; |
2725
|
|
|
} |
2726
|
|
|
} |
2727
|
|
|
|
2728
|
17 |
|
$classes = array_unique($classes); |
2729
|
|
|
|
2730
|
17 |
|
return elgg_trigger_plugin_hook('classes', 'icon', null, $classes); |
2731
|
|
|
} |
2732
|
|
|
|