Passed
Branch master (3ff077)
by Michael
03:41
created

PermissionForumHandler   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 109
dl 0
loc 249
rs 8.8
c 0
b 0
f 0
wmc 45

9 Methods

Rating   Name   Duplication   Size   Complexity  
B applyTemplate() 0 33 8
A __construct() 0 5 1
A getValidPerms() 0 15 4
B getValidItems() 0 33 9
A deleteByForum() 0 14 2
B getPermissions() 0 45 9
A setTemplate() 0 3 1
B getPermissionTable() 0 27 9
A getTemplate() 0 7 2

How to fix   Complexity   

Complex Class

Complex classes like PermissionForumHandler 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 PermissionForumHandler, and based on these observations, apply Extract Interface, too.

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
use Xmf\IPAddress;
15
use Xmf\Yaml;
16
use XoopsModules\Newbb;
17
18
//defined("NEWBB_HANDLER_PERMISSION") || require_once __DIR__  .'/permission.php';
19
//define("NEWBB_HANDLER_PERMISSION_FORUM", 1);
20
21
if (\defined('FORUM_PERM_ITEMS') && \class_exists('ForumPermissionHandler')) {
22
    exit('access denied');
23
}
24
// irmtfan add pdf and print permissions.
25
\define('FORUM_PERM_ITEMS', 'access,view,post,reply,edit,delete,addpoll,vote,attach,noapprove,type,html,signature,pdf,print');
26
27
/**
28
 * Class PermissionForumHandler
29
 */
