Passed
Push — templating ( 0cf8c2 )
by Daniel
20:43
created

services/blocks/config/cfg_handler.php (1 issue)

1
<?php
2
3
/**
4
 *
5
 * @package sitemaker
6
 * @copyright (c) 2015 Daniel A. (blitze)
7
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
8
 *
9
 */
10
11
namespace blitze\sitemaker\services\blocks\config;
12
13
class cfg_handler
14
{
15
	/** @var \phpbb\request\request_interface */
16
	protected $request;
17
18
	/** @var \phpbb\template\template */
19
	protected $template;
20
21
	/** @var \phpbb\language\language */
22
	protected $translator;
23
24
	/** @var \blitze\sitemaker\services\blocks\config\cfg_factory */
25
	protected $cfg_fields_factory;
26
27
	/** @var \blitze\sitemaker\services\groups */
28
	protected $groups;
29
30
	/** @var string phpBB root path */
31
	protected $phpbb_root_path;
32
33
	/** @var string phpEx */
34
	protected $php_ext;
35
36
	/**
37
	 * Constructor
38
	 *
39
	 * @param \phpbb\request\request_interface						$request				Request object
40
	 * @param \phpbb\template\template								$template				Template object
41
	 * @param \phpbb\language\language								$translator				Language object
42
	 * @param \blitze\sitemaker\services\blocks\config\cfg_factory	$cfg_fields_factory		Block config fields factory
43
	 * @param \blitze\sitemaker\services\groups						$groups					Groups object
44
	 * @param string												$phpbb_root_path		phpBB root path
45
	 * @param string												$php_ext				phpEx
46
	 */
47
	public function __construct(\phpbb\request\request_interface $request, \phpbb\template\template $template, \phpbb\language\language $translator, \blitze\sitemaker\services\blocks\config\cfg_factory $cfg_fields_factory, \blitze\sitemaker\services\groups $groups, $phpbb_root_path, $php_ext)
48
	{
49
		$this->request = $request;
50
		$this->template = $template;
51
		$this->translator = $translator;
52
		$this->cfg_fields_factory = $cfg_fields_factory;
53
		$this->groups = $groups;
54
		$this->phpbb_root_path = $phpbb_root_path;
55
		$this->php_ext = $php_ext;
56
	}
57
58
	/**
59
	 * @param array $block_data
60
	 * @param array $default_settings
61
	 * @return mixed
62
	 */
63
	public function get_edit_form(array $block_data, array $default_settings)
64
	{
65
		// @codeCoverageIgnoreStart
66
		if (!function_exists('build_cfg_template'))
67
		{
68
			include($this->phpbb_root_path . 'includes/functions_acp.' . $this->php_ext);
69
		}
70
		// @codeCoverageIgnoreEnd
71
72
		$this->generate_config_fields($block_data['settings'], $default_settings);
73
74
		return $this->get_form($block_data);
75
	}
76
77
	/**
78
	 * @param array $default_settings
79
	 * @return array
80
	 */
81
	public function get_submitted_settings(array $default_settings)
82
	{
83
		$cfg_array = $this->request->variable('config', array('' => ''), true);
84
		$cfg_array = $this->decode_source_html($cfg_array);
85
		$errors = $this->validate_block_settings($default_settings, $cfg_array);
86
87
		if (sizeof($errors))
88
		{
89
			throw new \Exception(join("\n", $errors));
90
		}
91
92
		$this->get_multi_select($cfg_array, $default_settings);
93
94
		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
	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
		$errors = array();
112
		validate_config_vars($default_settings, $cfg_array, $errors);
113
114
		return $errors;
115
	}
116
117
	/**
118
	 * As a workaround to prevent mod_security and similar from preventing us from posting html/script,
119
	 * we use encodeURI before submitting data via ajax (see develop/blocks/manager.js).
120
	 * This decodes the data before submitting to the database
121
	 *
122
	 * @param array $cfg_array
123
	 * @return array
124
	 */
125
	private function decode_source_html(array $cfg_array)
126
	{
127
		if (isset($cfg_array['source']))
128
		{
129
			$cfg_array['source'] = rawurldecode($cfg_array['source']);
130
		}
131
132
		return $cfg_array;
133
	}
134
135
	/**
136
	 * Get the html form
137
	 *
138
	 * @param array $block_data
139
	 * @return mixed
140
	 */
141
	private function get_form(array $block_data)
142
	{
143
		$selected_groups = cfg_utils::ensure_array($block_data['permission']);
144
145
		$this->template->assign_vars(array(
146
			'S_BLOCK_ID'	=> $block_data['bid'],
147
			'S_ACTIVE'		=> $block_data['status'],
148
			'S_TYPE'		=> $block_data['type'],
149
			'S_VIEW'		=> $block_data['view'],
150
			'S_HIDE_TITLE'	=> $block_data['hide_title'],
151
			'S_BLOCK_CLASS'	=> trim($block_data['class']),
152
			'S_GROUP_OPS'	=> $this->groups->get_options('all', $selected_groups),
153
		));
154
155
		$this->template->set_filenames(array(
156
			'block_settings' => 'block_settings.html',
157
		));
158
159
		return $this->template->assign_display('block_settings');
160
	}
161
162
	/**
163
	 * Generate block configuration fields
164
	 *
165
	 * @param array $db_settings
166
	 * @param array $default_settings
167
	 */
168
	private function generate_config_fields(array &$db_settings, array $default_settings)
169
	{
170
		foreach ($default_settings as $field => $vars)
171
		{
172
			if (!$this->is_input_field($field, $vars))
173
			{
174
				continue;
175
			}
176
177
			// set some defaults for optional props
178
			$vars += array(
179
				'explain'		=> false,
180
				'lang_explain'	=> '',
181
				'lang'			=> '', // optional for hidden field type
182
			);
183
184
			$db_settings[$field] = $this->get_field_value($field, $vars['default'], $db_settings);
185
186
			$this->template->assign_block_vars('cfg_fields', array_merge(
187
				$this->get_field_template($field, $db_settings, $vars),
188
				array(
189
					'KEY'			=> $field,
190
					'TITLE'			=> $this->translator->lang($vars['lang']),
191
					'S_EXPLAIN'		=> $vars['explain'],
192
					'TITLE_EXPLAIN'	=> $vars['lang_explain'],
193
				)
194
			));
195
		}
196
	}
197
198
	/**
199
	 * Get the field html
200
	 *
201
	 * @param string $field
202
	 * @param array $db_settings
203
	 * @param array $vars
204
	 * @return []
0 ignored issues
show
Documentation Bug introduced by
The doc comment [] at position 0 could not be parsed: Unknown type name '[' at position 0 in [].
Loading history...
205
	 */
206
	private function get_field_template($field, array &$db_settings, array &$vars)
207
	{
208
		global $module;
209
210
		$vars['lang_explain'] = $this->explain_field($vars);
211
		$append = $this->append_field($vars);
212
213
		/**
214
		 * as our own custom fields return an array while phpbb expects a string
215
		 * and appends to that string, we remove it here to prevent an error
216
		 */
217
		unset($vars['append']);
218
219
		$type = explode(':', $vars['type']);
220
		$object = $this->get_field_object($vars, $type, $db_settings, $field);
221
222
		$tpl_data = array(
223
			'append'	=> $append,
224
		);
225
226
		// We fake this class as it is needed by the build_cfg_template function
227
		$module = new \stdClass();
228
		$module->module = $object;
229
230
		$tpl = build_cfg_template($type, $field, $db_settings, $field, $vars);
231
232
		if (is_array($tpl) && $object instanceof \blitze\sitemaker\services\blocks\config\fields\cfg_field_interface)
233
		{
234
			$tpl_data['template'] = $object->get_template();
235
			$tpl_data['tpl_data'] = $tpl;
236
		}
237
		else
238
		{
239
			$tpl_data['content'] = $tpl;
240
		}
241
242
		return array_change_key_case($tpl_data, CASE_UPPER);
243
	}
244
245
	/**
246
	 * @param array $vars
247
	 * @param array $type
248
	 * @param array $db_settings
249
	 * @param string $field
250
	 * @return object
251
	 */
252
	private function get_field_object(array &$vars, array &$type, array &$db_settings, $field)
253
	{
254
		if (empty($vars['object']))
255
		{
256
			if (($object = $this->cfg_fields_factory->get($type[0])) !== false)
257
			{
258
				$this->set_params($field, $vars, $db_settings);
259
				$object->prep_field($vars, $type, $field, $db_settings);
260
			}
261
		}
262
		else
263
		{
264
			$object = $vars['object'];
265
			$this->set_params($field, $vars, $db_settings);
266
		}
267
268
		return $object;
269
	}
270
271
	/**
272
	 * Set field legend
273
	 *
274
	 * @param string $field
275
	 * @param string|array $vars
276
	 * @return boolean
277
	 */
278
	private function is_input_field($field, $vars)
279
	{
280
		return ($this->set_legend($field, $vars) || !is_array($vars)) ? false : true;
281
	}
282
283
	/**
284
	 * Set field legend
285
	 *
286
	 * @param string $field
287
	 * @param string|array $vars
288
	 * @return boolean
289
	 */
290
	private function set_legend($field, $vars)
291
	{
292
		if (strpos($field, 'legend') !== false)
293
		{
294
			$this->template->assign_block_vars('cfg_fields', array(
295
				'S_LEGEND'	=> $field,
296
				'LEGEND'	=> $this->translator->lang($vars)
297
			));
298
299
			return true;
300
		}
301
302
		return false;
303
	}
304
305
	/**
306
	 * Get field details
307
	 *
308
	 * @param array $vars
309
	 * @return mixed|string
310
	 */
311
	private function explain_field(array $vars)
312
	{
313
		$l_explain = '';
314
		if (!empty($vars['explain']))
315
		{
316
			$l_explain = (!empty($vars['lang_explain'])) ? $this->translator->lang($vars['lang_explain']) : $this->translator->lang($vars['lang'] . '_EXPLAIN');
317
		}
318
319
		return $l_explain;
320
	}
321
322
	/**
323
	 * Add text after field
324
	 *
325
	 * @param array $vars
326
	 * @return mixed|string
327
	 */
328
	private function append_field(array $vars)
329
	{
330
		$append = '';
331
		if (!empty($vars['append']))
332
		{
333
			$append = $this->translator->lang($vars['append']);
334
		}
335
336
		return $append;
337
	}
338
339
	/**
340
	 * Set field parameters
341
	 *
342
	 * @param string $field
343
	 * @param array $vars
344
	 * @param array $settings
345
	 */
346
	private function set_params($field, array &$vars, array $settings)
347
	{
348
		if (isset($vars['options']))
349
		{
350
			$vars['params'][] = $vars['options'];
351
			$vars['params'][] = $settings[$field];
352
		}
353
	}
354
355
	/**
356
	 * Get field value
357
	 *
358
	 * @param string $field
359
	 * @param mixed $default
360
	 * @param array $db_settings
361
	 * @return mixed
362
	 */
363
	private function get_field_value($field, $default, array $db_settings)
364
	{
365
		return (isset($db_settings[$field])) ? $db_settings[$field] : $default;
366
	}
367
368
	/**
369
	 * @param array $cfg_array
370
	 * @param array $df_settings
371
	 */
372
	private function get_multi_select(array &$cfg_array, array $df_settings)
373
	{
374
		$multi_select = $this->request->variable('config', array('' => array(0 => '')), true);
375
		$multi_select = array_filter($multi_select);
376
377
		foreach ($multi_select as $field => $settings)
378
		{
379
			$cfg_array[$field] = (!empty($settings)) ? $settings : $df_settings[$field]['default'];
380
		}
381
	}
382
}
383