categorie   D
last analyzed

Complexity

Total Complexity 59

Size/Duplication

Total Lines 526
Duplicated Lines 4.94 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 59
lcom 1
cbo 1
dl 26
loc 526
rs 4.08
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A need_approval() 0 4 1
B make_cat_jumpbox() 9 50 6
B make_cat_select() 9 43 9
D display() 0 126 16
A get() 0 25 3
A generate_dir_nav() 0 34 3
A dir_submit_type() 0 18 4
C watch_categorie() 8 83 14
A getname() 0 17 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like categorie often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use categorie, and based on these observations, apply Extract Interface, too.

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\core;
12
13
use \ernadoo\phpbbdirectory\core\helper;
14
15
class categorie extends helper
16
{
17
	/** @var \phpbb\db\driver\driver_interface */
18
	protected $db;
19
20
	/** @var \phpbb\config\config */
21
	protected $config;
22
23
	/** @var \phpbb\language\language */
24
	protected $language;
25
26
	/** @var \phpbb\template\template */
27
	protected $template;
28
29
	/** @var \phpbb\user */
30
	protected $user;
31
32
	/** @var \phpbb\controller\helper */
33
	protected $helper;
34
35
	/** @var \phpbb\request\request */
36
	protected $request;
37
38
	/** @var \phpbb\auth\auth */
39
	protected $auth;
40
41
	/** @var \phpbb\cron\manager */
42
	protected $cron;
43
44
45
	/** @var array data */
46
	public $data = array();
47
48
	/**
49
	* Constructor
50
	*
51
	* @param \phpbb\db\driver\driver_interface 		$db			Database object
52
	* @param \phpbb\config\config 					$config		Config object
53
	* @param \phpbb\language\language				$language	Language object
54
	* @param \phpbb\template\template 				$template	Template object
55
	* @param \phpbb\user 							$user		User object
56
	* @param \phpbb\controller\helper 				$helper		Controller helper object
57
	* @param \phpbb\request\request 				$request	Request object
58
	* @param \phpbb\auth\auth 						$auth		Auth object
59
	* @param \phpbb\cron\manager					$cron		Cron object
60
	*/
61
	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\language\language $language, \phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\request\request $request, \phpbb\auth\auth $auth, \phpbb\cron\manager $cron)
62
	{
63
		$this->db			= $db;
64
		$this->config		= $config;
65
		$this->language		= $language;
66
		$this->template		= $template;
67
		$this->user			= $user;
68
		$this->helper		= $helper;
69
		$this->request		= $request;
70
		$this->auth			= $auth;
71
		$this->cron 		= $cron;
72
	}
73
74
	/**
75
	* Function for get approval setting
76
	* used in edit mode for test the setting of new category's link
77
	*
78
	* @return bool
79
	*/
80
	public function need_approval()
81
	{
82
		return (bool) $this->data['cat_validate'];
83
	}
84
85
	/**
86
	* Generate Jumpbox
87
	*
88
	* @return null
89
	*/
90
	public function make_cat_jumpbox()
91
	{
92
		$sql = 'SELECT cat_id, cat_name, parent_id, left_id, right_id
93
			FROM ' . $this->categories_table . '
94
			ORDER BY left_id ASC';
95
		$result = $this->db->sql_query($sql);
96
97
		$right = $padding = 0;
98
		$padding_store = array('0' => 0);
99
		$display_jumpbox = false;
100
		$iteration = 0;
101
102
		while ($row = $this->db->sql_fetchrow($result))
103
		{
104
			$display_jumpbox = true;
105
106 View Code Duplication
			if ($row['left_id'] < $right)
107
			{
108
				$padding++;
109
				$padding_store[$row['parent_id']] = $padding;
110
			}
111
			else if ($row['left_id'] > $right + 1)
112
			{
113
				$padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : $padding;
114
			}
115
116
			$right = $row['right_id'];
117
118
			$this->template->assign_block_vars('jumpbox_forums', array(
119
				'FORUM_ID'			=> $row['cat_id'],
120
				'FORUM_NAME'		=> $row['cat_name'],
121
				'S_FORUM_COUNT'		=> $iteration,
122
				'LINK'				=> $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $row['cat_id']),
123
			));
124
125
			for ($i = 0; $i < $padding; $i++)
126
			{
127
				$this->template->assign_block_vars('jumpbox_forums.level', array());
128
			}
129
			$iteration++;
130
		}
