Completed
Pull Request — master (#32)
by Jakub
35:01
created

admin_controller::success()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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\ads\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\ads\ad\manager */
31
	protected $manager;
32
33
	/** @var \phpbb\ads\location\manager */
34
	protected $location_manager;
35
36
	/** @var \phpbb\log\log */
37
	protected $log;
38
39
	/** @var \phpbb\config\db_text */
40
	protected $config_text;
41
42
	/** @var \phpbb\config\config */
43
	protected $config;
44
45
	/** @var string php_ext */
46
	protected $php_ext;
47
48
	/** @var string ext_path */
49
	protected $ext_path;
50
51
	/** @var string Custom form action */
52
	protected $u_action;
53
54
	/** @var array Form validation errors */
55
	protected $errors = array();
56
57
	/**
58
	* Constructor
59
	*
60
	* @param \phpbb\template\template				$template			Template object
61
	* @param \phpbb\user							$user				User object
62
	* @param \phpbb\request\request					$request			Request object
63
	* @param \phpbb\ads\ad\manager					$manager			Advertisement manager object
64
	* @param \phpbb\ads\location\manager			$location_manager	Template location manager object
65
	* @param \phpbb\log\log							$log				The phpBB log system
66
	* @param \phpbb\config\db_text					$config_text		Config text object
67 34
	* @param \phpbb\config\config					$config				Config object
68
	* @param string									$php_ext			PHP extension
69 34
	* @param string									$ext_path			Path to this extension
70 34
	*/
71 34
	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\request\request $request, \phpbb\ads\ad\manager $manager, \phpbb\ads\location\manager $location_manager, \phpbb\log\log $log, \phpbb\config\db_text $config_text, \phpbb\config\config $config, $php_ext, $ext_path)
72 34
	{
73 34
		$this->template = $template;
74 34
		$this->user = $user;
75 34
		$this->request = $request;
76 34
		$this->manager = $manager;
77 34
		$this->location_manager = $location_manager;
78 34
		$this->log = $log;
79
		$this->config_text = $config_text;
80
		$this->config = $config;
81
		$this->php_ext = $php_ext;
82
		$this->ext_path = $ext_path;
83
	}
84
85 6
	/**
86
	* Process user request for manage mode
87 6
	*
88
	* @return void
89
	*/
90 6
	public function mode_manage()
91 6
	{
92 6
		$this->setup();
93 5
94 5
		// Trigger specific action
95
		$action = $this->request->variable('action', '');
96
		if (in_array($action, array('add', 'edit', 'enable', 'disable', 'delete')))
97 6
		{
98 6
			$this->{'action_' . $action}();
99
		}
100
101
		// Otherwise default to this
102
		$this->list_ads();
103
	}
104
105 3
	/**
106
	* Process user request for settings mode
107 3
	*
108
	* @return void
109 3
	*/
110 3
	public function mode_settings()
111 3
	{
112
		$this->setup();
113 2
114 2
		add_form_key('phpbb/ads/settings');
115 1
		if ($this->request->is_set_post('submit'))
116 1
		{
117
			// Validate form key
118 2
			if (!check_form_key('phpbb/ads/settings'))
119 2
			{
120 1
				$this->errors[] = $this->user->lang('FORM_INVALID');
121
			}
122 1
123
			if (empty($this->errors))
124
			{
125 1
				$this->config->set('phpbb_ads_adblocker_message', $this->request->variable('adblocker_message', 0));
126 1
				$this->config_text->set('phpbb_ads_hide_groups', json_encode($this->request->variable('hide_groups', array(0))));
127 1
128 1
				$this->success('ACP_AD_SETTINGS_SAVED');
129 1
			}
130
131 2
			$this->template->assign_vars(array(
132 2
				'S_ERROR'		=> (bool) count($this->errors),
133 2
				'ERROR_MSG'		=> count($this->errors) ? implode('<br />', $this->errors) : '',
134
			));
135 2
		}
136
137 2
		$hide_groups = json_decode($this->config_text->get('phpbb_ads_hide_groups'), true);
138 2
		$groups = $this->manager->load_groups();
139 2
		foreach ($groups as $group)
140 2
		{
141 2
			$group_name = ($group['group_type'] == GROUP_SPECIAL) ? $this->user->lang('G_' . $group['group_name']) : $group['group_name'];
142 2
143 2
			$this->template->assign_block_vars('groups', array(
144
				'ID'			=> $group['group_id'],
145
				'NAME'			=> $group_name,
146
				'S_SELECTED'	=> in_array($group['group_id'], $hide_groups),
147
			));
148
		}
149
150
		$this->template->assign_vars(array(
151 28
			'U_ACTION'			=> $this->u_action,
152
			'ADBLOCKER_MESSAGE'	=> $this->config['phpbb_ads_adblocker_message'],
153 28
		));
154 28
	}
