Passed
Push — 1.4.0 ( 26901a...ea1ce7 )
by Sylver
02:59
created

category   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 437
Duplicated Lines 0 %

Importance

Changes 23
Bugs 0 Features 0
Metric Value
eloc 246
dl 0
loc 437
rs 6
c 23
b 0
f 0
wmc 55

15 Methods

Rating   Name   Duplication   Size   Complexity  
A get_version() 0 16 2
A __construct() 0 13 1
A smilies_count() 0 12 3
A shoutbox_smilies() 0 44 4
A set_order() 0 19 6
B select_categories() 0 29 8
A shoutbox_smilies_popup() 0 50 5
A get_max_id() 0 10 1
A capitalize() 0 3 1
B extract_list_categories() 0 50 11
A get_first_order() 0 11 1
A get_max_order() 0 10 1
A move_cat() 0 38 3
A adm_list_cat() 0 52 5
A reset_first_cat() 0 6 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 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
			$select .= '<option value="-1"' . (($cat == -1) ? ' selected="selected"' : '') . '>' . $this->language->lang('SC_CATEGORY_ANY') . '</option>';
117
		}
118
119
		$sql = 'SELECT *
120
			FROM ' . $this->smilies_category_table . "
121
				WHERE cat_lang = '$lang'
122
				ORDER BY cat_order ASC";
123
		$result = $this->db->sql_query($sql);
124
		while ($row = $this->db->sql_fetchrow($result))
125
		{
126
			if (!$row['cat_nb'] && $empty)
127
			{
128
				continue;
129
			}
130
			$selected = ($cat === (int) $row['cat_id']) ? ' selected="selected"' : '';
131
			$select .= '<option title="' . $row['cat_name'] . '" value="' . $row['cat_id'] . '"' . $selected . '> ' . $row['cat_name'] . '</option>';
132
		}
133
		$this->db->sql_freeresult($result);
134
135
		$selected_default = (!$cat) ? ' selected="selected"' : '';
136
		$select .= '<option title="' . $this->language->lang('SC_CATEGORY_DEFAUT') . '" value="0"' . $selected_default . '> ' . $this->language->lang('SC_CATEGORY_DEFAUT') . '</option>';
137
138
		return $select;
139
	}
140
141
	public function capitalize($var)
142
	{
143
		return $this->db->sql_escape(ucfirst(strtolower(trim($var))));
144
	}
145
146
	public function get_max_order()
147
	{
148
		// Get max order id...
149
		$sql = 'SELECT MAX(cat_order) AS maxi
150
			FROM ' . $this->smilies_category_table;
151
		$result = $this->db->sql_query($sql);
152
		$max = (int) $this->db->sql_fetchfield('maxi', $result);
153
		$this->db->sql_freeresult($result);
154
155
		return $max;
156
	}
157
158
	public function get_max_id()
159
	{
160
		// Get max id...
161
		$sql = 'SELECT MAX(cat_id) AS id_max
162
			FROM ' . $this->smilies_category_table;
163
		$result = $this->db->sql_query($sql);
164
		$id_max = (int) $this->db->sql_fetchfield('id_max', $result);
165
		$this->db->sql_freeresult($result);
166
167
		return $id_max;
168
	}
169
170
	public function get_first_order()
171
	{
172
		// Get first order id...
173
		$sql = 'SELECT cat_order, cat_id
174
			FROM ' . $this->smilies_category_table . '
175
			ORDER BY cat_order ASC';
176
		$result = $this->db->sql_query_limit($sql, 1);
177
		$mini = (int) $this->db->sql_fetchfield('cat_id');
178
		$this->db->sql_freeresult($result);
179
180
		return $mini;
181
	}
182
183
	public function extract_list_categories($cat)
184
	{
185
		$title = '';
186
		$cat_order = $i = 0;
187
		$lang = $this->user->lang_name;
188
		$sql = $this->db->sql_build_query('SELECT', [
189
			'SELECT'	=> '*',
190
			'FROM'		=> [$this->smilies_category_table => ''],
191
			'WHERE'		=> "cat_lang = '$lang'",
192
			'ORDER_BY'	=> 'cat_order ASC',
193
		]);
194
		$result = $this->db->sql_query($sql);
195
		while ($row = $this->db->sql_fetchrow($result))
196
		{
197
			// Choose only non-empty categories
198
			if ($row['cat_nb'])
199
			{
200
				$actual_cat = (int) $row['cat_id'] === $cat;
201
				$this->template->assign_block_vars('categories', [
202
					'CLASS'			=> $actual_cat ? 'cat-active' : 'cat-inactive',
203
					'SEPARATE'		=> ($i > 0) ? ' - ' : '',
204
					'CAT_ID'		=> $row['cat_id'],
205
					'CAT_ORDER'		=> $row['cat_order'],
206
					'CAT_NAME'		=> $row['cat_name'] ? $row['cat_name'] : $row['cat_title'],
207
					'CAT_NB'		=> $row['cat_nb'],
208
				]);
209
				$i++;
210
211
				// Keep these values in memory
212
				$title = $actual_cat ? $row['cat_name'] : $title;
213
				$cat_order = $row['cat_order'];
214
			}
215
		}
216
		$this->db->sql_freeresult($result);
217
218
		// Add the Unclassified category if not empty
219
		$nb = $this->smilies_count(0);
220
		if ($nb)
221
		{
222
			$this->template->assign_block_vars('categories', [
223
				'CLASS'			=> ($cat === 0) ? 'cat-active' : 'cat-inactive',
224
				'SEPARATE'		=> ($i > 0) ? ' - ' : '',
225
				'CAT_ID'		=> 0,
226
				'CAT_ORDER'		=> $cat_order + 1,
227
				'CAT_NAME'		=> $this->language->lang('SC_CATEGORY_DEFAUT'),
228
				'CAT_NB'		=> $nb,
229
			]);
230
		}
231
232
		return (!$cat) ? $this->language->lang('SC_CATEGORY_DEFAUT') : $title;
233
	}