131
		$this->db->sql_freeresult($result);
132
		unset($padding_store);
133
134
		$this->template->assign_vars(array(
135
			'S_DISPLAY_JUMPBOX'			=> $display_jumpbox,
136
		));
137
138
		return;
139
	}
140
141
	/**
142
	* Generate a list of directory's categories
143
	*
144
	* @param	int		$select_id		Selected category
145
	* @param	array	$ignore_id		Array of ignored categories
146
	* @return	string	$cat_list		html code
147
	*/
148
	public function make_cat_select($select_id = 0, $ignore_id = array())
149
	{
150
		$ignore_id = is_array($ignore_id) ? $ignore_id : array($ignore_id);
151
152
		// This query is identical to the jumpbox one
153
		$sql = 'SELECT cat_id, cat_name, parent_id, left_id, right_id
154
			FROM ' . $this->categories_table . '
155
			ORDER BY left_id ASC';
156
		$result = $this->db->sql_query($sql);
157
158
		$right = 0;
159
		$padding_store = array('0' => '');
160
		$padding = '';
161
		$cat_list = '';
162
163
		while ($row = $this->db->sql_fetchrow($result))
164
		{
165 View Code Duplication
			if ($row['left_id'] < $right)
166
			{
167
				$padding .= '&nbsp; &nbsp;';
168
				$padding_store[$row['parent_id']] = $padding;
169
			}
170
			else if ($row['left_id'] > $right + 1)
171
			{
172
				$padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : '';
173
			}
174
175
			$right = $row['right_id'];
176
			$disabled = false;
177
178
			if (in_array($row['cat_id'], $ignore_id))
179
			{
180
				$disabled = true;
181
			}
182
183
			$selected = (($row['cat_id'] == $select_id) ? ' selected="selected"' : '');
184
			$cat_list .= '<option value="' . $row['cat_id'] . '"' . (($disabled) ? ' disabled="disabled" class="disabled-option"' : $selected) . '>' . $padding . $row['cat_name'] . '</option>';
185
		}
186
		$this->db->sql_freeresult($result);
187
		unset($padding_store);
188
189
		return $cat_list;
190
	}
191
192
	/**
193
	* Display cat or subcat
194
	*
195
	* @return	null
196
	*/
197
	public function display()