155
156
	/**
157
	* Set page url
158
	*
159
	* @param string $u_action Custom form action
160
	* @return void
161 1
	*/
162
	public function set_page_url($u_action)
163 1
	{
164
		$this->u_action = $u_action;
165
	}
166
167
	/**
168
	* Get ACP page title for Ads module
169
	*
170
	* @return string	Language string for Ads ACP module
171 16
	*/
172
	public function get_page_title()
173 7
	{
174 7
		return $this->user->lang('ACP_PHPBB_ADS_TITLE');
175
	}
176 7
177 7
	/**
178 7
	* Add an advertisement
179 6
	*
180
	* @return void
181
	*/
182 6
	public function action_add()
183 1
	{
184 1
		$preview = $this->request->is_set_post('preview');
185
		$submit = $this->request->is_set_post('submit');
186 5
187 1
		add_form_key('phpbb/ads/add');
188 1
		if ($preview || $submit)
189
		{
190 1
			$data = $this->get_form_data('phpbb/ads/add');
191
192 1 View Code Duplication
			if ($preview)
193
			{
194
				$this->ad_preview($data['ad_code']);
195 5
			}
196 16
			else if (empty($this->errors))
197 5
			{
198
				$ad_id = $this->manager->insert_ad($data);
199
				$this->manager->insert_ad_locations($ad_id, $data['ad_locations']);
200 1
201
				$this->log('ADD', $data['ad_name']);
202
203
				$this->success('ACP_AD_ADD_SUCCESS');
204 6
			}
205 6
206 6
			$this->assign_locations($data);
207 6
			$this->assign_form_data($data);
208 6
		}
209 6
		else
210
		{
211
			$this->assign_locations();
212
		}
213
214
		// Set output vars for display in the template
215
		$this->template->assign_vars(array(
216 9
			'S_ADD_AD'				=> true,
217
			'U_BACK'				=> $this->u_action,
218 9
			'U_ACTION'				=> "{$this->u_action}&amp;action=add",
219 9
			'PICKER_DATE_FORMAT'	=> self::DATE_FORMAT,
220 9
		));
221
	}
222 9
223 9
	/**
224 9
	* Edit an advertisement
225 7
	*
226
	* @return void
227
	*/
228 7
	public function action_edit()
