Test Failed
Push — master ( 8c47c2...3acf9f )
by Steve
12:37
created

mod/developers/start.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Elgg developer tools
4
 */
5
6
use Elgg\DevelopersPlugin\Hooks;
7
8
// we want to run this as soon as possible - other plugins should not need to do this
9
developers_process_settings();
10
11
elgg_register_event_handler('init', 'system', 'developers_init');
12
13
function developers_init() {
14
15
	elgg_register_plugin_hook_handler('register', 'menu:page', '_developers_page_menu');
16
		
17
	elgg_extend_view('admin.css', 'developers/css');
18
	elgg_extend_view('elgg.css', 'developers/css');
19
20
	elgg_register_page_handler('theme_sandbox', 'developers_theme_sandbox_controller');
21
	elgg_register_page_handler('developers_ajax_demo', 'developers_ajax_demo_controller');
22
23
	elgg_register_external_view('developers/ajax'); // for lightbox in sandbox
24
	elgg_register_ajax_view('developers/ajax_demo.html');
25
	$sandbox_css = elgg_get_simplecache_url('theme_sandbox.css');
26
	elgg_register_css('dev.theme_sandbox', $sandbox_css);
27
28
	elgg_register_ajax_view('forms/developers/ajax_demo');
29
	elgg_register_ajax_view('theme_sandbox/components/tabs/ajax');
30
}
31
32
function developers_process_settings() {
33
	$settings = elgg_get_plugin_from_id('developers')->getAllSettings();
34
35
	ini_set('display_errors', (int) !empty($settings['display_errors']));
36
37
	if (!empty($settings['screen_log'])) {
38
		// don't show in action/simplecache
39
		$path = substr(current_page_url(), strlen(elgg_get_site_url()));
40
		if (!preg_match('~^(cache|action)/~', $path)) {
41
			$cache = new ElggLogCache();
42
			elgg_set_config('log_cache', $cache);
43
			elgg_register_plugin_hook_handler('debug', 'log', [$cache, 'insertDump']);
44
			elgg_register_plugin_hook_handler('view_vars', 'page/elements/html', function($hook, $type, $vars, $params) {
45
				$vars['body'] .= elgg_view('developers/log');
46
				return $vars;
47
			});
48
		}
49
	}
50
51
	if (!empty($settings['show_strings'])) {
52
		// Beginning and end to make sure both early-rendered and late-loaded translations get included
53
		elgg_register_event_handler('init', 'system', 'developers_decorate_all_translations', 1);
54
		elgg_register_event_handler('init', 'system', 'developers_decorate_all_translations', 1000);
55
	}
56
57
	if (!empty($settings['show_modules'])) {
58
		elgg_require_js('elgg/dev/amd_monitor');
59
	}
60
61
	if (!empty($settings['wrap_views'])) {
62
		elgg_register_plugin_hook_handler('view', 'all', 'developers_wrap_views', 600);
63
	}
64
65
	if (!empty($settings['log_events'])) {
66
		elgg_register_event_handler('all', 'all', 'developers_log_events', 1);
67
		elgg_register_plugin_hook_handler('all', 'all', 'developers_log_events', 1);
68
	}
69
70
	if (!empty($settings['show_gear']) && elgg_is_admin_logged_in() && !elgg_in_context('admin')) {
71
		elgg_require_js('elgg/dev/gear');
72
		elgg_register_ajax_view('developers/gear_popup');
73
		elgg_register_simplecache_view('elgg/dev/gear.html');
74
75
		$handler = [Hooks::class, 'alterMenuSectionVars'];
76
		elgg_register_plugin_hook_handler('view_vars', 'navigation/menu/elements/section', $handler);
77
78
		$handler = [Hooks::class, 'alterMenuSections'];
79
		elgg_register_plugin_hook_handler('view', 'navigation/menu/elements/section', $handler);
80
81
		$handler = [Hooks::class, 'alterMenu'];
82
		elgg_register_plugin_hook_handler('view', 'navigation/menu/default', $handler);
83
	}
84
}
85
86
/**
87
 * Register menu items for the page menu
88
 *
89
 * @param string $hook
90
 * @param string $type
91
 * @param array  $return
92
 * @param array  $params
93
 * @return array
94
 *
95
 * @access private
96
 *
97
 * @since 3.0
98
 */
