Passed
Push — release-3.2.0 ( 0c5bd3...24bcfb )
by Daniel
11:19 queued 06:31
created

cfg_handler   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 439
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 127
dl 0
loc 439
rs 8.8798
c 0
b 0
f 0
wmc 44

23 Methods

Rating   Name   Duplication   Size   Complexity  
A prep_checkbox_field_for_display() 0 5 1
A get_field_value() 0 3 2
A append_field() 0 9 2
A generate_config_fields() 0 25 3
A prep_radio_field_for_display() 0 7 2
A get_field_object() 0 20 3
A set_params() 0 6 2
A set_legend() 0 13 2
A get_edit_form() 0 12 2
A get_field_template() 0 14 1
A get_form() 0 19 1
A __construct() 0 10 1
A prep_select_field_for_display() 0 11 1
A is_input_field() 0 3 3
A decode_source_html() 0 8 2
A explain_field() 0 9 3
A validate_block_settings() 0 13 2
A get_submitted_settings() 0 14 2
A prep_hidden_field_for_display() 0 3 1
A prep_custom_field_for_display() 0 4 2
A get_multi_select() 0 8 3
A prep_multi_select_field_for_display() 0 5 1
A prep_code_field_for_display() 0 12 2

How to fix   Complexity   

Complex Class

Complex classes like cfg_handler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use cfg_handler, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *
4
 * @package sitemaker
5
 * @copyright (c) 2015 Daniel A. (blitze)
6
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
 *
8
 */
9
10
namespace blitze\sitemaker\services\blocks;
11
12
class cfg_handler extends cfg_fields
13
{
14
	/** @var \phpbb\request\request_interface */
15
	protected $request;
16
17
	/** @var \phpbb\template\template */
18
	protected $template;
19
20
	/** @var \phpbb\language\language */
21
	protected $translator;
22
23
	/** @var \blitze\sitemaker\services\groups */
24
	protected $groups;
25
26
	/** @var string phpBB root path */
27
	protected $phpbb_root_path;
28
29
	/** @var string phpEx */
30
	protected $php_ext;
31
32
	/**
33
	 * Constructor
34
	 *
35
	 * @param \phpbb\request\request_interface		$request				Request object
36
	 * @param \phpbb\template\template				$template				Template object
37
	 * @param \phpbb\language\language				$translator				Language object
38
	 * @param \blitze\sitemaker\services\groups		$groups					Groups object
39
	 * @param string								$phpbb_root_path		phpBB root path
40
	 * @param string								$php_ext				phpEx
41
	 */
42
	public function __construct(\phpbb\request\request_interface $request, \phpbb\template\template $template, \phpbb\language\language $translator, \blitze\sitemaker\services\groups $groups, $phpbb_root_path, $php_ext)
43
	{
44
		parent::__construct($translator);
45
46
		$this->request = $request;
47
		$this->template = $template;
48
		$this->translator = $translator;
49
		$this->groups = $groups;
50
		$this->phpbb_root_path = $phpbb_root_path;
51
		$this->php_ext = $php_ext;
52
	}
53
54
	/**
55
	 * @param array $block_data
56
	 * @param array $default_settings
57
	 * @return mixed
58
	 */
59
	public function get_edit_form(array $block_data, array $default_settings)
60
	{
61
		// @codeCoverageIgnoreStart
62
		if (!function_exists('build_cfg_template'))
63
		{
64
			include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext);
65
		}
66
		// @codeCoverageIgnoreEnd
67
68
		$this->generate_config_fields($block_data['settings'], $default_settings);
69
70
		return $this->get_form($block_data);
71
	}
72
73
	/**
74
	 * @param array $default_settings
75
	 * @return array
76
	 */
77
	public function get_submitted_settings(array $default_settings)
78
	{
79
		$cfg_array = $this->request->variable('config', array('' => ''), true);
80
		$cfg_array = $this->decode_source_html($cfg_array);
81
		$errors = $this->validate_block_settings($default_settings, $cfg_array);
82
83
		if (sizeof($errors))
84
		{
85
			throw new \Exception(join("\n", $errors));
86
		}
87
88
		$this->get_multi_select($cfg_array, $default_settings);
89
90
		return array_intersect_key($cfg_array, $default_settings);
91
	}
92
93
	/**
94
	 * @param array $default_settings
95
	 * @param array $cfg_array
96
	 * @return array
97
	 */
98
	protected function validate_block_settings(array $default_settings, array $cfg_array)
99
	{
100
		// @codeCoverageIgnoreStart
101
		if (!function_exists('validate_config_vars'))
102
		{
103
			include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext);
104
		}
105
		// @codeCoverageIgnoreEnd
106
107
		$errors = array();
108
		validate_config_vars($default_settings, $cfg_array, $errors);
109
110
		return $errors;
111
	}
112
113
	/**
114
	 * As a workaround to prevent mod_security and similar from preventing us from posting html/script,
115
	 * we use encodeURI before submitting data via ajax (see develop/blocks/manager.js).
116
	 * This decodes the data before submitting to the database
117
	 *
118
	 * @param array $cfg_array
119
	 * @return array
120
	 */
