Passed
Push — 1.5.0 ( 8846b6...5b3637 )
by Sylver
03:05
created

category   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 522
Duplicated Lines 0 %

Importance

Changes 26
Bugs 0 Features 0
Metric Value
eloc 299
c 26
b 0
f 0
dl 0
loc 522
rs 3.52
wmc 61

19 Methods

Rating   Name   Duplication   Size   Complexity  
A get_version() 0 16 2
A __construct() 0 13 1
A get_max_id() 0 10 1
A capitalize() 0 3 1
A smilies_count() 0 12 3
A get_first_order() 0 11 1
A get_max_order() 0 10 1
A shoutbox_smilies() 0 43 4
A set_order() 0 19 6
B select_categories() 0 30 8
A shoutbox_smilies_popup() 0 38 4
A move_cat() 0 29 3
B extract_list_categories() 0 47 10
A get_cat_name() 0 20 2
A get_cat_nb() 0 10 1
A reset_first_cat() 0 8 4
A adm_list_cat() 0 52 5
A edit_smiley() 0 31 1
A edit_multi_smiley() 0 37 3

How to fix   Complexity   

Complex Class

Complex classes like category 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.

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 category, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *
4
 * @package		Breizh Smilies Categories Extension
5
 * @copyright	(c) 2020-2023 Sylver35  https://breizhcode.com
6
 * @license		http://opensource.org/licenses/gpl-license.php GNU Public License
7
 *
8
 */
