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
|
19 |
|
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
|
181 |
|
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
|
|
|
* @access private |
89
|
|
|
* @since 1.9 |
90
|
|
|
*/ |
91
|
|
|
function _elgg_is_valid_viewtype($viewtype) { |
92
|
|
|
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
|
40 |
|
elgg_register_external_view($view, false); |
135
|
40 |
|
} |
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
|
46 |
|
_elgg_services()->ajax->registerView($view); |
159
|
|
|
|
160
|
46 |
|
if ($cacheable) { |
161
|
37 |
|
_elgg_services()->views->registerCacheableView($view); |
162
|
|
|
} |
163
|
46 |
|
} |
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
|
362 |
|
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
|
280 |
|
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
|
280 |
|
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
|
|
|
* @access private |
266
|
|
|
*/ |
267
|
|
|
function elgg_view_deprecated($view, array $vars, $suggestion, $version) { |
268
|
|
|
return _elgg_services()->views->renderDeprecatedView($view, $vars, $suggestion, $version); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Extends a view with another view. |
273
|
|
|
* |
274
|
|
|
* The output of any view can be prepended or appended to any other view. |
275
|
|
|
* |
276
|
|
|
* The default action is to append a view. If the priority is less than 500, |
277
|
|
|
* the output of the extended view will be appended to the original view. |
278
|
|
|
* |
279
|
|
|
* Views can be extended multiple times, and extensions are not checked for |
280
|
|
|
* uniqueness. Use {@link elgg_unextend_view()} to help manage duplicates. |
281
|
|
|
* |
282
|
|
|
* Priority can be specified and affects the order in which extensions |
283
|
|
|
* are appended or prepended. |
284
|
|
|
* |
285
|
|
|
* @see elgg_prepend_css_urls() If the extension is CSS, you may need to use this to fix relative URLs. |
286
|
|
|
* |
287
|
|
|
* @param string $view The view to extend. |
288
|
|
|
* @param string $view_extension This view is added to $view |
289
|
|
|
* @param int $priority The priority, from 0 to 1000, to add at (lowest numbers displayed first) |
290
|
|
|
* |
291
|
|
|
* @return void |
292
|
|
|
* @since 1.7.0 |
293
|
|
|
*/ |
294
|
|
|
function elgg_extend_view($view, $view_extension, $priority = 501) { |
295
|
32 |
|
_elgg_services()->views->extendView($view, $view_extension, $priority); |
296
|
32 |
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* Unextends a view. |
300
|
|
|
* |
301
|
|
|
* @param string $view The view that was extended. |
302
|
|
|
* @param string $view_extension This view that was added to $view |
303
|
|
|
* |
304
|
|
|
* @return bool |
305
|
|
|
* @since 1.7.2 |
306
|
|
|
*/ |
307
|
|
|
function elgg_unextend_view($view, $view_extension) { |
308
|
31 |
|
return _elgg_services()->views->unextendView($view, $view_extension); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** |
312
|
|
|
* Get the views (and priorities) that extend a view. |
313
|
|
|
* |
314
|
|
|
* @note extensions may change anytime, especially during the [init, system] event |
315
|
|
|
* |
316
|
|
|
* @param string $view View name |
317
|
|
|
* |
318
|
|
|
* @return string[] Keys returned are view priorities. |
319
|
|
|
* @since 2.3 |
320
|
|
|
*/ |
321
|
|
|
function elgg_get_view_extensions($view) { |
322
|
|
|
$list = _elgg_services()->views->getViewList($view); |
323
|
|
|
unset($list[500]); |
324
|
|
|
return $list; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* In CSS content, prepend a path to relative URLs. |
329
|
|
|
* |
330
|
|
|
* This is useful to process a CSS view being used as an extension. |
331
|
|
|
* |
332
|
|
|
* @param string $css CSS |
333
|
|
|
* @param string $path Path to prepend. E.g. "foo/bar/" or "../" |
334
|
|
|
* |
335
|
|
|
* @return string |
336
|
|
|
* @since 2.2 |
337
|
|
|
*/ |
338
|
|
|
function elgg_prepend_css_urls($css, $path) { |
339
|
|
|
return Minify_CSS_UriRewriter::prepend($css, $path); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* Assembles and outputs a full page. |
344
|
|
|
* |
345
|
|
|
* A "page" in Elgg is determined by the current view type and |
346
|
|
|
* can be HTML for a browser, RSS for a feed reader, or |
347
|
|
|
* Javascript, PHP and a number of other formats. |
348
|
|
|
* |
349
|
|
|
* For HTML pages, use the 'head', 'page' plugin hook for setting meta elements |
350
|
|
|
* and links. |
351
|
|
|
* |
352
|
|
|
* @param string $title Title |
353
|
|
|
* @param string $body Body |
354
|
|
|
* @param string $page_shell Optional page shell to use. See page/shells view directory |
355
|
|
|
* @param array $vars Optional vars array to pass to the page |
356
|
|
|
* shell. Automatically adds title, body, head, and sysmessages |
357
|
|
|
* |
358
|
|
|
* @return string The contents of the page |
359
|
|
|
* @since 1.8 |
360
|
|
|
*/ |
361
|
|
|
function elgg_view_page($title, $body, $page_shell = 'default', $vars = []) { |
362
|
12 |
|
$timer = _elgg_services()->timer; |
363
|
12 |
|
if (!$timer->hasEnded(['build page'])) { |
364
|
9 |
|
$timer->end(['build page']); |
365
|
|
|
} |
366
|
12 |
|
$timer->begin([__FUNCTION__]); |
367
|
|
|
|
368
|
12 |
|
$params = []; |
369
|
12 |
|
$params['identifier'] = _elgg_services()->request->getFirstUrlSegment(); |
370
|
12 |
|
$params['segments'] = _elgg_services()->request->getUrlSegments(); |
371
|
12 |
|
array_shift($params['segments']); |
372
|
12 |
|
$page_shell = elgg_trigger_plugin_hook('shell', 'page', $params, $page_shell); |
373
|
|
|
|
374
|
|
|
|
375
|
12 |
|
$system_messages = _elgg_services()->systemMessages; |
376
|
|
|
|
377
|
12 |
|
$messages = null; |
378
|
12 |
|
if ($system_messages->count()) { |
379
|
2 |
|
$messages = $system_messages->dumpRegister(); |
380
|
|
|
|
381
|
2 |
|
if (isset($messages['error'])) { |
382
|
|
|
// always make sure error is the first type |
383
|
|
|
$errors = [ |
384
|
2 |
|
'error' => $messages['error'] |
385
|
|
|
]; |
386
|
|
|
|
387
|
2 |
|
unset($messages['error']); |
388
|
2 |
|
$messages = array_merge($errors, $messages); |
389
|
|
|
} |
390
|
|
|
} |
391
|
|
|
|
392
|
12 |
|
$vars['title'] = $title; |
393
|
12 |
|
$vars['body'] = $body; |
394
|
12 |
|
$vars['sysmessages'] = $messages; |
395
|
12 |
|
$vars['page_shell'] = $page_shell; |
396
|
|
|
|
397
|
|
|
// head has keys 'title', 'metas', 'links' |
398
|
12 |
|
$head_params = _elgg_views_prepare_head($title); |
399
|
|
|
|
400
|
12 |
|
$vars['head'] = elgg_trigger_plugin_hook('head', 'page', $vars, $head_params); |
401
|
|
|
|
402
|
12 |
|
$vars = elgg_trigger_plugin_hook('output:before', 'page', null, $vars); |
403
|
|
|
|
404
|
12 |
|
$output = elgg_view("page/$page_shell", $vars); |
405
|
|
|
|
406
|
|
|
|
407
|
|
|
// Allow plugins to modify the output |
408
|
12 |
|
$output = elgg_trigger_plugin_hook('output', 'page', $vars, $output); |
409
|
|
|
|
410
|
12 |
|
$timer->end([__FUNCTION__]); |
411
|
12 |
|
return $output; |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* Render a resource view. Use this in your page handler to hand off page rendering to |
416
|
|
|
* a view in "resources/". If not found in the current viewtype, we try the "default" viewtype. |
417
|
|
|
* |
418
|
|
|
* @param string $name The view name without the leading "resources/" |
419
|
|
|
* @param array $vars Arguments passed to the view |
420
|
|
|
* |
421
|
|
|
* @return string |
422
|
|
|
* @throws \Elgg\PageNotFoundException |
423
|
|
|
*/ |
424
|
|
|
function elgg_view_resource($name, array $vars = []) { |
425
|
6 |
|
$view = "resources/$name"; |
426
|
|
|
|
427
|
6 |
|
if (elgg_view_exists($view)) { |
428
|
6 |
|
return _elgg_services()->views->renderView($view, $vars); |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
if (elgg_get_viewtype() !== 'default' && elgg_view_exists($view, 'default')) { |
432
|
|
|
return _elgg_services()->views->renderView($view, $vars, 'default'); |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
_elgg_services()->logger->error("The view $view is missing."); |
436
|
|
|
|
437
|
|
|
// only works for default viewtype |
438
|
|
|
throw new \Elgg\PageNotFoundException(); |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* Prepare the variables for the html head |
443
|
|
|
* |
444
|
|
|
* @param string $title Page title for <head> |
445
|
|
|
* @return array |
446
|
|
|
* @access private |
447
|
|
|
*/ |
448
|
|
|
function _elgg_views_prepare_head($title) { |
449
|
|
|
$params = [ |
450
|
12 |
|
'links' => [], |
451
|
|
|
'metas' => [], |
452
|
|
|
]; |
453
|
|
|
|
454
|
12 |
|
if (empty($title)) { |
455
|
|
|
$params['title'] = _elgg_config()->sitename; |
456
|
|
|
} else { |
457
|
12 |
|
$params['title'] = $title . ' : ' . _elgg_config()->sitename; |
458
|
|
|
} |
459
|
|
|
|
460
|
12 |
|
$params['metas']['content-type'] = [ |
461
|
|
|
'http-equiv' => 'Content-Type', |
462
|
|
|
'content' => 'text/html; charset=utf-8', |
463
|
|
|
]; |
464
|
|
|
|
465
|
12 |
|
$params['metas']['description'] = [ |
466
|
12 |
|
'name' => 'description', |
467
|
12 |
|
'content' => _elgg_config()->sitedescription |
468
|
|
|
]; |
469
|
|
|
|
470
|
|
|
// https://developer.chrome.com/multidevice/android/installtohomescreen |
471
|
12 |
|
$params['metas']['viewport'] = [ |
472
|
|
|
'name' => 'viewport', |
473
|
|
|
'content' => 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0', |
474
|
|
|
]; |
475
|
12 |
|
$params['metas']['mobile-web-app-capable'] = [ |
476
|
|
|
'name' => 'mobile-web-app-capable', |
477
|
|
|
'content' => 'yes', |
478
|
|
|
]; |
479
|
12 |
|
$params['metas']['apple-mobile-web-app-capable'] = [ |
480
|
|
|
'name' => 'apple-mobile-web-app-capable', |
481
|
|
|
'content' => 'yes', |
482
|
|
|
]; |
483
|
|
|
|
484
|
|
|
// RSS feed link |
485
|
12 |
|
if (_elgg_has_rss_link()) { |
486
|
|
|
$url = current_page_url(); |
487
|
|
|
if (substr_count($url, '?')) { |
488
|
|
|
$url .= "&view=rss"; |
489
|
|
|
} else { |
490
|
|
|
$url .= "?view=rss"; |
491
|
|
|
} |
492
|
|
|
$params['links']['rss'] = [ |
493
|
|
|
'rel' => 'alternative', |
494
|
|
|
'type' => 'application/rss+xml', |
495
|
|
|
'title' => 'RSS', |
496
|
|
|
'href' => $url, |
497
|
|
|
]; |
498
|
|
|
} |
499
|
|
|
|
500
|
12 |
|
return $params; |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
|
504
|
|
|
/** |
505
|
|
|
* Add favicon link tags to HTML head |
506
|
|
|
* |
507
|
|
|
* @param string $hook "head" |
508
|
|
|
* @param string $type "page" |
509
|
|
|
* @param array $head_params Head params |
510
|
|
|
* <code> |
511
|
|
|
* [ |
512
|
|
|
* 'title' => '', |
513
|
|
|
* 'metas' => [], |
514
|
|
|
* 'links' => [], |
515
|
|
|
* ] |
516
|
|
|
* </code> |
517
|
|
|
* @param array $params Hook params |
518
|
|
|
* @return array |
519
|
|
|
*/ |
520
|
|
|
function _elgg_views_prepare_favicon_links($hook, $type, $head_params, $params) { |
521
|
|
|
|
522
|
2 |
|
$head_params['links']['apple-touch-icon'] = [ |
523
|
2 |
|
'rel' => 'apple-touch-icon', |
524
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-128.png'), |
525
|
|
|
]; |
526
|
|
|
|
527
|
|
|
// favicons |
528
|
2 |
|
$head_params['links']['icon-ico'] = [ |
529
|
2 |
|
'rel' => 'icon', |
530
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon.ico'), |
531
|
|
|
]; |
532
|
2 |
|
$head_params['links']['icon-vector'] = [ |
533
|
2 |
|
'rel' => 'icon', |
534
|
2 |
|
'sizes' => '16x16 32x32 48x48 64x64 128x128', |
535
|
2 |
|
'type' => 'image/svg+xml', |
536
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon.svg'), |
537
|
|
|
]; |
538
|
2 |
|
$head_params['links']['icon-16'] = [ |
539
|
2 |
|
'rel' => 'icon', |
540
|
2 |
|
'sizes' => '16x16', |
541
|
2 |
|
'type' => 'image/png', |
542
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-16.png'), |
543
|
|
|
]; |
544
|
2 |
|
$head_params['links']['icon-32'] = [ |
545
|
2 |
|
'rel' => 'icon', |
546
|
2 |
|
'sizes' => '32x32', |
547
|
2 |
|
'type' => 'image/png', |
548
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-32.png'), |
549
|
|
|
]; |
550
|
2 |
|
$head_params['links']['icon-64'] = [ |
551
|
2 |
|
'rel' => 'icon', |
552
|
2 |
|
'sizes' => '64x64', |
553
|
2 |
|
'type' => 'image/png', |
554
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-64.png'), |
555
|
|
|
]; |
556
|
2 |
|
$head_params['links']['icon-128'] = [ |
557
|
2 |
|
'rel' => 'icon', |
558
|
2 |
|
'sizes' => '128x128', |
559
|
2 |
|
'type' => 'image/png', |
560
|
2 |
|
'href' => elgg_get_simplecache_url('graphics/favicon-128.png'), |
561
|
|
|
]; |
562
|
|
|
|
563
|
2 |
|
return $head_params; |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
/** |
567
|
|
|
* Displays a layout with optional parameters. |
568
|
|
|
* |
569
|
|
|
* Layouts are templates provide consistency by organizing blocks of content on the page. |
570
|
|
|
* |
571
|
|
|
* Plugins should use one of the core layouts: |
572
|
|
|
* - default Primary template with one, two or no sidebars |
573
|
|
|
* - admin Admin page template |
574
|
|
|
* - error Error page template |
575
|
|
|
* - widgets Widgets canvas |
576
|
|
|
* |
577
|
|
|
* Plugins can create and use custom layouts by placing a layout view |
578
|
|
|
* in "page/layouts/<layout_name>" and calling elgg_view_layout(<layout_name>). |
579
|
|
|
* |
580
|
|
|
* For a full list of parameters supported by each of these layouts see |
581
|
|
|
* corresponding layout views. |
582
|
|
|
* |
583
|
|
|
* @param string $layout_name Layout name |
584
|
|
|
* Corresponds to a view in "page/layouts/<layout_name>". |
585
|
|
|
* @param array $vars Layout parameters |
586
|
|
|
* An associative array of parameters to pass to |
587
|
|
|
* the layout hooks and views. |
588
|
|
|
* Route 'identifier' and 'segments' of the page being |
589
|
|
|
* rendered will be added to this array automatially, |
590
|
|
|
* allowing plugins to alter layout views and subviews |
591
|
|
|
* based on the current route. |
592
|
|
|
* @return string |
593
|
|
|
*/ |
594
|
|
|
function elgg_view_layout($layout_name, $vars = []) { |
595
|
3 |
|
$timer = _elgg_services()->timer; |
596
|
3 |
|
if (!$timer->hasEnded(['build page'])) { |
597
|
2 |
|
$timer->end(['build page']); |
598
|
|
|
} |
599
|
3 |
|
$timer->begin([__FUNCTION__]); |
600
|
|
|
|
601
|
|
|
// Help plugins transition without breaking them |
602
|
3 |
|
switch ($layout_name) { |
603
|
|
|
case 'content' : |
604
|
1 |
|
$layout_name = 'default'; |
605
|
1 |
|
$vars = _elgg_normalize_content_layout_vars($vars); |
606
|
1 |
|
break; |
607
|
|
|
|
608
|
|
|
case 'one_sidebar' : |
609
|
|
|
$layout_name = 'default'; |
610
|
|
|
$vars['sidebar'] = elgg_extract('sidebar', $vars, '', false); |
611
|
|
|
$vars['sidebar_alt'] = false; |
612
|
|
|
break; |
613
|
|
|
|
614
|
|
|
case 'one_column' : |
615
|
|
|
$layout_name = 'default'; |
616
|
|
|
$vars['sidebar'] = false; |
617
|
|
|
$vars['sidebar_alt'] = false; |
618
|
|
|
break; |
619
|
|
|
|
620
|
|
|
case 'two_sidebar' : |
621
|
|
|
$layout_name = 'default'; |
622
|
|
|
$vars['sidebar'] = elgg_extract('sidebar', $vars, '', false); |
623
|
|
|
$vars['sidebar_alt'] = elgg_extract('sidebar_alt', $vars, '', false); |
624
|
|
|
break; |
625
|
|
|
} |
626
|
|
|
|
627
|
3 |
|
if (isset($vars['nav'])) { |
628
|
|
|
// Temporary helper until all core views are updated |
629
|
|
|
$vars['breadcrumbs'] = $vars['nav']; |
630
|
|
|
unset($vars['nav']); |
631
|
|
|
} |
632
|
|
|
|
633
|
3 |
|
$vars['identifier'] = _elgg_services()->request->getFirstUrlSegment(); |
634
|
3 |
|
$vars['segments'] = _elgg_services()->request->getUrlSegments(); |
635
|
3 |
|
array_shift($vars['segments']); |
636
|
|
|
|
637
|
3 |
|
$layout_name = elgg_trigger_plugin_hook('layout', 'page', $vars, $layout_name); |
638
|
|
|
|
639
|
3 |
|
$vars['layout'] = $layout_name; |
640
|
|
|
|
641
|
|
|
$layout_views = [ |
642
|
3 |
|
"page/layouts/$layout_name", |
643
|
3 |
|
"page/layouts/default", |
644
|
|
|
]; |
645
|
|
|
|
646
|
3 |
|
$output = ''; |
647
|
3 |
|
foreach ($layout_views as $layout_view) { |
648
|
3 |
|
if (elgg_view_exists($layout_view)) { |
649
|
2 |
|
$output = elgg_view($layout_view, $vars); |
650
|
3 |
|
break; |
651
|
|
|
} |
652
|
|
|
} |
653
|
|
|
|
654
|
3 |
|
$timer->end([__FUNCTION__]); |
655
|
3 |
|
return $output; |
656
|
|
|
} |
657
|
|
|
|
658
|
|
|
/** |
659
|
|
|
* Normalizes deprecated content layout $vars for use in default layout |
660
|
|
|
* Helper function to assist plugins transitioning to 3.0 |
661
|
|
|
* |
662
|
|
|
* @param array $vars Vars |
663
|
|
|
* @return array |
664
|
|
|
* @access private |
665
|
|
|
*/ |
666
|
|
|
function _elgg_normalize_content_layout_vars(array $vars = []) { |
667
|
|
|
|
668
|
1 |
|
$context = elgg_extract('context', $vars, elgg_get_context()); |
669
|
|
|
|
670
|
1 |
|
$vars['title'] = elgg_extract('title', $vars, ''); |
671
|
1 |
|
if (!$vars['title'] && $vars['title'] !== false) { |
672
|
|
|
$vars['title'] = elgg_echo($context); |
673
|
|
|
} |
674
|
|
|
|
675
|
|
|
// 1.8 supported 'filter_override' |
676
|
1 |
|
if (isset($vars['filter_override'])) { |
677
|
|
|
$vars['filter'] = $vars['filter_override']; |
678
|
|
|
} |
679
|
|
|
|
680
|
|
|
// register the default content filters |
681
|
1 |
|
if (!isset($vars['filter']) && $context) { |
682
|
|
|
$selected = elgg_extract('filter_context', $vars); |
683
|
|
|
$vars['filter'] = elgg_get_filter_tabs($context, $selected, null, $vars); |
684
|
|
|
$vars['filter_id'] = $context; |
685
|
|
|
$vars['filter_value'] = $selected; |
686
|
|
|
} |
687
|
|
|
|
688
|
1 |
|
return $vars; |
689
|
|
|
} |
690
|
|
|
|
691
|
|
|
/** |
692
|
|
|
* Render a menu |
693
|
|
|
* |
694
|
|
|
* @see elgg_register_menu_item() for documentation on adding menu items and |
695
|
|
|
* navigation.php for information on the different menus available. |
696
|
|
|
* |
697
|
|
|
* This function triggers a 'register', 'menu:<menu name>' plugin hook that enables |
698
|
|
|
* plugins to add menu items just before a menu is rendered. This is used by |
699
|
|
|
* dynamic menus (menus that change based on some input such as the user hover |
700
|
|
|
* menu). Using elgg_register_menu_item() in response to the hook can cause |
701
|
|
|
* incorrect links to show up. See the blog plugin's blog_owner_block_menu() |
702
|
|
|
* for an example of using this plugin hook. |
703
|
|
|
* |
704
|
|
|
* An additional hook is the 'prepare', 'menu:<menu name>' which enables plugins |
705
|
|
|
* to modify the structure of the menu (sort it, remove items, set variables on |
706
|
|
|
* the menu items). |
707
|
|
|
* |
708
|
|
|
* Preset (unprepared) menu items passed to the this function with the $vars |
709
|
|
|
* argument, will be merged with the registered items (registered with |
710
|
|
|
* elgg_register_menu_item()). The combined set of menu items will be passed |
711
|
|
|
* to 'register', 'menu:<menu_name>' hook. |
712
|
|
|
* |
713
|
|
|
* Plugins that pass preset menu items to this function and do not wish to be |
714
|
|
|
* affected by plugin hooks (e.g. if you are displaying multiple menus with |
715
|
|
|
* the same name on the page) should instead choose a unqie menu name |
716
|
|
|
* and define a menu_view argument to render menus consistently. |
717
|
|
|
* For example, if you have multiple 'filter' menus on the page: |
718
|
|
|
* <code> |
719
|
|
|
* elgg_view_menu("filter:$uid", [ |
720
|
|
|
* 'items' => $items, |
721
|
|
|
* 'menu_view' => 'navigation/menu/filter', |
722
|
|
|
* ]); |
723
|
|
|
* </code> |
724
|
|
|
* |
725
|
|
|
* elgg_view_menu() uses views in navigation/menu |
726
|
|
|
* |
727
|
|
|
* @param string|Menu|UnpreparedMenu $menu Menu name (or object) |
728
|
|
|
* @param array $vars An associative array of display options for the menu. |
729
|
|
|
* |
730
|
|
|
* Options include: |
731
|
|
|
* items => an array of unprepared menu items |
732
|
|
|
* as ElggMenuItem or menu item factory options |
733
|
|
|
* sort_by => string or php callback |
734
|
|
|
* string options: 'name', 'priority', 'title' (default), |
735
|
|
|
* 'register' (registration order) or a |
736
|
|
|
* php callback (a compare function for usort) |
737
|
|
|
* handler: string the page handler to build action URLs |
738
|
|
|
* entity: \ElggEntity to use to build action URLs |
739
|
|
|
* class: string the class for the entire menu. |
740
|
|
|
* menu_view: name of the view to be used to render the menu |
741
|
|
|
* show_section_headers: bool show headers before menu sections. |
742
|
|
|
* |
743
|
|
|
* @return string |
744
|
|
|
* @since 1.8.0 |
745
|
|
|
*/ |
746
|
|
|
function elgg_view_menu($menu, array $vars = []) { |
747
|
|
|
|
748
|
33 |
|
$menu_view = elgg_extract('menu_view', $vars); |
749
|
33 |
|
unset($vars['menu_view']); |
750
|
|
|
|
751
|
33 |
|
if (is_string($menu)) { |
752
|
33 |
|
$menu = _elgg_services()->menus->getMenu($menu, $vars); |
753
|
|
|
} elseif ($menu instanceof UnpreparedMenu) { |
754
|
|
|
$menu = _elgg_services()->menus->prepareMenu($menu); |
755
|
|
|
} |
756
|
|
|
|
757
|
33 |
|
if (!$menu instanceof Menu) { |
758
|
|
|
throw new \InvalidArgumentException('$menu must be a menu name, a Menu, or UnpreparedMenu'); |
759
|
|
|
} |
760
|
|
|
|
761
|
33 |
|
$name = $menu->getName(); |
762
|
33 |
|
$params = $menu->getParams(); |
763
|
|
|
|
764
|
|
|
$views = [ |
765
|
33 |
|
$menu_view, |
766
|
33 |
|
"navigation/menu/$name", |
767
|
33 |
|
'navigation/menu/default', |
768
|
|
|
]; |
769
|
|
|
|
770
|
33 |
|
foreach ($views as $view) { |
771
|
33 |
|
if (elgg_view_exists($view)) { |
772
|
33 |
|
return elgg_view($view, $params); |
773
|
|
|
} |
774
|
|
|
} |
775
|
18 |
|
} |
776
|
|
|
|
777
|
|
|
/** |
778
|
|
|
* Render a menu item (usually as a link) |
779
|
|
|
* |
780
|
|
|
* @param \ElggMenuItem $item The menu item |
781
|
|
|
* @param array $vars Options to pass to output/url if a link |
782
|
|
|
* @return string |
783
|
|
|
* @since 1.9.0 |
784
|
|
|
*/ |
785
|
|
|
function elgg_view_menu_item(\ElggMenuItem $item, array $vars = []) { |
786
|
|
|
|
787
|
13 |
|
$vars = array_merge($item->getValues(), $vars); |
788
|
13 |
|
$vars['class'] = elgg_extract_class($vars, ['elgg-menu-content']); |
789
|
|
|
|
790
|
13 |
|
if ($item->getLinkClass()) { |
791
|
4 |
|
$vars['class'][] = $item->getLinkClass(); |
792
|
|
|
} |
793
|
|
|
|
794
|
13 |
|
if ($item->getHref() === false || $item->getHref() === null) { |
795
|
2 |
|
$vars['class'][] = 'elgg-non-link'; |
796
|
|
|
} |
797
|
|
|
|
798
|
13 |
|
if (!isset($vars['rel']) && !isset($vars['is_trusted'])) { |
799
|
13 |
|
$vars['is_trusted'] = true; |
800
|
|
|
} |
801
|
|
|
|
802
|
13 |
|
if ($item->getConfirmText()) { |
803
|
|
|
$vars['confirm'] = $item->getConfirmText(); |
804
|
|
|
} |
805
|
|
|
|
806
|
13 |
|
return elgg_view('output/url', $vars); |
807
|
|
|
} |
808
|
|
|
|
809
|
|
|
/** |
810
|
|
|
* Returns a string of a rendered entity. |
811
|
|
|
* |
812
|
|
|
* Entity views are either determined by setting the view property on the entity |
813
|
|
|
* or by having a view named after the entity $type/$subtype. Entities that have |
814
|
|
|
* neither a view property nor a defined $type/$subtype view will fall back to |
815
|
|
|
* using the $type/default view. |
816
|
|
|
* |
817
|
|
|
* The entity view is called with the following in $vars: |
818
|
|
|
* - \ElggEntity 'entity' The entity being viewed |
819
|
|
|
* |
820
|
|
|
* @tip This function can automatically appends annotations to entities if in full |
821
|
|
|
* view and a handler is registered for the entity:annotate. See https://github.com/Elgg/Elgg/issues/964 and |
822
|
|
|
* {@link elgg_view_entity_annotations()}. |
823
|
|
|
* |
824
|
|
|
* @param \ElggEntity $entity The entity to display |
825
|
|
|
* @param array $vars Array of variables to pass to the entity view. |
826
|
|
|
* 'full_view' Whether to show a full or condensed view. (Default: true) |
827
|
|
|
* 'item_view' Alternative view used to render this entity |
828
|
|
|
* |
829
|
|
|
* @return string HTML to display or false |
830
|
|
|
* @todo The annotation hook might be better as a generic plugin hook to append content. |
831
|
|
|
*/ |
832
|
|
|
function elgg_view_entity(\ElggEntity $entity, array $vars = []) { |
833
|
|
|
|
834
|
|
|
// No point continuing if entity is null |
835
|
9 |
|
if (!$entity || !($entity instanceof \ElggEntity)) { |
836
|
|
|
return false; |
837
|
|
|
} |
838
|
|
|
|
839
|
9 |
|
elgg_register_rss_link(); |
840
|
|
|
|
841
|
|
|
$defaults = [ |
842
|
9 |
|
'full_view' => true, |
843
|
|
|
]; |
844
|
|
|
|
845
|
9 |
|
$vars = array_merge($defaults, $vars); |
846
|
|
|
|
847
|
9 |
|
$vars['entity'] = $entity; |
848
|
|
|
|
849
|
9 |
|
$entity_type = $entity->getType(); |
850
|
9 |
|
$entity_subtype = $entity->getSubtype(); |
851
|
|
|
|
852
|
|
|
$entity_views = [ |
853
|
9 |
|
elgg_extract('item_view', $vars, ''), |
854
|
9 |
|
"$entity_type/$entity_subtype", |
855
|
9 |
|
"$entity_type/default", |
856
|
|
|
]; |
857
|
|
|
|
858
|
9 |
|
$contents = ''; |
859
|
9 |
|
foreach ($entity_views as $view) { |
860
|
9 |
|
if (elgg_view_exists($view)) { |
861
|
9 |
|
$contents = elgg_view($view, $vars); |
862
|
9 |
|
break; |
863
|
|
|
} |
864
|
|
|
} |
865
|
|
|
|
866
|
|
|
// Marcus Povey 20090616 : Speculative and low impact approach for fixing #964 |
867
|
9 |
|
if ($vars['full_view']) { |
868
|
7 |
|
$annotations = elgg_view_entity_annotations($entity, $vars['full_view']); |
869
|
|
|
|
870
|
7 |
|
if ($annotations) { |
871
|
|
|
$contents .= $annotations; |
872
|
|
|
} |
873
|
|
|
} |
874
|
9 |
|
return $contents; |
875
|
|
|
} |
876
|
|
|
|
877
|
|
|
/** |
878
|
|
|
* View the icon of an entity |
879
|
|
|
* |
880
|
|
|
* Entity views are determined by having a view named after the entity $type/$subtype. |
881
|
|
|
* Entities that do not have a defined icon/$type/$subtype view will fall back to using |
882
|
|
|
* the icon/$type/default view. |
883
|
|
|
* |
884
|
|
|
* @param \ElggEntity $entity The entity to display |
885
|
|
|
* @param string $size The size: tiny, small, medium, large |
886
|
|
|
* @param array $vars An array of variables to pass to the view. Some possible |
887
|
|
|
* variables are img_class and link_class. See the |
888
|
|
|
* specific icon view for more parameters. |
889
|
|
|
* |
890
|
|
|
* @return string HTML to display or false |
891
|
|
|
*/ |
892
|
|
|
function elgg_view_entity_icon(\ElggEntity $entity, $size = 'medium', $vars = []) { |
893
|
|
|
|
894
|
|
|
// No point continuing if entity is null |
895
|
14 |
|
if (!$entity || !($entity instanceof \ElggEntity)) { |
896
|
|
|
return false; |
897
|
|
|
} |
898
|
|
|
|
899
|
14 |
|
$vars['entity'] = $entity; |
900
|
14 |
|
$vars['size'] = $size; |
901
|
|
|
|
902
|
14 |
|
$entity_type = $entity->getType(); |
903
|
|
|
|
904
|
14 |
|
$subtype = $entity->getSubtype(); |
905
|
|
|
|
906
|
14 |
|
$contents = ''; |
907
|
14 |
|
if (elgg_view_exists("icon/$entity_type/$subtype")) { |
908
|
|
|
$contents = elgg_view("icon/$entity_type/$subtype", $vars); |
909
|
|
|
} |
910
|
14 |
|
if (empty($contents)) { |
911
|
14 |
|
$contents = elgg_view("icon/$entity_type/default", $vars); |
912
|
|
|
} |
913
|
14 |
|
if (empty($contents)) { |
914
|
13 |
|
$contents = elgg_view("icon/default", $vars); |
915
|
|
|
} |
916
|
|
|
|
917
|
14 |
|
return $contents; |
918
|
|
|
} |
919
|
|
|
|
920
|
|
|
/** |
921
|
|
|
* Returns a string of a rendered annotation. |
922
|
|
|
* |
923
|
|
|
* Annotation views are expected to be in annotation/$annotation_name. |
924
|
|
|
* If a view is not found for $annotation_name, the default annotation/default |
925
|
|
|
* will be used. |
926
|
|
|
* |
927
|
|
|
* @warning annotation/default is not currently defined in core. |
928
|
|
|
* |
929
|
|
|
* The annotation view is called with the following in $vars: |
930
|
|
|
* - \ElggEntity 'annotation' The annotation being viewed. |
931
|
|
|
* |
932
|
|
|
* @param \ElggAnnotation $annotation The annotation to display |
933
|
|
|
* @param array $vars Variable array for view. |
934
|
|
|
* 'item_view' Alternative view used to render an annotation |
935
|
|
|
* |
936
|
|
|
* @return string/false Rendered annotation |
937
|
|
|
*/ |
|
|
|
|
938
|
|
|
function elgg_view_annotation(\ElggAnnotation $annotation, array $vars = []) { |
939
|
|
|
elgg_register_rss_link(); |
940
|
|
|
|
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 |
985
|
|
|
* 'pagination' Display pagination? |
986
|
|
|
* 'base_url' Base URL of list (optional) |
987
|
|
|
* 'url_fragment' URL fragment to add to links if not present in base_url (optional) |
988
|
|
|
* 'position' Position of the pagination: before, after, or both |
989
|
|
|
* 'list_type' List type: 'list' (default), 'gallery' |
990
|
|
|
* 'list_type_toggle' Display the list type toggle? |
991
|
|
|
* 'no_results' Message to display if no results (string|Closure) |
992
|
|
|
* |
993
|
|
|
* @return string The rendered list of entities |
994
|
|
|
*/ |
995
|
|
|
function elgg_view_entity_list($entities, array $vars = []) { |
996
|
3 |
|
$offset = (int) get_input('offset', 0); |
997
|
|
|
|
998
|
|
|
// list type can be passed as request parameter |
999
|
3 |
|
$list_type = get_input('list_type', 'list'); |
1000
|
|
|
|
1001
|
|
|
$defaults = [ |
1002
|
3 |
|
'items' => $entities, |
1003
|
3 |
|
'list_class' => 'elgg-list-entity', |
1004
|
|
|
'full_view' => true, |
1005
|
|
|
'pagination' => true, |
1006
|
3 |
|
'list_type' => $list_type, |
1007
|
|
|
'list_type_toggle' => false, |
1008
|
3 |
|
'offset' => $offset, |
1009
|
|
|
'limit' => null, |
1010
|
|
|
]; |
1011
|
|
|
|
1012
|
3 |
|
$vars = array_merge($defaults, $vars); |
1013
|
|
|
|
1014
|
3 |
|
if (!$vars["limit"] && !$vars["offset"]) { |
1015
|
|
|
// no need for pagination if listing is unlimited |
1016
|
|
|
$vars["pagination"] = false; |
1017
|
|
|
} |
1018
|
|
|
|
1019
|
3 |
|
if ($vars['list_type'] == 'table') { |
1020
|
|
|
return elgg_view('page/components/table', $vars); |
1021
|
3 |
|
} elseif ($vars['list_type'] == 'list') { |
1022
|
3 |
|
return elgg_view('page/components/list', $vars); |
1023
|
|
|
} else { |
1024
|
|
|
return elgg_view('page/components/gallery', $vars); |
1025
|
|
|
} |
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|Closure) |
1042
|
|
|
* |
1043
|
|
|
* @return string The list of annotations |
1044
|
|
|
* @access private |
1045
|
|
|
*/ |
1046
|
|
|
function elgg_view_annotation_list($annotations, array $vars = []) { |
1047
|
|
|
$defaults = [ |
1048
|
1 |
|
'items' => $annotations, |
1049
|
|
|
'offset' => null, |
1050
|
|
|
'limit' => null, |
1051
|
1 |
|
'list_class' => 'elgg-list-annotation elgg-annotation-list', // @todo remove elgg-annotation-list in Elgg 1.9 |
1052
|
|
|
'full_view' => true, |
1053
|
1 |
|
'offset_key' => 'annoff', |
1054
|
|
|
]; |
1055
|
|
|
|
1056
|
1 |
|
$vars = array_merge($defaults, $vars); |
1057
|
|
|
|
1058
|
1 |
|
if (!$vars["limit"] && !$vars["offset"]) { |
1059
|
|
|
// no need for pagination if listing is unlimited |
1060
|
|
|
$vars["pagination"] = false; |
1061
|
|
|
} |
1062
|
|
|
|
1063
|
1 |
|
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
|
7 |
|
if (!($entity instanceof \ElggEntity)) { |
1082
|
|
|
return false; |
1083
|
|
|
} |
1084
|
|
|
|
1085
|
7 |
|
$entity_type = $entity->getType(); |
1086
|
|
|
|
1087
|
7 |
|
$annotations = elgg_trigger_plugin_hook('entity:annotate', $entity_type, |
1088
|
|
|
[ |
1089
|
7 |
|
'entity' => $entity, |
1090
|
7 |
|
'full_view' => $full_view, |
1091
|
|
|
] |
1092
|
|
|
); |
1093
|
|
|
|
1094
|
7 |
|
return $annotations; |
1095
|
|
|
} |
1096
|
|
|
|
1097
|
|
|
/** |
1098
|
|
|
* Renders a title. |
1099
|
|
|
* |
1100
|
|
|
* This is a shortcut for {@elgg_view page/elements/title}. |
1101
|
|
|
* |
1102
|
|
|
* @param string $title The page title |
1103
|
|
|
* @param array $vars View variables (was submenu be displayed? (deprecated)) |
1104
|
|
|
* |
1105
|
|
|
* @return string The HTML (etc) |
1106
|
|
|
*/ |
1107
|
|
|
function elgg_view_title($title, array $vars = []) { |
1108
|
|
|
$vars['title'] = $title; |
1109
|
|
|
|
1110
|
|
|
return elgg_view('page/elements/title', $vars); |
1111
|
|
|
} |
1112
|
|
|
|
1113
|
|
|
/** |
1114
|
|
|
* Displays a UNIX timestamp in a friendly way |
1115
|
|
|
* |
1116
|
|
|
* @see elgg_get_friendly_time() |
1117
|
|
|
* |
1118
|
|
|
* @param int $time A UNIX epoch timestamp |
1119
|
|
|
* |
1120
|
|
|
* @return string The friendly time HTML |
1121
|
|
|
* @since 1.7.2 |
1122
|
|
|
*/ |
1123
|
|
|
function elgg_view_friendly_time($time) { |
1124
|
9 |
|
$view = 'output/friendlytime'; |
1125
|
9 |
|
$vars = ['time' => $time]; |
1126
|
9 |
|
$viewtype = elgg_view_exists($view) ? '' : 'default'; |
1127
|
|
|
|
1128
|
9 |
|
return _elgg_view_under_viewtype($view, $vars, $viewtype); |
1129
|
|
|
} |
1130
|
|
|
|
1131
|
|
|
/** |
1132
|
|
|
* Returns rendered comments and a comment form for an entity. |
1133
|
|
|
* |
1134
|
|
|
* @tip Plugins can override the output by registering a handler |
1135
|
|
|
* for the comments, $entity_type hook. The handler is responsible |
1136
|
|
|
* for formatting the comments and the add comment form. |
1137
|
|
|
* |
1138
|
|
|
* @param \ElggEntity $entity The entity to view comments of |
1139
|
|
|
* @param bool $add_comment Include a form to add comments? |
1140
|
|
|
* @param array $vars Variables to pass to comment view |
1141
|
|
|
* |
1142
|
|
|
* @return string|false Rendered comments or false on failure |
1143
|
|
|
*/ |
1144
|
|
|
function elgg_view_comments($entity, $add_comment = true, array $vars = []) { |
1145
|
1 |
|
if (!($entity instanceof \ElggEntity)) { |
1146
|
|
|
return false; |
1147
|
|
|
} |
1148
|
|
|
|
1149
|
1 |
|
$vars['entity'] = $entity; |
1150
|
1 |
|
$vars['show_add_form'] = $add_comment; |
1151
|
1 |
|
$vars['class'] = elgg_extract('class', $vars, "{$entity->getSubtype()}-comments"); |
1152
|
|
|
|
1153
|
1 |
|
$output = elgg_trigger_plugin_hook('comments', $entity->getType(), $vars, false); |
1154
|
1 |
|
if ($output !== false) { |
1155
|
|
|
return $output; |
1156
|
|
|
} else { |
1157
|
1 |
|
return elgg_view('page/elements/comments', $vars); |
1158
|
|
|
} |
1159
|
|
|
} |
1160
|
|
|
|
1161
|
|
|
/** |
1162
|
|
|
* Wrapper function for the image block display pattern. |
1163
|
|
|
* |
1164
|
|
|
* Fixed width media on the side (image, icon, flash, etc.). |
1165
|
|
|
* Descriptive content filling the rest of the column. |
1166
|
|
|
* |
1167
|
|
|
* @note Use the $vars "image_alt" key to set an image on the right. If you do, you may pass |
1168
|
|
|
* in an empty string for $image to have only the right image. |
1169
|
|
|
* |
1170
|
|
|
* This is a shortcut for {@elgg_view page/components/image_block}. |
1171
|
|
|
* |
1172
|
|
|
* @param string $image The icon and other information |
1173
|
|
|
* @param string $body Description content |
1174
|
|
|
* @param array $vars Additional parameters for the view |
1175
|
|
|
* |
1176
|
|
|
* @return string |
1177
|
|
|
* @since 1.8.0 |
1178
|
|
|
*/ |
1179
|
|
|
function elgg_view_image_block($image, $body, $vars = []) { |
1180
|
13 |
|
$vars['image'] = $image; |
1181
|
13 |
|
$vars['body'] = $body; |
1182
|
13 |
|
return elgg_view('page/components/image_block', $vars); |
1183
|
|
|
} |
1184
|
|
|
|
1185
|
|
|
/** |