Completed
Push — master ( db8e66...00afbe )
by Daniel
09:03
created

cfg_handler::explain_field()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 1
crap 3
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\user */
21
	protected $user;
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\user							$user					User 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 51
	public function __construct(\phpbb\request\request_interface $request, \phpbb\template\template $template, \phpbb\user $user, \blitze\sitemaker\services\groups $groups, $phpbb_root_path, $php_ext)
43
	{
44 51
		parent::__construct($user);
45
46 51
		$this->request = $request;
47 51
		$this->template = $template;
48 51
		$this->user = $user;
49 51
		$this->groups = $groups;
50 51
		$this->phpbb_root_path = $phpbb_root_path;
51 51
		$this->php_ext = $php_ext;
52 51
	}
53
54
	/**
55
	 * @param array $block_data
56
	 * @param array $default_settings
57
	 * @return string
58
	 */
59 8
	public function get_edit_form(array $block_data, array $default_settings)
60
	{
61 8
		global $module;
62
63 8
		if (!function_exists('build_cfg_template'))
64 8
		{
65
			include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext); // @codeCoverageIgnore
66 1
		}
67
68
		// We fake this class as it is needed by the build_cfg_template function
69 8
		$module = new \stdClass();
70 8
		$module->module = $this;
71
72 8
		$this->generate_config_fields($block_data['settings'], $default_settings);
73
74 8
		return $this->get_form($block_data);
75
	}
76
77
	/**
78
	 * @param array $default_settings
79
	 * @return array|void
80
	 */
81 6
	public function get_submitted_settings(array $default_settings)
82
	{
83 6
		$cfg_array = utf8_normalize_nfc($this->request->variable('config', array('' => ''), true));
84 6
		$cfg_array = $this->decode_source_html($cfg_array);
85 6
		$errors = $this->validate_block_settings($default_settings, $cfg_array);
86
87 6
		if (sizeof($errors))
88 6
		{
89 1
			return array('errors' => join("\n", $errors));
90
		}
91
92 5
		$this->get_multi_select($cfg_array, $default_settings);
93
94 5
		return array_intersect_key($cfg_array, $default_settings);
95
	}
96
97
	/**
98
	 * @param array $default_settings
99
	 * @param array $cfg_array
100
	 * @return array
101
	 */
102 6
	protected function validate_block_settings(array $default_settings, array $cfg_array)
103
	{
104
		// @codeCoverageIgnoreStart
105
		if (!function_exists('validate_config_vars'))
106
		{
107
			include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext);
108
		}
109
		// @codeCoverageIgnoreEnd
110
111 6
		$errors = array();
112 6
		validate_config_vars($default_settings, $cfg_array, $errors);
113
114 6
		return $errors;
115
	}
116
117
	/**
118
	 * As a workaround to prevent mod_security and similar from preventing us
119
	 * from posting html/script, we use encodeURI before submitting data.
120
	 * This decodes the data before submitting to the database
121
	 *
122
	 * @param array $cfg_array
123
	 * @return array
124
	 */
125 6
	private function decode_source_html(array $cfg_array)
126
	{
127 6
		if (isset($cfg_array['source']))
128 6
		{
129
			$cfg_array['source'] = urldecode($cfg_array['source']);
130
		}
131
132 6
		return $cfg_array;
133
	}
134
135
	/**
136
	 * Get the html form
137
	 *
138
	 * @param array $block_data
139
	 * @return string
140
	 */
141 8
	private function get_form(array $block_data)
142
	{
143 8
		$selected_groups = $this->ensure_array($block_data['permission']);
144
145 8
		$this->template->assign_vars(array(
146 8
			'S_ACTIVE'		=> $block_data['status'],
147 8
			'S_TYPE'		=> $block_data['type'],
148 8
			'S_NO_WRAP'		=> $block_data['no_wrap'],
149 8
			'S_HIDE_TITLE'	=> $block_data['hide_title'],
150 8
			'S_BLOCK_CLASS'	=> trim($block_data['class']),
151 8
			'S_GROUP_OPS'	=> $this->groups->get_options('all', $selected_groups),
152 8
		));
153
154 8
		$this->template->set_filenames(array(
155 8
			'block_settings' => 'block_settings.html',
156 8
		));
157
158 8
		return $this->template->assign_display('block_settings');
159
	}
