Completed
Pull Request — master (#4)
by Jakub
14:22
created

admin_controller::action_add()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 49
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 49
ccs 0
cts 32
cp 0
rs 8.7972
cc 4
eloc 25
nc 3
nop 0
crap 20
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
20
	/** @var \phpbb\db\driver\driver_interface */
21
	protected $db;
22
23
	/** @var \phpbb\template\template */
24
	protected $template;
25
26
	/** @var \phpbb\user */
27
	protected $user;
28
29
	/** @var \phpbb\request\request */
30
	protected $request;
31
32
	/** @var \phpbb\admanagement\location\manager */
33
	protected $location_manager;
34
35
	/** @var string ads_table */
36
	protected $ads_table;
37
38
	/** @var string ad_locations_table */
39
	protected $ad_locations_table;
40
41
	/** @var string php_ext */
42
	protected $php_ext;
43
44
	/** @var string ext_path */
45
	protected $ext_path;
46
47
	/** @var string Custom form action */
48
	protected $u_action;
49
50
	/** @var array Form validation errors */
51
	protected $errors = array();
52
53
	/**
54
	* Constructor
55
	*
56
	* @param \phpbb\db\driver\driver_interface		$db					DB driver interface
57
	* @param \phpbb\template\template				$template			Template object
58
	* @param \phpbb\user							$user				User object
59
	* @param \phpbb\request\request					$request			Request object
60
	* @param \phpbb\admanagement\location\manager	$location_manager	Template location manager object
61
	* @param string									$ads_table			Ads table
62
	* @param string									$ad_locations_table	Ad locations table
63
	* @param string									$php_ext			PHP extension
64
	* @param string									$ext_path			Path to this extension
65
	*/
66
	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\template\template $template, \phpbb\user $user, \phpbb\request\request $request, \phpbb\admanagement\location\manager $location_manager, $ads_table, $ad_locations_table, $php_ext, $ext_path)
67
	{
68
		$this->db = $db;
69
		$this->template = $template;
70
		$this->user = $user;
71
		$this->request = $request;
72
		$this->location_manager = $location_manager;
73
		$this->ads_table = $ads_table;
74
		$this->ad_locations_table = $ad_locations_table;
75
		$this->php_ext = $php_ext;
76
		$this->ext_path = $ext_path;
77
	}
78
79
	/**
80
	* Process user request
81
	*
82
	* @return void
83
	*/
84
	public function main()
85
	{
86
		$this->user->add_lang_ext('phpbb/admanagement', 'acp');
87
88
		// Trigger specific action
89
		$action = $this->request->variable('action', '');
90
		if (in_array($action, array('add', 'edit', 'enable', 'disable', 'delete')))
91
		{
92
			$this->{'action_' . $action}();
93
		}
94
95
		// Otherwise default to this
96
		$this->list_ads();
97
	}
98
99
	/**
100
	* Set page url
101
	*
102
	* @param string $u_action Custom form action
103
	* @return void
104
	*/
105
	public function set_page_url($u_action)
106
	{
107
		$this->u_action = $u_action;
108
	}
109
110
	/**
111
	* Get ACP page title for Ads module
112
	*
113
	* @return string	Language string for Ads ACP module
114
	*/
115
	public function get_page_title()
116
	{
117
		return $this->user->lang('ACP_ADMANAGEMENT_TITLE');
118
	}
119
120
	/**
121
	* Add an advertisement
122
	*
123
	* @return void
124
	*/
125
	public function action_add()