99
function _developers_page_menu($hook, $type, $return, $params) {
100
	if (!elgg_in_context('admin') || !elgg_is_admin_logged_in()) {
101
		return;
102
	}
103
	
104
	$return[] = \ElggMenuItem::factory([
105
		'name' => 'dev_settings',
106
		'href' => 'admin/developers/settings',
107
		'text' => elgg_echo('settings'),
108
		'priority' => 10,
109
		'section' => 'develop',
110
	]);
111
	
112
	$return[] = \ElggMenuItem::factory([
113
		'name' => 'inspect',
114
		'text' => elgg_echo('admin:inspect'),
115
		'section' => 'develop',
116
	]);
117
	
118
	$inspect_options = developers_get_inspect_options();
119
	foreach ($inspect_options as $key => $value) {
120
		$return[] = \ElggMenuItem::factory([
121
			'name' => 'dev_inspect_' . elgg_get_friendly_title($key),
122
			'href' => "admin/develop_tools/inspect?" . http_build_query([
123
				'inspect_type' => $key,
124
			]),
125
			'text' => $value,
126
			'section' => 'develop',
127
			'parent_name' => 'inspect',
128
		]);
129
	}
130
	
131
	$return[] = \ElggMenuItem::factory([
132
		'name' => 'develop_tools',
133
		'text' => elgg_echo('admin:develop_tools'),
134
		'section' => 'develop',
135
	]);
136
	
137
	$return[] = \ElggMenuItem::factory([
138
		'name' => 'develop_tools:sandbox',
139
		'href' => 'admin/develop_tools/sandbox',
140
		'text' => elgg_echo('admin:develop_tools:sandbox'),
141
		'parent_name' => 'develop_tools',
142
		'section' => 'develop',
143
	]);
144
	
145
	$return[] = \ElggMenuItem::factory([
146
		'name' => 'develop_tools:unit_tests',
147
		'href' => 'admin/develop_tools/unit_tests',
148
		'text' => elgg_echo('admin:develop_tools:unit_tests'),
149
		'parent_name' => 'develop_tools',
150
		'section' => 'develop',
151
	]);
152
	
153
	return $return;
154
}
155
156
/**
157
 * Adds debug info to all translatable strings.
158
 */
159
function developers_decorate_all_translations() {
160
	$language = get_current_language();
161
	_developers_decorate_translations($language);
162
	_developers_decorate_translations('en');
163
}
164
165
/**
166
 * Appends " ($key)" to all strings for the given language.
167
 *
168
 * This function checks if the suffix has already been added so it is idempotent
169
 *
170
 * @param string $language Language code like "en"
171
 */
172
function _developers_decorate_translations($language) {
0 ignored issues
show
_developers_decorate_translations uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
173
	foreach ($GLOBALS['_ELGG']->translations[$language] as $key => &$value) {
174
		$needle = " ($key)";
175
		
176
		// if $value doesn't already end with " ($key)", append it
177
		if (substr($value, -strlen($needle)) !== $needle) {
178
			$value .= $needle;
179
		}
180
	}
181
}
182
183
/**
184
 * Post-process a view to add wrapper comments to it
185
 *
186
 * 1. Only process views served with the 'default' viewtype.
187
 * 2. Does not wrap views that are not HTML.
188
 * 4. Does not wrap input and output views (why?).
189
 * 5. Does not wrap html head or the primary page shells
190
 *
191
 * @warning this will break views in the default viewtype that return non-HTML data
192
 * that do not match the above restrictions.
193
 */