30
class PermissionForumHandler extends PermissionHandler
31
{
32
    protected string $templateFilename;
33
34
    /**
35
     * @param \XoopsDatabase|null $db
36
     */
37
    public function __construct(\XoopsDatabase $db = null)
38
    {
39
        //        $this->PermissionHandler($db);
40
        parent::__construct($db);
41
        $this->templateFilename = XOOPS_VAR_PATH . '/configs/newbb_permission_template.php';
42
    }
43
44
    /**
45
     * @param bool $fullname
46
     * @return array
47
     */
48
    public function getValidPerms(bool $fullname = false): array
49
    {
50
        static $validPerms = [];
51
        if (isset($validPerms[(int)$fullname])) {
52
            return $validPerms[(int)$fullname];
53
        }
54
        $items = \array_filter(\array_map('\trim', \explode(',', \FORUM_PERM_ITEMS)));
55
        if (!empty($fullname)) {
56
            foreach (\array_keys($items) as $key) {
57
                $items[$key] = 'forum_' . $items[$key];
58
            }
59
        }
60
        $validPerms[(int)$fullname] = $items;
61
62
        return $items;
63
    }
64
65
    /**
66
     * @param int $mid
67
     * @param int $id
68
     * @return array
69
     */
70
    public function getValidItems(int $mid, int $id = 0): array
71
    {
72
        static $suspension = [];
73
        $full_items = [];
74
        if (empty($mid)) {
75
            return $full_items;
76
        }
77
78
        require_once \dirname(__DIR__) . '/include/functions.user.php';
79
        $uid = \is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
80
        $ip  = IPAddress::fromRequest()->asReadable();
81
        if (!empty($GLOBALS['xoopsModuleConfig']['enable_usermoderate']) && !isset($suspension[$uid][$id])
82
            && !\newbbIsAdmin($id)) {
83
            /** @var ModerateHandler $moderateHandler */
84
            $moderateHandler = Helper::getInstance()->getHandler('Moderate');
85
            if ($moderateHandler->verifyUser($uid, '', $id)) {
86
                $suspension[$uid][$ip][$id] = 0;
87
            } else {
88
                $suspension[$uid][$ip][$id] = 1;
89
            }
90
        }
91
92
        $items = $this->getValidPerms();
93
        foreach ($items as $item) {
94
            /* skip access for suspended users */
95
            //if ( !empty($suspension[$uid][$ip][$id]) && in_array($item, array("post", "reply", "edit", "delete", "addpoll", "vote", "attach", "noapprove", "type")) ) continue;
96
            if (!empty($suspension[$uid][$ip][$id])) {
97
                continue;
98
            }
99
            $full_items[] = "'forum_{$item}'";
100
        }
101
102
        return $full_items;
103
    }
104
105
    /*
106
    * Returns permissions for a certain type
107
    *
108
    * @param int $id id of the item (forum, topic or possibly post) to get permissions for
109
    *
110
    * @return array
111
    */
112
113
    /**
114
     * @param int|mixed[] $id
115
     * @return array
116
     */
117
    public function getPermissions($id = 0): array
118
    {
119
        $permissions = [];
120
        if (\is_object($GLOBALS['xoopsModule']) && 'newbb' === $GLOBALS['xoopsModule']->getVar('dirname')) {
121
            $modid = $GLOBALS['xoopsModule']->getVar('mid');
122
        } else {
123
            /** @var \XoopsModuleHandler $moduleHandler */
124
            $moduleHandler = \xoops_getHandler('module');
125
            $xoopsNewBB    = $moduleHandler->getByDirname('newbb');
126
            $modid         = $xoopsNewBB->getVar('mid');
127
            unset($xoopsNewBB);
128
        }
129
130
        // Get user's groups
131
        $groups = \is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getGroups() : [XOOPS_GROUP_ANONYMOUS];
132
        // Create string of groupid's separated by commas, inserted in a set of brackets
133
        if ((is_countable($groups) ? \count($groups) : 0) < 1) {
134
            return [];
135
        }
136
        // Create criteria for getting only the permissions regarding this module and this user's groups
137
        $criteria = new \CriteriaCompo(new \Criteria('gperm_modid', $modid));
138
        $criteria->add(new \Criteria('gperm_groupid', '(' . \implode(',', $groups) . ')', 'IN'));
139
        if ($id) {
140
            if (\is_array($id)) {
141
                $criteria->add(new \Criteria('gperm_itemid', '(' . \implode(',', $id) . ')', 'IN'));
142
            } else {
143
                $criteria->add(new \Criteria('gperm_itemid', (int)$id));
144
            }
145
        }
146
        $gperm_names = \implode(', ', $this->getValidItems($modid, $id));
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type array<mixed,mixed>; however, parameter $id of XoopsModules\Newbb\Permi...andler::getValidItems() does only seem to accept integer, 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

146
        $gperm_names = \implode(', ', $this->getValidItems($modid, /** @scrutinizer ignore-type */ $id));
Loading history...
147
148
        // Add criteria for gpermnames
149
        $criteria->add(new \Criteria('gperm_name', '(' . $gperm_names . ')', 'IN'));
150
        // Get all permission objects in this module and for this user's groups
151
        $userpermissions = $this->getObjects($criteria, true);
152
153
        // Set the granted permissions to 1
154
        foreach ($userpermissions as $gperm_id => $gperm) {
155
            $permissions[$gperm->getVar('gperm_itemid')][$gperm->getVar('gperm_name')] = 1;
156
        }
157
        $userpermissions = null;
158
        unset($userpermissions);
159
160
        // Return the permission array
161
        return $permissions;
162
    }
163
164
    /**
165
     * @param int|Forum  $forum
166
     * @param bool $topic_locked
167
     * @param bool $isAdmin
168
     * @return array
169
     */
170
    public function getPermissionTable($forum = 0, bool $topic_locked = false, bool $isAdmin = false): array
171
    {
172
        $perm = [];
173
174
        $forumId = $forum;
175
        if (\is_object($forum)) {
176
            $forumId = $forum->getVar('forum_id');
177
        }
178
179
        $permissionSet = $this->getPermissions($forumId);
180
181
        $permItems = $this->getValidPerms();
182
        foreach ($permItems as $item) {
183
            if ('access' === $item) {
184
                continue;
185
            }
186
            if ($isAdmin
187
                || ((is_countable($permissionSet) && isset($permissionSet[$forumId]['forum_' . $item])
188
                     && (!$topic_locked
189
                         || 'view' === $item)))) {
190
                $perm[] = \constant('_MD_NEWBB_CAN_' . \mb_strtoupper((string) $item));
191
            } else {
192
                $perm[] = \constant('_MD_NEWBB_CANNOT_' . \mb_strtoupper((string) $item));
193
            }
194
        }
195
196
        return $perm;
197
    }
198
199
    /**
200
     * @param int $forum_id
201
     * @return bool
202
     */
203
    public function deleteByForum(int $forum_id): bool
204
    {
205
        $forum_id = (int)$forum_id;
206
        if (empty($forum_id)) {
207
            return false;
208
        }
209
        /** @var \XoopsGroupPermHandler $grouppermHandler */
210
        $grouppermHandler = \xoops_getHandler('groupperm');
211
        $criteria         = new \CriteriaCompo(new \Criteria('gperm_modid', $GLOBALS['xoopsModule']->getVar('mid')));
212
        $items            = $this->getValidPerms(true);
213
        $criteria->add(new \Criteria('gperm_name', "('" . \implode("', '", $items) . "')", 'IN'));
214
        $criteria->add(new \Criteria('gperm_itemid', $forum_id));
215
216
        return $grouppermHandler->deleteAll($criteria);
217
    }
218
219
    /**
220
     * @param int $forum
221
     * @param int $mid
222
     * @return bool
223
     */
224
    public function applyTemplate(int $forum, int $mid = 0): bool
225
    {
226
        if (!$perm_template = $this->getTemplate()) {
227
            return false;
228
        }
229
230
        if (empty($mid)) {
231
            if (\is_object($GLOBALS['xoopsModule']) && 'newbb' === $GLOBALS['xoopsModule']->getVar('dirname')) {
232
                $mid = $GLOBALS['xoopsModule']->getVar('mid');
233
            } else {
234
                /** @var \XoopsModuleHandler $moduleHandler */
235
                $moduleHandler = \xoops_getHandler('module');
236
                $newbb         = $moduleHandler->getByDirname('newbb');
237
                $mid           = $newbb->getVar('mid');
238
                unset($newbb);
239
            }
240
        }
241
242
        /** @var \XoopsMemberHandler $memberHandler */
243
        $memberHandler = \xoops_getHandler('member');
244
        $glist         = $memberHandler->getGroupList();
245
        $perms         = $this->getValidPerms(true);
246
        foreach (\array_keys($glist) as $group) {
247
            foreach ($perms as $perm) {
248
                if (!empty($perm_template[$group][$perm])) {
249
                    $this->validateRight($perm, (int)$forum, $group, $mid);
250
                } else {
251
                    $this->deleteRight($perm, (int)$forum, $group, $mid);
252
                }
253
            }
254
        }
255
256
        return true;
257
    }
258
259
    /**
260
     * @return array
261
     */
262
    public function getTemplate(): array
263
    {
264
        $perms = Yaml::readWrapped($this->templateFilename);
265
266
        $perms = (false !== $perms) ? $perms : [];
0 ignored issues
show
introduced by
The condition false !== $perms is always true.
Loading history...
267
268
        return $perms;
269
    }
270
271
    /**
272
     * @param array $perms
273
     * @param int   $groupid
274
     * @return bool|int
275
     */
276
    public function setTemplate(array $perms, int $groupid = 0)
277
    {
278
        return Yaml::saveWrapped($perms, $this->templateFilename);
279
    }
280
}
281