198
	{
199
		$cat_rows	= $subcats = array();
200
		$parent_id	= $visible_cats = 0;
201
202
		$sql_array = array(
203
			'SELECT'	=> 'cat_id, left_id, right_id, parent_id, cat_name, cat_desc, display_subcat_list, cat_desc_uid, cat_desc_bitfield, cat_desc_options, cat_links, cat_icon, cat_count_all',
204
			'FROM'		=> array(
205
				$this->categories_table => ''
206
			),
207
		);
208
209
		if (empty($this->data))
210
		{
211
			$root_data = array('cat_id' => 0);
212
			$sql_where = '';
213
		}
214
		else
215
		{
216
			$root_data = $this->data;
217
			$sql_where = 'left_id > ' . $root_data['left_id'] . ' AND left_id < ' . $root_data['right_id'];
218
		}
219
220
		$sql = $this->db->sql_build_query('SELECT', array(
221
			'SELECT'	=> $sql_array['SELECT'],
222
			'FROM'		=> $sql_array['FROM'],
223
224
			'WHERE'		=> $sql_where,
225
226
			'ORDER_BY'	=> 'left_id',
227
		));
228
229
		$result = $this->db->sql_query($sql);
230
231
		$branch_root_id = $root_data['cat_id'];
232
		while ($row = $this->db->sql_fetchrow($result))
233
		{
234
			$dir_cat_id = $row['cat_id'];
235
236
			if ($row['parent_id'] == $root_data['cat_id'] || $row['parent_id'] == $branch_root_id)
237
			{
238
				// Direct child of current branch
239
				$parent_id = $dir_cat_id;
240
				$cat_rows[$dir_cat_id] = $row;
241
			}
242
			else
243
			{
244
				$subcats[$parent_id][$dir_cat_id]['display'] = ($row['display_subcat_list']) ? true : false;
245
				$subcats[$parent_id][$dir_cat_id]['name'] = $row['cat_name'];
246
				$subcats[$parent_id][$dir_cat_id]['links'] = $row['cat_links'];
247
				$subcats[$parent_id][$dir_cat_id]['parent_id'] = $row['parent_id'];
248
			}
249
		}
250
		$this->db->sql_freeresult($result);
251
252
		foreach ($cat_rows as $row)
253
		{
254
			$visible_cats++;
255
			$dir_cat_id = $row['cat_id'];
256
257
			$subcats_list = array();
258
259
			// Generate list of subcats if we need to
260
			if (isset($subcats[$dir_cat_id]))
261
			{
262
				foreach ($subcats[$dir_cat_id] as $subcat_id => $subcat_row)
263
				{
264
					$row['cat_links'] = ($row['cat_count_all']) ? ($row['cat_links']+$subcat_row['links']) : $row['cat_links'];
265
266
					if ($subcat_row['display'] && $subcat_row['parent_id'] == $dir_cat_id)
267
					{
268
						$subcats_list[] = array(
269
							'link'		=> $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $subcat_id),
270
							'name'		=> $subcat_row['name'],
271
							'links'		=> $subcat_row['links']
272
						);
273
					}
274
					else
275
					{
276
						unset($subcats[$dir_cat_id][$subcat_id]);
277
					}
278
				}
279
			}
280
281
			$this->template->assign_block_vars('cat', array(
282
				'CAT_NAME'				=> $row['cat_name'],
283
				'CAT_DESC'				=> generate_text_for_display($row['cat_desc'], $row['cat_desc_uid'], $row['cat_desc_bitfield'], $row['cat_desc_options']),
284
				'CAT_LINKS'				=> $row['cat_links'],
285
				'CAT_IMG'				=> $this->get_img_path('icons', $row['cat_icon']),
286
287
				'U_CAT'					=> $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $row['cat_id']),
288
			));
289
290
			// Assign subcats loop for style authors
291
			foreach ($subcats_list as $subcat)
292
			{
293
				$this->template->assign_block_vars('cat.subcat', array(
294
					'U_CAT'		=> $subcat['link'],
295
					'CAT_NAME'	=> $subcat['name'],
296
					'CAT_LINKS'	=> $subcat['links']
297
				));
298
			}
299
		}
300
301
		$this->template->assign_vars(array(
302
			'S_AUTH_ADD'		=> $this->auth->acl_get('u_submit_dir'),
303
			'S_AUTH_SEARCH'		=> $this->auth->acl_get('u_search_dir'),
304
			'S_HAS_SUBCAT'		=> ($visible_cats) ? true : false,
305
			'S_ROOT'			=> empty($this->data),
306
307
			'U_MAKE_SEARCH'		=> $this->helper->route('ernadoo_phpbbdirectory_search_controller'),
308
		));
309
310
		// Do the categorie Prune thang - cron type job ...
311
		if (!$this->config['use_system_cron'])
312
		{
313
			$task = $this->cron->find_task('ernadoo.phpbbdirectory.cron.task.core.prune_categorie');
314
			$task->set_categorie_data($this->data);
315
316
			if ($task->is_ready())
317
			{
318
				$url = $task->get_url();
319
				$this->template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="" />');
320
			}
321
		}
322
	}
323
324
	/**
325
	* Get informations about a cat or subcat
326
	*
327
	* @param	int	$cat_id		The category ID
328
	* @return	null|false
329
	*/
330
	public function get($cat_id = 0)
