1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Elgg developer tools |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
use Elgg\DevelopersPlugin\Hooks; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Developers init |
10
|
|
|
* |
11
|
|
|
* @return void |
12
|
|
|
*/ |
13
|
|
|
function developers_init() { |
14
|
|
|
|
15
|
31 |
|
elgg_register_plugin_hook_handler('register', 'menu:page', '_developers_page_menu'); |
16
|
|
|
|
17
|
31 |
|
elgg_extend_view('admin.css', 'developers/css'); |
18
|
31 |
|
elgg_extend_view('elgg.css', 'developers/css'); |
19
|
|
|
|
20
|
31 |
|
elgg_register_page_handler('theme_sandbox', 'developers_theme_sandbox_controller'); |
|
|
|
|
21
|
31 |
|
elgg_register_page_handler('developers_ajax_demo', 'developers_ajax_demo_controller'); |
|
|
|
|
22
|
|
|
|
23
|
31 |
|
elgg_register_external_view('developers/ajax'); // for lightbox in sandbox |
24
|
31 |
|
elgg_register_ajax_view('developers/ajax_demo.html'); |
25
|
|
|
|
26
|
31 |
|
elgg_register_ajax_view('forms/developers/ajax_demo'); |
27
|
31 |
|
elgg_register_ajax_view('theme_sandbox/components/tabs/ajax'); |
28
|
31 |
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Process plugin settings before plugins are started |
32
|
|
|
* |
33
|
|
|
* @return void |
34
|
|
|
*/ |
35
|
|
|
function developers_process_settings() { |
36
|
18 |
|
$settings = elgg_get_plugin_from_id('developers')->getAllSettings(); |
37
|
|
|
|
38
|
18 |
|
ini_set('display_errors', (int) !empty($settings['display_errors'])); |
39
|
|
|
|
40
|
18 |
|
if (!empty($settings['screen_log'])) { |
41
|
|
|
// don't show in action/simplecache |
42
|
|
|
$path = substr(current_page_url(), strlen(elgg_get_site_url())); |
43
|
|
|
if (!preg_match('~^(cache|action)/~', $path)) { |
44
|
|
|
$cache = new ElggLogCache(); |
45
|
|
|
elgg_set_config('log_cache', $cache); |
46
|
|
|
elgg_register_plugin_hook_handler('debug', 'log', [$cache, 'insertDump']); |
47
|
|
|
elgg_register_plugin_hook_handler('view_vars', 'page/elements/html', function($hook, $type, $vars, $params) { |
|
|
|
|
48
|
|
|
$vars['body'] .= elgg_view('developers/log'); |
49
|
|
|
return $vars; |
50
|
|
|
}); |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
|
54
|
18 |
|
if (!empty($settings['show_strings'])) { |
55
|
|
|
// Beginning and end to make sure both early-rendered and late-loaded translations get included |
56
|
|
|
elgg_register_event_handler('init', 'system', 'developers_decorate_all_translations', 1); |
57
|
|
|
elgg_register_event_handler('init', 'system', 'developers_decorate_all_translations', 1000); |
58
|
|
|
} |
59
|
|
|
|
60
|
18 |
|
if (!empty($settings['show_modules'])) { |
61
|
|
|
elgg_require_js('elgg/dev/amd_monitor'); |
62
|
|
|
} |
63
|
|
|
|
64
|
18 |
|
if (!empty($settings['wrap_views'])) { |
65
|
|
|
elgg_register_plugin_hook_handler('view', 'all', 'developers_wrap_views', 600); |
66
|
|
|
} |
67
|
|
|
|
68
|
18 |
|
if (!empty($settings['log_events'])) { |
69
|
|
|
elgg_register_event_handler('all', 'all', 'developers_log_events', 1); |
70
|
|
|
elgg_register_plugin_hook_handler('all', 'all', 'developers_log_events', 1); |
71
|
|
|
} |
72
|
|
|
|
73
|
18 |
|
if (!empty($settings['show_gear']) && elgg_is_admin_logged_in() && !elgg_in_context('admin')) { |
74
|
|
|
elgg_require_js('elgg/dev/gear'); |
75
|
|
|
elgg_register_ajax_view('developers/gear_popup'); |
76
|
|
|
elgg_register_simplecache_view('elgg/dev/gear.html'); |
77
|
|
|
|
78
|
|
|
$handler = [Hooks::class, 'alterMenuSectionVars']; |
79
|
|
|
elgg_register_plugin_hook_handler('view_vars', 'navigation/menu/elements/section', $handler); |
80
|
|
|
|
81
|
|
|
$handler = [Hooks::class, 'alterMenuSections']; |
82
|
|
|
elgg_register_plugin_hook_handler('view', 'navigation/menu/elements/section', $handler); |
83
|
|
|
|
84
|
|
|
$handler = [Hooks::class, 'alterMenu']; |
85
|
|
|
elgg_register_plugin_hook_handler('view', 'navigation/menu/default', $handler); |
86
|
|
|
} |
87
|
|
|
|
88
|
18 |
|
if (!empty($settings['block_email'])) { |
89
|
|
|
$handler = [Hooks::class, 'blockOutgoingEmails']; |
90
|
|
|
elgg_register_plugin_hook_handler('transport', 'system:email', $handler); |
91
|
|
|
|
92
|
|
|
if (!empty($settings['forward_email'])) { |
93
|
|
|
$handler = [Hooks::class, 'setForwardEmailAddress']; |
94
|
|
|
elgg_register_plugin_hook_handler('prepare', 'system:email', $handler); |
95
|
|
|
} |
96
|
|
|
} |
97
|
18 |
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Register menu items for the page menu |
101
|
|
|
* |
102
|
|
|
* @param string $hook 'register' |
103
|
|
|
* @param string $type 'menu:page' |
104
|
|
|
* @param ElggMenuItem[] $return current return value |
105
|
|
|
* @param array $params supplied params |
106
|
|
|
* |
107
|
|
|
* @return void|ElggMenuItem[] |
108
|
|
|
* |
109
|
|
|
* @access private |
110
|
|
|
* @since 3.0 |
111
|
|
|
*/ |
112
|
|
|
function _developers_page_menu($hook, $type, $return, $params) { |
|
|
|
|
113
|
1 |
|
if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) { |
114
|
1 |
|
return; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
$return[] = \ElggMenuItem::factory([ |
118
|
|
|
'name' => 'dev_settings', |
119
|
|
|
'href' => 'admin/developers/settings', |
120
|
|
|
'text' => elgg_echo('settings'), |
121
|
|
|
'priority' => 10, |
122
|
|
|
'section' => 'develop', |
123
|
|
|
]); |
124
|
|
|
|
125
|
|
|
$return[] = \ElggMenuItem::factory([ |
126
|
|
|
'name' => 'inspect', |
127
|
|
|
'text' => elgg_echo('admin:inspect'), |
128
|
|
|
'section' => 'develop', |
129
|
|
|
]); |
130
|
|
|
|
131
|
|
|
$inspect_options = developers_get_inspect_options(); |
132
|
|
|
foreach ($inspect_options as $key => $value) { |
133
|
|
|
$return[] = \ElggMenuItem::factory([ |
134
|
|
|
'name' => 'dev_inspect_' . elgg_get_friendly_title($key), |
135
|
|
|
'href' => "admin/develop_tools/inspect?" . http_build_query([ |
136
|
|
|
'inspect_type' => $key, |
137
|
|
|
]), |
138
|
|
|
'text' => $value, |
139
|
|
|
'section' => 'develop', |
140
|
|
|
'parent_name' => 'inspect', |
141
|
|
|
]); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
$return[] = \ElggMenuItem::factory([ |
145
|
|
|
'name' => 'develop_tools', |
146
|
|
|
'text' => elgg_echo('admin:develop_tools'), |
147
|
|
|
'section' => 'develop', |
148
|
|
|
]); |
149
|
|
|
|
150
|
|
|
$return[] = \ElggMenuItem::factory([ |
151
|
|
|
'name' => 'develop_tools:sandbox', |
152
|
|
|
'href' => 'admin/develop_tools/sandbox', |
153
|
|
|
'text' => elgg_echo('admin:develop_tools:sandbox'), |
154
|
|
|
'parent_name' => 'develop_tools', |
155
|
|
|
'section' => 'develop', |
156
|
|
|
]); |
157
|
|
|
|
158
|
|
|
$return[] = \ElggMenuItem::factory([ |
159
|
|
|
'name' => 'develop_tools:entity_explorer', |
160
|
|
|
'href' => 'admin/develop_tools/entity_explorer', |
161
|
|
|
'text' => elgg_echo('admin:develop_tools:entity_explorer'), |
162
|
|
|
'parent_name' => 'develop_tools', |
163
|
|
|
'section' => 'develop', |
164
|
|
|
]); |
165
|
|
|
|
166
|
|
|
return $return; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Adds debug info to all translatable strings |
171
|
|
|
* |
172
|
|
|
* @return void |
173
|
|
|
*/ |
174
|
|
|
function developers_decorate_all_translations() { |
175
|
|
|
$language = get_current_language(); |
176
|
|
|
_developers_decorate_translations($language); |
177
|
|
|
_developers_decorate_translations('en'); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Appends " ($key)" to all strings for the given language. |
182
|
|
|
* |
183
|
|
|
* This function checks if the suffix has already been added so it is idempotent |
184
|
|
|
* |
185
|
|
|
* @param string $language Language code like "en" |
186
|
|
|
* |
187
|
|
|
* @return void |
188
|
|
|
*/ |
189
|
|
|
function _developers_decorate_translations($language) { |
190
|
|
|
$translations = _elgg_services()->translator->getLoadedTranslations(); |
191
|
|
|
|
192
|
|
|
foreach ($translations[$language] as $key => &$value) { |
193
|
|
|
$needle = " ($key)"; |
194
|
|
|
|
195
|
|
|
// if $value doesn't already end with " ($key)", append it |
196
|
|
|
if (substr($value, -strlen($needle)) !== $needle) { |
197
|
|
|
$value .= $needle; |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Post-process a view to add wrapper comments to it |
204
|
|
|
* |
205
|
|
|
* 1. Only process views served with the 'default' viewtype. |
206
|
|
|
* 2. Does not wrap views that are not HTML. |
207
|
|
|
* 4. Does not wrap input and output views (why?). |
208
|
|
|
* 5. Does not wrap html head or the primary page shells |
209
|
|
|
* |
210
|
|
|
* @warning this will break views in the default viewtype that return non-HTML data |
211
|
|
|
* that do not match the above restrictions. |
212
|
|
|
* |
213
|
|
|
* @param string $hook 'view' |
214
|
|
|
* @param string $type 'all' |
215
|
|
|
* @param string $result current return value |
216
|
|
|
* @param mixed $params supplied params |
217
|
|
|
* |
218
|
|
|
* @return void|string |
219
|
|
|
*/ |
220
|
|
|
function developers_wrap_views($hook, $type, $result, $params) { |
|
|
|
|
221
|
|
|
if (elgg_get_viewtype() != "default") { |
222
|
|
|
return; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
if (stristr(current_page_url(), elgg_normalize_url('cache/'))) { |
226
|
|
|
return; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
$excluded_bases = ['resources', 'input', 'output', 'embed', 'icon', 'json', 'xml']; |
230
|
|
|
|
231
|
|
|
$excluded_views = [ |
232
|
|
|
'page/default', |
233
|
|
|
'page/admin', |
234
|
|
|
'page/elements/head', |
235
|
|
|
]; |
236
|
|
|
|
237
|
|
|
$view = $params['view']; |
238
|
|
|
|
239
|
|
|
$view_hierarchy = explode('/', $view); |
240
|
|
|
if (in_array($view_hierarchy[0], $excluded_bases)) { |
241
|
|
|
return; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
if (in_array($view, $excluded_views)) { |
245
|
|
|
return; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
if ((new \SplFileInfo($view))->getExtension()) { |
249
|
|
|
return; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
if ($result) { |
253
|
|
|
$result = "<!-- developers:begin $view -->$result<!-- developers:end $view -->"; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
return $result; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Log the events and plugin hooks |
261
|
|
|
* |
262
|
|
|
* @param string $name the name of the event/hook |
263
|
|
|
* @param string $type the type of the event/hook |
264
|
|
|
* |
265
|
|
|
* @return void |
266
|
|
|
*/ |
267
|
|
|
function developers_log_events($name, $type) { |
268
|
|
|
|
269
|
|
|
// filter out some very common events |
270
|
|
|
if ($name == 'view' || $name == 'display' || $name == 'log' || $name == 'debug') { |
271
|
|
|
return; |
272
|
|
|
} |
273
|
|
|
if ($name == 'session:get' || $name == 'validate') { |
274
|
|
|
return; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
// 0 => this function |
278
|
|
|
// 1 => call_user_func_array |
279
|
|
|
// 2 => hook class trigger |
280
|
|
|
$stack = debug_backtrace(); |
281
|
|
|
if (isset($stack[2]['class']) && $stack[2]['class'] == 'Elgg\EventsService') { |
282
|
|
|
$event_type = 'Event'; |
283
|
|
|
} else { |
284
|
|
|
$event_type = 'Plugin hook'; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
if ($stack[3]['function'] == 'elgg_trigger_event' || $stack[3]['function'] == 'elgg_trigger_plugin_hook') { |
288
|
|
|
$index = 4; |
289
|
|
|
} else { |
290
|
|
|
$index = 3; |
291
|
|
|
} |
292
|
|
|
if (isset($stack[$index]['class'])) { |
293
|
|
|
$function = $stack[$index]['class'] . '::' . $stack[$index]['function'] . '()'; |
294
|
|
|
} else { |
295
|
|
|
$function = $stack[$index]['function'] . '()'; |
296
|
|
|
} |
297
|
|
|
if ($function == 'require_once()' || $function == 'include_once()') { |
298
|
|
|
$function = $stack[$index]['file']; |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
$msg = elgg_echo('developers:event_log_msg', [ |
302
|
|
|
$event_type, |
303
|
|
|
$name, |
304
|
|
|
$type, |
305
|
|
|
$function, |
306
|
|
|
]); |
307
|
|
|
elgg_dump($msg, false); |
|
|
|
|
308
|
|
|
|
309
|
|
|
unset($stack); |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
/** |
313
|
|
|
* Serve the theme sandbox pages |
314
|
|
|
* |
315
|
|
|
* @param array $page URL segments |
316
|
|
|
* |
317
|
|
|
* @return bool |
318
|
|
|
*/ |
319
|
|
|
function developers_theme_sandbox_controller($page) { |
320
|
|
|
if (!isset($page[0])) { |
321
|
|
|
forward('theme_sandbox/intro'); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
echo elgg_view_resource('theme_sandbox', [ |
325
|
|
|
'page' => $page[0], |
326
|
|
|
]); |
327
|
|
|
return true; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* Page handler for /developers_ajax_demo |
332
|
|
|
* |
333
|
|
|
* @return true |
334
|
|
|
*/ |
335
|
|
|
function developers_ajax_demo_controller() { |
336
|
|
|
echo elgg_view_resource('developers/ajax_demo'); |
337
|
|
|
return true; |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
/** |
341
|
|
|
* Get the available inspect options |
342
|
|
|
* |
343
|
|
|
* @return array |
344
|
|
|
*/ |
345
|
|
|
function developers_get_inspect_options() { |
346
|
|
|
$options = [ |
347
|
|
|
'Actions' => elgg_echo('developers:inspect:actions'), |
348
|
|
|
'Events' => elgg_echo('developers:inspect:events'), |
349
|
|
|
'Menus' => elgg_echo('developers:inspect:menus'), |
350
|
|
|
'Plugin Hooks' => elgg_echo('developers:inspect:pluginhooks'), |
351
|
|
|
'Simple Cache' => elgg_echo('developers:inspect:simplecache'), |
352
|
|
|
'Views' => elgg_echo('developers:inspect:views'), |
353
|
|
|
'Widgets' => elgg_echo('developers:inspect:widgets'), |
354
|
|
|
]; |
355
|
|
|
|
356
|
|
|
if (elgg_is_active_plugin('web_services')) { |
357
|
|
|
$options['Web Services'] = elgg_echo('developers:inspect:webservices'); |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
ksort($options); |
361
|
|
|
|
362
|
|
|
return $options; |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
return function() { |
366
|
|
|
// we want to run this as soon as possible - other plugins should not need to do this |
367
|
18 |
|
developers_process_settings(); |
368
|
|
|
|
369
|
18 |
|
elgg_register_event_handler('init', 'system', 'developers_init'); |
370
|
|
|
}; |
371
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.