126
	{
127
		add_form_key('phpbb/admanagement/add');
128
		if ($this->request->is_set_post('submit'))
129
		{
130
			$this->check_form_key('phpbb/admanagement/add');
131
132
			$data = $this->get_form_data();
133
134
			$this->validate($data);
135
136
			if (empty($this->errors))
137
			{
138
				// Do not store ad locations directly into ads table
139
				$ad_locations = $data['ad_locations'];
140
				unset($data['ad_locations']);
141
142
				// Insert the ad data to the database
143
				$sql = 'INSERT INTO ' . $this->ads_table . ' ' . $this->db->sql_build_array('INSERT', $data);
144
				$this->db->sql_query($sql);
145
146
				// Get new ad ID
147
				$ad_id = $this->db->sql_nextid();
148
149
				// Insert data to ad_locations table
150
				$sql_ary = array();
151
				foreach ($ad_locations as $ad_location)
152
				{
153
					$sql_ary[] = array(
154
						'ad_id'			=> $ad_id,
155
						'location_id'	=> $ad_location,
156
					);
157
				}
158
				$this->db->sql_multi_insert($this->ad_locations_table, $sql_ary);
159
160
				$this->success('ACP_AD_ADD_SUCCESS');
161
			}
162
163
			$this->assign_locations($data);
164
			$this->assign_form_data($data);
165
		}
166
167
		// Set output vars for display in the template
168
		$this->template->assign_vars(array(
169
			'S_ADD_AD'	=> true,
170
			'U_BACK'	=> $this->u_action,
171
		));
172
		$this->assign_locations();
173
	}
174
175
	/**
176
	* Edit an advertisement
177
	*
178
	* @return void
179
	*/
180
	public function action_edit()
181
	{
182
		$ad_id = $this->request->variable('id', 0);
183
184
		add_form_key('phpbb/admanagement/edit/' . $ad_id);
185
		if ($this->request->is_set_post('submit'))
186
		{
187
			$this->check_form_key('phpbb/admanagement/edit/' . $ad_id);
188
189
			$data = $this->get_form_data();
190
191
			$this->validate($data);
192
193
			if (empty($this->errors))
194
			{
195
				// Do not store ad locations directly into ads table
196
				$ad_locations = $data['ad_locations'];
197
				unset($data['ad_locations']);
198
199
				// Delete and repopulate ad locations
200
				$sql = 'DELETE FROM ' . $this->ad_locations_table . '
201
					WHERE ad_id = ' . (int) $ad_id;
202
				$this->db->sql_query($sql);
203
204
				// Insert data to ad_locations table
205
				$sql_ary = array();
206
				foreach ($ad_locations as $ad_location)
207
				{
208
					$sql_ary[] = array(
209
						'ad_id'			=> $ad_id,
210
						'location_id'	=> $ad_location,
211
					);
212
				}
213
				$this->db->sql_multi_insert($this->ad_locations_table, $sql_ary);
214
215
				// Insert the ad data to the database
216
				$sql = 'UPDATE ' . $this->ads_table . '
217
					SET ' . $this->db->sql_build_array('UPDATE', $data) . '
218
					WHERE ad_id = ' . (int) $ad_id;
219
				$this->db->sql_query($sql);
220
221
				if ($this->db->sql_affectedrows())
222
				{
223
					$this->success('ACP_AD_EDIT_SUCCESS');
224
				}
225
				$this->error('ACP_AD_DOES_NOT_EXIST');
226
			}
227
		}
228
		else
229
		{
230
			// Load ad data
231
			$sql = 'SELECT *
232
				FROM ' . $this->ads_table . '
233
				WHERE ad_id = ' . (int) $ad_id;
234
			$result = $this->db->sql_query($sql);
235
			$data = $this->db->sql_fetchrow($result);
236
			$this->db->sql_freeresult($result);
237
238
			if (empty($data))
239
			{
240
				$this->error('ACP_AD_DOES_NOT_EXIST');
241
			}
242
243
			// Load ad template locations
244
			$data['ad_locations'] = array();
245
246
			$sql = 'SELECT location_id
247
				FROM ' . $this->ad_locations_table . '
248
				WHERE ad_id = ' . (int) $ad_id;
249
			$result = $this->db->sql_query($sql);
250
			while ($row = $this->db->sql_fetchrow($result))
251
			{
252
				$data['ad_locations'][] = $row['location_id'];
253
			}
254
			$this->db->sql_freeresult($result);
255
		}
256
257
		// Set output vars for display in the template
258
		$this->template->assign_vars(array(
259
			'S_EDIT_AD'	=> true,
260
			'EDIT_ID'	=> $ad_id,
261
			'U_BACK'	=> $this->u_action,
262
		));
263
		$this->assign_locations($data);
264
		$this->assign_form_data($data);
265
	}
266
267
	/**
268
	* Enable an advertisement
269
	*
270
	* @return void
271
	*/
