Completed
Push — master ( c622f7...33a06a )
by Richard
09:52 queued 02:32
created

XoopsModuleHandler   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 269
Duplicated Lines 8.55 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 61.19%

Importance

Changes 0
Metric Value
dl 23
loc 269
ccs 82
cts 134
cp 0.6119
rs 9.6
c 0
b 0
f 0
wmc 32
lcom 1
cbo 9

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getById() 0 18 4
A insertModule() 0 17 4
C deleteModule() 0 87 7
A getByDirname() 0 20 4
D getObjectsArray() 10 35 9
A getNameList() 13 13 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * XOOPS Kernel Class
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       XOOPS Project (http://xoops.org)
13
 * @license         GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package         kernel
15
 * @since           2.0.0
16
 * @version         $Id$
17
 */
18
19
namespace Xoops\Core\Kernel\Handlers;
20
21
use Xoops\Core\Database\Connection;
22
use Xoops\Core\Kernel\Criteria;
23
use Xoops\Core\Kernel\CriteriaElement;
24
use Xoops\Core\Kernel\XoopsPersistableObjectHandler;
25
26
/**
27
 * XOOPS module handler class.
28
 *
29
 * This class is responsible for providing data access mechanisms to the data source
30
 * of XOOPS module class objects.
31
 *
32
 * @category  Xoops\Core\Kernel\XoopsModuleHandler
33
 * @package   Xoops\Core\Kernel
34
 * @author    Kazumi Ono <[email protected]>
35
 * @author    Taiwen Jiang <[email protected]>
36
 * @copyright 2000-2015 XOOPS Project (http://xoops.org)
37
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
38
 * @link      http://xoops.org
39
 */
40
class XoopsModuleHandler extends XoopsPersistableObjectHandler
41
{
42
    /**
43
     * holds an array of cached module references, indexed by module id
44
     *
45
     * @var array
46
     * @access private
47
     */
48
    private $cachedModulesByMid = array();
49
50
    /**
51
     * holds an array of cached module references, indexed by module dirname
52
     *
53
     * @var array
54
     * @access private
55
     */
56
    private $cachedModulesByDirname = array();
57
58
    /**
59
     * Constructor
60
     *
61
     * @param Connection|null $db database
62
     */
63 8
    public function __construct(Connection $db = null)
64
    {
65 8
        parent::__construct($db, 'system_module', '\Xoops\Core\Kernel\Handlers\XoopsModule', 'mid', 'dirname');
66 8
    }
67
68
    /**
69
     * Load a module from the database
70
     *
71
     * @param int $id ID of the module
72
     *
73
     * @return XoopsModule|bool on fail
74
     */
75 2
    public function getById($id = null)
76
    {
77 2
        $id = (int)($id);
78 2
        if ($id > 0) {
79 1
            if (!empty($this->cachedModulesByMid[$id])) {
80 1
                return $this->cachedModulesByMid[$id];
81
            } else {
82
                $module = parent::get($id);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (get() instead of getById()). Are you sure this is correct? If so, you might want to change this to $this->get().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
83
                if (!is_object($module)) {
84
                    return false;
85
                }
86
                $this->cachedModulesByMid[$id] = $module;
87
                $this->cachedModulesByDirname[$module->getVar('dirname')] = $module;
88
                return $module;
89
            }
90
        }
91 2
        return false;
92
    }
93
94
    /**
95
     * Load a module by its dirname
96
     *
97
     * @param string $dirname module directory name
98
     *
99
     * @return XoopsModule|bool FALSE on fail
100
     */
101 6
    public function getByDirname($dirname)
102
    {
103 6
        $dirname = basename(trim($dirname));
104
105 6
        if (!empty($this->cachedModulesByDirname[$dirname])) {
106 1
            return $this->cachedModulesByDirname[$dirname];
107
        } else {
108 6
            $criteria = new Criteria('dirname', $dirname);
109 6
            $modules = $this->getObjectsArray($criteria);
110 6
            if (count($modules) == 1 && is_object($modules[0])) {
111 2
                $module = $modules[0];
112
            } else {
113 4
                return false;
114
            }
115
            /* @var $module XoopsModule */
116 2
            $this->cachedModulesByDirname[$dirname] = $module;
117 2
            $this->cachedModulesByMid[$module->getVar('mid')] = $module;
118 2
            return $module;
119
        }
120
    }
121
122
    /**
123
     * Write a module to the database
124
     *
125
     * @param XoopsModule $module module to insert
126
     *
127
     * @return bool
128
     */
129 1
    public function insertModule(XoopsModule $module)
130
    {
131 1
        if (!parent::insert($module)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression parent::insert($module) of type integer|false is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (insert() instead of insertModule()). Are you sure this is correct? If so, you might want to change this to $this->insert().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
132
            return false;
133
        }
134
135 1
        $dirname = $module->getVar('dirname');
136 1
        $mid = $module->getVar('mid');
137
138 1
        if (!empty($this->cachedModulesByDirname[$dirname])) {
139
            unset($this->cachedModulesByDirname[$dirname]);
140
        }
141 1
        if (!empty($this->cachedModulesByMid[$mid])) {
142
            unset($this->cachedModulesByMid[$mid]);
143
        }
144 1
        return true;
145
    }
146
147
    /**
148
     * Delete a module from the database
149
     *
150
     * @param XoopsModule $module module to delete
151
     *
152
     * @return bool
153
     */
154 1
    public function deleteModule(XoopsModule $module)
155
    {
156 1
        if (!parent::delete($module)) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (delete() instead of deleteModule()). Are you sure this is correct? If so, you might want to change this to $this->delete().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
157
            return false;
158
        }
159
160 1
        $mid = $module->getVar('mid');
161 1
        $dirname = $module->getVar('dirname');
162
163
        // delete admin and read permissions assigned for this module
164 1
        $qb = $this->db2->createXoopsQueryBuilder();
165 1
        $eb = $qb->expr();
166 1
        $qb ->deletePrefix('system_permission')
167 1
            ->where(
168 1
                $eb->orX(
169 1
                    $eb->eq('gperm_name', $eb->literal('module_admin')),
170 1
                    $eb->eq('gperm_name', $eb->literal('module_read'))
171
                )
172
            )
173 1
            ->andWhere($eb->eq('gperm_itemid', ':itemid'))
174 1
            ->setParameter(':itemid', $mid, \PDO::PARAM_INT)
175 1
            ->execute();
176
177 1
        $qb->resetQueryParts(); // reset
178 1
        $qb ->select('block_id')
179 1
            ->fromPrefix('system_blockmodule', null)
180 1
            ->where($eb->eq('module_id', ':mid'))
181 1
            ->setParameter(':mid', $mid, \PDO::PARAM_INT);
182 1
        $result = $qb->execute();
183 1
        $block_id_arr = array();
184 1
        while ($myrow = $result->fetch(\PDO::FETCH_ASSOC)) {
185
            array_push($block_id_arr, $myrow['block_id']);
186
        }
187
188 1
        foreach ($block_id_arr as $i) {
189
            $qb->resetQueryParts(); // reset
190
            $qb ->select('COUNT(*)')
191
                ->fromPrefix('system_blockmodule', null)
192
                ->where($eb->ne('module_id', ':mid'))
193
                ->setParameter(':mid', $mid, \PDO::PARAM_INT)
194
                ->andWhere($eb->eq('block_id', ':bid'))
195
                ->setParameter(':bid', $i, \PDO::PARAM_INT);
196
            $result = $qb->execute();
197
            $count = $result->fetchColumn(0);
198
199
            if ($count > 0) {
200
                // this block has other entries, so delete the entry for this module
201
                $qb->resetQueryParts(); // reset
202
                $qb ->deletePrefix('system_blockmodule')
203
                    ->where($eb->eq('module_id', ':mid'))
204
                    ->setParameter(':mid', $mid, \PDO::PARAM_INT)
205
                    ->andWhere($eb->eq('block_id', ':bid'))
206
                    ->setParameter(':bid', $i, \PDO::PARAM_INT)
207
                    ->execute();
208
            } else {
209
                // this block does not have other entries, so disable the block and let it show
210
                // on top page only. otherwise, this block will not display anymore on block admin page!
211
                $qb->resetQueryParts(); // reset
212
                $qb ->updatePrefix('system_block')
213
                    ->set('visible', ':notvisible')
214
                    ->where($eb->eq('bid', ':bid'))
215
                    ->setParameter(':bid', $i, \PDO::PARAM_INT)
216
                    ->setParameter(':notvisible', 0, \PDO::PARAM_INT)
217
                    ->execute();
218
219
                $qb->resetQueryParts(); // reset
220
                $qb ->updatePrefix('system_blockmodule')
221
                    ->set('module_id', ':nomid')
222
                    ->where($eb->eq('module_id', ':mid'))
223
                    ->setParameter(':mid', $mid, \PDO::PARAM_INT)
224
                    ->setParameter(':nomid', -1, \PDO::PARAM_INT)
225
                    ->execute();
226
            }
227
        }
228
229 1
        if (!empty($this->cachedModulesByDirname[$dirname])) {
230
            unset($this->cachedModulesByDirname[$dirname]);
231
        }
232 1
        if (!empty($this->cachedModulesByMid[$mid])) {
233
            unset($this->cachedModulesByMid[$mid]);
234
        }
235 1
        $cache = \Xoops::getInstance()->cache();
236 1
        $cache->delete("system/module/id/{$mid}");
237 1
        $cache->delete("system/module/dirname/{$dirname}");
238 1
        $cache->delete("module/{$dirname}");
239 1
        return true;
240
    }
241
242
    /**
243
     * Load some modules
244
     *
245
     * @param CriteriaElement|null $criteria  criteria to match
246
     * @param boolean              $id_as_key Use the ID as key into the array
247
     *
248
     * @return array
249
     */
250 10
    public function getObjectsArray(CriteriaElement $criteria = null, $id_as_key = false)
251
    {
252 10
        $ret = array();
253 10
        $qb = $this->db2->createXoopsQueryBuilder();
254 10
        $qb->select('*')->fromPrefix('system_module', null);
255 10
        if (isset($criteria) && ($criteria instanceof CriteriaElement)) {
256 8
            $criteria->setSort('weight');
257 8
            $criteria->renderQb($qb);
258 8
            $qb->addOrderBy('mid', 'ASC');
259
        }
260
        // During install, we start with no tables and no installed modules. We need to
261
        // handle the resulting exceptions and return an empty array.
262
        try {
263 10
            if (!$result = $qb->execute()) {
264
                return $ret;
265
            }
266
        } catch (\Doctrine\DBAL\Driver\PDOException $e) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Driver\PDOException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
267
            return $ret;
268
        } catch (\Doctrine\DBAL\Exception\TableNotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Exception\TableNotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
269
            return $ret;
270
        } catch (\PDOException $e) {
271
            return $ret;
272
        }
273 10 View Code Duplication
        while ($myrow = $result->fetch(\PDO::FETCH_ASSOC)) {
274 6
            $module = new XoopsModule();
275 6
            $module->assignVars($myrow);
276 6
            if (!$id_as_key) {
277 3
                $ret[] = $module;
278
            } else {
279 3
                $ret[$myrow['mid']] = $module;
280
            }
281 6
            unset($module);
282
        }
283 10
        return $ret;
284
    }
285
286
    /**
287
     * returns an array of module names
288
     *
289
     * @param CriteriaElement|null $criteria       criteria
290
     * @param boolean              $dirname_as_key true  = array key is module directory
291
     *                                             false = array key is module id
292
     *
293
     * @return array
294
     */
295 1 View Code Duplication
    public function getNameList(CriteriaElement $criteria = null, $dirname_as_key = false)
296
    {
297 1
        $ret = array();
298 1
        $modules = $this->getObjectsArray($criteria, true);
299 1
        foreach (array_keys($modules) as $i) {
300 1
            if (!$dirname_as_key) {
301 1
                $ret[$i] = $modules[$i]->getVar('name');
302
            } else {
303
                $ret[$modules[$i]->getVar('dirname')] = $modules[$i]->getVar('name');
304
            }
305
        }
306 1
        return $ret;
307
    }
308
}
309