234
235
	public function shoutbox_smilies($event)
236
	{
237
		$i = $cat_order = 0;
238
		$list_cat = [];
239
		$lang = $this->user->lang_name;
240
241
		$sql = 'SELECT * 
242
			FROM ' . $this->smilies_category_table . "
243
				WHERE cat_lang = '$lang'
244
				ORDER BY cat_order ASC";
245
		$result = $this->db->sql_query($sql);
246
		while ($row = $this->db->sql_fetchrow($result))
247
		{
248
			// Choose only non-empty categories
249
			if ($row['cat_nb'])
250
			{
251
				$list_cat[$i] = [
252
					'cat_id'		=> (int) $row['cat_id'],
253
					'cat_order'		=> (int) $row['cat_order'],
254
					'cat_name'		=> (string) $row['cat_name'],
255
					'cat_nb'		=> (int) $row['cat_nb'],
256
				];
257
				$i++;
258
			}
259
			// Keep this value in memory
260
			$cat_order = (int) $row['cat_order'];
261
		}
262
		$this->db->sql_freeresult($result);
263
264
		// Add the Unclassified category if not empty
265
		$nb = $this->smilies_count(0, true);
266
		if ($nb)
267
		{
268
			$list_cat[$i] = [
269
				'cat_id'		=> 0,
270
				'cat_order'		=> $cat_order + 1,
271
				'cat_name'		=> $this->language->lang('SC_CATEGORY_DEFAUT'),
272
				'cat_nb'		=> $nb,
273
			];
274
		}
275
276
		$event['content'] = array_merge($event['content'], [
277
			'title_cat'		=> $this->language->lang('ACP_SC_SMILIES'),
278
			'categories'	=> $list_cat,
279
		]);
280
	}
281
282
	public function shoutbox_smilies_popup($event)
283
	{
284
		$cat = (int) $event['cat'];
285
		if ($cat > -1)
286
		{
287
			$i = 0;
288
			$smilies = [];
289
			$lang = $this->user->lang_name;
290
			$cat_name = $this->language->lang('SC_CATEGORY_DEFAUT');
291
292
			if ($cat > 0)
293
			{
294
				$sql = 'SELECT cat_name
295
					FROM ' . $this->smilies_category_table . "
296
						WHERE cat_lang = '$lang'
297
						AND cat_id = $cat";
298
				$result = $this->db->sql_query_limit($sql, 1);
299
				$row = $this->db->sql_fetchrow($result);
300
				$cat_name = $row['cat_name'];
301
				$this->db->sql_freeresult($result);
302
			}
303
304
			$sql = $this->db->sql_build_query('SELECT', [
305
				'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',
306
				'FROM'		=> [SMILIES_TABLE => ''],
307
				'WHERE'		=> 'category = ' . $cat,
308
				'GROUP_BY'	=> 'smiley_url',
309
				'ORDER_BY'	=> 'min_smiley_order ASC',
310
			]);
311
			$result = $this->db->sql_query($sql);
312
			while ($row = $this->db->sql_fetchrow($result))
313
			{
314
				$smilies[$i] = [
315
					'nb'		=> (int) $i,
316
					'code'		=> (string) $row['code'],
317
					'emotion'	=> (string) $row['emotion'],
318
					'image'		=> (string) $row['smiley_url'],
319
					'width'		=> (int) $row['smiley_width'],
320
					'height'	=> (int) $row['smiley_height'],
321
				];
322
				$i++;
323
			}
324
325
			$event['content'] = array_merge($event['content'], [
326
				'in_cat'		=> true,
327
				'cat'			=> $cat,
328
				'total'			=> $i,
329
				'smilies'		=> $smilies,
330
				'emptyRow'		=> (!$i) ? $this->language->lang('SC_SMILIES_EMPTY_CATEGORY') : '',
331
				'title'			=> $this->language->lang('SC_CATEGORY_IN', $cat_name),
332
			]);
333
		}
334
	}
335
336
	public function set_order($action, $current_order)