229 1
	{
230 1
		$ad_id = $this->request->variable('id', 0);
231
		$preview = $this->request->is_set_post('preview');
232 6
		$submit = $this->request->is_set_post('submit');
233 2
234
		add_form_key('phpbb/ads/edit/' . $ad_id);
235
		if ($preview || $submit)
236 2
		{
237
			$data = $this->get_form_data('phpbb/ads/edit/' . $ad_id);
238 1
239 1
			if ($preview)
240
			{
241 1
				$this->ad_preview($data['ad_code']);
242
			}
243 1 View Code Duplication
			else if (empty($this->errors))
244
			{
245 1
				$success = $this->manager->update_ad($ad_id, $data);
246
247 5
				if ($success)
248
				{
249
					// Only insert new ad locations to DB when ad exists
250
					$this->manager->delete_ad_locations($ad_id);
251 2
					$this->manager->insert_ad_locations($ad_id, $data['ad_locations']);
252 2
253 2
					$this->log('EDIT', $data['ad_name']);
254 1
255
					$this->success('ACP_AD_EDIT_SUCCESS');
256
				}
257
				$this->error('ACP_AD_DOES_NOT_EXIST');
258 1
			}
259
		}
260
		else
261
		{
262 6
			// Load ad data
263 6
			$data = $this->manager->get_ad($ad_id);
264 6
			if (empty($data))
265 6
			{
266 6
				$this->error('ACP_AD_DOES_NOT_EXIST');
267 6
			}
268 6
269 6
			// Load ad template locations
270 6
			$data['ad_locations'] = $this->manager->get_ad_locations($ad_id);
271
		}
272
273
		// Set output vars for display in the template
274
		$this->template->assign_vars(array(
275
			'S_EDIT_AD'				=> true,
276
			'EDIT_ID'				=> $ad_id,
277 3
			'U_BACK'				=> $this->u_action,
278
			'U_ACTION'				=> "{$this->u_action}&amp;action=edit&amp;id=" . $ad_id,
279 3
			'PICKER_DATE_FORMAT'	=> self::DATE_FORMAT,
280 1
		));
281
		$this->assign_locations($data);
282
		$this->assign_form_data($data);
283
	}
284
285
	/**
286
	* Enable an advertisement
287 3
	*
288
	* @return void
289 3
	*/
290 1
	public function action_enable()
291
	{
292
		$this->ad_enable(true);
293
	}
294
295
	/**
296
	* Disable an advertisement
297 3
	*
298
	* @return void
299 3
	*/
300
	public function action_disable()
301 3
	{
302 3
		$this->ad_enable(false);
303 3
	}
304
305 2
	/**
306
	* Delete an advertisement
307
	*
308 2
	* @return void
309 2
	*/
310
	public function action_delete()
311
	{
312 2
		$ad_id = $this->request->variable('id', 0);
313 2
		if ($ad_id)
314 1
		{
315
			if (confirm_box(true))
316
			{
317
				// Get ad data so that we can log ad name
318 1
				$ad_data = $this->manager->get_ad($ad_id);
319
320 1
				// Delete ad and it's template locations
321 1
				$this->manager->delete_ad_locations($ad_id);
322 1
				$success = $this->manager->delete_ad($ad_id);
323
324
				// Only notify user on error or if not ajax
325
				if (!$success)
326
				{
327
					$this->error('ACP_AD_DELETE_ERRORED');
328 1
				}
329 1
				else
330 1
				{
331 1
					$this->log('DELETE', $ad_data['ad_name']);
332
333 1
					if (!$this->request->is_ajax())
334
					{
335 1
						$this->success('ACP_AD_DELETE_SUCCESS');
336 1
					}
337
				}
338
			}
339
			else
340
			{
341
				confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
342
					'id'		=> $ad_id,
343 1
					'i'			=> $this->request->variable('i', ''),
344
					'mode'		=> $this->request->variable('mode', ''),
345 1
					'action'	=> 'delete'
346
				)));
347 1
			}
348 1
		}
349 1
	}
350 1
351 1
	/**
352 1
	* Display the ads
353 1
	*
354 1
	* @return void
355
	*/
356 1
	public function list_ads()
357 1
	{
358 1
		foreach ($this->manager->get_all_ads() as $row)
359 1
		{
360 1
			$ad_enabled = (int) $row['ad_enabled'];
361 1
			$ad_end_date = (int) $row['ad_end_date'];
362 1
			$ad_expired = $ad_end_date > 0 && $ad_end_date < time();
363 1
			if ($ad_expired && $ad_enabled)
364 1
			{
365 1
				$ad_enabled = 0;
366
				$this->manager->update_ad($row['ad_id'], array('ad_enabled' => 0));
367
			}
368 1
369 1
			$this->template->assign_block_vars('ads', array(
370
				'NAME'					=> $row['ad_name'],
371
				'END_DATE'				=> $ad_end_date ? $this->user->format_date($ad_end_date, self::DATE_FORMAT) : '',
372
				'S_END_DATE_EXPIRED'	=> $ad_expired,
373
				'S_ENABLED'				=> $ad_enabled,
374
				'U_ENABLE'				=> $this->u_action . '&amp;action=' . ($ad_enabled ? 'disable' : 'enable') . '&amp;id=' . $row['ad_id'],
375
				'U_EDIT'				=> $this->u_action . '&amp;action=edit&amp;id=' . $row['ad_id'],
376 9
				'U_DELETE'				=> $this->u_action . '&amp;action=delete&amp;id=' . $row['ad_id'],
377
			));
378 9
		}
379
380 9
		// Set output vars for display in the template
381 9
		$this->template->assign_var('U_ACTION_ADD', $this->u_action . '&amp;action=add');
382
	}
