Completed
Pull Request — master (#5)
by Jakub
08:28
created

admin_controller::validate()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
ccs 18
cts 18
cp 1
rs 8.8571
cc 6
eloc 9
nc 16
nop 2
crap 6
1
<?php
2
/**
3
 *
4
 * Advertisement management. An extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2017 phpBB Limited <https://www.phpbb.com>
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace phpbb\admanagement\controller;
12
13
/**
14
* Admin controller
15
*/
16
class admin_controller
17
{
18
	const MAX_NAME_LENGTH = 255;
19
	const DATE_FORMAT = 'Y-m-d';
20
21
	/** @var \phpbb\template\template */
22
	protected $template;
23
24
	/** @var \phpbb\user */
25
	protected $user;
26
27
	/** @var \phpbb\request\request */
28
	protected $request;
29
30
	/** @var \phpbb\admanagement\ad\manager */
31
	protected $manager;
32
33
	/** @var \phpbb\admanagement\location\manager */
34
	protected $location_manager;
35
36
	/** @var \phpbb\log\log */
37
	protected $log;
38
39
	/** @var string php_ext */
40
	protected $php_ext;
41
42
	/** @var string ext_path */
43
	protected $ext_path;
44
45
	/** @var string Custom form action */
46
	protected $u_action;
47
48
	/** @var array Form validation errors */
49
	protected $errors = array();
50
51
	/**
52
	* Constructor
53
	*
54
	* @param \phpbb\template\template				$template			Template object
55
	* @param \phpbb\user							$user				User object
56
	* @param \phpbb\request\request					$request			Request object
57
	* @param \phpbb\admanagement\ad\manager			$manager			Advertisement manager object
58
	* @param \phpbb\admanagement\location\manager	$location_manager	Template location manager object
59
	* @param \phpbb\log\log							$log				The phpBB log system
60
	* @param string									$php_ext			PHP extension
61
	* @param string									$ext_path			Path to this extension
62
	*/
63 31
	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\request\request $request, \phpbb\admanagement\ad\manager $manager, \phpbb\admanagement\location\manager $location_manager, \phpbb\log\log $log, $php_ext, $ext_path)
64
	{
65 31
		$this->template = $template;
66 31
		$this->user = $user;
67 31
		$this->request = $request;
68 31
		$this->manager = $manager;
69 31
		$this->location_manager = $location_manager;
70 31
		$this->log = $log;
71 31
		$this->php_ext = $php_ext;
72 31
		$this->ext_path = $ext_path;
73 31
	}
74
75
	/**
76
	* Process user request
77
	*
78
	* @return void
79
	*/
80 6
	public function main()
81
	{
82 6
		$this->user->add_lang_ext('phpbb/admanagement', 'acp');
83
84 6
		$this->manager->disable_expired_ads();
85
86 6
		$this->template->assign_var('S_PHPBB_ADMANAGEMENT', true);
87
88
		// Trigger specific action
89 6
		$action = $this->request->variable('action', '');
90 6
		if (in_array($action, array('add', 'edit', 'enable', 'disable', 'delete')))
91 6
		{
92 5
			$this->{'action_' . $action}();
93 5
		}
94
95
		// Otherwise default to this
96 6
		$this->list_ads();
97 6
	}
98
99
	/**
100
	* Set page url
101
	*
102
	* @param string $u_action Custom form action
103
	* @return void
104
	*/
105 25
	public function set_page_url($u_action)
106
	{
107 25
		$this->u_action = $u_action;
108 25
	}
109
110
	/**
111
	* Get ACP page title for Ads module
112
	*
113
	* @return string	Language string for Ads ACP module
114
	*/
115 1
	public function get_page_title()
116
	{
117 1
		return $this->user->lang('ACP_ADMANAGEMENT_TITLE');
118
	}
119
120
	/**
121
	* Add an advertisement
122
	*
123
	* @return void
124
	*/
125 7
	public function action_add()
126
	{
127 7
		$preview = $this->request->is_set_post('preview');
128 7
		$submit = $this->request->is_set_post('submit');
129
130 7
		add_form_key('phpbb/admanagement/add');
131 7
		if ($preview || $submit)
132 7
		{
133 6
			$data = $this->get_form_data();
134
135 6
			$this->validate($data, 'phpbb/admanagement/add');
136
137 View Code Duplication
			if ($preview)
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
138 6
			{
139 1
				$this->ad_preview($data['ad_code']);
140 1
			}
141
			else if (empty($this->errors))
142 5
			{
143 1
				$ad_id = $this->manager->insert_ad($data);
144 1
				$this->manager->insert_ad_locations($ad_id, $data['ad_locations']);
145
146 1
				$this->log('ADD', $data['ad_name']);
147
148 1
				$this->success('ACP_AD_ADD_SUCCESS');
149
			}
150
151 5
			$this->assign_locations($data);
152 5
			$this->assign_form_data($data);
153 5
		}
154
		else
155
		{
156 1
			$this->assign_locations();
157
		}
158
159
		// Set output vars for display in the template
160 6
		$this->template->assign_vars(array(
161 6
			'S_ADD_AD'				=> true,
162 6
			'U_BACK'				=> $this->u_action,
163 6
			'PICKER_DATE_FORMAT'	=> self::DATE_FORMAT,
164 6
		));
165 6
	}
166
167
	/**
168
	* Edit an advertisement
169
	*
170
	* @return void
171
	*/
172 10
	public function action_edit()
173
	{
174 9
		$ad_id = $this->request->variable('id', 0);
175 9
		$preview = $this->request->is_set_post('preview');
176 9
		$submit = $this->request->is_set_post('submit');
177
178 9
		add_form_key('phpbb/admanagement/edit/' . $ad_id);
179 9
		if ($preview || $submit)
180 9
		{
181 7
			$data = $this->get_form_data();
182
183 7
			$this->validate($data, 'phpbb/admanagement/edit/' . $ad_id);
184
185
			if ($preview)
186 7
			{
187 1
				$this->ad_preview($data['ad_code']);
188 1
			}
189 View Code Duplication
			else if (empty($this->errors))
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190 6
			{
191 2
				$success = $this->manager->update_ad($ad_id, $data);
192
193
				if ($success)
194 2
				{
195
					// Only insert new ad locations to DB when ad exists
196 10
					$this->manager->delete_ad_locations($ad_id);
197 1
					$this->manager->insert_ad_locations($ad_id, $data['ad_locations']);
198
199 1
					$this->log('EDIT', $data['ad_name']);
200
201 1
					$this->success('ACP_AD_EDIT_SUCCESS');
202
				}
203 1
				$this->error('ACP_AD_DOES_NOT_EXIST');
204
			}
205 5
		}
206
		else
207
		{
208
			// Load ad data
209 2
			$data = $this->manager->get_ad($ad_id);
210 2
			if (empty($data))
211 2
			{
212 1
				$this->error('ACP_AD_DOES_NOT_EXIST');
213
			}
214
215
			// Load ad template locations
216 1
			$data['ad_locations'] = $this->manager->get_ad_locations($ad_id);
217
		}
218
219
		// Set output vars for display in the template
220 6
		$this->template->assign_vars(array(
221 6
			'S_EDIT_AD'				=> true,
222 6
			'EDIT_ID'				=> $ad_id,
223 6
			'U_BACK'				=> $this->u_action,
224 6
			'PICKER_DATE_FORMAT'	=> self::DATE_FORMAT,
225 6
		));
226 6
		$this->assign_locations($data);
227 6
		$this->assign_form_data($data);
228 6
	}
229
230
	/**
231
	* Enable an advertisement
232
	*
233
	* @return void
234
	*/
235 3
	public function action_enable()
236
	{
237 3
		$this->ad_enable(true);
238 1
	}
239
240
	/**
241
	* Disable an advertisement
242
	*
243
	* @return void
244
	*/
245 3
	public function action_disable()
246
	{
247 3
		$this->ad_enable(false);
248 1
	}
249
250
	/**
251
	* Delete an advertisement
252
	*
253
	* @return void
254
	*/
255 3
	public function action_delete()
256
	{
257 3
		$ad_id = $this->request->variable('id', 0);
258
		if ($ad_id)
259 3
		{
260 3
			if (confirm_box(true))
261 3
			{
262
				// Get ad data so that we can log ad name
263 2
				$ad_data = $this->manager->get_ad($ad_id);
264
265
				// Delete ad and it's template locations
266 2
				$this->manager->delete_ad_locations($ad_id);
267 2
				$success = $this->manager->delete_ad($ad_id);
268
269
				// Only notify user on error or if not ajax
270 2
				if (!$success)
271 2
				{
272 1
					$this->error('ACP_AD_DELETE_ERRORED');
273
				}
274
				else
275
				{
276 1
					$this->log('DELETE', $ad_data['ad_name']);
277
278 1
					if (!$this->request->is_ajax())
279 1
					{
280 1
						$this->success('ACP_AD_DELETE_SUCCESS');
281
					}
282
				}
283
			}
284
			else
285
			{
286 1
				confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
287 1
					'id'		=> $ad_id,
288 1
					'i'			=> $this->request->variable('i', ''),
289 1
					'mode'		=> $this->request->variable('mode', ''),
290
					'action'	=> 'delete'
291 1
				)));
292
			}
