Completed
Pull Request — master (#25)
by Erwan
04:33
created

cat::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 2 Features 0
Metric Value
c 5
b 2
f 0
dl 0
loc 21
rs 9.3142
cc 2
eloc 17
nc 2
nop 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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