Completed
Push — master ( 7b04d5...593857 )
by Richard
26s
created

XoopsModuleHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
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
use Doctrine\DBAL\FetchMode;
26
use Doctrine\DBAL\ParameterType;
27
28
/**
29
 * XOOPS module handler class.
30
 *
31
 * This class is responsible for providing data access mechanisms to the data source
32
 * of XOOPS module class objects.
33
 *
34
 * @category  Xoops\Core\Kernel\XoopsModuleHandler
35
 * @package   Xoops\Core\Kernel
36
 * @author    Kazumi Ono <[email protected]>
37
 * @author    Taiwen Jiang <[email protected]>
38
 * @copyright 2000-2019 XOOPS Project (https://xoops.org)
39
 * @license   GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
40
 */
41
class XoopsModuleHandler extends XoopsPersistableObjectHandler
42
{
43
    /**
44
     * holds an array of cached module references, indexed by module id
45
     *
46
     * @var array
47
     * @access private
48
     */
49
    private $cachedModulesByMid = array();
50
51
    /**
52
     * holds an array of cached module references, indexed by module dirname
53
     *
54
     * @var array
55
     * @access private
56
     */
57
    private $cachedModulesByDirname = array();
58
59
    /**
60
     * Constructor
61
     *
62
     * @param Connection|null $db database
63
     */
64 9
    public function __construct(Connection $db = null)
65
    {
66 9
        parent::__construct($db, 'system_module', '\Xoops\Core\Kernel\Handlers\XoopsModule', 'mid', 'dirname');
67 9
    }
68
69
    /**
70
     * Load a module from the database
71
     *
72
     * @param int $id ID of the module
73
     *
74
     * @return XoopsModule|false on fail
75
     */
76 2
    public function getById($id = null)
77
    {
78 2
        $id = (int)($id);
79 2
        if ($id > 0) {
80 1
            if (!empty($this->cachedModulesByMid[$id])) {
81 1
                return $this->cachedModulesByMid[$id];
82
            } else {
83
                $module = parent::get($id);
84
                if (!is_object($module)) {
85
                    return false;
86
                }
87
                $this->cachedModulesByMid[$id] = $module;
88
                $this->cachedModulesByDirname[$module->getVar('dirname')] = $module;
89
                return $module;
90
            }
91
        }
92 2
        return false;
93
    }
94
95
    /**
96
     * Load a module by its dirname
97
     *
98
     * @param string $dirname module directory name
99
     *
100
     * @return XoopsModule|false FALSE on fail
101
     */
102 7
    public function getByDirname($dirname)
103
    {
104 7
        $dirname = basename(trim($dirname));
105
106 7
        if (!empty($this->cachedModulesByDirname[$dirname])) {
107 2
            return $this->cachedModulesByDirname[$dirname];
108
        } else {
109 6
            $criteria = new Criteria('dirname', $dirname);
110 6
            $modules = $this->getObjectsArray($criteria);
111 6
            if (count($modules) == 1 && is_object($modules[0])) {
112 2
                $module = $modules[0];
113
            } else {
114 4
                return false;
115
            }
116
            /* @var $module XoopsModule */
117 2
            $this->cachedModulesByDirname[$dirname] = $module;
118 2
            $this->cachedModulesByMid[$module->getVar('mid')] = $module;
119 2
            return $module;
120
        }
121
    }
122
123
    /**
124
     * Write a module to the database
125
     *
126
     * @param XoopsModule $module module to insert
127
     *
128
     * @return bool
129
     */
130 1
    public function insertModule(XoopsModule $module)
131
    {
132 1
        if (false === parent::insert($module)) {
133
            return false;
134
        }
135
136 1
        $dirname = $module->getVar('dirname');
137 1
        $mid = $module->getVar('mid');
138
139 1
        if (!empty($this->cachedModulesByDirname[$dirname])) {
140
            unset($this->cachedModulesByDirname[$dirname]);
141
        }
142 1
        if (!empty($this->cachedModulesByMid[$mid])) {
143
            unset($this->cachedModulesByMid[$mid]);
144
        }
145 1
        return true;
146
    }
147
148
    /**
149
     * Delete a module from the database
150
     *
151
     * @param XoopsModule $module module to delete
152
     *
153
     * @return bool
154
     */
155 1
    public function deleteModule(XoopsModule $module)
156
    {
157 1
        if (!parent::delete($module)) {
158
            return false;
159
        }
160
161 1
        $mid = $module->getVar('mid');
162 1
        $dirname = $module->getVar('dirname');
163
164
        // delete admin and read permissions assigned for this module
165 1
        $qb = $this->db2->createXoopsQueryBuilder();
166 1
        $eb = $qb->expr();
167 1
        $qb ->deletePrefix('system_permission')
168 1
            ->where(
169 1
                $eb->orX(
170 1
                    $eb->eq('gperm_name', $eb->literal('module_admin')),
171 1
                    $eb->eq('gperm_name', $eb->literal('module_read'))
172
                )
173
            )
174 1
            ->andWhere($eb->eq('gperm_itemid', ':itemid'))
175 1
            ->setParameter(':itemid', $mid, ParameterType::INTEGER)
176 1
            ->execute();
177
178 1
        $qb->resetQueryParts(); // reset
179 1
        $qb ->select('block_id')
180 1
            ->fromPrefix('system_blockmodule', null)
181 1
            ->where($eb->eq('module_id', ':mid'))
182 1
            ->setParameter(':mid', $mid, ParameterType::INTEGER);
183 1
        $result = $qb->execute();
184 1
        $block_id_arr = array();
185 1
        while ($myrow = $result->fetch(FetchMode::ASSOCIATIVE)) {
186
            array_push($block_id_arr, $myrow['block_id']);
187
        }
188
189 1
        foreach ($block_id_arr as $i) {
190
            $qb->resetQueryParts(); // reset
191
            $qb ->select('COUNT(*)')
192
                ->fromPrefix('system_blockmodule', null)
193
                ->where($eb->neq('module_id', ':mid'))
194
                ->setParameter(':mid', $mid, ParameterType::INTEGER)
195
                ->andWhere($eb->eq('block_id', ':bid'))
196
                ->setParameter(':bid', $i, ParameterType::INTEGER);
197
            $result = $qb->execute();
198
            $count = $result->fetchColumn(0);
199
200
            if ($count > 0) {
201
                // this block has other entries, so delete the entry for this module
202
                $qb->resetQueryParts(); // reset
203
                $qb ->deletePrefix('system_blockmodule')
204
                    ->where($eb->eq('module_id', ':mid'))
205
                    ->setParameter(':mid', $mid, ParameterType::INTEGER)
206
                    ->andWhere($eb->eq('block_id', ':bid'))
207
                    ->setParameter(':bid', $i, ParameterType::INTEGER)
208
                    ->execute();
209
            } else {
210
                // this block does not have other entries, so disable the block and let it show
211
                // on top page only. otherwise, this block will not display anymore on block admin page!
212
                $qb->resetQueryParts(); // reset
213
                $qb ->updatePrefix('system_block')
214
                    ->set('visible', ':notvisible')
215
                    ->where($eb->eq('bid', ':bid'))
216
                    ->setParameter(':bid', $i, ParameterType::INTEGER)
217
                    ->setParameter(':notvisible', 0, ParameterType::INTEGER)
218
                    ->execute();
219
220
                $qb->resetQueryParts(); // reset
221
                $qb ->updatePrefix('system_blockmodule')
222
                    ->set('module_id', ':nomid')
223
                    ->where($eb->eq('module_id', ':mid'))
224
                    ->setParameter(':mid', $mid, ParameterType::INTEGER)
225
                    ->setParameter(':nomid', -1, ParameterType::INTEGER)
226
                    ->execute();
227
            }
228
        }
229
230 1
        if (!empty($this->cachedModulesByDirname[$dirname])) {
231
            unset($this->cachedModulesByDirname[$dirname]);
232
        }
233 1
        if (!empty($this->cachedModulesByMid[$mid])) {
234
            unset($this->cachedModulesByMid[$mid]);
235
        }
236 1
        $cache = \Xoops::getInstance()->cache();
237 1
        $cache->delete("system/module/id/{$mid}");
238 1
        $cache->delete("system/module/dirname/{$dirname}");
239 1
        $cache->delete("module/{$dirname}");
240 1
        return true;
241
    }
242
243
    /**
244
     * Load some modules
245
     *
246
     * @param CriteriaElement|null $criteria  criteria to match
247
     * @param bool                 $id_as_key Use the ID as key into the array
248
     *
249
     * @return array
250
     */
251 10
    public function getObjectsArray(CriteriaElement $criteria = null, $id_as_key = false)
252
    {
253 10
        $ret = array();
254 10
        $qb = $this->db2->createXoopsQueryBuilder();
255 10
        $qb->select('*')->fromPrefix('system_module', null);
256 10
        if (isset($criteria) && ($criteria instanceof CriteriaElement)) {
257 8
            $criteria->setSort('weight');
258 8
            $criteria->renderQb($qb);
259 8
            $qb->addOrderBy('mid', 'ASC');
260
        }
261
        // During install, we start with no tables and no installed modules. We need to
262
        // handle the resulting exceptions and return an empty array.
263
        try {
264 10
            if (!$result = $qb->execute()) {
265 10
                return $ret;
266
            }
267
        } catch (\Throwable $e) {
268
            /** should get specific exceptions */
269
            \Xoops::getInstance()->events()->triggerEvent('core.exception', $e);
270
            return $ret;
271
        }
272 10
        while ($myrow = $result->fetch(FetchMode::ASSOCIATIVE)) {
273 6
            $module = new XoopsModule();
274 6
            $module->assignVars($myrow);
275 6
            if (!$id_as_key) {
276 3
                $ret[] = $module;
277
            } else {
278 3
                $ret[$myrow['mid']] = $module;
279
            }
280 6
            unset($module);
281
        }
282 10
        return $ret;
283
    }
284
285
    /**
286
     * returns an array of module names
287
     *
288
     * @param CriteriaElement|null $criteria       criteria
289
     * @param bool                 $dirname_as_key true  = array key is module directory
290
     *                                             false = array key is module id
291
     *
292
     * @return array
293
     */
294 1
    public function getNameList(CriteriaElement $criteria = null, $dirname_as_key = false)
295
    {
296 1
        $ret = array();
297 1
        $modules = $this->getObjectsArray($criteria, true);
298 1
        foreach (array_keys($modules) as $i) {
299 1
            if (!$dirname_as_key) {
300 1
                $ret[$i] = $modules[$i]->getVar('name');
301
            } else {
302 1
                $ret[$modules[$i]->getVar('dirname')] = $modules[$i]->getVar('name');
303
            }
304
        }
305 1
        return $ret;
306
    }
307
}
308