TypeHandler   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 171
rs 9.92
c 0
b 0
f 0
wmc 31

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
B getByForum() 0 29 6
A delete() 0 24 6
D updateByForum() 0 63 17
A cleanOrphan() 0 11 1
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Newbb;
4
5
/**
6
 * NewBB,  the forum module for XOOPS project
7
 *
8
 * @copyright      XOOPS Project (https://xoops.org)
9
 * @license        GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
10
 * @author         Taiwen Jiang (phppp or D.J.) <[email protected]>
11
 * @since          4.00
12
 */
13
14
/**
15
 * Type object handler class.
16
 *
17
 * @author    D.J. (phppp)
18
 * @copyright copyright &copy; 2006 XOOPS Project
19
 */
20
class TypeHandler extends \XoopsPersistableObjectHandler
21
{
22
    /**
23
     * @param null|\XoopsDatabase $db
24
     */
25
    public function __construct(\XoopsDatabase $db = null)
26
    {
27
        parent::__construct($db, 'newbb_type', Type::class, 'type_id', 'type_name');
28
    }
29
30
    /**
31
     * Get types linked to a forum
32
     *
33
     * @param mixed $forums single forum ID or an array of forum IDs
34
     * @return array associative array of types (name, color, order)
35
     */
36
    public function getByForum($forums = null): array
37
    {
38
        $ret = [];
39
40
        $forums = (\is_array($forums) ? \array_filter(\array_map('\intval', \array_map('\trim', $forums))) : (empty($forums) ? 0 : [(int)$forums]));
41
42
        $sql = '    SELECT o.type_id, o.type_name, o.type_color, l.type_order'
43
               . '     FROM '
44
               . $this->db->prefix('newbb_type_forum')
45
               . ' AS l '
46
               . "         LEFT JOIN {$this->table} AS o ON o.{$this->keyName} = l.{$this->keyName} "
47
               . '     WHERE '
48
               . '        l.forum_id '
49
               . (empty($forums) ? 'IS NOT NULL' : 'IN (' . \implode(', ', $forums) . ')')
0 ignored issues
show
Bug introduced by
It seems like $forums can also be of type integer; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
               . (empty($forums) ? 'IS NOT NULL' : 'IN (' . \implode(', ', /** @scrutinizer ignore-type */ $forums) . ')')
Loading history...
50
               . '         ORDER BY l.type_order ASC';
51
52
        $result = $this->db->query($sql);
53
        if ($this->db->isResultSet($result)) {
54
            while (false !== ($myrow = $this->db->fetchArray($result))) {
55
                $ret[$myrow[$this->keyName]] = [
56
                    'type_id'    => $myrow[$this->keyName],
57
                    'type_order' => $myrow['type_order'],
58
                    'type_name'  => \htmlspecialchars((string)$myrow['type_name'], \ENT_QUOTES | \ENT_HTML5),
59
                    'type_color' => \htmlspecialchars((string)$myrow['type_color'], \ENT_QUOTES | \ENT_HTML5),
60
                ];
61
            }
62
        }
63
64
        return $ret;
65
    }
66
67
    /**
68
     * Update types linked to a forum
69
     *
70
     * @param int   $forum_id
71
     * @param array $types
72
     * @return bool
73
     */
74
    public function updateByForum(int $forum_id, array $types): bool
75
    {
76
        $forum_id = (int)$forum_id;
77
        if (empty($forum_id)) {
78
            return false;
79
        }
80
81
        $types_existing = $this->getByForum($forum_id);
82
        $types_valid    = [];
83
        $types_add      = [];
84
        $types_update   = [];
85
        foreach (\array_keys($types_existing) as $key) {
86
            if (empty($types[$key])) {
87
                continue;
88
            }
89
            $types_valid[] = $key;
90
            if ($types[$key] !== $types_existing[$key]['type_order']) {
91
                $types_update[] = $key;
92
            }
93
        }
94
        foreach (\array_keys($types) as $key) {
95
            if (!empty($types[$key]) && !isset($types_existing[$key])) {
96
                $types_add[] = $key;
97
            }
98
        }
99
        $types_valid  = \array_filter($types_valid);
100
        $types_add    = \array_filter($types_add);
101
        $types_update = \array_filter($types_update);
102
103
        if (!empty($types_valid)) {
104
            $sql = 'DELETE FROM ' . $this->db->prefix('newbb_type_forum') . ' WHERE ' . ' forum_id = ' . $forum_id . ' AND ' . // irmtfan bug fix: delete other forums types when update the type for a specific forum
105
                   "     {$this->keyName} NOT IN (" . \implode(', ', $types_valid) . ')';
106
            if (false === ($result = $this->db->queryF($sql))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
107
            }
108
        }
109
110
        if (!empty($types_update)) {
111
            $type_query = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $type_query is dead and can be removed.
Loading history...
112
            foreach ($types_update as $key) {
113
                $order = $types[$key];
114
                if ($types_existing[$key]['type_order'] == $order) {
115
                    continue;
116
                }
117
                $sql = 'UPDATE ' . $this->db->prefix('newbb_type_forum') . " SET type_order = {$order}" . " WHERE  {$this->keyName} = {$key} AND forum_id = {$forum_id}";
118
                if (false === ($result = $this->db->queryF($sql))) {
119
                }
120
            }
121
        }
122
123
        if (!empty($types_add)) {
124
            $type_query = [];
125
            foreach ($types_add as $key) {
126
                $order = $types[$key];
127
                //if (!in_array($key, $types_add)) continue;
128
                $type_query[] = "({$key}, {$forum_id}, {$order})";
129
            }
130
            $sql = 'INSERT INTO ' . $this->db->prefix('newbb_type_forum') . ' (type_id, forum_id, type_order) ' . ' VALUES ' . \implode(', ', $type_query);
131
            if (false === ($result = $this->db->queryF($sql))) {
132
                //xoops_error($this->db->error());
133
            }
134
        }
135
136
        return true;
137
    }
138
139
    /**
140
     * delete an object as well as links relying on it
141
     *
142
     * @param Type|\XoopsObject $object {@link Type}
143
     * @param bool              $force  flag to force the query execution despite security settings
144
     * @return bool
145
     */
146
    public function delete(\XoopsObject $object, $force = true): bool
147
    {
148
        if (!\is_object($object) || !$object->getVar($this->keyName)) {
149
            return false;
150
        }
151
        $queryFunc = empty($force) ? 'query' : 'queryF';
152
153
        /*
154
         * Remove forum-type links
155
         */
156
        $sql = 'DELETE' . ' FROM ' . $this->db->prefix('newbb_type_forum') . ' WHERE  ' . $this->keyName . ' = ' . $object->getVar($this->keyName);
157
        if (false === ($result = $this->db->{$queryFunc}($sql))) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
158
            // xoops_error($this->db->error());
159
        }
160
161
        /*
162
         * Reset topic type linked to this type
163
         */
164
        $sql = 'UPATE' . ' ' . $this->db->prefix('newbb_topics') . ' SET ' . $this->keyName . '=0' . ' WHERE  ' . $this->keyName . ' = ' . $object->getVar($this->keyName);
165
        if (false === ($result = $this->db->{$queryFunc}($sql))) {
166
            //xoops_error($this->db->error());
167
        }
168
169
        return parent::delete($object, $force);
170
    }
171
172
    /**
173
     * clean orphan links from database
174
     *
175
     * @param string $table_link
176
     * @param string $field_link
177
     * @param string $field_object
178
     * @return bool   true on success
179
     */
180
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = ''): bool //cleanOrphan()
181
    {
182
        /* clear forum-type links */
183
        $sql = 'DELETE FROM ' . $this->db->prefix('newbb_type_forum') . " WHERE ({$this->keyName} NOT IN ( SELECT DISTINCT {$this->keyName} FROM {$this->table}) )";
184
        $this->db->queryF($sql);
185
186
        /* reconcile topic-type link */
187
        $sql = 'UPATE ' . $this->db->prefix('newbb_topics') . " SET {$this->keyName} = 0" . " WHERE ({$this->keyName} NOT IN ( SELECT DISTINCT {$this->keyName} FROM {$this->table}) )";
188
        $this->db->queryF($sql);
189
190
        return true;
191
    }
192
}
193