Issues (9)

src/Settings.php (9 issues)

1
<?php
2
3
namespace solutosoft\settings;
4
5
use Yii;
6
use yii\base\Component;
7
use yii\db\Connection;
8
use yii\db\Query;
9
use yii\base\Event;
10
use yii\helpers\Json;
11
12
class Settings extends Component
13
{
14
    /**
15
     * @event SettingsEvent an event that is triggered before execute command.
16
     */
17
    const EVENT_BEFORE_EXECUTE = 'beforeExecute';
18
19
    /*
20
     * @var array The settings cache
21
     */
22
    private $_data = [];
23
24
    /**
25
     * @var string Name of the table where configurations will be stored
26
     */
27
    public $tableName = '{{%setting}}';
28
29
    /**
30
     * @var string Name of column where keys will be stored
31
     */
32
    public $keyColumnName = 'key';
33
34
    /**
35
     * @var string Name of column where values will be stored
36
     */
37
    public $valueColumnName = 'value';
38
39
    /**
40
     * @return Connection the DB connection instance
41
     */
42 2
    protected function getDb()
43
    {
44 2
        return Yii::$app->getDb();
45
    }
46
47
    /**
48
     * Whether the setting exists in the database
49
     * @param string $name the setting name
50
     * @return bool
51
     */
52 2
    protected function exists($name)
53
    {
54 2
        $event = $this->beforeExecute();
55 2
        $key = $this->buildCacheKey($name, $event->data);
0 ignored issues
show
Are you sure the assignment to $key is correct as $this->buildCacheKey($name, $event->data) targeting solutosoft\settings\Settings::buildCacheKey() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
56
57 2
        if (isset($this->_data[$key])) {
58 1
            return true;
59
        }
60
61 2
        $query = $this->createQuery($name);
62
63 2
        if ($event->data) {
64 1
            $query->andWhere($event->data);
65
        }
66
67 2
        return $query->exists();
68
    }
69
70
    /**
71
     * Returns setting value from database
72
     * @param string $name setting name
73
     * @return mixed $defaultValue
74
     */
75 2
    public function get($name, $defaultValue = null)
76
    {
77 2
        $event = $this->beforeExecute();
78 2
        $key = $this->buildCacheKey($name, $event->data);
0 ignored issues
show
Are you sure the assignment to $key is correct as $this->buildCacheKey($name, $event->data) targeting solutosoft\settings\Settings::buildCacheKey() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
79
80 2
        if (isset($this->_data[$key])) {
81 2
            return $this->_data[$key];
82
        }
83
84 1
        $query = $this->createQuery($name);
85
86 1
        if ($event->data) {
87
            $query->andWhere($event->data);
88
        }
89
90 1
        $row = $query->one($this->getDb());
91
92 1
        $value = ($row) ? $row[$this->valueColumnName] : null;
93
94 1
        if (is_string($value) && trim($value) == '') {
95
            $value = null;
96
        }
97
98 1
        if ($value === null) {
99 1
            $value = $defaultValue;
100
        }
101
102 1
        $this->_data[$name] = $value;
103 1
        return $value;
104
    }
105
106
    /**
107
     * Store setting value to database
108
     * @param string $name
109
     * @param mixed $value
110
     */
111 2
    public function set($name, $value)
112
    {
113 2
        $db = $this->getDb();
114 2
        $event = $this->beforeExecute();
115
116 2
        $key = $this->buildCacheKey($name, $event->data);
0 ignored issues
show
Are you sure the assignment to $key is correct as $this->buildCacheKey($name, $event->data) targeting solutosoft\settings\Settings::buildCacheKey() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
117 2
        $values = [$this->valueColumnName => is_bool($value) ? (int)$value : $value];
118 2
        $where = [$this->keyColumnName => $name];
119
120 2
        if ($event->data) {
121 1
            $values = array_merge($event->data, $values);
122 1
            $where = array_merge($event->data, $where);
123
        }
124
125 2
        if ($this->exists($name)) {
126 1
            $db->createCommand()
127 1
                ->update($this->tableName, $values, $where)
128 1
                ->execute();
129
        } else  {
130 2
            $values = array_merge($values, $where);
131
132 2
            $db->createCommand()
133 2
                ->insert($this->tableName, $values)
134 2
                ->execute();
135
        }
136
137 2
        $this->_data[$key] = $value;
138 2
    }
139
140
    /**
141
     * Retrieves all setting stored in database
142
     * @return array
143
     */
144 2
    public function all()
145
    {
146 2
        $result = [];
147 2
        $event = $this->beforeExecute();
148
149 2
        $query = $this->createQuery()
150 2
            ->addSelect($this->keyColumnName);
151
152 2
        if ($event->data) {
153 1
            $query->andWhere($event->data);
154
        }
155
156 2
        $rows = $query->all($this->getDb());
157
158 2
        foreach ($rows as $row) {
159 2
            $value = $row[$this->valueColumnName];
160 2
            $name = $row[$this->keyColumnName];
161 2
            $key = $this->buildCacheKey($name, $event->data);
0 ignored issues
show
Are you sure the assignment to $key is correct as $this->buildCacheKey($name, $event->data) targeting solutosoft\settings\Settings::buildCacheKey() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
162
163 2
            $result[$name] = $value;
164 2
            $this->_data[$key] = $value;
165
        }
166
167 2
        return $result;
168
    }
169
170
    /**
171
     * Store all settings in database
172
     * @param array $names
173
     */
174 1
    public function save($names)
175
    {
176 1
        foreach ($names as $key => $value) {
177 1
            $this->set($key, $value) ;
178
        }
179 1
    }
180
181
    /**
182
     * Remove specified setting
183
     * @param array|string $name
184
     */
185 1
    public function remove($name)
186
    {
187 1
        $event = $this->beforeExecute();
188 1
        $key = $this->buildCacheKey($name, $event->data);
0 ignored issues
show
Are you sure the assignment to $key is correct as $this->buildCacheKey($name, $event->data) targeting solutosoft\settings\Settings::buildCacheKey() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
It seems like $name can also be of type array; however, parameter $name of solutosoft\settings\Settings::buildCacheKey() does only seem to accept string, 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

188
        $key = $this->buildCacheKey(/** @scrutinizer ignore-type */ $name, $event->data);
Loading history...
189 1
        $where = [$this->keyColumnName => $name];
190
191 1
        if ($event->data) {
192
            $where = array_merge($event->data, $where);
193
        }
194
195 1
        $this->getDb()
196 1
            ->createCommand()
197 1
            ->delete($this->tableName, $where)
198 1
            ->execute();
199
200 1
        unset($this->_data[$key]);
201 1
    }
202
203
    /**
204
     * Removes all settings
205
     */
206 1
    public function removeAll()
207
    {
208 1
        $event = $this->beforeExecute();
209 1
        $where = $event->data ? $event->data : '';
210
211 1
        $this->getDb()
212 1
            ->createCommand()
213 1
            ->delete($this->tableName, $where)
214 1
            ->execute();
215
216 1
        $this->_data[] = [];
217 1
    }
218
219
    /**
220
     * Creates query to find settings value
221
     * @param string $name
222
     * @return \yii\db\Query
223
     */
224 2
    protected function createQuery($name = null)
225
    {
226 2
        $query = (new Query())
227 2
            ->select([$this->valueColumnName])
228 2
            ->from($this->tableName);
229
230 2
        if ($name) {
231 2
            $query->andWhere([$this->keyColumnName => $name]);
232
        }
233
234 2
        return $query;
235
    }
236
237
    /**
238
     * This method is called at the before execute db command
239
     * @return yii\base\Event
240
     */
241 2
    protected function beforeExecute()
242
    {
243 2
        $event = new Event();
244 2
        $this->trigger(self::EVENT_BEFORE_EXECUTE, $event);
245 2
        return $event;
246
    }
247
248
    /**
249
     * Builds the unique cache key
250
     * @param string $name
251
     * @param array $data
252
     * @return void
253
     */
254 2
    protected function buildCacheKey($name, $data)
255
    {
256 2
        if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
257 1
            return Json::encode($data) . $name;
0 ignored issues
show
Bug Best Practice introduced by
The expression return yii\helpers\Json::encode($data) . $name returns the type string which is incompatible with the documented return type void.
Loading history...
258
        }
259 1
        return $name;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $name returns the type string which is incompatible with the documented return type void.
Loading history...
260
    }
261
262
}
263