331
	{
332
		if ($cat_id)
333
		{
334
			$sql_array = array(
335
				'SELECT'	=> 'c.*, w.notify_status',
336
				'FROM'		=> array(
337
						$this->categories_table	=> 'c'),
338
				'LEFT_JOIN'	=> array(
339
						array(
340
							'FROM'	=> array($this->watch_table	=> 'w'),
341
							'ON'	=> 'c.cat_id = w.cat_id AND w.user_id = ' . (int) $this->user->data['user_id']
342
						),
343
				),
344
				'WHERE'		=> 'c.cat_id = ' . (int) $cat_id
345
			);
346
			$sql = $this->db->sql_build_query('SELECT', $sql_array);
347
			$result = $this->db->sql_query($sql);
348
			if (!($this->data = $this->db->sql_fetchrow($result)))
349
			{
350
				return false;
351
			}
352
			$this->db->sql_freeresult($result);
353
		}
354
	}
355
356
	/**
357
	* Create category navigation links for given category, create parent
358
	* list if currently null, assign basic category info to template
359
	*
360
	* @param	array	$dir_cat_data
361
	*/
362
	public function generate_dir_nav(&$dir_cat_data)
363
	{
364
		global $phpbb_container;
365
366
		$nestedset_category = $phpbb_container->get('ernadoo.phpbbdirectory.core.nestedset_category');
367
368
		// Get cat parents
369
		$dir_cat_parents = $nestedset_category->get_path_basic_data($dir_cat_data);
370
371
		$microdata_attr = 'data-category-id';
372
373
		// Build navigation links
374
		if (!empty($dir_cat_parents))
375
		{
376
			foreach ($dir_cat_parents as $parent_cat_id => $parent_data)
377
			{
378
				$this->template->assign_block_vars('dir_navlinks', array(
379
					'BREADCRUMB_NAME'	=> $parent_data['cat_name'],
380
					'FORUM_ID'			=> $parent_cat_id,
381
					'MICRODATA'			=> $microdata_attr . '="' . $parent_cat_id . '"',
382
					'U_BREADCRUMB'		=> $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $parent_cat_id),
383
				));
384
			}
385
		}
386
387
		$this->template->assign_block_vars('dir_navlinks', array(
388
			'BREADCRUMB_NAME'	=> $dir_cat_data['cat_name'],
389
			'FORUM_ID'			=> $dir_cat_data['cat_id'],
390
			'MICRODATA'			=> $microdata_attr . '="' . $dir_cat_data['cat_id'] . '"',
391
			'U_BREADCRUMB'		=> $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $dir_cat_data['cat_id']),
392
		));
393
394
		return;
395
	}
396
397
	/**
398
	* Return good key language
399
	*
400
	* @param	bool	$validate	True if approbation needed before publication
401
	* @return	string				Information about approval, depends on user auth level
402
	* @throws	\phpbb\exception\runtime_exception
403
	*/
404
	public function dir_submit_type($validate)
405
	{
406
		if ($validate)
407
		{
408
			if ($this->auth->acl_get('a_'))
409
			{
410
				return $this->language->lang('DIR_SUBMIT_TYPE_3');
411
			}
412
			else if ($this->auth->acl_get('m_'))
413
			{
414
				return $this->language->lang('DIR_SUBMIT_TYPE_4');
415
			}
416
417
			return $this->language->lang('DIR_SUBMIT_TYPE_1');
418
		}
419
420
		return $this->language->lang('DIR_SUBMIT_TYPE_2');
421
	}
422
423
	/**
424
	* Category watching common code
425
	*
426
	* @param	string		$mode			Watch or unwatch a category
427
	* @param	array		$s_watching		An empty array, passed by reference
428
	* @param	int			$user_id		The user ID
429
	* @param	int			$cat_id			The category ID
430
	* @param	string		$notify_status	User is watching the category?
431
	* @return	null|string
432
	*/
433
	public function watch_categorie($mode, &$s_watching, $user_id, $cat_id, $notify_status)