337
	{
338
		$switch_order_id = 0;
339
		$max_order = $this->get_max_order();
340
		if ($current_order == 1 && $action == 'move_up')
341
		{
342
			return $switch_order_id;
343
		}
344
345
		if (($current_order == $max_order) && ($action == 'move_down'))
346
		{
347
			return $switch_order_id;
348
		}
349
350
		// on move_down, switch position with next order_id...
351
		// on move_up, switch position with previous order_id...
352
		$switch_order_id = ($action === 'move_down') ? $current_order + 1 : $current_order - 1;
353
354
		return $switch_order_id;
355
	}
356
357
	public function adm_list_cat($u_action)
358
	{
359
		$i = $cat = 0;
360
		$max = $this->get_max_order();
361
		$sql = $this->db->sql_build_query('SELECT', [
362
			'SELECT'	=> 'l.lang_iso, l.lang_local_name, c.*',
363
			'FROM'		=> [LANG_TABLE => 'l'],
364
			'LEFT_JOIN'	=> [
365
				[
366
					'FROM'	=> [$this->smilies_category_table => 'c'],
367
					'ON'	=> 'cat_lang = lang_iso',
368
				],
369
			],
370
			'ORDER_BY'	=> 'cat_order ASC, cat_lang_id ASC',
371
		]);
372
		$result = $this->db->sql_query($sql);
373
		while ($row = $this->db->sql_fetchrow($result))
374
		{
375
			if (!$row)
376
			{
377
				$this->template->assign_vars([
378
					'EMPTY_ROW'	=> true,
379
				]);
380
			}
381
			else
382
			{
383
				$this->template->assign_block_vars('categories', [
384
					'CAT_NR'			=> $i + 1,
385
					'LANG_EMPTY'		=> !$row['cat_id'] && !$row['cat_order'] && !$row['cat_name'],
386
					'SPACER_CAT'		=> $this->language->lang('SC_CATEGORY_IN', $row['cat_title']),
387
					'CAT_LANG'			=> $row['lang_local_name'],
388
					'CAT_ISO'			=> $row['lang_iso'],
389
					'CAT_ID'			=> $row['cat_id'],
390
					'CAT_ORDER'			=> $row['cat_order'],
391
					'CAT_TRANSLATE'		=> $row['cat_name'],
392
					'CAT_NB'			=> $row['cat_nb'],
393
					'ROW'				=> (int) $row['cat_id'] !== $cat,
394
					'ROW_MAX'			=> (int) $row['cat_order'] === $max,
395
					'U_EDIT'			=> $u_action . '&amp;action=edit&amp;id=' . $row['cat_id'],
396
					'U_DELETE'			=> $u_action . '&amp;action=delete&amp;id=' . $row['cat_id'],
397
				]);
398
				$i++;
399
				// Keep this value in memory
400
				$cat = (int) $row['cat_id'];
401
			}
402
		}
403
		$this->db->sql_freeresult($result);
404
405
		$this->template->assign_vars([
406
			'IN_LIST_CAT'	=> true,
407
			'U_ACTION'		=> $u_action,
408
			'U_MOVE_CATS'	=> $this->helper->route('sylver35_smiliescat_ajax_list_cat'),
409
		]);
410
	}
411
412
	public function reset_first_cat($current_order, $switch_order_id)
413
	{
414
		$first = $this->get_first_order();
415
		if ($current_order === 1 || $switch_order_id === 1)
416
		{
417
			$this->config->set('smilies_category_nb', $first);
418
		}
419
	}
420
421
	public function move_cat($action, $id)
422
	{
423
		$id = (int) $id;
424
		// Get current order id and title...
425
		$sql = 'SELECT cat_order, cat_title
426
			FROM ' . $this->smilies_category_table . '
427
				WHERE cat_id = ' . $id;
428
		$result = $this->db->sql_query($sql);
429
		$row = $this->db->sql_fetchrow($result);
430
		$current_order = (int) $row['cat_order'];
431
		$title = $row['cat_title'];
432
		$this->db->sql_freeresult($result);
433
434
		$switch_order_id = $this->set_order($action, $current_order);
435
		if ($switch_order_id === 0)
436
		{
437
			return;
438
		}
439
440
		$sql = 'UPDATE ' . $this->smilies_category_table . "
441
			SET cat_order = $current_order
442
			WHERE cat_order = $switch_order_id
443
				AND cat_id <> $id";
444
		$this->db->sql_query($sql);
445
		$move_executed = (bool) $this->db->sql_affectedrows();
446
447
		// Only update the other entry too if the previous entry got updated
448
		if ($move_executed)
449
		{
450
			$sql = 'UPDATE ' . $this->smilies_category_table . "
451
				SET cat_order = $switch_order_id
452
				WHERE cat_order = $current_order
453
					AND cat_id = $id";
454
			$this->db->sql_query($sql);
455
		}
456
457
		$this->reset_first_cat($current_order, $switch_order_id);
458
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_SC_' . strtoupper($action) . '_CAT', time(), [$title]);
459
	}
460
}
461