This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the PhpMob package. |
||
5 | * |
||
6 | * (c) Ishmael Doss <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | declare(strict_types=1); |
||
13 | |||
14 | namespace PhpMob\Settings\Manager; |
||
15 | |||
16 | use Doctrine\Common\Collections\ArrayCollection; |
||
17 | use Doctrine\Common\Collections\Collection; |
||
18 | use Doctrine\Common\Persistence\ManagerRegistry; |
||
19 | use Doctrine\Common\Persistence\ObjectManager; |
||
20 | use PhpMob\Settings\Model\Setting; |
||
21 | use PhpMob\Settings\Model\SettingInterface; |
||
22 | use PhpMob\Settings\Provider\SettingProviderInterface; |
||
23 | use PhpMob\Settings\Schema\SettingSchemaRegistryInterface; |
||
24 | use PhpMob\Settings\Type\TypeTransformerInterface; |
||
25 | |||
26 | /** |
||
27 | * @author Ishmael Doss <[email protected]> |
||
28 | */ |
||
29 | class SettingManager implements SettingManagerInterface |
||
30 | { |
||
31 | /** |
||
32 | * @var ObjectManager |
||
33 | */ |
||
34 | private $manager; |
||
35 | |||
36 | /** |
||
37 | * @var SettingSchemaRegistryInterface |
||
38 | */ |
||
39 | private $schemaRegistry; |
||
40 | |||
41 | /** |
||
42 | * @var SettingProviderInterface |
||
43 | */ |
||
44 | private $provider; |
||
45 | |||
46 | /** |
||
47 | * @var TypeTransformerInterface |
||
48 | */ |
||
49 | private $transformer; |
||
50 | |||
51 | /** |
||
52 | * @var SettingInterface[]|Collection |
||
53 | */ |
||
54 | private $globalSettings; |
||
55 | |||
56 | /** |
||
57 | * @var Collection |
||
58 | */ |
||
59 | private $userSettings; |
||
60 | |||
61 | public function __construct( |
||
62 | ManagerRegistry $managerRegistry, |
||
63 | SettingProviderInterface $provider, |
||
64 | SettingSchemaRegistryInterface $schemaRegistry, |
||
65 | TypeTransformerInterface $transformer |
||
66 | ) { |
||
67 | $this->manager = $managerRegistry->getManagerForClass(Setting::class); |
||
68 | $this->provider = $provider; |
||
69 | $this->schemaRegistry = $schemaRegistry; |
||
70 | $this->transformer = $transformer; |
||
71 | |||
72 | $this->globalSettings = new ArrayCollection(); |
||
73 | $this->userSettings = new ArrayCollection(); |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * @param string $owner |
||
78 | * |
||
79 | * @return mixed|null |
||
80 | */ |
||
81 | private function getUserSettings(string $owner) |
||
82 | { |
||
83 | if (!$this->userSettings->get($owner)) { |
||
84 | $this->userSettings->set($owner, $this->provider->findUserSettings($owner)); |
||
85 | } |
||
86 | |||
87 | return $this->userSettings->get($owner); |
||
88 | } |
||
89 | |||
90 | /** |
||
91 | * @param string|null $owner |
||
92 | */ |
||
93 | private function loadSettings(?string $owner) |
||
94 | { |
||
95 | $owner && $this->getUserSettings($owner); |
||
0 ignored issues
–
show
|
|||
96 | |||
97 | if (!$owner && $this->globalSettings->isEmpty()) { |
||
0 ignored issues
–
show
The expression
$owner of type string|null is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
98 | $this->globalSettings = $this->provider->findGlobalSettings(); |
||
99 | } |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * @param Collection $settings |
||
104 | * @param string $section |
||
105 | * @param string $key |
||
106 | * @param string|null $owner |
||
107 | * |
||
108 | * @return Collection |
||
109 | */ |
||
110 | private function filter(Collection $settings, string $section, string $key, ?string $owner) |
||
111 | { |
||
112 | return $settings->filter( |
||
113 | function (SettingInterface $setting) use ($section, $key, $owner) { |
||
114 | return $section === $setting->getSection() |
||
115 | && $key === $setting->getKey() |
||
116 | && $owner === $setting->getOwner(); |
||
117 | } |
||
118 | ); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * @param $section |
||
123 | * @param $key |
||
124 | * @param string|null $owner |
||
125 | * |
||
126 | * @return SettingInterface|null |
||
127 | */ |
||
128 | private function findSetting($section, $key, ?string $owner) |
||
129 | { |
||
130 | $this->loadSettings($owner); |
||
131 | |||
132 | return $owner |
||
133 | ? $this->filter($this->getUserSettings($owner), $section, $key, $owner)->first() |
||
134 | : $this->filter($this->globalSettings, $section, $key, null)->first(); |
||
0 ignored issues
–
show
It seems like
$this->globalSettings can also be of type array<integer,object<Php...odel\SettingInterface>> ; however, PhpMob\Settings\Manager\SettingManager::filter() does only seem to accept object<Doctrine\Common\Collections\Collection> , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
135 | } |
||
136 | |||
137 | /** |
||
138 | * @param $section |
||
139 | * @param string|null $owner |
||
140 | */ |
||
141 | private function assertSectionScope($section, ?string $owner) |
||
142 | { |
||
143 | try { |
||
144 | $section = $this->schemaRegistry->getSection($section); |
||
145 | } catch (\InvalidArgumentException $e) { |
||
146 | throw new \LogicException($e->getMessage()); |
||
147 | } |
||
148 | |||
149 | if ((!empty($owner) && !$section->isOwnerAware()) || (empty($owner) && $section->isOwnerAware())) { |
||
150 | throw new \LogicException('Wrong section accessing.'); |
||
151 | } |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * {@inheritdoc} |
||
156 | */ |
||
157 | public function setSetting(string $section, string $key, $value, ?string $owner = null, $autoFlush = false): void |
||
158 | { |
||
159 | $this->assertSectionScope($section, $owner); |
||
160 | |||
161 | $setting = $this->findSetting($section, $key, $owner) ?: new Setting(); |
||
162 | $setting->setOwner($owner); |
||
163 | $setting->setSection($section); |
||
164 | $setting->setKey($key); |
||
165 | $setting->setValue($this->transformer->transform($section, $key, $value)); |
||
166 | $setting->setUpdatedAt(new \DateTime()); |
||
167 | |||
168 | if ($autoFlush) { |
||
169 | $this->manager->persist($setting); |
||
170 | $this->manager->flush(); |
||
171 | } |
||
172 | } |
||
173 | |||
174 | /** |
||
175 | * {@inheritdoc} |
||
176 | */ |
||
177 | public function getSetting(string $section, string $key, ?string $owner = null) |
||
178 | { |
||
179 | $this->assertSectionScope($section, $owner); |
||
180 | |||
181 | if (!$setting = $this->findSetting($section, $key, $owner)) { |
||
182 | return null; |
||
183 | } |
||
184 | |||
185 | return $this->transformer->reverse($section, $key, $setting->getValue()); |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * {@inheritdoc} |
||
190 | */ |
||
191 | public function flush(): void |
||
192 | { |
||
193 | foreach ($this->globalSettings->toArray() as $setting) { |
||
194 | $this->manager->persist($setting); |
||
195 | } |
||
196 | |||
197 | /** @var Collection $userSettings */ |
||
198 | foreach ($this->userSettings->toArray() as $userSettings) { |
||
199 | foreach ($userSettings->toArray() as $setting) { |
||
200 | $this->manager->persist($setting); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | $this->manager->flush(); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * {@inheritdoc} |
||
209 | */ |
||
210 | public function get(string $path, ?string $owner = null) |
||
211 | { |
||
212 | @list($section, $key) = explode('.', $path); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
213 | |||
214 | if (empty($key)) { |
||
215 | return null; |
||
216 | } |
||
217 | |||
218 | return $this->getSetting($section, $key, $owner); |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * {@inheritdoc} |
||
223 | */ |
||
224 | public function set(string $path, $value, ?string $owner = null): void |
||
225 | { |
||
226 | @list($section, $key) = explode('.', $path); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||
227 | |||
228 | if (empty($key)) { |
||
229 | throw new \InvalidArgumentException("The $path should be something like: `section.key`."); |
||
230 | } |
||
231 | |||
232 | $this->setSetting($section, $key, $value, $owner, true); |
||
233 | } |
||
234 | } |
||
235 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: