Completed
Pull Request — master (#48)
by Jakub
08:27
created

admin_controller::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 13
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 12
nc 1
nop 11
crap 2

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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