Passed
Pull Request — master (#94)
by Matt
02:12
created

acp_controller::save_settings()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 15
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 25
rs 9.7666
1
<?php
2
/**
3
 *
4
 * phpBB Media Embed PlugIn extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2016 phpBB Limited <https://www.phpbb.com>
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace phpbb\mediaembed\controller;
12
13
use phpbb\config\config;
0 ignored issues
show
Bug introduced by
The type phpbb\config\config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use phpbb\config\db_text;
0 ignored issues
show
Bug introduced by
The type phpbb\config\db_text was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use phpbb\language\language;
0 ignored issues
show
Bug introduced by
The type phpbb\language\language was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use phpbb\log\log;
0 ignored issues
show
Bug introduced by
The type phpbb\log\log was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use phpbb\mediaembed\cache\cache as media_cache;
18
use phpbb\request\request;
0 ignored issues
show
Bug introduced by
The type phpbb\request\request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use phpbb\template\template;
0 ignored issues
show
Bug introduced by
The type phpbb\template\template was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use phpbb\textformatter\s9e\factory as textformatter;
0 ignored issues
show
Bug introduced by
The type phpbb\textformatter\s9e\factory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use phpbb\user;
0 ignored issues
show
Bug introduced by
The type phpbb\user was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
23
/**
24
 * phpBB Media Embed ACP module controller.
25
 */
26
class acp_controller implements acp_controller_interface
27
{
28
	/** @var config $config */
29
	protected $config;
30
31
	/** @var db_text $config_text */
32
	protected $config_text;
33
34
	/** @var language $language */
35
	protected $language;
36
37
	/** @var log $log */
38
	protected $log;
39
40
	/** @var media_cache $media_cache */
41
	protected $media_cache;
42
43
	/** @var request $request */
44
	protected $request;
45
46
	/** @var template $template */
47
	protected $template;
48
49
	/** @var textformatter $textformatter */
50
	protected $textformatter;
51
52
	/** @var user $user */
53
	protected $user;
54
55
	/** @var array $enabled_sites */
56
	protected $enabled_sites;
57
58
	/** @var string $u_action */
59
	public $u_action;
60
61
	/** @var array An array of errors */
62
	protected $errors = [];
63
64
	/**
65
	 * Constructor
66
	 */
67
	public function __construct(config $config, db_text $config_text, language $language, log $log, media_cache $media_cache, request $request, template $template, textformatter $textformatter, user $user)
68
	{
69
		$this->config = $config;
70
		$this->config_text = $config_text;
71
		$this->language = $language;
72
		$this->log = $log;
73
		$this->media_cache = $media_cache;
74
		$this->request = $request;
75
		$this->template = $template;
76
		$this->textformatter = $textformatter;
77
		$this->user = $user;
78
79
		$this->language->add_lang('acp', 'phpbb/mediaembed');
80
	}
81
82
	/**
83
	 * Set page url
84
	 *
85
	 * @param string $u_action Custom form action
86
	 */
87
	public function set_page_url($u_action)
88
	{
89
		$this->u_action = $u_action;
90
	}
91
92
	/**
93
	 * Get ACP page title for module
94
	 *
95
	 * @param string $mode
96
	 * @return string Language string for ACP module
97
	 */
98
	public function get_page_title($mode)
99
	{
100
		return $this->language->lang('ACP_MEDIA_' . strtoupper($mode));
101
	}
102
103
	/**
104
	 * Add settings template vars to the form
105
	 */
106
	public function display_settings()
107
	{
108
		$this->template->assign_vars([
109
			'S_MEDIA_EMBED_BBCODE'       => $this->config['media_embed_bbcode'],
110
			'S_MEDIA_EMBED_ALLOW_SIG'    => $this->config['media_embed_allow_sig'],
111
			'S_MEDIA_EMBED_PARSE_URLS'   => $this->config['media_embed_parse_urls'],
112
			'S_MEDIA_EMBED_ENABLE_CACHE' => $this->config['media_embed_enable_cache'],
113
			'S_MEDIA_EMBED_FULL_WIDTH'   => $this->config['media_embed_full_width'],
114
			'S_MEDIA_EMBED_MAX_WIDTHS'   => $this->get_media_embed_max_width(),
115
			'U_ACTION'                   => $this->u_action,
116
		]);
117
	}
118
119
	/**
120
	 * Add manage sites template vars to the form
121
	 */
122
	public function display_manage()
123
	{
124
		$this->template->assign_vars([
125
			'MEDIA_SITES' => $this->get_sites(),
126
			'U_ACTION'    => $this->u_action,
127
			'ERRORS'      => $this->errors,
128
		]);
129
	}
130
131
	/**
132
	 * Save settings data to the database
133
	 *
134
	 * @return array Message and code for trigger error
135
	 */
136
	public function save_settings()
137
	{
138
		$this->config->set('media_embed_bbcode', $this->request->variable('media_embed_bbcode', 0));
139
		$this->config->set('media_embed_allow_sig', $this->request->variable('media_embed_allow_sig', 0));
140
		$this->config->set('media_embed_parse_urls', $this->request->variable('media_embed_parse_urls', 0));
141
		$this->config->set('media_embed_enable_cache', $this->request->variable('media_embed_enable_cache', 0));
142
		$this->config->set('media_embed_full_width', $this->request->variable('media_embed_full_width', 0));
143
144
		$this->set_media_embed_max_width();
145
146
		$this->media_cache->purge_textformatter_cache();
147
148
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_PHPBB_MEDIA_EMBED_SETTINGS');
149
150
		if (count($this->errors))
151
		{
152
			return [
153
				'code' => E_USER_WARNING,
154
				'message' => $this->language->lang('ACP_MEDIA_ERROR_MSG', implode('<br>', $this->errors))
155
			];
156
		}
157
158
		return [
159
			'code' => E_USER_NOTICE,
160
			'message' => $this->language->lang('CONFIG_UPDATED')
161
		];
162
	}
163
164
	/**
165
	 * Save site managed data to the database
166
	 *
167
	 * @return array Message and code for trigger error
168
	 */
169
	public function save_manage()
170
	{
171
		$this->config_text->set('media_embed_sites', json_encode($this->request->variable('mark', [''])));
172
173
		$this->media_cache->purge_textformatter_cache();
174
175
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_PHPBB_MEDIA_EMBED_MANAGE');
176
177
		return [
178
			'code' => E_USER_NOTICE,
179
			'message' => $this->language->lang('CONFIG_UPDATED')
180
		];
181
	}
182
183
	/**
184
	 * Purge all Media Embed cache files
185
	 */
186
	public function purge_mediaembed_cache()
187
	{
188
		$this->media_cache->purge_mediaembed_cache();
189
190
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_PHPBB_MEDIA_EMBED_CACHE_PURGED');
191
192
		return [
193
			'code' => E_USER_NOTICE,
194
			'message' => $this->language->lang('PURGE_CACHE_SUCCESS')
195
		];
196
197
	}
198
199
	/**
200
	 * Get a list of available sites
201
	 *
202
	 * @return array An array of available sites
203
	 */
204
	protected function get_sites()
205
	{
206
		$sites = [];
207
208
		$configurator = $this->textformatter->get_configurator();
209
		foreach ($configurator->MediaEmbed->defaultSites as $siteId => $siteConfig)
210
		{
211
			$disabled = isset($configurator->BBCodes[$siteId]);
212
			$sites[$siteId] = [
213
				'id'       => $siteId,
214
				'name'     => $siteConfig['name'],
215
				'title'    => $this->language->lang($disabled ? 'ACP_MEDIA_SITE_DISABLED' : 'ACP_MEDIA_SITE_TITLE', $siteId),
216
				'enabled'  => in_array($siteId, $this->get_enabled_sites()),
217
				'disabled' => $disabled,
218
			];
219
		}
220
221
		ksort($sites);
222
223
		$this->errors = array_diff($this->get_enabled_sites(), array_keys($sites));
224
225
		return $sites;
226
	}
227
228
	/**
229
	 * Get enabled media sites stored in the database
230
	 *
231
	 * @return array An array of enabled sites
232
	 */
233
	protected function get_enabled_sites()
234
	{
235
		if ($this->enabled_sites === null)
236
		{
237
			$sites = json_decode($this->config_text->get('media_embed_sites'), true);
238
			$this->enabled_sites = is_array($sites) ? $sites : [];
239
		}
240
241
		return $this->enabled_sites;
242
	}
243
244
	/**
245
	 * Store the media embed max width value to the config text as JSON,
246
	 * with some basic input validation and array formatting.
247
	 */
248
	protected function set_media_embed_max_width()
249
	{
250
		$input = $this->request->variable('media_embed_max_width', '');
251
252
		if ($input)
253
		{
254
			$lines = array_unique(explode("\n", $input));
255
256
			foreach ($lines as $key => $line)
257
			{
258
				$parts = explode(':', $line);
259
				if (count($parts) !== 2)
260
				{
261
					unset($lines[$key]);
262
					continue;
263
				}
264
265
				$lines[$key] = array_combine(['site', 'width'], array_map('trim', $parts));
266
			}
267
268
			$input = json_encode(array_filter($lines, [$this, 'validate']));
269
		}
270
271
		$this->config_text->set('media_embed_max_width', strtolower($input));
272
	}
273
274
	/**
275
	 * Get the stored media embed max width data from config text and convert
276
	 * from JSON to the formatting used in the ACP textarea field.
277
	 *
278
	 * @return string
279
	 */
280
	protected function get_media_embed_max_width()
281
	{
282
		$config = json_decode($this->config_text->get('media_embed_max_width'), true);
283
284
		if ($config)
285
		{
286
			foreach ($config as &$item)
287
			{
288
				$item = implode(':', $item);
289
			}
290
291
			unset($item);
292
		}
293
294
		return $config ? implode("\n", $config) : '';
295
	}
296
297
	/**
298
	 * Validate the input for media embed max widths
299
	 * 'site' key value should be a word
300
	 * 'width' key value should be a number appended with either px or %
301
	 *
302
	 * @param array $input The array to check
303
	 * @return bool True if array contains valid values, false if not
304
	 * @throws \Exception
305
	 */
306
	protected function validate($input)
307
	{
308
		// First, lets get all the available media embed site IDs
309
		static $default_sites;
310
311
		if (null === $default_sites)
312
		{
313
			$configurator = $this->textformatter->get_configurator();
314
			$default_sites = array_keys(iterator_to_array($configurator->MediaEmbed->defaultSites));
315
		}
316
317
		// Next create an array to hold any errors
318
		$errors = [];
319
320
		// Check to see if the site id provided exists in Media Embed
321
		if (!in_array($input['site'], $default_sites))
322
		{
323
			$errors[] = $this->language->lang('ACP_MEDIA_INVALID_SITE', $input['site'], $input['width']);
324
		}
325
326
		// Check to see if the width provided is a valid number followed px or %
327
		if (!preg_match('/^\d+(?:%|px)$/', $input['width']))
328
		{
329
			$errors[] = $this->language->lang('ACP_MEDIA_INVALID_WIDTH', $input['site'], $input['width']);
330
		}
331
332
		// Update the errors object with any new errors
333
		$this->errors = array_merge($this->errors, $errors);
334
335
		return empty($errors);
336
	}
337
}
338