Completed
Push — 3.2.x ( b8f3d7...182c32 )
by Erwan
01:52
created

cat::_check_route()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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