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
|
|||||
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 The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
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 The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
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 The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
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 The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() 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
![]() |
|||||
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
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 ![]() |
|||||
257 | 1 | return Json::encode($data) . $name; |
|||
0 ignored issues
–
show
|
|||||
258 | } |
||||
259 | 1 | return $name; |
|||
0 ignored issues
–
show
|
|||||
260 | } |
||||
261 | |||||
262 | } |
||||
263 |
This check looks for function or method calls that always return null and whose return value is assigned to a variable.
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.