Completed
Pull Request — master (#5)
by Jakub
29:08 queued 26:59
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 16
CRAP Score 6.0493

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 20
ccs 16
cts 18
cp 0.8889
rs 8.8571
cc 6
eloc 9
nc 16
nop 2
crap 6.0493
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 H:i';
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 29
	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 29
		$this->template = $template;
66 29
		$this->user = $user;
67 29
		$this->request = $request;
68 29
		$this->manager = $manager;
69 29
		$this->location_manager = $location_manager;
70 29
		$this->log = $log;
71 29
		$this->php_ext = $php_ext;
72 29
		$this->ext_path = $ext_path;
73 29
	}
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
		// Trigger specific action
85 6
		$action = $this->request->variable('action', '');
86 6
		if (in_array($action, array('add', 'edit', 'enable', 'disable', 'delete')))
87 6
		{
88 5
			$this->{'action_' . $action}();
89 5
		}
90
91
		// Otherwise default to this
92 6
		$this->list_ads();
93 6
	}
94
95
	/**
96
	* Set page url
97
	*
98
	* @param string $u_action Custom form action
99
	* @return void
100
	*/
101 23
	public function set_page_url($u_action)
102
	{
103 23
		$this->u_action = $u_action;
104 23
	}
105
106
	/**
107
	* Get ACP page title for Ads module
108
	*
109
	* @return string	Language string for Ads ACP module
110
	*/
111 1
	public function get_page_title()
112
	{
113 1
		return $this->user->lang('ACP_ADMANAGEMENT_TITLE');
114
	}
115
116
	/**
117
	* Add an advertisement
118
	*
119
	* @return void
120
	*/
121 6
	public function action_add()
122
	{
123 6
		$preview = $this->request->is_set_post('preview');
124 6
		$submit = $this->request->is_set_post('submit');
125
126 6
		add_form_key('phpbb/admanagement/add');
127 6
		if ($preview || $submit)
128 6
		{
129 5
			$data = $this->get_form_data();
130
131 5
			$this->validate($data, 'phpbb/admanagement/add');
132
133 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...
134 5
			{
135 1
				$this->ad_preview($data['ad_code']);
136 1
			}
137
			else if (empty($this->errors))
138 4
			{
139 1
				$ad_id = $this->manager->insert_ad($data);
140 1
				$this->manager->insert_ad_locations($ad_id, $data['ad_locations']);
141
142 1
				$this->log('ADD', $data['ad_name']);
143
144 1
				$this->success('ACP_AD_ADD_SUCCESS');
145
			}
146
147 4
			$this->assign_locations($data);
148 4
			$this->assign_form_data($data);
149 4
		}
150
		else
151
		{
152 1
			$this->assign_locations();
153
		}
154
155
		// Set output vars for display in the template
156 5
		$this->template->assign_vars(array(
157 5
			'S_ADD_AD'				=> true,
158 5
			'U_BACK'				=> $this->u_action,
159 5
			'PICKER_DATE_FORMAT'	=> self::DATE_FORMAT,
160 5
		));
161 5
	}
162
163
	/**
164
	* Edit an advertisement
165
	*
166
	* @return void
167
	*/
168 8
	public function action_edit()
169
	{
170 8
		$ad_id = $this->request->variable('id', 0);
171 8
		$preview = $this->request->is_set_post('preview');
172 8
		$submit = $this->request->is_set_post('submit');
173
174 8
		add_form_key('phpbb/admanagement/edit/' . $ad_id);
175 8
		if ($preview || $submit)
176 8
		{
177 6
			$data = $this->get_form_data();
178
179 6
			$this->validate($data, 'phpbb/admanagement/edit/' . $ad_id);
180
181
			if ($preview)
182 6
			{
183 1
				$this->ad_preview($data['ad_code']);
184 1
			}
185 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...
186 5
			{
187 2
				$success = $this->manager->update_ad($ad_id, $data);
188
189
				if ($success)
190 2
				{
191
					// Only insert new ad locations to DB when ad exists
192 1
					$this->manager->delete_ad_locations($ad_id);
193 1
					$this->manager->insert_ad_locations($ad_id, $data['ad_locations']);
194
195 1
					$this->log('EDIT', $data['ad_name']);
196
197 1
					$this->success('ACP_AD_EDIT_SUCCESS');
198
				}
199 1
				$this->error('ACP_AD_DOES_NOT_EXIST');
200
			}
201 4
		}
202
		else
203
		{
204
			// Load ad data
205 2
			$data = $this->manager->get_ad($ad_id);
206 2
			if (empty($data))
207 2
			{
208 1
				$this->error('ACP_AD_DOES_NOT_EXIST');
209
			}
210
211
			// Load ad template locations
212 1
			$data['ad_locations'] = $this->manager->get_ad_locations($ad_id);
213
		}
214
215
		// Set output vars for display in the template
216 5
		$this->template->assign_vars(array(
217 5
			'S_EDIT_AD'				=> true,
218 5
			'EDIT_ID'				=> $ad_id,
219 5
			'U_BACK'				=> $this->u_action,
220 5
			'PICKER_DATE_FORMAT'	=> self::DATE_FORMAT,
221 5
		));
222 5
		$this->assign_locations($data);
223 5
		$this->assign_form_data($data);
224 5
	}