160
161
	/**
162
	 * Generate block configuration fields
163
	 *
164
	 * @param array $db_settings
165
	 * @param array $default_settings
166
	 */
167 8
	private function generate_config_fields(array &$db_settings, array $default_settings)
168
	{
169 8
		foreach ($default_settings as $field => $vars)
170
		{
171 7
			if ($this->set_legend($field, $vars) || !is_array($vars))
172 7
			{
173 7
				continue;
174
			}
175
176 7
			$db_settings[$field] = $this->get_field_value($field, $vars['default'], $db_settings);
177 7
			$content = $this->get_field_template($field, $db_settings, $vars);
178
179 7
			$this->template->assign_block_vars('options', array(
180 7
				'KEY'			=> $field,
181 7
				'TITLE'			=> $this->user->lang($vars['lang']),
182 7
				'S_EXPLAIN'		=> $vars['explain'],
183 7
				'TITLE_EXPLAIN'	=> $vars['lang_explain'],
184 7
				'CONTENT'		=> $content,
185 7
			));
186 7
			unset($default_settings[$field]);
187 8
		}
188 8
	}
189
190
	/**
191
	 * Get the field html
192
	 *
193
	 * @param string $field
194
	 * @param array $db_settings
195
	 * @param array $vars
196
	 * @return string
197
	 */
198 7
	private function get_field_template($field, array &$db_settings, array &$vars)
199
	{
200 7
		$vars['lang_explain'] = $this->explain_field($vars);
201 7
		$vars['append'] = $this->append_field($vars);
202
203 7
		$type = explode(':', $vars['type']);
204 7
		$method = 'prep_' . $type[0] . '_field_for_display';
205
206 7
		if (is_callable(array($this, $method)))
207 7
		{
208 7
			$this->set_params($field, $vars, $db_settings);
209 7
			$this->$method($vars, $type, $field, $db_settings);
210 7
		}
211
212 7
		return build_cfg_template($type, $field, $db_settings, $field, $vars);
213
	}
214
215
	/**
216
	 * Set field legend
217
	 *
218
	 * @param string $field
219
	 * @param string|array $vars
220
	 * @return boolean
221
	 */
222 7
	private function set_legend($field, $vars)
223
	{
224 7
		if (strpos($field, 'legend') !== false)
225 7
		{
226 7
			$this->template->assign_block_vars('options', array(
227 7
				'S_LEGEND'	=> $field,
228 7
				'LEGEND'	=> $this->user->lang($vars)
229 7
			));
230
231 7
			return true;
232
		}
233
234 7
		return false;
235
	}
236
237
	/**
238
	 * Get field details
239
	 *
240
	 * @param array $vars
241
	 * @return mixed|string
242
	 */
243 7
	private function explain_field(array $vars)
244
	{
245 7
		$l_explain = '';
246 7
		if (!empty($vars['explain']))
247 7
		{
248 2
			$l_explain = (isset($vars['lang_explain'])) ? $this->user->lang($vars['lang_explain']) : $this->user->lang($vars['lang'] . '_EXPLAIN');
249 2
		}
250
251 7
		return $l_explain;
252
	}
253
254
	/**
255
	 * Add text after field
256
	 *
257
	 * @param array $vars
258
	 * @return mixed|string
259
	 */
260 7
	private function append_field(array $vars)
261
	{
262 7
		$append = '';
263 7
		if (!empty($vars['append']))
264 7
		{
265 1
			$append = $this->user->lang($vars['append']);
266 1
		}
267
268 7
		return $append;
269
	}
270
271
	/**
272
	 * Set field parameters
273
	 *
274
	 * @param string $field
275
	 * @param array $vars
276
	 * @param array $settings
277
	 */
278 7
	private function set_params($field, array &$vars, array $settings)