272
	public function action_enable()
273
	{
274
		$this->ad_enable(true);
275
	}
276
277
	/**
278
	* Disable an advertisement
279
	*
280
	* @return void
281
	*/
282
	public function action_disable()
283
	{
284
		$this->ad_enable(false);
285
	}
286
287
	/**
288
	* Delete an advertisement
289
	*
290
	* @return void
291
	*/
292
	public function action_delete()
293
	{
294
		$ad_id = $this->request->variable('id', 0);
295
		if ($ad_id)
296
		{
297
			if (confirm_box(true))
298
			{
299
				// Delete all template locations
300
				$sql = 'DELETE FROM ' . $this->ad_locations_table . '
301
					WHERE ad_id = ' . (int) $ad_id;
302
				$this->db->sql_query($sql);
303
304
				// Delete advertisement
305
				$sql = 'DELETE FROM ' . $this->ads_table . '
306
					WHERE ad_id = ' . (int) $ad_id;
307
				$this->db->sql_query($sql);
308
309
				// Only notify user on error or if not ajax
310
				if (!$this->db->sql_affectedrows())
311
				{
312
					$this->error('ACP_AD_DELETE_ERRORED');
313
				}
314
				else if (!$this->request->is_ajax())
315
				{
316
					$this->success('ACP_AD_DELETE_SUCCESS');
317
				}
318
			}
319
			else
320
			{
321
				confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
322
					'id'		=> $ad_id,
323
					'i'			=> $this->request->variable('i', ''),
324
					'mode'		=> $this->request->variable('mode', ''),
325
					'action'	=> 'delete'
326
				)));
327
			}
328
		}
329
	}
330
331
	/**
332
	* Display the ads
333
	*
334
	* @return void
335
	*/
336
	public function list_ads()
337
	{
338
		$sql = 'SELECT ad_id, ad_name, ad_enabled
339
			FROM ' . $this->ads_table;
340
		$result = $this->db->sql_query($sql);
341
		while ($row = $this->db->sql_fetchrow($result))
342
		{
343
			$ad_enabled = (int) $row['ad_enabled'];
344
345
			$this->template->assign_block_vars('ads', array(
346
				'NAME'		=> $row['ad_name'],
347
				'S_ENABLED'	=> $ad_enabled,
348
				'U_ENABLE'	=> $this->u_action . '&amp;action=' . ($ad_enabled ? 'disable' : 'enable') . '&amp;id=' . $row['ad_id'],
349
				'U_PREVIEW'	=> append_sid(generate_board_url() . '/index.' . $this->php_ext, 'ad_preview=' . $row['ad_id']),
350
				'U_EDIT'	=> $this->u_action . '&amp;action=edit&amp;id=' . $row['ad_id'],
351
				'U_DELETE'	=> $this->u_action . '&amp;action=delete&amp;id=' . $row['ad_id'],
352
			));
353
		}
354
		$this->db->sql_freeresult($result);
355
356
		// Set output vars for display in the template
357
		$this->template->assign_vars(array(
358
			'U_ACTION_ADD'	=> $this->u_action . '&amp;action=add',
359
			'ICON_PREVIEW'	=> '<img src="' . $this->ext_path . 'adm/images/icon_preview.png" alt="' . $this->user->lang('AD_PREVIEW') . '" title="' . $this->user->lang('AD_PREVIEW') . '" />',
360
		));
361
	}
362
363
	/**
364
	* Enable/disable an advertisement
365
	*
366
	* @param	bool	$enable	Enable or disable the advertisement?
367
	* @return void
368
	*/
369
	protected function ad_enable($enable)
