Completed
Pull Request — master (#49)
by Jakub
10:38 queued 02:02
created

admin_controller::action_edit()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 56
Code Lines 30

Duplication

Lines 16
Ratio 28.57 %

Code Coverage

Tests 35
CRAP Score 7.0529

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 16
loc 56
ccs 35
cts 39
cp 0.8974
rs 7.7489
cc 7
eloc 30
nc 6
nop 0
crap 7.0529

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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