Completed
Pull Request — master (#5)
by Jakub
31:20
created

admin_controller::set_page_url()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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