225
226
	/**
227
	* Enable an advertisement
228
	*
229
	* @return void
230
	*/
231 3
	public function action_enable()
232
	{
233 3
		$this->ad_enable(true);
234 1
	}
235
236
	/**
237
	* Disable an advertisement
238
	*
239
	* @return void
240
	*/
241 3
	public function action_disable()
242
	{
243 3
		$this->ad_enable(false);
244 1
	}
245
246
	/**
247
	* Delete an advertisement
248
	*
249
	* @return void
250
	*/
251 3
	public function action_delete()
252
	{
253 3
		$ad_id = $this->request->variable('id', 0);
254
		if ($ad_id)
255 3
		{
256 3
			if (confirm_box(true))
257 3
			{
258
				// Get ad data so that we can log ad name
259 2
				$ad_data = $this->manager->get_ad($ad_id);
260
261
				// Delete ad and it's template locations
262 2
				$this->manager->delete_ad_locations($ad_id);
263 2
				$success = $this->manager->delete_ad($ad_id);
264
265
				// Only notify user on error or if not ajax
266 2
				if (!$success)
267 2
				{
268 1
					$this->error('ACP_AD_DELETE_ERRORED');
269
				}
270
				else
271
				{
272 1
					$this->log('DELETE', $ad_data['ad_name']);
273
274 1
					if (!$this->request->is_ajax())
275 1
					{
276 1
						$this->success('ACP_AD_DELETE_SUCCESS');
277
					}
278
				}
279
			}
280
			else
281
			{
282 1
				confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
283 1
					'id'		=> $ad_id,
284 1
					'i'			=> $this->request->variable('i', ''),
285 1
					'mode'		=> $this->request->variable('mode', ''),
286
					'action'	=> 'delete'
287 1
				)));
288
			}
289 1
		}
290 1
	}
291
292
	/**
293
	* Display the ads
294
	*
295
	* @return void
296
	*/
297 1
	public function list_ads()
298
	{
299 1
		foreach ($this->manager->get_all_ads() as $row)
300
		{
301 1
			$ad_enabled = (int) $row['ad_enabled'];
302
303 1
			$this->template->assign_block_vars('ads', array(
304 1
				'NAME'		=> $row['ad_name'],
305 1
				'S_ENABLED'	=> $ad_enabled,
306 1
				'U_ENABLE'	=> $this->u_action . '&amp;action=' . ($ad_enabled ? 'disable' : 'enable') . '&amp;id=' . $row['ad_id'],
307 1
				'U_EDIT'	=> $this->u_action . '&amp;action=edit&amp;id=' . $row['ad_id'],
308 1
				'U_DELETE'	=> $this->u_action . '&amp;action=delete&amp;id=' . $row['ad_id'],
309 1
			));
310 1
		}
311
312
		// Set output vars for display in the template
313 1
		$this->template->assign_vars(array(
314 1
			'U_ACTION_ADD'	=> $this->u_action . '&amp;action=add',
315 1
		));
316 1
	}
317
318
	/**
319
	* Enable/disable an advertisement
320
	*
321
	* @param	bool	$enable	Enable or disable the advertisement?
322
	* @return void
323
	*/
324 4
	protected function ad_enable($enable)
325
	{
326 4
		$ad_id = $this->request->variable('id', 0);
327
328 4
		$success = $this->manager->update_ad($ad_id, array(
329 4
			'ad_enabled'	=> (int) $enable,
330 4
		));
331
332
		// If AJAX was used, show user a result message
333 4
		if ($this->request->is_ajax())
334 4
		{
335
			$json_response = new \phpbb\json_response;
336
			$json_response->send(array(
337
				'text'	=> $this->user->lang($enable ? 'ENABLED' : 'DISABLED'),
338
				'title'	=> $this->user->lang('AD_ENABLE_TITLE', (int) $enable),
339
			));
340
		}
341
342
		// Otherwise, show traditional infobox
343
		if ($success)
344 4
		{
345 2
			$this->success($enable ? 'ACP_AD_ENABLE_SUCCESS' : 'ACP_AD_DISABLE_SUCCESS');
346
		}
347
		else
348
		{
349 2
			$this->error($enable ? 'ACP_AD_ENABLE_ERRORED' : 'ACP_AD_DISABLE_ERRORED');
350
		}
351
	}