194
function developers_wrap_views($hook, $type, $result, $params) {
195
	if (elgg_get_viewtype() != "default") {
196
		return;
197
	}
198
199
	$excluded_bases = ['resources', 'input', 'output', 'embed', 'icon', 'json', 'xml'];
200
201
	$excluded_views = [
202
		'page/default',
203
		'page/admin',
204
		'page/elements/head',
205
	];
206
207
	$view = $params['view'];
208
209
	$view_hierarchy = explode('/', $view);
210
	if (in_array($view_hierarchy[0], $excluded_bases)) {
211
		return;
212
	}
213
214
	if (in_array($view, $excluded_views)) {
215
		return;
216
	}
217
	
218
	if ((new \SplFileInfo($view))->getExtension()) {
219
		return;
220
	}
221
222
	if ($result) {
223
		$result = "<!-- developers:begin $view -->$result<!-- developers:end $view -->";
224
	}
225
226
	return $result;
227
}
228
229
/**
230
 * Log the events and plugin hooks
231
 */
232
function developers_log_events($name, $type) {
233
234
	// filter out some very common events
235
	if ($name == 'view' || $name == 'display' || $name == 'log' || $name == 'debug') {
236
		return;
237
	}
238
	if ($name == 'session:get' || $name == 'validate') {
239
		return;
240
	}
241
242
	// 0 => this function
243
	// 1 => call_user_func_array
244
	// 2 => hook class trigger
245
	$stack = debug_backtrace();
246
	if (isset($stack[2]['class']) && $stack[2]['class'] == 'Elgg\EventsService') {
247
		$event_type = 'Event';
248
	} else {
249
		$event_type = 'Plugin hook';
250
	}
251
252
	if ($stack[3]['function'] == 'elgg_trigger_event' || $stack[3]['function'] == 'elgg_trigger_plugin_hook') {
253
		$index = 4;
254
	} else {
255
		$index = 3;
256
	}
257
	if (isset($stack[$index]['class'])) {
258
		$function = $stack[$index]['class'] . '::' . $stack[$index]['function'] . '()';
259
	} else {
260
		$function = $stack[$index]['function'] . '()';
261
	}
262
	if ($function == 'require_once()' || $function == 'include_once()') {
263
		$function = $stack[$index]['file'];
264
	}
265
266
	$msg = elgg_echo('developers:event_log_msg', [
267
		$event_type,
268
		$name,
269
		$type,
270
		$function,
271
	]);
272
	elgg_dump($msg, false);
273
274
	unset($stack);
275
}
276
277
/**
278
 * Serve the theme sandbox pages
279
 *
280
 * @param array $page
281
 * @return bool
282
 */
283
function developers_theme_sandbox_controller($page) {
284
	if (!isset($page[0])) {
285
		forward('theme_sandbox/intro');
286
	}
287
288
	echo elgg_view_resource('theme_sandbox', [
289
		'page' => $page[0],
290
	]);
291
	return true;
292
}
293
294
function developers_ajax_demo_controller() {
295
	echo elgg_view_resource('developers/ajax_demo');
296
	return true;
297
}
298
299
/**
300
 * Get the available inspect options
301
 *
302
 * @return array
303
 */
304
function developers_get_inspect_options() {
305
	$options = [
306
		'Actions' => elgg_echo('developers:inspect:actions'),
307
		'Events' => elgg_echo('developers:inspect:events'),
308
		'Menus' => elgg_echo('developers:inspect:menus'),
309
		'Plugin Hooks' => elgg_echo('developers:inspect:pluginhooks'),
310
		'Simple Cache' => elgg_echo('developers:inspect:simplecache'),
311
		'Views' => elgg_echo('developers:inspect:views'),
312
		'Widgets' => elgg_echo('developers:inspect:widgets'),
313
	];
314
	
315
	if (elgg_is_active_plugin('web_services')) {
316
		$options['Web Services'] = elgg_echo('developers:inspect:webservices');
317
	}
318
	
319
	ksort($options);
320
	
321
	return $options;
322
}
323