383
384
	/**
385
	* Perform general tasks
386
	*
387
	* @return void
388
	*/
389 4
	protected function setup()
390
	{
391 4
		$this->user->add_lang_ext('phpbb/ads', 'acp');
392
393 4
		$this->template->assign_var('S_PHPBB_ADS', true);
394 4
	}
395 4
396
	/**
397
	* Enable/disable an advertisement
398 4
	*
399 4
	* @param	bool	$enable	Enable or disable the advertisement?
400
	* @return void
401
	*/
402
	protected function ad_enable($enable)
403
	{
404
		$ad_id = $this->request->variable('id', 0);
405
406
		$success = $this->manager->update_ad($ad_id, array(
407
			'ad_enabled'	=> (int) $enable,
408
		));
409 4
410 2
		// If AJAX was used, show user a result message
411
		if ($this->request->is_ajax())
412
		{
413
			$json_response = new \phpbb\json_response;
414 2
			$json_response->send(array(
415
				'text'	=> $this->user->lang($enable ? 'ENABLED' : 'DISABLED'),
416
				'title'	=> $this->user->lang('AD_ENABLE_TITLE', (int) $enable),
417
			));
418
		}
419
420
		// Otherwise, show traditional infobox
421
		if ($success)
422
		{
423
			$this->success($enable ? 'ACP_AD_ENABLE_SUCCESS' : 'ACP_AD_DISABLE_SUCCESS');
424 13
		}
425
		else
426
		{
427 13
			$this->error($enable ? 'ACP_AD_ENABLE_ERRORED' : 'ACP_AD_DISABLE_ERRORED');
428 13
		}
429 13
	}
430 13
431 13
	/**
432 13
	* Get admin form data.
433 13
	*
434
	* @param	string	$form_name	The form name.
435
	* @return	array	Form data
436 13
	*/
437 13
	protected function get_form_data($form_name)
438 2
	{
439 2
		$data = array(
440
			'ad_name'		=> $this->request->variable('ad_name', '', true),
441
			'ad_note'		=> $this->request->variable('ad_note', '', true),
442 13
			'ad_code'		=> $this->request->variable('ad_code', '', true),
443 13
			'ad_enabled'	=> $this->request->variable('ad_enabled', 0),
444 2
			'ad_locations'	=> $this->request->variable('ad_locations', array('')),
445 2
			'ad_end_date'	=> $this->request->variable('ad_end_date', ''),
446 13
			'ad_priority'	=> $this->request->variable('ad_priority', 5),
447 13
		);
448 2
449 2
		// Validate form key
450
		if (!check_form_key($form_name))
451
		{
452 13
			$this->errors[] = $this->user->lang('FORM_INVALID');
453 13
		}
454 4
455
		// Validate ad name
456 4
		if ($data['ad_name'] === '')
457 4
		{
458 2
			$this->errors[] = $this->user->lang('AD_NAME_REQUIRED');
459 2
		}
460 4
		if (truncate_string($data['ad_name'], self::MAX_NAME_LENGTH) !== $data['ad_name'])
461 9
		{
462 9
			$this->errors[] = $this->user->lang('AD_NAME_TOO_LONG', self::MAX_NAME_LENGTH);
463
		}
464
465
		// Validate ad end date
466
		if (preg_match('#^\d{4}\-\d{2}\-\d{2}$#', $data['ad_end_date']))
467 9
		{
468
			$data['ad_end_date'] = (int) $this->user->get_timestamp_from_format(self::DATE_FORMAT, $data['ad_end_date']);
469
470 13
			if ($data['ad_end_date'] < time())
471
			{
472
				$this->errors[] = $this->user->lang('AD_END_DATE_INVALID');
473
			}
474
		}
475
		else if ($data['ad_end_date'] !== '')
476
		{
477
			$this->errors[] = $this->user->lang('AD_END_DATE_INVALID');
478
		}
479 11
		else
480
		{
481 11
			$data['ad_end_date'] = 0;
482 11
		}
483 11
484
		// Validate ad priority
485 11
		if ($data['ad_priority'] < 1 || $data['ad_priority'] > 10)
486 11
		{
487 11
			$this->errors[] = $this->user->lang('AD_PRIORITY_INVALID');
488 11
		}
489 11
490 11
		return $data;
491 11
	}