121
	private function decode_source_html(array $cfg_array)
122
	{
123
		if (isset($cfg_array['source']))
124
		{
125
			$cfg_array['source'] = rawurldecode($cfg_array['source']);
126
		}
127
128
		return $cfg_array;
129
	}
130
131
	/**
132
	 * Get the html form
133
	 *
134
	 * @param array $block_data
135
	 * @return mixed
136
	 */
137
	private function get_form(array $block_data)
138
	{
139
		$selected_groups = $this->ensure_array($block_data['permission']);
140
141
		$this->template->assign_vars(array(
142
			'S_BLOCK_ID'	=> $block_data['bid'],
143
			'S_ACTIVE'		=> $block_data['status'],
144
			'S_TYPE'		=> $block_data['type'],
145
			'S_VIEW'		=> $block_data['view'],
146
			'S_HIDE_TITLE'	=> $block_data['hide_title'],
147
			'S_BLOCK_CLASS'	=> trim($block_data['class']),
148
			'S_GROUP_OPS'	=> $this->groups->get_options('all', $selected_groups),
149
		));
150
151
		$this->template->set_filenames(array(
152
			'block_settings' => 'block_settings.html',
153
		));
154
155
		return $this->template->assign_display('block_settings');
156
	}
157
158
	/**
159
	 * Generate block configuration fields
160
	 *
161
	 * @param array $db_settings
162
	 * @param array $default_settings
163
	 */
164
	private function generate_config_fields(array &$db_settings, array $default_settings)
165
	{
166
		foreach ($default_settings as $field => $vars)
167
		{
168
			if (!$this->is_input_field($field, $vars))
169
			{
170
				continue;
171
			}
172
173
			// set some defaults for optional props
174
			$vars += array(
175
				'explain'		=> false,
176
				'lang_explain'	=> '',
177
				'lang'			=> '', // optional for hidden field type
178
			);
179
180
			$db_settings[$field] = $this->get_field_value($field, $vars['default'], $db_settings);
181
			$content = $this->get_field_template($field, $db_settings, $vars);
182
183
			$this->template->assign_block_vars('options', array(
184
				'KEY'			=> $field,
185
				'TITLE'			=> $this->translator->lang($vars['lang']),
186
				'S_EXPLAIN'		=> $vars['explain'],
187
				'TITLE_EXPLAIN'	=> $vars['lang_explain'],
188
				'CONTENT'		=> $content,
189
			));
190
		}
191
	}
192
193
	/**
194
	 * Get the field html
195
	 *
196
	 * @param string $field
197
	 * @param array $db_settings
198
	 * @param array $vars
199
	 * @return string
200
	 */
201
	private function get_field_template($field, array &$db_settings, array &$vars)
202
	{
203
		global $module;
204
205
		$vars['lang_explain'] = $this->explain_field($vars);
206
		$vars['append'] = $this->append_field($vars);
207
208
		$type = explode(':', $vars['type']);
209
210
		// We fake this class as it is needed by the build_cfg_template function
211
		$module = new \stdClass();
212
		$module->module = $this->get_field_object($vars, $type, $db_settings, $field);
213
214
		return build_cfg_template($type, $field, $db_settings, $field, $vars);
215
	}
216
217
	/**
218
	 * @param array $vars
219
	 * @param array $type
220
	 * @param array $db_settings
221
	 * @param string $field
222
	 * @return object
223
	 */
224
	private function get_field_object(array &$vars, array &$type, array &$db_settings, $field)
225
	{
226
		if (empty($vars['object']))
227
		{
228
			$object = $this;
229
			$method = 'prep_' . $type[0] . '_field_for_display';
230
231
			if (is_callable(array($this, $method)))
232
			{
233
				$this->set_params($field, $vars, $db_settings);
234
				$this->$method($vars, $type, $field, $db_settings);
235
			}
236
		}
237
		else
238
		{
239
			$object = $vars['object'];
240
			$this->set_params($field, $vars, $db_settings);
241
		}
242
243
		return $object;
244
	}
245
246
	/**
247
	 * Set field legend
248
	 *
249
	 * @param string $field
250
	 * @param string|array $vars
251
	 * @return boolean
252
	 */
253
	private function is_input_field($field, $vars)
254
	{
255
		return ($this->set_legend($field, $vars) || !is_array($vars)) ? false : true;
256
	}
257
258
	/**
259
	 * Set field legend
260
	 *
261
	 * @param string $field
262
	 * @param string|array $vars
263
	 * @return boolean
264
	 */
265
	private function set_legend($field, $vars)
266
	{
267
		if (strpos($field, 'legend') !== false)
268
		{
269
			$this->template->assign_block_vars('options', array(
270
				'S_LEGEND'	=> $field,
271
				'LEGEND'	=> $this->translator->lang($vars)
272
			));
273
274
			return true;
275
		}
276
277
		return false;
278
	}
279
280
	/**
281
	 * Get field details
282
	 *
283
	 * @param array $vars
284
	 * @return mixed|string
285
	 */
286
	private function explain_field(array $vars)