9
10
namespace sylver35\smiliescat\core;
11
12
use phpbb\cache\driver\driver_interface as cache;
13
use phpbb\db\driver\driver_interface as db;
14
use phpbb\config\config;
15
use phpbb\controller\helper;
16
use phpbb\user;
17
use phpbb\language\language;
18
use phpbb\template\template;
19
use phpbb\extension\manager;
20
use phpbb\log\log;
21
22
class category
23
{
24
	/** @var \phpbb\cache\driver\driver_interface */
25
	protected $cache;
26
27
	/** @var \phpbb\db\driver\driver_interface */
28
	protected $db;
29
30
	/** @var \phpbb\config\config */
31
	protected $config;
32
33
	/* @var \phpbb\controller\helper */
34
	protected $helper;
35
36
	/** @var \phpbb\user */
37
	protected $user;
38
39
	/** @var \phpbb\language\language */
40
	protected $language;
41
42
	/** @var \phpbb\template\template */
43
	protected $template;
44
45
	/** @var \phpbb\extension\manager "Extension Manager" */
46
	protected $ext_manager;
47
48
	/** @var \phpbb\log\log */
49
	protected $log;
50
51
	/**
52
	 * The database tables
53
	 *
54
	 * @var string */
55
	protected $smilies_category_table;
56
57
	/** @var string phpBB root path */
58
	protected $root_path;
59
60
	/**
61
	 * Constructor
62
	 */
63
	public function __construct(cache $cache, db $db, config $config, helper $helper, user $user, language $language, template $template, manager $ext_manager, log $log, $smilies_category_table, $root_path)
64
	{
65
		$this->cache = $cache;
66
		$this->db = $db;
67
		$this->config = $config;
68
		$this->helper = $helper;
69
		$this->user = $user;
70
		$this->language = $language;
71
		$this->template = $template;
72
		$this->ext_manager = $ext_manager;
73
		$this->log = $log;
74
		$this->smilies_category_table = $smilies_category_table;
75
		$this->root_path = $root_path;
76
	}
77
78
	public function get_version()
79
	{
80
		if (($data = $this->cache->get('_smiliescat_version')) === false)
81
		{
82
			$md_manager = $this->ext_manager->create_extension_metadata_manager('sylver35/smiliescat');
83
			$meta = $md_manager->get_metadata();
84
85
			$data = [
86
				'version'	=> $meta['version'],
87
				'homepage'	=> $meta['homepage'],
88
			];
89
			// cache for 7 days
90
			$this->cache->put('_smiliescat_version', $data, 604800);
91
		}
92
93
		return $data;
94
	}
95
96
	public function smilies_count($cat, $compact = false)
97
	{
98
		$sql = $this->db->sql_build_query('SELECT', [
99
			'SELECT'	=> (!$compact) ? 'COUNT(DISTINCT smiley_id) AS smilies_count' : 'COUNT(DISTINCT smiley_url) AS smilies_count',
100
			'FROM'		=> [SMILIES_TABLE => ''],
101
			'WHERE'		=> ($cat > -1) ? 'category = ' . (int) $cat : "code <> ''",
102
		]);
103
		$result = $this->db->sql_query($sql);
104
		$nb = (int) $this->db->sql_fetchfield('smilies_count');
105
		$this->db->sql_freeresult($result);
106
107
		return $nb;
108
	}
109
110
	public function select_categories($cat, $modify = false, $empty = false)
111
	{
112
		$lang = $this->user->lang_name;
113
		$select = '<option disabled="disabled">' . $this->language->lang('SC_CATEGORY_SELECT') . '</option>';
114
		if ($modify)
115
		{
116
			$selected = ((int) $cat === -1) ? ' selected="selected"' : '';
117
			$select .= '<option value="-1"' . $selected . '>' . $this->language->lang('SC_CATEGORY_ANY') . '</option>';
118
		}
119
120
		$sql = 'SELECT *
121
			FROM ' . $this->smilies_category_table . "
122
				WHERE cat_lang = '$lang'
123
				ORDER BY cat_order ASC";
124
		$result = $this->db->sql_query($sql);
125
		while ($row = $this->db->sql_fetchrow($result))
126
		{
127
			if (!$row['cat_nb'] && $empty)
128
			{
129
				continue;
130
			}
131
			$selected = ((int) $cat === (int) $row['cat_id']) ? ' selected="selected"' : '';
132
			$select .= '<option title="' . $row['cat_name'] . '" value="' . $row['cat_id'] . '"' . $selected . '> ' . $row['cat_name'] . '</option>';
133
		}
134
		$this->db->sql_freeresult($result);
135
136
		$selected_default = (!$cat) ? ' selected="selected"' : '';
137
		$select .= '<option title="' . $this->language->lang('SC_CATEGORY_DEFAUT') . '" value="0"' . $selected_default . '> ' . $this->language->lang('SC_CATEGORY_DEFAUT') . '</option>';
138
139
		return $select;
140
	}
141
142
	public function capitalize($var)
143
	{
144
		return ucfirst(strtolower(trim($var)));
145
	}
146
147
	public function get_max_order()
148
	{
149
		// Get max order id...
150
		$sql = 'SELECT MAX(cat_order) AS maxi
151
			FROM ' . $this->smilies_category_table;
152
		$result = $this->db->sql_query($sql);
153
		$max = (int) $this->db->sql_fetchfield('maxi');
154
		$this->db->sql_freeresult($result);
155
156
		return $max;
157
	}
158
159
	public function get_max_id()
160
	{
161
		// Get max id...
162
		$sql = 'SELECT MAX(cat_id) AS id_max
163
			FROM ' . $this->smilies_category_table;
164
		$result = $this->db->sql_query($sql);
165
		$id_max = (int) $this->db->sql_fetchfield('id_max');
166
		$this->db->sql_freeresult($result);
167
168
		return $id_max;
169
	}
170
171
	public function get_first_order()
172
	{
173
		// Get first order id...
174
		$sql = 'SELECT cat_order, cat_id
175
			FROM ' . $this->smilies_category_table . '
176
			ORDER BY cat_order ASC';
177
		$result = $this->db->sql_query_limit($sql, 1);
178
		$first = (int) $this->db->sql_fetchfield('cat_id');
179
		$this->db->sql_freeresult($result);
180
181
		return $first;
182
	}
183
184
	public function get_cat_nb($id)
185
	{
186
		$sql = 'SELECT cat_nb
187
			FROM ' . $this->smilies_category_table . '
188
				WHERE cat_id = ' . (int) $id;
189
		$result = $this->db->sql_query($sql);
190
		$cat_nb = (int) $this->db->sql_fetchfield('cat_nb');
191
		$this->db->sql_freeresult($result);
192
193
		return $cat_nb;
194
	}
195
196
	public function extract_list_categories($cat)
197
	{
198
		$title = '';
199
		$cat_order = $i = 0;
200
		$lang = $this->user->lang_name;
201
		$sql = $this->db->sql_build_query('SELECT', [
202
			'SELECT'	=> '*',
203
			'FROM'		=> [$this->smilies_category_table => ''],
204
			'WHERE'		=> "cat_nb <> 0 AND cat_lang = '$lang'",
205
			'ORDER_BY'	=> 'cat_order ASC',
206
		]);
207
		$result = $this->db->sql_query($sql);
208
		while ($row = $this->db->sql_fetchrow($result))
209
		{
210
			$actual_cat = (int) $row['cat_id'] === $cat;
211
			$this->template->assign_block_vars('categories', [
212
				'CLASS'			=> $actual_cat ? 'cat-active' : 'cat-inactive',
213
				'SEPARATE'		=> ($i > 0) ? ' - ' : '',
214
				'CAT_NAME'		=> $row['cat_name'] ? $row['cat_name'] : $row['cat_title'],
215
				'CAT_ORDER'		=> $row['cat_order'],
216
				'CAT_ID'		=> $row['cat_id'],
217
				'CAT_NB'		=> $row['cat_nb'],
218
				'U_CAT'			=> $this->helper->route('sylver35_smiliescat_smilies_pop', ['select' => $row['cat_id']]),
219
			]);
220
			$i++;
221
222
			// Keep these values in memory
223
			$title = $actual_cat ? $row['cat_name'] : $title;
224
			$cat_order = $row['cat_order'];
225
		}
226
		$this->db->sql_freeresult($result);
227
228
		// Add the Unclassified category if not empty
229
		if ($nb = $this->smilies_count(0))
230
		{
231
			$this->template->assign_block_vars('categories', [
232
				'CLASS'			=> ($cat === 0) ? 'cat-active' : 'cat-inactive',
233
				'SEPARATE'		=> ($i > 0) ? ' - ' : '',
234
				'CAT_NAME'		=> $this->language->lang('SC_CATEGORY_DEFAUT'),
235
				'CAT_ORDER'		=> $cat_order + 1,
236
				'CAT_ID'		=> 0,
237
				'CAT_NB'		=> $nb,
238
				'U_CAT'			=> $this->helper->route('sylver35_smiliescat_smilies_pop', ['select' => 0]),
239
			]);
240
		}
241
242
		return (!$cat) ? $this->language->lang('SC_CATEGORY_DEFAUT') : $title;
243
	}
244
245
	public function shoutbox_smilies($event)
246
	{
247
		$i = $cat_order = 0;
248
		$list_cat = [];
249
		$lang = $this->user->lang_name;
250
251
		$sql = 'SELECT * 
252
			FROM ' . $this->smilies_category_table . "
253
				WHERE cat_lang = '$lang'
254
				ORDER BY cat_order ASC";
255
		$result = $this->db->sql_query($sql);
256
		while ($row = $this->db->sql_fetchrow($result))
257
		{
258
			// Choose only non-empty categories
259
			if ($row['cat_nb'])
260
			{
261
				$list_cat[$i] = [
262
					'cat_id'		=> (int) $row['cat_id'],
263
					'cat_order'		=> (int) $row['cat_order'],
264
					'cat_name'		=> (string) $row['cat_name'],
265
					'cat_nb'		=> (int) $row['cat_nb'],
266
				];
267
				$i++;
268
			}
269
			// Keep this value in memory
270
			$cat_order = (int) $row['cat_order'];
271
		}
272
		$this->db->sql_freeresult($result);
273
274
		// Add the Unclassified category if not empty
275
		if ($nb = $this->smilies_count(0, true))
276
		{
277
			$list_cat[$i] = [
278
				'cat_id'		=> 0,
279
				'cat_order'		=> $cat_order + 1,
280
				'cat_name'		=> $this->language->lang('SC_CATEGORY_DEFAUT'),
281
				'cat_nb'		=> $nb,
282
			];
283
		}
284
285
		$event['content'] = array_merge($event['content'], [
286
			'title_cat'		=> $this->language->lang('ACP_SC_SMILIES'),
287
			'categories'	=> $list_cat,
288
		]);
289
	}
290
291
	public function shoutbox_smilies_popup($event)
292
	{
293
		$cat = (int) $event['cat'];
294
		if ($cat !== -1)
295
		{
296
			$i = 0;
297
			$smilies = [];
298
			$cat_name = $this->get_cat_name($cat);
299
300
			$sql = [
301
				'SELECT'	=> 'smiley_url, MIN(smiley_id) AS smiley_id, MIN(code) AS code, MIN(smiley_order) AS min_smiley_order, MIN(smiley_width) AS smiley_width, MIN(smiley_height) AS smiley_height, MIN(emotion) AS emotion',
302
				'FROM'		=> [SMILIES_TABLE => ''],
303
				'WHERE'		=> 'category = ' . $cat,
304
				'GROUP_BY'	=> 'smiley_url',
305
				'ORDER_BY'	=> 'min_smiley_order ASC',
306
			];
307
			$result = $this->db->sql_query($this->db->sql_build_query('SELECT', $sql));
308
			while ($row = $this->db->sql_fetchrow($result))
309
			{
310
				$smilies[$i] = [
311
					'nb'		=> (int) $i,
312
					'code'		=> (string) $row['code'],
313
					'emotion'	=> (string) $row['emotion'],
314
					'image'		=> (string) $row['smiley_url'],
315
					'width'		=> (int) $row['smiley_width'],
316
					'height'	=> (int) $row['smiley_height'],
317
				];
318
				$i++;
319
			}
320
			$this->db->sql_freeresult($result);
321
322
			$event['content'] = array_merge($event['content'], [
323
				'in_cat'		=> true,
324
				'cat'			=> $cat,
325
				'total'			=> $i,
326
				'smilies'		=> $smilies,
327
				'emptyRow'		=> ($i === 0) ? $this->language->lang('SC_SMILIES_EMPTY_CATEGORY') : '',
328
				'title'			=> $this->language->lang('SC_CATEGORY_IN', $cat_name),
329
			]);
330
		}
331
	}
332
333
	private function get_cat_name($cat)
334
	{
335
		if ($cat > 0)
336
		{
337
			$lang = $this->user->lang_name;
338
			$sql = 'SELECT cat_name
339
				FROM ' . $this->smilies_category_table . "
340
					WHERE cat_lang = '$lang'
341
					AND cat_id = $cat";
342
			$result = $this->db->sql_query_limit($sql, 1);
343
			$row = $this->db->sql_fetchrow($result);
344
			$cat_name = $row['cat_name'];
345
			$this->db->sql_freeresult($result);
346
		}
347
		else
348
		{
349
			$cat_name = $this->language->lang('SC_CATEGORY_DEFAUT');
350
		}
351
352
		return $cat_name;
353
	}
354
355
	public function set_order($action, $current_order)
356
	{
357
		$switch_order_id = 0;
358
		$max_order = $this->get_max_order();
359
		if ($current_order === 1 && $action === 'move_up')
360
		{
361
			return $switch_order_id;
362
		}
363
364
		if (($current_order === $max_order) && ($action === 'move_down'))
365
		{
366
			return $switch_order_id;
367
		}
368
369
		// on move_down, switch position with next order_id...
370
		// on move_up, switch position with previous order_id...
371
		$switch_order_id = ($action === 'move_down') ? $current_order + 1 : $current_order - 1;
372
373
		return $switch_order_id;
374
	}
375
376
	public function adm_list_cat($u_action)
377
	{
378
		$i = $cat = 0;
379
		$max = $this->get_max_order();
380
		$sql = $this->db->sql_build_query('SELECT', [
381
			'SELECT'	=> 'l.lang_iso, l.lang_local_name, c.*',
382
			'FROM'		=> [LANG_TABLE => 'l'],
383
			'LEFT_JOIN'	=> [
384
				[
385
					'FROM'	=> [$this->smilies_category_table => 'c'],
386
					'ON'	=> 'cat_lang = lang_iso',
387
				],
388
			],
389
			'ORDER_BY'	=> 'cat_order ASC, cat_lang_id ASC',
390
		]);
391
		$result = $this->db->sql_query($sql);
392
		while ($row = $this->db->sql_fetchrow($result))
393
		{
394
			if (!$row)
395
			{
396
				$this->template->assign_vars([
397
					'EMPTY_ROW' =>	true,
398
				]);
399
			}
400
			else
401
			{
402
				$this->template->assign_block_vars('categories', [
403
					'CAT_NR'			=> $i + 1,
404
					'LANG_EMPTY'		=> !$row['cat_id'] && !$row['cat_order'] && !$row['cat_name'],
405
					'SPACER_CAT'		=> $this->language->lang('SC_CATEGORY_IN', $row['cat_title']),
406
					'CAT_LANG'			=> $row['lang_local_name'],
407
					'CAT_ISO'			=> $row['lang_iso'],
408
					'CAT_ID'			=> $row['cat_id'],
409
					'CAT_ORDER'			=> $row['cat_order'],
410
					'CAT_TRANSLATE'		=> $row['cat_name'],
411
					'CAT_NB'			=> $row['cat_nb'],
412
					'ROW'				=> (int) $row['cat_id'] !== $cat,
413
					'ROW_MAX'			=> (int) $row['cat_order'] === $max,
414
					'U_EDIT'			=> $u_action . '&amp;action=edit&amp;id=' . $row['cat_id'],
415
					'U_DELETE'			=> $u_action . '&amp;action=delete&amp;id=' . $row['cat_id'],
416
				]);
417
				$i++;
418
				// Keep this value in memory
419
				$cat = (int) $row['cat_id'];
420
			}
421
		}
422
		$this->db->sql_freeresult($result);
423
424
		$this->template->assign_vars([
425
			'IN_LIST_CAT'	=> true,
426
			'U_ACTION'		=> $u_action,
427
			'U_MOVE_CATS'	=> $this->helper->route('sylver35_smiliescat_ajax_list_cat'),
428
		]);
429
	}
430
431
	public function reset_first_cat($current_order, $switch_order_id)
432
	{
433
		$first = $this->get_first_order();
434
		if ($current_order === 1 || $switch_order_id === 1)
435
		{
436
			if ($this->get_cat_nb($first) > 0)
437
			{
438
				$this->config->set('smilies_category_nb', $first);
439
			}
440
		}
441
	}
442
443
	public function move_cat($id, $action)
444
	{
445
		// Get current order id and title...
446
		$sql = 'SELECT cat_order, cat_title
447
			FROM ' . $this->smilies_category_table . '
448
				WHERE cat_id = ' . $id;
449
		$result = $this->db->sql_query($sql);
450
		$row = $this->db->sql_fetchrow($result);
451
		$current_order = (int) $row['cat_order'];
452
		$title = $row['cat_title'];
453
		$this->db->sql_freeresult($result);
454
455
		$switch_order_id = $this->set_order($action, $current_order);
456
		if ($switch_order_id === 0)
457
		{
458
			return;
459
		}
460
461
		$this->db->sql_query('UPDATE ' . $this->smilies_category_table . " SET cat_order = $current_order WHERE cat_order = $switch_order_id AND cat_id <> $id");
462
		$move_executed = (bool) $this->db->sql_affectedrows();
463
464
		// Only update the other entry too if the previous entry got updated
465
		if ($move_executed)
466
		{
467
			$this->db->sql_query('UPDATE ' . $this->smilies_category_table . " SET cat_order = $switch_order_id WHERE cat_order = $current_order AND cat_id = $id");
468
		}
469
470
		$this->reset_first_cat($current_order, $switch_order_id);
471
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_SC_' . strtoupper($action) . '_CAT', time(), [$title]);
472
	}
473
474
	public function edit_smiley($id, $start, $u_action)
475
	{
476
		$lang = $this->user->lang_name;
477
		$sql = $this->db->sql_build_query('SELECT', [
478
			'SELECT'	=> 's.*, c.*',
479
			'FROM'		=> [SMILIES_TABLE => 's'],
480
			'LEFT_JOIN'	=> [
481
				[
482
					'FROM'	=> [$this->smilies_category_table => 'c'],
483
					'ON'	=> "c.cat_id = s.category AND c.cat_lang = '$lang'",
484
				],
485
			],
486
			'WHERE'	=> 's.smiley_id = ' . (int) $id,
487
		]);
488
		$result = $this->db->sql_query($sql);
489
		$row = $this->db->sql_fetchrow($result);
490
491
		$this->template->assign_vars([
492
			'WIDTH'				=> $row['smiley_width'],
493
			'HEIGHT'			=> $row['smiley_height'],
494
			'CODE'				=> $row['code'],
495
			'EMOTION'			=> $row['emotion'],
496
			'CATEGORY'			=> $row['cat_name'],
497
			'EX_CAT'			=> $row['cat_id'],
498
			'SELECT_CATEGORY'	=> $this->select_categories($row['cat_id'], false, false),
499
			'IMG_SRC'			=> $this->root_path . $this->config['smilies_path'] . '/' . $row['smiley_url'],
500
			'U_MODIFY'			=> $u_action . '&amp;action=modify&amp;id=' . $row['smiley_id'] . '&amp;start=' . $start,
501
			'U_BACK'			=> $u_action,
502
			'S_IN_LIST'			=> false,
503
		]);
504
		$this->db->sql_freeresult($result);
505
	}
506
507
	public function edit_multi_smiley($list, $start, $u_action)
508
	{
509
		$i = 0;
510
		$lang = $this->user->lang_name;
511
		$sql = $this->db->sql_build_query('SELECT', [
512
			'SELECT'	=> 's.*, c.*',
513
			'FROM'		=> [SMILIES_TABLE => 's'],
514
			'LEFT_JOIN'	=> [
515
				[
516
					'FROM'	=> [$this->smilies_category_table => 'c'],
517
					'ON'	=> "c.cat_id = s.category AND cat_lang = '$lang'",
518
				],
519
			],
520
			'WHERE'		=> $this->db->sql_in_set('smiley_id', $list),
521
			'ORDER_BY'	=> 'cat_order ASC, s.smiley_order ASC',
522
		]);
523
		$result = $this->db->sql_query($sql);
524
		while ($row = $this->db->sql_fetchrow($result))
525
		{
526
			$row['cat_name'] = ($row['category']) ? $row['cat_name'] : $this->language->lang('SC_CATEGORY_DEFAUT');
527
			$this->template->assign_block_vars('items', [
528
				'IMG_SRC'		=>  $this->root_path . $this->config['smilies_path'] . '/' . $row['smiley_url'],
529
				'WIDTH'			=> $row['smiley_width'],
530
				'HEIGHT'		=> $row['smiley_height'],
531
				'ID'			=> $row['smiley_id'],
532
				'CODE'			=> $row['code'],
533
				'EMOTION'		=> $row['emotion'],
534
				'CATEGORY'		=> $row['cat_name'],
535
			]);
536
			$i++;
537
		}
538
		$this->db->sql_freeresult($result);
539
540
		$this->template->assign_vars([
541
			'SELECT_CATEGORY'	=> $this->select_categories(-1),
542
			'U_MODIFY'			=> $u_action . '&amp;action=modify_list&amp;start=' . $start,
543
			'S_IN_LIST'			=> true,
544
		]);
545
	}
546
}
547