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

admin_controller::list_ads()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

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