434
	{
435
		// Is user watching this thread?
436
		if ($user_id != ANONYMOUS)
437
		{
438
			$can_watch = true;
439
440
			if (!is_null($notify_status) && $notify_status !== '')
441
			{
442
				if ($mode == 'unwatch')
443
				{
444
					$sql = 'DELETE FROM ' . $this->watch_table . "
445
						WHERE cat_id = $cat_id
446
							AND user_id = $user_id";
447
					$this->db->sql_query($sql);
448
449
					$redirect_url = $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $cat_id);
450
					$message = $this->language->lang('DIR_NOT_WATCHING_CAT');
451
452 View Code Duplication
					if (!$this->request->is_ajax())
453
					{
454
						$message .= '<br /><br />' . $this->language->lang('DIR_CLICK_RETURN_CAT', '<a href="' . $redirect_url . '">', '</a>');
455
					}
456
457
					meta_refresh(3, $redirect_url);
458
					return $message;
459
				}
460
				else
461
				{
462
					$is_watching = true;
463
464
					if ($notify_status != NOTIFY_YES)
465
					{
466
						$sql = 'UPDATE ' . $this->watch_table . '
467
							SET notify_status = ' . NOTIFY_YES . "
468
							WHERE cat_id = $cat_id
469
								AND user_id = $user_id";
470
						$this->db->sql_query($sql);
471
					}
472
				}
473
			}
474
			else
475
			{
476
				if ($mode == 'watch')
477
				{
478
					$sql = 'INSERT INTO ' . $this->watch_table . " (user_id, cat_id, notify_status)
479
						VALUES ($user_id, $cat_id, " . NOTIFY_YES . ')';
480
					$this->db->sql_query($sql);
481
482
					$redirect_url = $this->helper->route('ernadoo_phpbbdirectory_dynamic_route_' . $cat_id);
483
					$message = $this->language->lang('DIR_ARE_WATCHING_CAT');
484
485 View Code Duplication
					if (!$this->request->is_ajax())
486
					{
487
						$message .= '<br /><br />' . $this->language->lang('DIR_CLICK_RETURN_CAT', '<a href="' . $redirect_url . '">', '</a>');
488
					}
489
490
					meta_refresh(3, $redirect_url);
491
					return $message;
492
				}
493
				else
494
				{
495
					$is_watching = false;
496
				}
497
			}
498
		}
499
		else
500
		{
501
			$can_watch = false;
502
			$is_watching = false;
503
		}
504
505
		if ($can_watch)
506
		{
507
			$s_watching['link'] 		= $this->helper->route('ernadoo_phpbbdirectory_suscribe_controller', array('cat_id' => $cat_id, 'mode' => (($is_watching) ? 'unwatch' : 'watch')));
508
			$s_watching['link_toggle'] 	= $this->helper->route('ernadoo_phpbbdirectory_suscribe_controller', array('cat_id' => $cat_id, 'mode' => ((!$is_watching) ? 'unwatch' : 'watch')));
509
			$s_watching['title'] 		= $this->language->lang((($is_watching) ? 'DIR_STOP' : 'DIR_START') . '_WATCHING_CAT');
510
			$s_watching['title_toggle'] = $this->language->lang(((!$is_watching) ? 'DIR_STOP' : 'DIR_START') . '_WATCHING_CAT');
511
			$s_watching['is_watching'] 	= $is_watching;
512
		}
513
514
		return;
515
	}
516
517
	/**
518
	* Return Category name
519
	*
520
	* @param	int		$cat_id		The category ID
521
	* @return	string				The category name
522
	*/
523
	static public function getname($cat_id)
524
	{
525
		global $db, $phpbb_container;
526
527
		$categories_table = $phpbb_container->getParameter('tables.dir.categories');
528
529
		$sql = 'SELECT cat_name
530
			FROM ' . $categories_table . '
531
			WHERE cat_id = ' . (int) $cat_id;
532
		$result = $db->sql_query($sql);
533
		$row = $db->sql_fetchrow($result);
534
535
		if (!empty($row))
536
		{
537
			return $row['cat_name'];
538
		}
539
	}
540
}
541