cat::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.584
c 0
b 0
f 0
cc 2
nc 2
nop 10

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
* phpBB Directory extension for the phpBB Forum Software package.
5
*
6
* @copyright (c) 2014 ErnadoO <http://www.phpbb-services.com>
7
* @license GNU General Public License, version 2 (GPL-2.0)
8
*
9
*/
10
11
namespace ernadoo\phpbbdirectory\controller\acp;
12
13
use \ernadoo\phpbbdirectory\core\helper;
14
15
class cat extends helper
16
{
17
	/** @var \phpbb\cache\service */
18
	protected $cache;
19
20
	/** @var \phpbb\db\driver\driver_interface */
21
	protected $db;
22
23
	/** @var \phpbb\controller\helper */
24
	protected $helper;
25
26
	/** @var \phpbb\language\language */
27
	protected $language;
28
29
	/** @var \phpbb\log\log */
30
	protected $phpbb_log;
31
32
	/** @var \phpbb\request\request */
33
	protected $request;
34
35
	/** @var \phpbb\template\template */
36
	protected $template;
37
38
	/** @var \phpbb\user */
39
	protected $user;
40
41
	/** @var \ernadoo\phpbbdirectory\core\categorie */
42
	protected $categorie;
43
44
	/** @var \ernadoo\phpbbdirectory\core\nestedset_category */
45
	protected $nestedset_category;
46
47
	/** @var string Custom form action */
48
	protected $u_action;
49
50
	/** @var string */
51
	private $action;
52
53
	/** @var array */
54
	private $cat_data = array();
55
56
	/** @var int */
57
	private $cat_id;
58
59
	/** @var array */
60
	private $errors = array();
61
62
	/** @var string */
63
	private $form_key;
64
65
	/** @var int */
66
	private $parent_id;
67
68
	/** @var bool */
69
	private $update;
70
71
	/**
72
	* Constructor
73
	*
74
	* @param \phpbb\cache\service								$cache				Cache object
75
	* @param \phpbb\db\driver\driver_interface 					$db					Database object
76
	* @param \phpbb\controller\helper							$helper				Helper object
77
	* @param \phpbb\language\language							$language			Language object
78
	* @param \phpbb\log\log										$log				Log object
79
	* @param \phpbb\request\request								$request			Request object
80
	* @param \phpbb\template\template							$template			Template object
81
	* @param \phpbb\user										$user				User object
82
	* @param \ernadoo\phpbbdirectory\core\categorie				$categorie			PhpBB Directory extension categorie object
83
	* @param \ernadoo\phpbbdirectory\core\nestedset_category	$nestedset_category	PhpBB Directory extension nestedset object
84
	*/
85
	public function __construct(\phpbb\cache\service $cache, \phpbb\db\driver\driver_interface $db, \phpbb\controller\helper $helper, \phpbb\language\language $language, \phpbb\log\log $log, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user, \ernadoo\phpbbdirectory\core\categorie $categorie, \ernadoo\phpbbdirectory\core\nestedset_category $nestedset_category)
86
	{
87
		$this->cache				= $cache;
88
		$this->db					= $db;
89
		$this->helper				= $helper;
90
		$this->language				= $language;
91
		$this->phpbb_log			= $log;
92
		$this->request				= $request;
93
		$this->template				= $template;
94
		$this->user					= $user;
95
		$this->categorie			= $categorie;
96
		$this->nestedset_category	= $nestedset_category;
97
98
		$this->form_key = 'acp_dir_cat';
99
		add_form_key($this->form_key);
100
101
		$this->action		= $this->request->variable('action', '');
102
		$this->cat_id		= $request->variable('c', 0);
103
		$this->parent_id	= $request->variable('parent_id', 0);
104
		$this->update		= ($this->request->is_set_post('update')) ? true : false;
105
	}
106
107
	/**
108
	* Initialize defaults data for add page
109
	*
110
	* @return null
111
	*/
112
	public function action_add()
113
	{
114
		$this->cat_id = $this->parent_id;
115
		$parents_list = $this->categorie->make_cat_select($this->parent_id);
116
117
		// Fill categorie data with default values
118
		if (!$this->update)
119
		{
120
			$this->cat_data = array(
121
				'parent_id'				=> $this->parent_id,
122
				'cat_name'				=> $this->request->variable('cat_name', '', true),
123
				'cat_route'				=> '',
124
				'cat_desc'				=> '',
125
				'cat_icon'				=> '',
126
				'cat_allow_comments'	=> true,
127
				'cat_allow_votes'		=> true,
128
				'cat_must_describe'		=> true,
129
				'cat_count_all'			=> false,
130
				'cat_validate'			=> false,
131
				'enable_icons'			=> false,
132
133
				'display_subcat_list'	=> true,
134
135
				'cat_link_back'			=> false,
136
				'cat_cron_enable'		=> false,
137
				'cat_cron_freq'			=> 7,
138
				'cat_cron_nb_check'		=> 1,
139
			);
140
		}
141
142
		$this->_display_cat_form($parents_list);
143
	}
144
145
	/**
146
	* Display deleting page
147
	*
148
	* @return null
149
	*/
150
	public function action_delete()
151
	{
152 View Code Duplication
		if (!$this->cat_id)
153
		{
154
			trigger_error($this->language->lang('DIR_NO_CAT') . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
155
		}
156
157
		$this->cat_data = $this->_get_cat_info($this->cat_id);
158
159
		$subcats_id = array();
160
		$subcats = $this->nestedset_category->get_subtree_data($this->cat_id);
161
162
		foreach ($subcats as $row)
163
		{
164
			$subcats_id[] = $row['cat_id'];
165
		}
166
167
		$cat_list = $this->categorie->make_cat_select((int) $this->cat_data['parent_id'], $subcats_id);
168
169
		$sql = 'SELECT cat_id
170
			FROM ' . $this->categories_table . '
171
			WHERE cat_id <> ' . (int) $this->cat_id;
172
		$result = $this->db->sql_query_limit($sql, 1);
173
174
		if ($this->db->sql_fetchrow($result))
175
		{
176
			$this->template->assign_vars(array(
177
				'S_MOVE_DIR_CAT_OPTIONS'	=> $this->categorie->make_cat_select((int) $this->cat_data['parent_id'], $subcats_id))
178
			);
179
		}
180
		$this->db->sql_freeresult($result);
181
182
		$parent_id = ($this->parent_id == $this->cat_id) ? 0 : $this->parent_id;
183
184
		$this->template->assign_vars(array(
185
			'S_DELETE_DIR_CAT'		=> true,
186
			'U_ACTION'				=> $this->u_action . "&amp;parent_id={$parent_id}&amp;action=delete&amp;c=$this->cat_id",
187
			'U_BACK'				=> $this->u_action . '&amp;parent_id=' . $this->parent_id,
188
189
			'DIR_CAT_NAME'			=> $this->cat_data['cat_name'],
190
			'S_HAS_SUBCATS'			=> ($this->cat_data['right_id'] - $this->cat_data['left_id'] > 1) ? true : false,
191
			'S_CATS_LIST'			=> $cat_list,
192
			'S_ERROR'				=> (count($this->errors)) ? true : false,
193
			'ERROR_MSG'				=> (count($this->errors)) ? implode('<br />', $this->errors) : '')
194
		);
195
196
		return;
197
	}
198
199
	/**
200
	* Initialize data for edit page
201
	*
202
	* @return null
203
	*/
204
	public function action_edit()
205
	{
206
		$row = $this->_get_cat_info($this->cat_id);
207
208
		if (!$this->update)
209
		{
210
			$this->cat_data = $row;
211
		}
212
		else
213
		{
214
			$this->cat_data['left_id'] = $row['left_id'];
215
			$this->cat_data['right_id'] = $row['right_id'];
216
		}
217
218
		// Make sure no direct child categories are able to be selected as parents.
219
		$exclude_cats = array();
220
		foreach ($this->nestedset_category->get_subtree_data($this->cat_id) as $row2)
221
		{
222
			$exclude_cats[] = $row2['cat_id'];
223
		}
224
		$parents_list = $this->categorie->make_cat_select((int) $this->cat_data['parent_id'], $exclude_cats);
225
226
		$this->_display_cat_form($parents_list);
227
	}
228
229
	/**
230
	* Move order categories
231
	*
232
	* @return null
233
	*/
234
	public function action_move()
235
	{
236 View Code Duplication
		if (!$this->cat_id)
237
		{
238
			trigger_error($this->language->lang('DIR_NO_CAT') . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
239
		}
240
241
		$sql = 'SELECT cat_id, cat_name, parent_id, left_id, right_id
242
			FROM ' . $this->categories_table . '
243
			WHERE cat_id = ' . (int) $this->cat_id;
244
		$result = $this->db->sql_query($sql);
245
		$row = $this->db->sql_fetchrow($result);
246
		$this->db->sql_freeresult($result);
247
248 View Code Duplication
		if (!$row)
249
		{
250
			trigger_error($this->language->lang('DIR_NO_CAT') . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
251
		}
252
253
		try
254
		{
255
			$move_cat_name = $this->nestedset_category->{$this->action}($this->cat_id);
256
		}
257
		catch (\Exception $e)
258
		{
259
			trigger_error($e->getMessage(), E_USER_WARNING);
260
		}
261
262
		if ($move_cat_name !== false)
263
		{
264
			$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_' . strtoupper($this->action), time(), array($row['cat_name'], $move_cat_name));
265
			$this->cache->destroy('sql', $this->categories_table);
266
		}
267
268
		if ($this->request->is_ajax())
269
		{
270
			$json_response = new \phpbb\json_response;
271
			$json_response->send(array('success' => ($move_cat_name !== false)));
272
		}
273
	}
274
275
	/**
276
	* Display progress bar for syncinc categories
277
	*
278
	* @return null
279
	*/
280
	public function action_progress_bar()
281
	{
282
		$start = $this->request->variable('start', 0);
283
		$total = $this->request->variable('total', 0);
284
285
		adm_page_header($this->language->lang('SYNC_IN_PROGRESS'));
286
287
		$this->template->set_filenames(array(
288
			'body'	=> 'progress_bar.html')
289
		);
290
291
		$this->template->assign_vars(array(
292
			'L_PROGRESS'			=> $this->language->lang('SYNC_IN_PROGRESS'),
293
			'L_PROGRESS_EXPLAIN'	=> ($start && $total) ? $this->language->lang('SYNC_IN_PROGRESS_EXPLAIN', $start, $total) : $this->language->lang('SYNC_IN_PROGRESS'))
294
		);
295
296
		adm_page_footer();
297
	}
298
299
	/**
300
	* Get link's ID interval for _sync_dir_links()
301
	*
302
	* @return null
303
	*/
304
	public function action_sync()
305
	{
306 View Code Duplication
		if (!$this->cat_id)
307
		{
308
			trigger_error($this->language->lang('DIR_NO_CAT') . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
309
		}
310
311
		@set_time_limit(0);
312
313
		$sql = 'SELECT cat_name, cat_links
314
			FROM ' . $this->categories_table . '
315
			WHERE cat_id = ' . (int) $this->cat_id;
316
		$result = $this->db->sql_query($sql);
317
		$row = $this->db->sql_fetchrow($result);
318
		$this->db->sql_freeresult($result);
319
320 View Code Duplication
		if (!$row)
321
		{
322
			trigger_error($this->language->lang('DIR_NO_CAT') . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
323
		}
324
325
		$sql = 'SELECT MIN(link_id) as min_link_id, MAX(link_id) as max_link_id
326
			FROM ' . $this->links_table . '
327
			WHERE link_cat = ' . (int) $this->cat_id . '
328
				AND link_active = 1';
329
		$result = $this->db->sql_query($sql);
330
		$row2 = $this->db->sql_fetchrow($result);
331
		$this->db->sql_freeresult($result);
332
333
		// Typecast to int if there is no data available
334
		$row2['min_link_id'] = (int) $row2['min_link_id'];
335
		$row2['max_link_id'] = (int) $row2['max_link_id'];
336
337
		$start = $this->request->variable('start', $row2['min_link_id']);
338
339
		$batch_size = 200;
340
		$end = $start + $batch_size;
341
342
		// Sync all links in batch mode...
343
		$this->_sync_dir_links($start, $end);
344
345
		if ($end < $row2['max_link_id'])
346
		{
347
			// We really need to find a way of showing statistics... no progress here
348
			$sql = 'SELECT COUNT(link_id) as num_links
349
				FROM ' . $this->links_table . '
350
				WHERE link_cat = ' . (int) $this->cat_id . '
351
						AND link_active = 1
352
						AND link_id BETWEEN ' . (int) $start . ' AND ' . (int) $end;
353
			$result = $this->db->sql_query($sql);
354
			$links_done = $this->request->variable('links_done', 0) + (int) $this->db->sql_fetchfield('num_links');
355
			$this->db->sql_freeresult($result);
356
357
			$start += $batch_size;
358
359
			$url = $this->u_action . "&amp;parent_id={$this->parent_id}&amp;c=$this->cat_id&amp;action=sync&amp;start=$start&amp;links_done=$links_done&amp;total={$row['cat_links']}";
360
361
			meta_refresh(0, $url);
362
363
			$this->template->assign_vars(array(
364
				'UA_PROGRESS_BAR'		=> $this->u_action . "&amp;action=progress_bar&amp;start=$links_done&amp;total={$row['cat_links']}",
365
				'S_CONTINUE_SYNC'		=> true,
366
				'L_PROGRESS_EXPLAIN'	=> $this->language->lang('SYNC_IN_PROGRESS_EXPLAIN', $links_done, $row['cat_links']))
367
			);
368
369
			return;
370
		}
371
372
		$url = $this->u_action . "&amp;parent_id={$this->parent_id}&amp;c=$this->cat_id&amp;action=sync_cat";
373
		meta_refresh(0, $url);
374
375
		$this->template->assign_vars(array(
376
			'UA_PROGRESS_BAR'		=> $this->u_action . '&amp;action=progress_bar',
377
			'S_CONTINUE_SYNC'		=> true,
378
			'L_PROGRESS_EXPLAIN'	=> $this->language->lang('SYNC_IN_PROGRESS_EXPLAIN', 0, $row['cat_links']))
379
		);
380
381
		return;
382
	}
383
384
	/**
385
	* Sync category data
386
	*
387
	* @return null
388
	*/
389
	public function action_sync_cat()
390
	{
391
		$sql = 'SELECT cat_name
392
			FROM ' . $this->categories_table . '
393
			WHERE cat_id = ' . (int) $this->cat_id;
394
		$result = $this->db->sql_query($sql);
395
		$row = $this->db->sql_fetchrow($result);
396
		$this->db->sql_freeresult($result);
397
398 View Code Duplication
		if (!$row)
399
		{
400
			trigger_error($this->language->lang('DIR_NO_CAT') . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id), E_USER_WARNING);
401
		}
402
403
		$this->_sync_dir_cat($this->cat_id);
404
405
		$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_SYNC', time(), array($row['cat_name']));
406
		$this->cache->destroy('sql', $this->categories_table);
407
408
		$this->template->assign_var('L_DIR_CAT_RESYNCED', $this->language->lang('DIR_CAT_RESYNCED', $row['cat_name']));
409
	}
410
411
	/**
412
	* Display categories page
413
	*
414
	* @return null
415
	*/
416
	public function display_cats()
417
	{
418
		// Default management page
419
		if (!$this->parent_id)
420
		{
421
			$navigation = $this->language->lang('DIR_INDEX');
422
		}
423
		else
424
		{
425
			$navigation = '<a href="' . $this->u_action . '">' . $this->language->lang('DIR_INDEX') . '</a>';
426
427
			$cats_nav = $this->nestedset_category->get_path_data($this->parent_id);
428
429
			foreach ($cats_nav as $row)
430
			{
431
				if ($row['cat_id'] == $this->parent_id)
432
				{
433
					$navigation .= ' -&gt; ' . $row['cat_name'];
434
				}
435
				else
436
				{
437
					$navigation .= ' -&gt; <a href="' . $this->u_action . '&amp;parent_id=' . $row['cat_id'] . '">' . $row['cat_name'] . '</a>';
438
				}
439
			}
440
		}
441
442
		// Jumpbox
443
		$cat_box = $this->categorie->make_cat_select($this->parent_id);
444
445
		if ($this->action == 'sync' || $this->action == 'sync_cat')
446
		{
447
			$this->template->assign_var('S_RESYNCED', true);
448
		}
449
450
		$sql = 'SELECT cat_id, parent_id, right_id, left_id, cat_name, cat_icon, cat_desc_uid, cat_desc_bitfield, cat_desc, cat_desc_options, cat_links
451
			FROM ' . $this->categories_table . '
452
			WHERE parent_id = ' . (int) $this->parent_id . '
453
			ORDER BY left_id';
454
		$result = $this->db->sql_query($sql);
455
456
		if ($row = $this->db->sql_fetchrow($result))
457
		{
458
			do
459
			{
460
				$folder_image = ($row['left_id'] + 1 != $row['right_id']) ? '<img src="images/icon_subfolder.gif" alt="' . $this->language->lang('DIR_SUBCAT') . '" />' : '<img src="images/icon_folder.gif" alt="' . $this->language->lang('FOLDER') . '" />';
461
462
				$url = $this->u_action . "&amp;parent_id=$this->parent_id&amp;c={$row['cat_id']}";
463
464
				$this->template->assign_block_vars('cats', array(
465
					'FOLDER_IMAGE'		=> $folder_image,
466
					'CAT_IMAGE'			=> ($row['cat_icon']) ? '<img src="' . $this->get_img_path('icons', $row['cat_icon']) . '" alt="" />' : '',
467
					'CAT_NAME'			=> $row['cat_name'],
468
					'CAT_DESCRIPTION'	=> generate_text_for_display($row['cat_desc'], $row['cat_desc_uid'], $row['cat_desc_bitfield'], $row['cat_desc_options']),
469
					'CAT_LINKS'			=> $row['cat_links'],
470
471
					'U_CAT'				=> $this->u_action . '&amp;parent_id=' . $row['cat_id'],
472
					'U_MOVE_UP'			=> $url . '&amp;action=move_up',
473
					'U_MOVE_DOWN'		=> $url . '&amp;action=move_down',
474
					'U_EDIT'			=> $url . '&amp;action=edit',
475
					'U_DELETE'			=> $url . '&amp;action=delete',
476
					'U_SYNC'			=> $url . '&amp;action=sync')
477
				);
478
			}
479
			while ($row = $this->db->sql_fetchrow($result));
480
		}
481
		else if ($this->parent_id)
482
		{
483
			$row = $this->_get_cat_info($this->parent_id);
484
485
			$url = $this->u_action . '&amp;parent_id=' . $this->parent_id . '&amp;c=' . $row['cat_id'];
486
487
			$this->template->assign_vars(array(
488
				'S_NO_CATS'			=> true,
489
490
				'U_EDIT'			=> $url . '&amp;action=edit',
491
				'U_DELETE'			=> $url . '&amp;action=delete',
492
				'U_SYNC'			=> $url . '&amp;action=sync')
493
			);
494
		}
495
		$this->db->sql_freeresult($result);
496
497
		$this->template->assign_vars(array(
498
			'ERROR_MSG'		=> (count($this->errors)) ? implode('<br />', $this->errors) : '',
499
			'NAVIGATION'	=> $navigation,
500
			'CAT_BOX'		=> $cat_box,
501
			'U_SEL_ACTION'	=> $this->u_action,
502
			'U_ACTION'		=> $this->u_action . '&amp;parent_id=' . $this->parent_id,
503
504
			'UA_PROGRESS_BAR'	=> $this->u_action . '&amp;action=progress_bar',
505
		));
506
	}
507
508
	/**
509
	* Set page url
510
	*
511
	* @param	string $u_action Custom form action
512
	* @return	null
513
	* @access	public
514
	*/
515
	public function set_page_url($u_action)
516
	{
517
		$this->u_action = $u_action;
518
	}
519
520
	/**
521
	* Update cat table
522
	*
523
	* @return null
524
	*/
525
	public function update()
526
	{
527
		if (!check_form_key($this->form_key))
528
		{
529
			$this->update = false;
530
			$this->errors[] = $this->language->lang('FORM_INVALID');
531
			return;
532
		}
533
534
		switch ($this->action)
535
		{
536
			case 'delete':
537
				$action_subcats	= $this->request->variable('action_subcats', '');
538
				$subcats_to_id	= $this->request->variable('subcats_to_id', 0);
539
				$action_links	= $this->request->variable('action_links', '');
540
				$links_to_id	= $this->request->variable('links_to_id', 0);
541
542
				try
543
				{
544
					$this->errors = $this->_delete_cat($action_links, $action_subcats, $links_to_id, $subcats_to_id);
545
				}
546
				catch (\Exception $e)
547
				{
548
					trigger_error($e->getMessage(), E_USER_WARNING);
549
				}
550
551
				$message = 'DIR_CAT_DELETED';
552
553
				break;
554
555
			case 'edit':
556
				$this->cat_data = array(
557
					'cat_id'		=>	$this->cat_id
558
				);
559
				// No break here
560
			case 'add':
561
562
				$this->cat_data += array(
563
					'parent_id'				=> $this->request->variable('cat_parent_id', (int) $this->parent_id),
564
					'cat_parents'			=> '',
565
					'cat_name'				=> $this->request->variable('cat_name', '', true),
566
					'cat_route'				=> $this->request->variable('cat_route', ''),
567
					'cat_desc'				=> $this->request->variable('cat_desc', '', true),
568
					'cat_desc_uid'			=> '',
569
					'cat_desc_options'		=> 7,
570
					'cat_desc_bitfield'		=> '',
571
					'cat_icon'				=> $this->request->variable('cat_icon', ''),
572
					'display_subcat_list'	=> $this->request->variable('display_on_index', false),
573
					'cat_allow_comments'	=> $this->request->variable('allow_comments', 1),
574
					'cat_allow_votes'		=> $this->request->variable('allow_votes', 1),
575
					'cat_must_describe'		=> $this->request->variable('must_describe', 1),
576
					'cat_count_all'			=> $this->request->variable('count_all', 0),
577
					'cat_validate'			=> $this->request->variable('validate', 0),
578
					'cat_link_back'			=> $this->request->variable('link_back', 0),
579
					'cat_cron_enable'		=> $this->request->variable('cron_enable', 0),
580
					'cat_cron_freq'			=> $this->request->variable('cron_every', 7),
581
					'cat_cron_nb_check'		=> $this->request->variable('nb_check', 1),
582
				);
583
584
				// Get data for cat description if specified
585
				if ($this->cat_data['cat_desc'])
586
				{
587
					generate_text_for_storage($this->cat_data['cat_desc'], $this->cat_data['cat_desc_uid'], $this->cat_data['cat_desc_bitfield'], $this->cat_data['cat_desc_options'], $this->request->variable('desc_parse_bbcode', false), $this->request->variable('desc_parse_urls', false), $this->request->variable('desc_parse_smilies', false));
588
				}
589
590
				try
591
				{
592
					$this->errors = $this->_update_cat_data();
593
				}
594
				catch (\Exception $e)
595
				{
596
					trigger_error($e->getMessage(), E_USER_WARNING);
597
				}
598
599
				$message = ($this->action == 'add') ? 'DIR_CAT_CREATED' : 'DIR_CAT_UPDATED';
600
601
			break;
602
		}
603
604 View Code Duplication
		if (!count($this->errors))
605
		{
606
			// Purge the cache to refresh route collections
607
			$this->cache->purge();
608
609
			trigger_error($this->language->lang($message) . adm_back_link($this->u_action . '&amp;parent_id=' . $this->parent_id));
610
		}
611
	}
612
613
	/**
614
	* Check route
615
	*
616
	* @param string $route Route text
617
	* @return null
618
	* @access public
619
	* @throws \phpbb\pages\exception\unexpected_value
620
	*/
621
	private function _check_route($route)
622
	{
623
		// Route is a required field
624
		if (empty($route))
625
		{
626
			$this->errors[] = $this->language->lang('DIR_CAT_ROUTE_EMPTY');
627
			return;
628
		}
629
630
		// Route should not contain any unexpected special characters
631
		if (!preg_match('/^[^!"#$%&*\'()+,.\/\\\\:;<=>?@\\[\\]^`{|}~ ]*$/', $route))
632
		{
633
			$this->errors[] = $this->language->lang('DIR_CAT_ROUTE_ILLEGAL_CHARACTERS');
634
		}
635
636
		$sql = 'SELECT cat_route
637
			FROM ' . $this->categories_table  . "
638
			WHERE cat_route = '" . $this->db->sql_escape($route) . "'
639
				AND cat_id <> " . $this->cat_id;
640
		$result = $this->db->sql_query_limit($sql, 1);
641
		$row = $this->db->sql_fetchrow($result);
642
		$this->db->sql_freeresult($result);
643
644
		if ($row)
645
		{
646
			$this->errors[] = $this->language->lang('DIR_CAT_ROUTE_NOT_UNIQUE');
647
		}
648
	}
649
650
	/**
651
	* Display form
652
	*
653
	* @param	string $parents_list	Drop-down list
654
	* @return	null
655
	*/
656
	private function _display_cat_form($parents_list)
657
	{
658
		$dir_cat_desc_data = array(
659
			'text'			=> $this->cat_data['cat_desc'],
660
			'allow_bbcode'	=> true,
661
			'allow_smilies'	=> true,
662
			'allow_urls'	=> true
663
		);
664
665
		// Parse desciption if specified
666
		if ($this->cat_data['cat_desc'])
667
		{
668
			if (!isset($this->cat_data['cat_desc_uid']))
669
			{
670
				// Before we are able to display the preview and plane text, we need to parse our $request->variable()'d value...
671
				$this->cat_data['cat_desc_uid'] = '';
672
				$this->cat_data['cat_desc_bitfield'] = '';
673
				$this->cat_data['cat_desc_options'] = 0;
674
675
				generate_text_for_storage($this->cat_data['cat_desc'], $this->cat_data['cat_desc_uid'], $this->cat_data['cat_desc_bitfield'], $this->cat_data['cat_desc_options'], $this->request->variable('desc_allow_bbcode', false), $this->request->variable('desc_allow_urls', false), $this->request->variable('desc_allow_smilies', false));
676
			}
677
678
			// decode...
679
			$dir_cat_desc_data = generate_text_for_edit($this->cat_data['cat_desc'], $this->cat_data['cat_desc_uid'], $this->cat_data['cat_desc_options']);
680
		}
681
682
		$this->template->assign_vars(array(
683
			'S_EDIT_CAT'		=> true,
684
			'S_ERROR'			=> (count($this->errors)) ? true : false,
685
			'S_CAT_PARENT_ID'	=> $this->cat_data['parent_id'],
686
			'S_ADD_ACTION'		=> ($this->action == 'add') ? true : false,
687
688
			'U_BACK'			=> $this->u_action . '&amp;parent_id=' . $this->parent_id,
689
			'U_EDIT_ACTION'		=> $this->u_action . "&amp;parent_id={$this->parent_id}&amp;action=$this->action&amp;c=$this->cat_id",
690
691
			'L_TITLE'					=> $this->language->lang('DIR_' . strtoupper($this->action) . '_CAT'),
692
			'ERROR_MSG'					=> (count($this->errors)) ? implode('<br />', $this->errors) : '',
693
			'ICON_IMAGE'				=> ($this->cat_data['cat_icon']) ? $this->get_img_path('icons', $this->cat_data['cat_icon']) : 'images/spacer.gif',
694
695
			'DIR_ICON_PATH'				=> $this->get_img_path('icons'),
696
			'DIR_CAT_NAME'				=> $this->cat_data['cat_name'],
697
			'DIR_CAT_ROUTE'				=> $this->cat_data['cat_route'],
698
			'DIR_CAT_DESC'				=> $dir_cat_desc_data['text'],
699
700
			'S_DESC_BBCODE_CHECKED'		=> ($dir_cat_desc_data['allow_bbcode']) ? true : false,
701
			'S_DESC_SMILIES_CHECKED'	=> ($dir_cat_desc_data['allow_smilies']) ? true : false,
702
			'S_DESC_URLS_CHECKED'		=> ($dir_cat_desc_data['allow_urls']) ? true : false,
703
			'S_DISPLAY_SUBCAT_LIST'		=> ($this->cat_data['display_subcat_list']) ? true : false,
704
			'S_PARENT_OPTIONS'			=> $parents_list,
705
			'S_ICON_OPTIONS'			=> $this->_get_dir_icon_list($this->get_img_path('icons'), $this->cat_data['cat_icon']),
706
			'S_ALLOW_COMMENTS'			=> ($this->cat_data['cat_allow_comments']) ? true : false,
707
			'S_ALLOW_VOTES'				=> ($this->cat_data['cat_allow_votes']) ? true : false,
708
			'S_MUST_DESCRIBE'			=> ($this->cat_data['cat_must_describe']) ? true : false,
709
			'S_COUNT_ALL'				=> ($this->cat_data['cat_count_all']) ? true : false,
710
			'S_VALIDATE'				=> ($this->cat_data['cat_validate']) ? true : false,
711
712
			'DIR_CRON_EVERY'			=> $this->cat_data['cat_cron_freq'],
713
			'DIR_NEXT_CRON_ACTION'		=> !empty($this->cat_data['cat_cron_next']) ? $this->user->format_date($this->cat_data['cat_cron_next']) : '-',
714
			'DIR_CRON_NB_CHECK'			=> $this->cat_data['cat_cron_nb_check'],
715
716
			'S_LINK_BACK'				=> ($this->cat_data['cat_link_back']) ? true : false,
717
			'S_CRON_ENABLE'				=> ($this->cat_data['cat_cron_enable']) ? true : false,
718
719
			'U_DATE'					=> $this->helper->route('ernadoo_phpbbdirectory_ajax_date_controller'),
720
			'U_SLUG'					=> $this->helper->route('ernadoo_phpbbdirectory_ajax_slug_controller'),
721
		));
722
723
		return;
724
	}
725
726
	/**
727
	* Get category details
728
	*
729
	* @param	int		$cat_id	The category ID
730
	* @return 	array
731
	*/
732 View Code Duplication
	private function _get_cat_info($cat_id)
733
	{
734
		$sql = 'SELECT cat_id, parent_id, right_id, left_id, cat_desc, cat_desc_uid, cat_desc_options, cat_icon, cat_name, cat_route, display_subcat_list, cat_allow_comments, cat_allow_votes, cat_must_describe, cat_count_all, cat_validate, cat_cron_freq, cat_cron_nb_check, cat_link_back, cat_cron_enable, cat_cron_next
735
			FROM ' . $this->categories_table . '
736
			WHERE cat_id = ' . (int) $cat_id;
737
		$result = $this->db->sql_query($sql);
738
		$row = $this->db->sql_fetchrow($result);
739
		$this->db->sql_freeresult($result);
740
741
		if (!$row)
742
		{
743
			trigger_error('DIR_ERROR_NO_CATS', E_USER_ERROR);
744
		}
745
746
		return $row;
747
	}
748
749
	/**
750
	* Update category data
751
	*
752
	* @return array
753
	*/
754
	private function _update_cat_data()
755
	{
756
		if (!$this->cat_data['cat_name'])
757
		{
758
			$this->errors[] = $this->language->lang('DIR_CAT_NAME_EMPTY');
759
		}
760
761
		$this->_check_route($this->cat_data['cat_route']);
762
763
		if (utf8_strlen($this->cat_data['cat_desc']) > 4000)
764
		{
765
			$this->errors[] = $this->language->lang('DIR_CAT_DESC_TOO_LONG');
766
		}
767
768
		if (($this->cat_data['cat_cron_enable'] && $this->cat_data['cat_cron_freq'] <= 0) || $this->cat_data['cat_cron_nb_check'] < 0)
769
		{
770
			$this->errors[] = $this->language->lang('DIR_CAT_DATA_NEGATIVE');
771
		}
772
773
		// Unset data that are not database fields
774
		$cat_data_sql = $this->cat_data;
775
776
		// What are we going to do tonight Brain? The same thing we do everynight,
777
		// try to take over the world ... or decide whether to continue update
778
		// and if so, whether it's a new cat/link or an existing one
779
		if (count($this->errors))
780
		{
781
			return $this->errors;
782
		}
783
784
		if (!$cat_data_sql['cat_link_back'])
785
		{
786
			$cat_data_sql['cat_cron_enable'] = 0;
787
			$cat_data_sql['cat_cron_next'] = 0;
788
		}
789
790
		if (!$cat_data_sql['parent_id'])
791
		{
792
			$cat_data_sql['display_subcat_list'] = 0;
793
		}
794
795
		// no cat_id means we're creating a new categorie
796
		if (!isset($cat_data_sql['cat_id']))
797
		{
798
			if ($cat_data_sql['cat_cron_enable'])
799
			{
800
				$cat_data_sql['cat_cron_next'] = time() + $cat_data_sql['cat_cron_freq']*86400;
801
			}
802
803
			$this->cat_data = $this->nestedset_category->insert($cat_data_sql);
804
805
			if ($cat_data_sql['parent_id'])
806
			{
807
				$this->nestedset_category->change_parent($this->cat_data['cat_id'], $cat_data_sql['parent_id']);
808
			}
809
810
			$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_ADD', time(), array($this->cat_data['cat_name']));
811
		}
812
		else
813
		{
814
			$row = $this->_get_cat_info($cat_data_sql['cat_id']);
815
816
			if ($row['parent_id'] != $cat_data_sql['parent_id'])
817
			{
818
				$this->nestedset_category->change_parent($cat_data_sql['cat_id'], $cat_data_sql['parent_id']);
819
			}
820
821
			if ($cat_data_sql['cat_cron_enable'] && ($row['cat_cron_freq'] != $cat_data_sql['cat_cron_freq'] || !$row['cat_cron_enable']))
822
			{
823
				$cat_data_sql['cat_cron_next'] = time() + $cat_data_sql['cat_cron_freq']*86400;
824
			}
825
826
			if ($row['cat_name'] != $cat_data_sql['cat_name'])
827
			{
828
				// the cat name has changed, clear the parents list of all categories (for safety)
829
				$sql = 'UPDATE ' . $this->categories_table . "
830
					SET cat_parents = ''";
831
				$this->db->sql_query($sql);
832
			}
833
834
			// Setting the cat id to the categorie id is not really received well by some dbs. ;)
835
			unset($cat_data_sql['cat_id']);
836
837
			$sql = 'UPDATE ' . $this->categories_table . '
838
				SET ' . $this->db->sql_build_array('UPDATE', $cat_data_sql) . '
839
				WHERE cat_id = ' . (int) $this->cat_id;
840
			$this->db->sql_query($sql);
841
842
			$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_EDIT', time(), array($this->cat_data['cat_name']));
843
		}
844
845
		return $this->errors;
846
	}
847
848
	/**
849
	* Remove complete category
850
	*
851
	* @param	string		$action_links	Action for categories links
852
	* @param	string		$action_subcats	Action for sub-categories
853
	* @param	int			$links_to_id	New category ID for links
854
	* @param	int			$subcats_to_id	New category ID for sub-categories
855
	* @return 	array|null
856
	*/
857
	private function _delete_cat($action_links = 'delete', $action_subcats = 'delete', $links_to_id = 0, $subcats_to_id = 0)
858
	{
859
		$this->cat_data = $this->_get_cat_info($this->cat_id);
860
861
		$log_action_links = $log_action_cats = $links_to_name = $subcats_to_name = '';
862
863
		if ($action_links == 'delete')
864
		{
865
			$log_action_links = 'LINKS';
866
			$this->_delete_cat_content();
867
		}
868
		else if ($action_links == 'move')
869
		{
870
			if (!$links_to_id)
871
			{
872
				$this->errors[] = $this->language->lang('DIR_NO_DESTINATION_CAT');
873
			}
874
			else
875
			{
876
				$log_action_links = 'MOVE_LINKS';
877
878
				$sql = 'SELECT cat_name
879
					FROM ' . $this->categories_table . '
880
					WHERE cat_id = ' . (int) $links_to_id;
881
				$result = $this->db->sql_query($sql);
882
				$row = $this->db->sql_fetchrow($result);
883
				$this->db->sql_freeresult($result);
884
885
				if (!$row)
886
				{
887
					throw new \OutOfBoundsException('DIR_NO_CAT');
888
				}
889
				else
890
				{
891
					$links_to_name = $row['cat_name'];
892
					$this->_move_cat_content($this->cat_id, $links_to_id);
893
				}
894
			}
895
		}
896
897
		if (count($this->errors))
898
		{
899
			return $this->errors;
900
		}
901
902
		if ($action_subcats == 'delete')
903
		{
904
			$log_action_cats = 'CATS';
905
		}
906
		else if ($action_subcats == 'move')
907
		{
908
			if (!$subcats_to_id)
909
			{
910
				$this->errors[] = $this->language->lang('DIR_NO_DESTINATION_CAT');
911
			}
912
			else
913
			{
914
				$log_action_cats = 'MOVE_CATS';
915
916
				$subcats_to_name = $row['cat_name'];
917
				$this->nestedset_category->move_children($this->cat_id, $subcats_to_id);
918
			}
919
		}
920
921
		if (count($this->errors))
922
		{
923
			return $this->errors;
924
		}
925
926
		$this->nestedset_category->delete($this->cat_id);
927
928
		$log_action = implode('_', array($log_action_links, $log_action_cats));
929
930
		switch ($log_action)
931
		{
932 View Code Duplication
			case 'MOVE_LINKS_MOVE_CATS':
933
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_MOVE_LINKS_MOVE_CATS', time(), array($links_to_name, $subcats_to_name, $this->cat_data['cat_name']));
934
			break;
935
936 View Code Duplication
			case 'MOVE_LINKS_CATS':
937
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_MOVE_LINKS_CATS', time(), array($links_to_name, $this->cat_data['cat_name']));
938
			break;
939
940 View Code Duplication
			case 'LINKS_MOVE_CATS':
941
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_LINKS_MOVE_CATS', time(), array($subcats_to_name, $this->cat_data['cat_name']));
942
			break;
943
944 View Code Duplication
			case '_MOVE_CATS':
945
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_MOVE_CATS', time(), array($subcats_to_name, $this->cat_data['cat_name']));
946
			break;
947
948 View Code Duplication
			case 'MOVE_LINKS_':
949
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_MOVE_LINKS', time(), array($links_to_name, $this->cat_data['cat_name']));
950
			break;
951
952 View Code Duplication
			case 'LINKS_CATS':
953
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_LINKS_CATS', time(), array($this->cat_data['cat_name']));
954
			break;
955
956 View Code Duplication
			case '_CATS':
957
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_CATS', time(), array($this->cat_data['cat_name']));
958
			break;
959
960 View Code Duplication
			case 'LINKS_':
961
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_LINKS', time(), array($this->cat_data['cat_name']));
962
			break;
963
964 View Code Duplication
			default:
965
				$this->phpbb_log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_DIR_CAT_DEL_CAT', time(), array($this->cat_data['cat_name']));
966
			break;
967
		}
968
	}
969
970
	/**
971
	* Move category content from one to another forum
972
	*
973
	* @param	int	$from_id
974
	* @param	int	$to_id
975
	* @return	null
976
	*/
977
	private function _move_cat_content($from_id, $to_id)
978
	{
979
		$sql = 'UPDATE ' . $this->links_table . '
980
			SET link_cat = ' . (int) $to_id . '
981
			WHERE link_cat = ' . (int) $from_id;
982
		$this->db->sql_query($sql);
983
984
		$sql = 'DELETE FROM ' . $this->watch_table . '
985
			WHERE cat_id = ' . (int) $from_id;
986
		$this->db->sql_query($sql);
987
988
		$this->_sync_dir_cat($to_id);
989
	}
990
991
	/**
992
	* Delete category content
993
	*
994
	* @return null
995
	*/
996
	private function _delete_cat_content()
997
	{
998
		$this->db->sql_transaction('begin');
999
1000
		// Before we remove anything we make sure we are able to adjust the post counts later. ;)
1001
		$sql = 'SELECT link_id, link_banner
1002
			FROM ' . $this->links_table . '
1003
			WHERE link_cat = ' . (int) $this->cat_id;
1004
		$result = $this->db->sql_query($sql);
1005
1006
		$link_ids = array();
1007
		while ($row = $this->db->sql_fetchrow($result))
1008
		{
1009
			$link_ids[] = $row['link_id'];
1010
1011 View Code Duplication
			if ($row['link_banner'] && !preg_match('/^(http:\/\/|https:\/\/|ftp:\/\/|ftps:\/\/|www\.).+/si', $row['link_banner']))
1012
			{
1013
				$banner_img = $this->get_banner_path(basename($row['link_banner']));
1014
1015
				if (file_exists($banner_img))
1016
				{
1017
					@unlink($banner_img);
1018
				}
1019
			}
1020
		}
1021
		$this->db->sql_freeresult($result);
1022
1023
		if (count($link_ids))
1024
		{
1025
			// Delete links datas
1026
			$link_datas_ary = array(
1027
				$this->comments_table	=> 'comment_link_id',
1028
				$this->votes_table		=> 'vote_link_id',
1029
			);
1030
1031
			foreach ($link_datas_ary as $table => $field)
1032
			{
1033
				$this->db->sql_query("DELETE FROM $table WHERE " . $this->db->sql_in_set($field, $link_ids));
1034
			}
1035
		}
1036
1037
		// Delete cats datas
1038
		$cat_datas_ary = array(
1039
			$this->links_table	=> 'link_cat',
1040
			$this->watch_table	=> 'cat_id',
1041
		);
1042
1043
		foreach ($cat_datas_ary as $table => $field)
1044
		{
1045
			$this->db->sql_query("DELETE FROM $table WHERE $field = " . (int) $this->cat_id);
1046
		}
1047
1048
		$this->db->sql_transaction('commit');
1049
	}
1050
1051
	/**
1052
	* Update links counter
1053
	*
1054
	* @param	int $cat_id	The category ID
1055
	* @return	null
1056
	*/
1057
	private function _sync_dir_cat($cat_id)
1058
	{
1059
		$sql = 'SELECT COUNT(link_id) AS num_links
1060
			FROM ' . $this->links_table . '
1061
			WHERE link_cat = ' . (int) $cat_id . '
1062
				AND link_active = 1';
1063
		$result = $this->db->sql_query($sql);
1064
		$total_links = (int) $this->db->sql_fetchfield('num_links');
1065
		$this->db->sql_freeresult($result);
1066
1067
		$sql = 'UPDATE ' . $this->categories_table . '
1068
			SET cat_links = ' . $total_links . '
1069
			WHERE cat_id = ' . (int) $cat_id;
1070
		$this->db->sql_query($sql);
1071
	}
1072
1073
	/**
1074
	* Update link data (note, vote, comment)
1075
	*
1076
	* @param	int	$start
1077
	* @param	int	$stop
1078
	* @return	null
1079
	*/
1080
	private function _sync_dir_links($start, $stop)
1081
	{
1082
		$sql_ary = array(
1083
			'link_comment'	=> 0,
1084
			'link_note'		=> 0,
1085
			'link_vote'		=> 0,
1086
		);
1087
1088
		$sql = 'UPDATE ' . $this->links_table . '
1089
			SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . '
1090
			WHERE link_id BETWEEN ' . (int) $start . ' AND ' . (int) $stop;
1091
		$this->db->sql_query($sql);
1092
1093
		$sql = 'SELECT vote_link_id, COUNT(vote_note) AS nb_vote, SUM(vote_note) AS total FROM ' . $this->votes_table . '
1094
			WHERE vote_link_id BETWEEN ' . (int) $start . ' AND ' . (int) $stop . '
1095
			GROUP BY vote_link_id';
1096
		$result = $this->db->sql_query($sql);
1097
		while ($tmp = $this->db->sql_fetchrow($result))
1098
		{
1099
			$sql = 'UPDATE ' . $this->links_table . '
1100
				SET link_note = ' . (int) $tmp['total'] . ', link_vote = ' . (int) $tmp['nb_vote'] . '
1101
				WHERE link_id = ' . (int) $tmp['vote_link_id'];
1102
			$this->db->sql_query($sql);
1103
		}
1104
		$this->db->sql_freeresult($result);
1105
1106
		$sql = 'SELECT 	comment_link_id, COUNT(comment_id) AS nb_comment
1107
			FROM ' . $this->comments_table . '
1108
			WHERE comment_link_id BETWEEN ' . (int) $start . ' AND ' . (int) $stop . '
1109
			GROUP BY comment_link_id';
1110
		$result = $this->db->sql_query($sql);
1111
		while ($tmp = $this->db->sql_fetchrow($result))
1112
		{
1113
			$sql = 'UPDATE ' . $this->links_table . '
1114
				SET link_comment = ' . (int) $tmp['nb_comment'] . '
1115
				WHERE link_id = ' . (int) $tmp['comment_link_id'];
1116
			$this->db->sql_query($sql);
1117
		}
1118
		$this->db->sql_freeresult($result);
1119
	}
1120
1121
	/**
1122
	* Display icons drop-down list
1123
	*
1124
	* @param	string	$icons_path
1125
	* @param	string	$img_selected
1126
	* @return	string
1127
	*/
1128
	private function _get_dir_icon_list($icons_path, $img_selected)
1129
	{
1130
		$imglist = filelist($icons_path, '');
1131
		$filename_list = '<option value="">----------</option>';
1132
1133
		foreach ($imglist as $path => $img_ary)
1134
		{
1135
			sort($img_ary);
1136
1137
			foreach ($img_ary as $img)
1138
			{
1139
				$img = $path . $img;
1140
				$selected = '';
1141
1142
				if (strlen($img) > 255)
1143
				{
1144
					continue;
1145
				}
1146
1147
				if ($img == $img_selected)
1148
				{
1149
					$selected = ' selected="selected"';
1150
				}
1151
1152
				$filename_list .= '<option value="' . htmlspecialchars($img) . '"' . $selected . '>' . $img . '</option>';
1153
			}
1154
		}
1155
1156
		return ($filename_list);
1157
	}
1158
}
1159