293 1
		}
294 1
	}
295
296
	/**
297
	* Display the ads
298
	*
299
	* @return void
300
	*/
301 1
	public function list_ads()
302
	{
303 1
		foreach ($this->manager->get_all_ads() as $row)
304
		{
305 1
			$ad_enabled = (int) $row['ad_enabled'];
306
307 1
			$this->template->assign_block_vars('ads', array(
308 1
				'NAME'				=> $row['ad_name'],
309 1
				'END_DATE'			=> $row['ad_end_date'] ? $this->user->format_date($row['ad_end_date'], self::DATE_FORMAT) : '',
310 1
				'END_DATE_EXPIRED'	=> (int) $row['ad_end_date'] < time(),
311 1
				'S_ENABLED'			=> $ad_enabled,
312 1
				'U_ENABLE'			=> $this->u_action . '&amp;action=' . ($ad_enabled ? 'disable' : 'enable') . '&amp;id=' . $row['ad_id'],
313 1
				'U_EDIT'			=> $this->u_action . '&amp;action=edit&amp;id=' . $row['ad_id'],
314 1
				'U_DELETE'			=> $this->u_action . '&amp;action=delete&amp;id=' . $row['ad_id'],
315 1
			));
316 1
		}
317
318
		// Set output vars for display in the template
319 1
		$this->template->assign_var('U_ACTION_ADD', $this->u_action . '&amp;action=add');
320 1
	}