279
	{
280 7
		if (isset($vars['options']))
281 7
		{
282 4
			$vars['params'][] = $vars['options'];
283 4
			$vars['params'][] = $settings[$field];
284 4
		}
285 7
	}
286
287
	/**
288
	 * Get field value
289
	 *
290
	 * @param string $field
291
	 * @param mixed $default
292
	 * @param array $db_settings
293
	 * @return mixed
294
	 */
295 7
	private function get_field_value($field, $default, array $db_settings)
296
	{
297 7
		return (isset($db_settings[$field])) ? $db_settings[$field] : $default;
298
	}
299
300
	/**
301
	 * @param array $vars
302
	 */
303 1
	private function prep_select_field_for_display(array &$vars)
304
	{
305 1
		$this->add_lang_vars($vars['params'][0]);
306
307 1
		$vars['function'] = (!empty($vars['function'])) ? $vars['function'] : 'build_select';
308 1
	}
309
310
	/**
311
	 * @param array $vars
312
	 * @param array $type
313
	 * @param string $field
314
	 */
315 3
	private function prep_checkbox_field_for_display(array &$vars, array &$type, $field)
316
	{
317 2
		$this->add_lang_vars($vars['params'][0]);
318
319 3
		$vars['method'] = 'build_checkbox';
320 2
		$vars['params'][] = $field;
321 2
		$type[0] = 'custom';
322 2
	}
323
324
	/**
325
	 * @param array $vars
326
	 * @param array $type
327
	 * @param string $field
328
	 */
329 2
	private function prep_radio_field_for_display(array &$vars, array &$type, $field)
330
	{
331 2
		if (!isset($type[1]))
332 2
		{
333 1
			$this->add_lang_vars($vars['params'][0]);
334
335 1
			$vars['method'] = 'build_radio';
336 1
			$vars['params'][] = $field;
337 1
			$type[0] = 'custom';
338 1
		}
339 2
	}
340
341
	/**
342
	 * @param array $vars
343
	 * @param array $type
344
	 * @param string $field
345
	 */
346 1
	private function prep_multi_select_field_for_display(array &$vars, array &$type, $field)
347
	{
348 1
		$this->prep_checkbox_field_for_display($vars, $type, $field);
349
350 1
		$vars['method'] ='build_multi_select';
351 1
	}
352
353
	/**
354
	 * @param array $vars
355
	 * @param array $type
356
	 */
357 1
	private function prep_hidden_field_for_display(array &$vars, array &$type)
358
	{
359 1
		$vars['method'] = 'build_hidden';
360 1
		$vars['explain'] = '';
361 1
		$vars['lang'] = '';
362 1
		$type[0] = 'custom';
363 1
	}
364
365
	/**
366
	 * @param array $vars
367
	 * @param array $type
368
	 */
369 1
	private function prep_custom_field_for_display(array &$vars, array &$type)
370
	{
371 1
		$vars['function'] = (!empty($vars['function'])) ? $vars['function'] : '';
372 1
		$type[0] = 'custom';
373 1
	}
374
375
	/**
376
	 * this looks bad but its the only way without modifying phpbb code
377
	 * this is for select items that do not need to be translated
378
	 * @param array $options
379
	 */
380 4
	private function add_lang_vars(array $options)
381
	{
382 4
		foreach ($options as $title)
383
		{
384 4
			if (!isset($this->user->lang[$title]))
385 4
			{
386 4
				$this->user->lang[$title] = $title;
387 4
			}
388 4
		}
389 4
	}
390
391
	/**
392
	 * @param array $cfg_array
393
	 * @param array $df_settings
394
	 */
395 5
	private function get_multi_select(array &$cfg_array, array $df_settings)
396
	{
397 5
		$multi_select = utf8_normalize_nfc($this->request->variable('config', array('' => array('' => '')), true));
398 5
		$multi_select = array_filter($multi_select);
399
400 5
		foreach ($multi_select as $field => $settings)
401
		{
402 1
			$cfg_array[$field] = (!empty($settings)) ? $settings : $df_settings[$field]['default'];
403 5
		}
404 5
	}
405
}
406