492
493
	/**
494
	* Assign form data to the template.
495
	*
496
	* @param	array	$data	The form data.
497
	* @return void
498 11
	*/
499
	protected function assign_form_data($data)
500 11
	{
501 11
		$this->template->assign_vars(array(
502 8
			'S_ERROR'		=> (bool) count($this->errors),
503
			'ERROR_MSG'		=> count($this->errors) ? implode('<br />', $this->errors) : '',
504
505 3
			'AD_NAME'		=> $data['ad_name'],
506 3
			'AD_NOTE'		=> $data['ad_note'],
507 3
			'AD_CODE'		=> $data['ad_code'],
508
			'AD_ENABLED'	=> $data['ad_enabled'],
509
			'AD_END_DATE'	=> $this->prepare_end_date($data['ad_end_date']),
510
			'AD_PRIORITY'	=> $data['ad_priority'],
511
		));
512
	}
513
514
	/**
515
	* Prepare end date for display
516
	*
517
	* @param	mixed	$end_date	End date.
518
	* @return	string	End date prepared for display.
519 12
	*/
520
	protected function prepare_end_date($end_date)
521 12
	{
522
		if (empty($end_date))
523 12
		{
524 12
			return '';
525 12
		}
526 12
527 12
		if (is_numeric($end_date))
528 12
		{
529 12
			return $this->user->format_date($end_date, self::DATE_FORMAT);
530 12
		}
531
532
		return (string) $end_date;
533
	}
534
535
	/**
536
	* Assign template locations data to the template.
537
	*
538 2
	* @param	mixed	$data	The form data or nothing.
539
	* @return	void
540 2
	*/
541 2
	protected function assign_locations($data = false)
542
	{
543
		foreach ($this->location_manager->get_all_locations() as $location_id => $location_data)
544
		{
545
			$this->template->assign_block_vars('ad_locations', array(
546
				'LOCATION_ID'	=> $location_id,
547
				'LOCATION_DESC'	=> $location_data['desc'],
548 6
				'LOCATION_NAME'	=> $location_data['name'],
549
				'S_SELECTED'	=> $data ? in_array($location_id, $data['ad_locations']) : false,
550 6
			));
551
		}
552
	}
553
554
	/**
555
	* Prepare advertisement preview
556
	*
557
	* @param	string	$code	Ad code to preview
558 5
	* @return	void
559
	*/
560 5
	protected function ad_preview($code)
561
	{
562
		$this->template->assign_var('PREVIEW', htmlspecialchars_decode($code));
563
	}
564
565
	/**
566
	* Print success message.
567
	*
568
	* It takes arguments in the form of a language key, followed by language substitution values.
569
	*/
570 3
	protected function success()
571
	{
572 3
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action));
573 3
	}
574
575
	/**
576
	* Print error message.
577
	*
578
	* It takes arguments in the form of a language key, followed by language substitution values.
579
	*/
580
	protected function error()
581
	{
582
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action), E_USER_WARNING);
583
	}
584
585
	/**
586
	* Log action
587
	*
588
	* @param	string	$action		Performed action in uppercase
589
	* @param	string	$ad_name	Advertisement name
590
	* @return	void
591
	*/
592
	protected function log($action, $ad_name)
593
	{
594
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_PHPBB_ADS_' . $action . '_LOG', time(), array($ad_name));
595
	}
596
}
597