321
322
	/**
323
	* Enable/disable an advertisement
324
	*
325
	* @param	bool	$enable	Enable or disable the advertisement?
326
	* @return void
327
	*/
328 4
	protected function ad_enable($enable)
329
	{
330 4
		$ad_id = $this->request->variable('id', 0);
331
332 4
		$success = $this->manager->update_ad($ad_id, array(
333 4
			'ad_enabled'	=> (int) $enable,
334 4
		));
335
336
		// If AJAX was used, show user a result message
337 4
		if ($this->request->is_ajax())
338 4
		{
339
			$json_response = new \phpbb\json_response;
340
			$json_response->send(array(
341
				'text'	=> $this->user->lang($enable ? 'ENABLED' : 'DISABLED'),
342
				'title'	=> $this->user->lang('AD_ENABLE_TITLE', (int) $enable),
343
			));
344
		}
345
346
		// Otherwise, show traditional infobox
347
		if ($success)
348 4
		{
349 2
			$this->success($enable ? 'ACP_AD_ENABLE_SUCCESS' : 'ACP_AD_DISABLE_SUCCESS');
350
		}
351
		else
352
		{
353 2
			$this->error($enable ? 'ACP_AD_ENABLE_ERRORED' : 'ACP_AD_DISABLE_ERRORED');
354
		}
355
	}
356
357
	/**
358
	* Get admin form data.
359
	*
360
	* @return	array	Form data
361
	*/
362 13
	protected function get_form_data()
363
	{
364
		return array(
365 13
			'ad_name'		=> $this->request->variable('ad_name', '', true),
366 13
			'ad_note'		=> $this->request->variable('ad_note', '', true),
367 13
			'ad_code'		=> $this->request->variable('ad_code', '', true),
368 13
			'ad_enabled'	=> $this->request->variable('ad_enabled', 0),
369 13
			'ad_locations'	=> $this->request->variable('ad_locations', array('')),
370 13
			'ad_end_date'	=> (int) $this->user->get_timestamp_from_format(self::DATE_FORMAT, $this->request->variable('ad_end_date', '')),
371 13
		);
372
	}