287
	{
288
		$l_explain = '';
289
		if (!empty($vars['explain']))
290
		{
291
			$l_explain = (!empty($vars['lang_explain'])) ? $this->translator->lang($vars['lang_explain']) : $this->translator->lang($vars['lang'] . '_EXPLAIN');
292
		}
293
294
		return $l_explain;
295
	}
296
297
	/**
298
	 * Add text after field
299
	 *
300
	 * @param array $vars
301
	 * @return mixed|string
302
	 */
303
	private function append_field(array $vars)
304
	{
305
		$append = '';
306
		if (!empty($vars['append']))
307
		{
308
			$append = $this->translator->lang($vars['append']);
309
		}
310
311
		return $append;
312
	}
313
314
	/**
315
	 * Set field parameters
316
	 *
317
	 * @param string $field
318
	 * @param array $vars
319
	 * @param array $settings
320
	 */
321
	private function set_params($field, array &$vars, array $settings)
322
	{
323
		if (isset($vars['options']))
324
		{
325
			$vars['params'][] = $vars['options'];
326
			$vars['params'][] = $settings[$field];
327
		}
328
	}
329
330
	/**
331
	 * Get field value
332
	 *
333
	 * @param string $field
334
	 * @param mixed $default
335
	 * @param array $db_settings
336
	 * @return mixed
337
	 */
338
	private function get_field_value($field, $default, array $db_settings)
339
	{
340
		return (isset($db_settings[$field])) ? $db_settings[$field] : $default;
341
	}
342
343
	/**
344
	 * @param array $vars
345
	 * @param array $type
346
	 * @param string $field
347
	 */
348
	private function prep_select_field_for_display(array &$vars, array &$type, $field)
349
	{
350
		// set defaults for types: field type, size, multi select, toggle key
351
		$type += array('', 1, false, '');
352
353
		$vars['method'] = 'build_select';
354
		$vars['params'][] = $field;
355
		$vars['params'][] = (int) $type[1];		// size
356
		$vars['params'][] = (bool) $type[2];	// multi select
357
		$vars['params'][] = (string) $type[3];	// togggle key
358
		$type[0] = 'custom';
359
	}
360
361
	/**
362
	 * @param array $vars
363
	 * @param array $type
364
	 * @param string $field
365
	 */
366
	private function prep_checkbox_field_for_display(array &$vars, array &$type, $field)
367
	{
368
		$vars['method'] = 'build_checkbox';
369
		$vars['params'][] = $field;
370
		$type[0] = 'custom';
371
	}
372
373
	/**
374
	 * @param array $vars
375
	 * @param array $type
376
	 * @param string $field
377
	 */
378
	private function prep_radio_field_for_display(array &$vars, array &$type, $field)
379
	{
380
		if (!isset($type[1]))
381
		{
382
			$vars['method'] = 'build_radio';
383
			$vars['params'][] = $field;
384
			$type[0] = 'custom';
385
		}
386
	}
387
388
	/**
389
	 * @param array $vars
390
	 * @param array $type
391
	 * @param string $field
392
	 * @param array $db_settings
393
	 */
394
	private function prep_code_field_for_display(array &$vars, array &$type, $field, array $db_settings)
395
	{
396
		if (!isset($type[1]))
397
		{
398
			$vars['method'] = 'build_code_editor';
399
			$vars['params'] = array_reverse(array_filter((array)$vars['params']));
400
			$vars['params'][] = $vars['lang_explain'];
401
			$vars['params'][] = $db_settings[$field];
402
			$vars['params'][] = $field;
403
			$vars['params'] = array_reverse($vars['params']);
404
			
405
			$type[0] = 'custom';
406
		}
407
	}
408
409
	/**
410
	 * @param array $vars
411
	 * @param array $type
412
	 * @param string $field
413
	 */
414
	private function prep_multi_select_field_for_display(array &$vars, array &$type, $field)
415
	{
416
		$this->prep_checkbox_field_for_display($vars, $type, $field);
417
418
		$vars['method'] ='build_multi_select';
419
	}
420
421
	/**
422
	 * @param array $vars
423
	 */
424
	private function prep_hidden_field_for_display(array &$vars)
425
	{
426
		unset($vars);
427
	}
428
429
	/**
430
	 * @param array $vars
431
	 * @param array $type
432
	 */
433
	private function prep_custom_field_for_display(array &$vars, array &$type)
434
	{
435
		$vars['function'] = (!empty($vars['function'])) ? $vars['function'] : '';
436
		$type[0] = 'custom';
437
	}
438
439
	/**
440
	 * @param array $cfg_array
441
	 * @param array $df_settings
442
	 */
443
	private function get_multi_select(array &$cfg_array, array $df_settings)
444
	{
445
		$multi_select = $this->request->variable('config', array('' => array(0 => '')), true);
446
		$multi_select = array_filter($multi_select);
447
448
		foreach ($multi_select as $field => $settings)
449
		{
450
			$cfg_array[$field] = (!empty($settings)) ? $settings : $df_settings[$field]['default'];
451
		}
452
	}
453
}
454