370
	{
371
		$ad_id = $this->request->variable('id', 0);
372
373
		$sql = 'UPDATE ' . $this->ads_table . '
374
			SET ad_enabled = ' . (int) $enable . '
375
			WHERE ad_id = ' . (int) $ad_id;
376
		$this->db->sql_query($sql);
377
		$success = (bool) $this->db->sql_affectedrows();
378
379
		// If AJAX was used, show user a result message
380
		if ($this->request->is_ajax())
381
		{
382
			$json_response = new \phpbb\json_response;
383
			$json_response->send(array(
384
				'text'	=> $this->user->lang($enable ? 'ENABLED' : 'DISABLED'),
385
				'title'	=> $this->user->lang('AD_ENABLE_TITLE', (int) $enable),
386
			));
387
		}
388
389
		// Otherwise, show traditional infobox
390
		if ($success)
391
		{
392
			$this->success($enable ? 'ACP_AD_ENABLE_SUCCESS' : 'ACP_AD_DISABLE_SUCCESS');
393
		}
394
		else
395
		{
396
			$this->error($enable ? 'ACP_AD_ENABLE_ERRORED' : 'ACP_AD_DISABLE_ERRORED');
397
		}
398
	}
399
400
	/**
401
	* Check the form key.
402
	*
403
	* @param	string	$form_name	The name of the form.
404
	* @return void
405
	*/
406
	protected function check_form_key($form_name)
407
	{
408
		if (!check_form_key($form_name))
409
		{
410
			$this->errors[] = $this->user->lang('FORM_INVALID');
411
		}
412
	}
413
414
	/**
415
	* Get admin form data.
416
	*
417
	* @return	array	Form data
418
	*/
419
	protected function get_form_data()
420
	{
421
		return array(
422
			'ad_name'		=> $this->request->variable('ad_name', '', true),
423
			'ad_note'		=> $this->request->variable('ad_note', '', true),
424
			'ad_code'		=> $this->request->variable('ad_code', '', true),
425
			'ad_enabled'	=> $this->request->variable('ad_enabled', 0),
426
			'ad_locations'	=> $this->request->variable('ad_locations', array('')),
427
		);
428
	}
429
430
	/**
431
	* Validate form data.
432
	*
433
	* @param	array	$data	The form data.
434
	* @return void
435
	*/
436
	protected function validate($data)
437
	{
438
		if ($data['ad_name'] === '')
439
		{
440
			$this->errors[] = $this->user->lang('AD_NAME_REQUIRED');
441
		}
442
		if (truncate_string($data['ad_name'], self::MAX_NAME_LENGTH) !== $data['ad_name'])
443
		{
444
			$this->errors[] = $this->user->lang('AD_NAME_TOO_LONG', self::MAX_NAME_LENGTH);
445
		}
446
	}
447
448
	/**
449
	* Assign form data to the template.
450
	*
451
	* @param	array	$data	The form data.
452
	* @return void
453
	*/
454
	protected function assign_form_data($data)
455
	{
456
		$this->template->assign_vars(array(
457
			'S_ERROR'		=> (bool) count($this->errors),
458
			'ERROR_MSG'		=> count($this->errors) ? implode('<br />', $this->errors) : '',
459
460
			'AD_NAME'		=> $data['ad_name'],
461
			'AD_NOTE'		=> $data['ad_note'],
462
			'AD_CODE'		=> $data['ad_code'],
463
			'AD_ENABLED'	=> $data['ad_enabled'],
464
		));
465
	}
466
467
	/**
468
	* Assign template locations data to the template.
469
	*
470
	* @param	mixed	$data	The form data or nothing.
471
	* @return	void
472
	*/
473
	protected function assign_locations($data = false)
474
	{
475
		foreach ($this->location_manager->get_all_locations() as $location_id => $location_data)
476
		{
477
			$this->template->assign_block_vars('ad_locations', array(
478
				'LOCATION_ID'	=> $location_id,
479
				'LOCATION_DESC'	=> $location_data['desc'],
480
				'LOCATION_NAME'	=> $location_data['name'],
481
				'S_SELECTED'	=> $data ? in_array($location_id, $data['ad_locations']) : false,
482
			));
483
		}
484
	}
485
486
	/**
487
	* Print success message.
488
	*
489
	* It takes arguments in the form of a language key, followed by language substitution values.
490
	*/
491
	protected function success()
492
	{
493
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action));
494
	}
495
496
	/**
497
	* Print error message.
498
	*
499
	* It takes arguments in the form of a language key, followed by language substitution values.
500
	*/
501
	protected function error()
502
	{
503
		trigger_error(call_user_func_array(array($this->user, 'lang'), func_get_args()) . adm_back_link($this->u_action), E_USER_WARNING);
504
	}
505
}
506