373
374
	/**
375
	* Validate form data.
376
	*
377
	* @param	array	$data		The form data.
378
	* @param	string	$form_name	The form name.
379
	* @return void
380
	*/
381 13
	protected function validate($data, $form_name)
382
	{
383 13
		if (!check_form_key($form_name))
384 13
		{
385 2
			$this->errors[] = $this->user->lang('FORM_INVALID');
386 2
		}
387
388 13
		if ($data['ad_name'] === '')
389 13
		{
390 2
			$this->errors[] = $this->user->lang('AD_NAME_REQUIRED');
391 2
		}
392 13
		if (truncate_string($data['ad_name'], self::MAX_NAME_LENGTH) !== $data['ad_name'])
393 13
		{
394 2
			$this->errors[] = $this->user->lang('AD_NAME_TOO_LONG', self::MAX_NAME_LENGTH);
395 2
		}
396 13
		if ($data['ad_end_date'] != 0 && $data['ad_end_date'] < time())
397 13
		{
398 2
			$this->errors[] = $this->user->lang('AD_END_DATE_INVALID');
399 2
		}
400 13
	}
401
402
	/**
403
	* Assign form data to the template.
404
	*
405
	* @param	array	$data	The form data.
406
	* @return void
407
	*/
408 11
	protected function assign_form_data($data)
409
	{
410 11
		$this->template->assign_vars(array(
411 11
			'S_ERROR'		=> (bool) count($this->errors),
412 11
			'ERROR_MSG'		=> count($this->errors) ? implode('<br />', $this->errors) : '',
413
414 11
			'AD_NAME'		=> $data['ad_name'],
415 11
			'AD_NOTE'		=> $data['ad_note'],
416 11
			'AD_CODE'		=> $data['ad_code'],
417 11
			'AD_ENABLED'	=> $data['ad_enabled'],
418 11
			'AD_END_DATE'	=> $data['ad_end_date'] ? $this->user->format_date($data['ad_end_date'], self::DATE_FORMAT) : '',
419 11
		));
420 11
	}
421
422
	/**
423
	* Assign template locations data to the template.
424
	*
425
	* @param	mixed	$data	The form data or nothing.
426
	* @return	void
427
	*/
428 12
	protected function assign_locations($data = false)
429
	{
430 12
		foreach ($this->location_manager->get_all_locations() as $location_id => $location_data)
431
		{
432 12
			$this->template->assign_block_vars('ad_locations', array(
433 12
				'LOCATION_ID'	=> $location_id,
434 12
				'LOCATION_DESC'	=> $location_data['desc'],
435 12
				'LOCATION_NAME'	=> $location_data['name'],
436 12
				'S_SELECTED'	=> $data ? in_array($location_id, $data['ad_locations']) : false,
437 12
			));
438 12
		}
439 12
	}
440
441
	/**
442
	* Prepare advertisement preview
443
	*
444
	* @param	string	$code	Ad code to preview
445
	* @return	void
446
	*/
447 2
	protected function ad_preview($code)
448
	{
449 2
		$this->template->assign_var('PREVIEW', htmlspecialchars_decode($code));
450 2
	}
451
452
	/**
453
	* Print success message.
454
	*
455
	* It takes arguments in the form of a language key, followed by language substitution values.
456
	*/
457 5
	protected function success()
458
	{
459 5
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action));
460
	}
461
462
	/**
463
	* Print error message.
464
	*
465
	* It takes arguments in the form of a language key, followed by language substitution values.
466
	*/
467 5
	protected function error()
468
	{
469 5
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action), E_USER_WARNING);
470
	}
471
472
	/**
473
	* Log action
474
	*
475
	* @param	string	$action		Performed action in uppercase
476
	* @param	string	$ad_name	Advertisement name
477
	* @return	void
478
	*/
479 3
	protected function log($action, $ad_name)
480
	{
481 3
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_ADMANAGEMENT_' . $action . '_LOG', time(), array($ad_name));
482 3
	}
483
}
484