352
353
	/**
354
	* Get admin form data.
355
	*
356
	* @return	array	Form data
357
	*/
358 11
	protected function get_form_data()
359
	{
360
		return array(
361 11
			'ad_name'		=> $this->request->variable('ad_name', '', true),
362 11
			'ad_note'		=> $this->request->variable('ad_note', '', true),
363 11
			'ad_code'		=> $this->request->variable('ad_code', '', true),
364 11
			'ad_enabled'	=> $this->request->variable('ad_enabled', 0),
365 11
			'ad_locations'	=> $this->request->variable('ad_locations', array('')),
366 11
			'ad_end_date'	=> (int) $this->user->get_timestamp_from_format(self::DATE_FORMAT, $this->request->variable('ad_end_date', '')),
367 11
		);
368
	}
369
370
	/**
371
	* Validate form data.
372
	*
373
	* @param	array	$data		The form data.
374
	* @param	string	$form_name	The form name.
375
	* @return void
376
	*/
377 11
	protected function validate($data, $form_name)
378
	{
379 11
		if (!check_form_key($form_name))
380 11
		{
381 2
			$this->errors[] = $this->user->lang('FORM_INVALID');
382 2
		}
383
384 11
		if ($data['ad_name'] === '')
385 11
		{
386 2
			$this->errors[] = $this->user->lang('AD_NAME_REQUIRED');
387 2
		}
388 11
		if (truncate_string($data['ad_name'], self::MAX_NAME_LENGTH) !== $data['ad_name'])
389 11
		{
390 2
			$this->errors[] = $this->user->lang('AD_NAME_TOO_LONG', self::MAX_NAME_LENGTH);
391 2
		}
392 11
		if ($data['ad_end_date'] != 0 && $data['ad_end_date'] < time())
393 11
		{
394
			$this->errors[] = $this->user->lang('AD_END_DATE_INVALID');
395
		}
396 11
	}
397
398
	/**
399
	* Assign form data to the template.
400
	*
401
	* @param	array	$data	The form data.
402
	* @return void
403
	*/
404 9
	protected function assign_form_data($data)
405
	{
406 9
		$this->template->assign_vars(array(
407 9
			'S_ERROR'		=> (bool) count($this->errors),
408 9
			'ERROR_MSG'		=> count($this->errors) ? implode('<br />', $this->errors) : '',
409
410 9
			'AD_NAME'		=> $data['ad_name'],
411 9
			'AD_NOTE'		=> $data['ad_note'],
412 9
			'AD_CODE'		=> $data['ad_code'],
413 9
			'AD_ENABLED'	=> $data['ad_enabled'],
414 9
			'AD_END_DATE'	=> $data['ad_end_date'] ? $this->user->format_date($data['ad_end_date'], self::DATE_FORMAT) : '',
415 9
		));
416 9
	}
417
418
	/**
419
	* Assign template locations data to the template.
420
	*
421
	* @param	mixed	$data	The form data or nothing.
422
	* @return	void
423
	*/
424 10
	protected function assign_locations($data = false)
425
	{
426 10
		foreach ($this->location_manager->get_all_locations() as $location_id => $location_data)
427
		{
428 10
			$this->template->assign_block_vars('ad_locations', array(
429 10
				'LOCATION_ID'	=> $location_id,
430 10
				'LOCATION_DESC'	=> $location_data['desc'],
431 10
				'LOCATION_NAME'	=> $location_data['name'],
432 10
				'S_SELECTED'	=> $data ? in_array($location_id, $data['ad_locations']) : false,
433 10
			));
434 10
		}
435 10
	}
436
437
	/**
438
	* Prepare advertisement preview
439
	*
440
	* @param	string	$code	Ad code to preview
441
	* @return	void
442
	*/
443 2
	protected function ad_preview($code)
444
	{
445 2
		$this->template->assign_var('PREVIEW', htmlspecialchars_decode($code));
446 2
	}
447
448
	/**
449
	* Print success message.
450
	*
451
	* It takes arguments in the form of a language key, followed by language substitution values.
452
	*/
453 5
	protected function success()
454
	{
455 5
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action));
456
	}
457
458
	/**
459
	* Print error message.
460
	*
461
	* It takes arguments in the form of a language key, followed by language substitution values.
462
	*/
463 5
	protected function error()
464
	{
465 5
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action), E_USER_WARNING);
466
	}
467
468
	/**
469
	* Log action
470
	*
471
	* @param	string	$action		Performed action in uppercase
472
	* @param	string	$ad_name	Advertisement name
473
	* @return	void
474
	*/
475 3
	protected function log($action, $ad_name)
476
	{
477 3
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_ADMANAGEMENT_' . $action . '_LOG', time(), array($ad_name));
478 3
	}
479
}
480