Completed
Pull Request — master (#462)
by Richard
15:21
created

XoopsConfigHandler   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 287
Duplicated Lines 37.63 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 74.36%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 37
c 2
b 0
f 0
lcom 1
cbo 9
dl 108
loc 287
rs 8.6
ccs 87
cts 117
cp 0.7436

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A createConfig() 0 5 1
A getConfig() 9 9 2
B insertConfig() 21 21 6
B deleteConfig() 21 21 7
A getConfigs() 15 15 3
A getConfigCount() 0 4 1
A getConfigsByModule() 0 12 3
B getConfigsByCat() 21 21 5
A createConfigOption() 0 5 1
A getConfigOption() 0 5 1
A getConfigOptions() 0 4 1
A getConfigOptionsCount() 0 4 1
A getConfigList() 21 21 4

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
 * @author          Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17
 * @version         $Id$
18
 */
19
20
namespace Xoops\Core\Kernel\Handlers;
21
22
use Xoops\Core\Kernel\Criteria;
23
use Xoops\Core\Kernel\CriteriaCompo;
24
use Xoops\Core\Kernel\CriteriaElement;
25
use Xoops\Core\Kernel\XoopsObjectHandler;
26
27
/**
28
 * XOOPS configuration handling class.
29
 * This class acts as an interface for handling general configurations of XOOPS
30
 * and its modules.
31
 *
32
 * @category  Xoops\Core\Kernel\Handlers\XoopsConfigHandler
33
 * @package   Xoops\Core\Kernel
34
 * @author    Kazumi Ono <[email protected]>
35
 * @copyright 2000-2015 XOOPS Project (http://xoops.org)
36
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
37
 * @link      http://xoops.org
38
 * @todo    Tests that need to be made:
39
 *          - error handling
40
 */
41
class XoopsConfigHandler extends XoopsObjectHandler
42
{
43
    /**
44
     * holds reference to config item handler(DAO) class
45
     *
46
     * @var       XoopsConfigItemHandler
47
     */
48
    private $itemHandler;
49
50
    /**
51
     * holds reference to config option handler(DAO) class
52
     *
53
     * @var       XoopsConfigOptionHandler
54
     */
55
    private $optionHandler;
56
57
    /**
58
     * holds an array of cached references to config value arrays,
59
     *  indexed on module id and category id
60
     *
61
     * @var     array
62
     */
63
    private $cachedConfigs = array();
64
65
    /**
66
     * Constructor
67
     */
68 17
    public function __construct()
69
    {
70 17
        $this->itemHandler = \Xoops::getInstance()->getHandlerConfigItem();
0 ignored issues
show
Documentation Bug introduced by
It seems like \Xoops::getInstance()->getHandlerConfigItem() can also be of type object<XoopsObjectHandler> or object<XoopsPersistableObjectHandler>. However, the property $itemHandler is declared as type object<Xoops\Core\Kernel...XoopsConfigItemHandler>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
71 17
        $this->optionHandler = \Xoops::getInstance()->getHandlerConfigOption();
0 ignored issues
show
Documentation Bug introduced by
It seems like \Xoops::getInstance()->getHandlerConfigOption() can also be of type object<XoopsObjectHandler> or object<XoopsPersistableObjectHandler>. However, the property $optionHandler is declared as type object<Xoops\Core\Kernel...opsConfigOptionHandler>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
72 17
    }
73
74
    /**
75
     * Create a config
76
     *
77
     * @return  XoopsConfigItem
78
     */
79 1
    public function createConfig()
80
    {
81 1
        $instance = $this->itemHandler->create();
82 1
        return $instance;
83
    }
84
85
    /**
86
     * Get a config
87
     *
88
     * @param int  $id          ID of the config
89
     * @param bool $withoptions load the config's options now?
90
     *
91
     * @return   XoopsConfigItem
92
     */
93 2 View Code Duplication
    public function getConfig($id, $withoptions = false)
94
    {
95
        /* @var $config XoopsConfigItem */
96 2
        $config = $this->itemHandler->get($id);
97 2
        if ($withoptions == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
98 1
            $config->setConfOptions($this->getConfigOptions(new Criteria('conf_id', $id)));
99 1
        }
100 2
        return $config;
101
    }
102
103
    /**
104
     * insert a new config in the database
105
     *
106
     * @param XoopsConfigItem $config configuration item
107
     *
108
     * @return bool
109
     */
110 2 View Code Duplication
    public function insertConfig(XoopsConfigItem $config)
111
    {
112 2
        if (!$this->itemHandler->insert($config)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->itemHandler->insert($config) 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...
113
            return false;
114
        }
115 2
        $options = $config->getConfOptions();
116 2
        $count = count($options);
117 2
        $conf_id = $config->getVar('conf_id');
118 2
        for ($i = 0; $i < $count; ++$i) {
119
            $options[$i]->setVar('conf_id', $conf_id);
120
            if (!$this->optionHandler->insert($options[$i])) {
121
                foreach ($options[$i]->getErrors() as $msg) {
122
                    $config->setErrors($msg);
123
                }
124
            }
125
        }
126 2
        if (!empty($this->cachedConfigs[$config->getVar('conf_modid')][$config->getVar('conf_catid')])) {
127
            unset($this->cachedConfigs[$config->getVar('conf_modid')][$config->getVar('conf_catid')]);
128
        }
129 2
        return true;
130
    }
131
132
    /**
133
     * Delete a config from the database
134
     *
135
     * @param XoopsConfigItem $config configuration item
136
     *
137
     * @return bool
138
     */
139 2 View Code Duplication
    public function deleteConfig(XoopsConfigItem $config)
140
    {
141 2
        if (!$this->itemHandler->delete($config)) {
142
            return false;
143
        }
144 2
        $options = $config->getConfOptions();
145 2
        $count = count($options);
146 2
        if ($count == 0) {
147 2
            $options = $this->getConfigOptions(new Criteria('conf_id', $config->getVar('conf_id')));
148 2
            $count = count($options);
149 2
        }
150 2
        if (is_array($options) && $count > 0) {
151
            for ($i = 0; $i < $count; ++$i) {
152
                $this->optionHandler->delete($options[$i]);
153
            }
154
        }
155 2
        if (!empty($this->cachedConfigs[$config->getVar('conf_modid')][$config->getVar('conf_catid')])) {
156
            unset($this->cachedConfigs[$config->getVar('conf_modid')][$config->getVar('conf_catid')]);
157
        }
158 2
        return true;
159
    }
160
161
    /**
162
     * get one or more Configs
163
     *
164
     * @param CriteriaElement|null $criteria  criteria to match
165
     * @param bool                 $id_as_key Use the configs' ID as keys?
166
     *
167
     * @return XoopsConfigItem[]
168
     */
169 3 View Code Duplication
    public function getConfigs(CriteriaElement $criteria = null, $id_as_key = false)
170
    {
171 3
        $criteria2 = new CriteriaCompo();
172 3
        if ($criteria) {
173 2
            $criteria2->add($criteria);
174 2
            if (!$criteria->getSort()) {
175 2
                $criteria2->setSort('conf_order');
176 2
                $criteria2->setOrder('ASC');
177 2
            }
178 2
        } else {
179 1
            $criteria2->setSort('conf_order');
180 1
            $criteria2->setOrder('ASC');
181
        }
182 3
        return $this->itemHandler->getObjects($criteria2, $id_as_key);
183
    }
184
185
    /**
186
     * Count some configs
187
     *
188
     * @param CriteriaElement|null $criteria criteria to match
189
     *
190
     * @return int
191
     */
192 1
    public function getConfigCount(CriteriaElement $criteria = null)
193
    {
194 1
        return $this->itemHandler->getCount($criteria);
195
    }
196
197
    /**
198
     * Get configs from a certain module
199
     *
200
     * @param int $module ID of a module
201
     *
202
     * @return array of configuration values
203
     */
204
    public function getConfigsByModule($module = 0)
205
    {
206
        $ret = array();
207
        $criteria = new Criteria('conf_modid', (int)($module));
208
        $configs = $this->getConfigs($criteria, true);
209
        if (is_array($configs)) {
210
            foreach (array_keys($configs) as $i) {
211
                $ret[$configs[$i]->getVar('conf_name')] = $configs[$i]->getConfValueForOutput();
212
            }
213
        }
214
        return $ret;
215
    }
216
217
    /**
218
     * Get configs from a certain category
219
     *
220
     * @param int $category ID of a category
221
     * @param int $module   ID of a module
222
     *
223
     * @return array of configuration values
224
     *
225
     * @deprecated Use getConfigsByModule instead
226
     */
227 1 View Code Duplication
    public function getConfigsByCat($category, $module = 0)
228
    {
229 1
        static $_cachedConfigs;
230 1
        if (!empty($_cachedConfigs[$module][$category])) {
231
            return $_cachedConfigs[$module][$category];
232
        } else {
233 1
            $ret = array();
234 1
            $criteria = new CriteriaCompo(new Criteria('conf_modid', (int)($module)));
235 1
            if (!empty($category)) {
236 1
                $criteria->add(new Criteria('conf_catid', (int)($category)));
237 1
            }
238 1
            $configs = $this->getConfigs($criteria, true);
239 1
            if (is_array($configs)) {
240 1
                foreach (array_keys($configs) as $i) {
241
                    $ret[$configs[$i]->getVar('conf_name')] = $configs[$i]->getConfValueForOutput();
242 1
                }
243 1
            }
244 1
            $_cachedConfigs[$module][$category] = $ret;
245 1
            return $_cachedConfigs[$module][$category];
246
        }
247
    }
248
249
    /**
250
     * Make a new XoopsConfigOption
251
     *
252
     * @return XoopsConfigOption
253
     */
254 1
    public function createConfigOption()
255
    {
256 1
        $inst = $this->optionHandler->create();
257 1
        return $inst;
258
    }
259
260
    /**
261
     * Get a XoopsConfigOption
262
     *
263
     * @param int $id ID of the config option
264
     *
265
     * @return XoopsConfigOption
266
     */
267 1
    public function getConfigOption($id)
268
    {
269 1
        $inst = $this->optionHandler->get($id);
270 1
        return $inst;
271
    }
272
273
    /**
274
     * Get one or more XoopsConfigOption objects
275
     *
276
     * @param CriteriaElement|null $criteria  criteria to match
277
     * @param bool                 $id_as_key Use IDs as keys in the array?
278
     *
279
     * @return XoopsConfigOption[]
280
     */
281 4
    public function getConfigOptions(CriteriaElement $criteria = null, $id_as_key = false)
282
    {
283 4
        return $this->optionHandler->getObjects($criteria, $id_as_key);
284
    }
285
286
    /**
287
     * Count options
288
     *
289
     * @param CriteriaElement|null $criteria criteria to match
290
     *
291
     * @return int Count of options matching $criteria
292
     */
293 1
    public function getConfigOptionsCount(CriteriaElement $criteria = null)
294
    {
295 1
        return $this->optionHandler->getCount($criteria);
296
    }
297
298
    /**
299
     * Get a list of configs
300
     *
301
     * @param int $conf_modid ID of the modules
302
     * @param int $conf_catid ID of the category
303
     *
304
     * @return    array   Associative array of name=>value pairs.
305
     */
306 1 View Code Duplication
    public function getConfigList($conf_modid, $conf_catid = 0)
307
    {
308 1
        if (!empty($this->cachedConfigs[$conf_modid][$conf_catid])) {
309
            return $this->cachedConfigs[$conf_modid][$conf_catid];
310
        } else {
311 1
            $criteria = new CriteriaCompo(new Criteria('conf_modid', $conf_modid));
312 1
            if (empty($conf_catid)) {
313 1
                $criteria->add(new Criteria('conf_catid', $conf_catid));
314 1
            }
315 1
            $criteria->setSort('conf_order');
316 1
            $criteria->setOrder('ASC');
317 1
            $configs = $this->itemHandler->getObjects($criteria);
318 1
            $confcount = count($configs);
319 1
            $ret = array();
320 1
            for ($i = 0; $i < $confcount; ++$i) {
321 1
                $ret[$configs[$i]->getVar('conf_name')] = $configs[$i]->getConfValueForOutput();
322 1
            }
323 1
            $this->cachedConfigs[$conf_modid][$conf_catid] = $ret;
324 1
            return $ret;
325
        }
326
    }
327
}
328