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 | namespace SilverStripe\Config\Collections; |
||
4 | |||
5 | use SilverStripe\Config\Middleware\DeltaMiddleware; |
||
6 | |||
7 | /** |
||
8 | * Applies config modifications as a set of deltas on top of the |
||
9 | * middleware, instead of as modifications to the underlying list. |
||
10 | */ |
||
11 | class DeltaConfigCollection extends MemoryConfigCollection |
||
12 | { |
||
13 | /** |
||
14 | * Remove delta |
||
15 | */ |
||
16 | const REMOVE = 'remove'; |
||
17 | |||
18 | /** |
||
19 | * Merge delta |
||
20 | */ |
||
21 | const MERGE = 'merge'; |
||
22 | |||
23 | /** |
||
24 | * Remove all config for this class |
||
25 | */ |
||
26 | const CLEAR = 'clear'; |
||
27 | |||
28 | /** |
||
29 | * Replace all config for this class |
||
30 | */ |
||
31 | const REPLACE = 'replace'; |
||
32 | |||
33 | /** |
||
34 | * Set delta |
||
35 | */ |
||
36 | const SET = 'set'; |
||
37 | |||
38 | /** |
||
39 | * @var DeltaMiddleware |
||
40 | */ |
||
41 | protected $deltaMiddleware = null; |
||
42 | |||
43 | /** |
||
44 | * List of deltas keyed by class |
||
45 | * |
||
46 | * @var array |
||
47 | */ |
||
48 | protected $deltas = []; |
||
49 | |||
50 | /** |
||
51 | * True if removeAll() is applied |
||
52 | * |
||
53 | * @var bool |
||
54 | */ |
||
55 | protected $deltaReset = false; |
||
56 | |||
57 | /** |
||
58 | * Construct a delta collection |
||
59 | * |
||
60 | * @param bool $trackMetadata Set to true to track metadata |
||
61 | * @param int $middlewareFlag Flag to use to disable delta middleware (optional) |
||
62 | */ |
||
63 | 4 | public function __construct($trackMetadata = false, $middlewareFlag = 0) |
|
64 | { |
||
65 | 4 | parent::__construct($trackMetadata); |
|
66 | 4 | $this->deltaMiddleware = new DeltaMiddleware($this, $middlewareFlag); |
|
67 | 4 | $this->postInit(); |
|
68 | 4 | } |
|
69 | |||
70 | /** |
||
71 | * Create a delta collection from a parent collection |
||
72 | * |
||
73 | * @param ConfigCollectionInterface $parent |
||
74 | * @param int $middlewareFlag Flag to use to disable delta middleware (optional) |
||
75 | * @return static |
||
76 | */ |
||
77 | 4 | public static function createFromCollection(ConfigCollectionInterface $parent, $middlewareFlag = 0) |
|
78 | { |
||
79 | // Copy properties to subclass |
||
80 | 4 | $collection = new static(); |
|
81 | 4 | foreach (get_object_vars($parent) as $key => $value) { |
|
82 | 4 | $collection->$key = $value; |
|
83 | 4 | } |
|
84 | |||
85 | // Set middleware flag |
||
86 | $collection |
||
87 | 4 | ->getDeltaMiddleware() |
|
88 | 4 | ->setDisableFlag($middlewareFlag); |
|
89 | |||
90 | // Ensure back-links are re-created between middleware and collection |
||
91 | 4 | $collection->postInit(); |
|
92 | 4 | return $collection; |
|
93 | } |
||
94 | |||
95 | /** |
||
96 | * Get middleware for handling deltas |
||
97 | * |
||
98 | * @return DeltaMiddleware |
||
99 | */ |
||
100 | 4 | public function getDeltaMiddleware() |
|
101 | { |
||
102 | 4 | return $this->deltaMiddleware; |
|
103 | } |
||
104 | |||
105 | 4 | public function getMiddlewares() |
|
106 | { |
||
107 | 4 | $middlewares = parent::getMiddlewares(); |
|
108 | 4 | array_unshift($middlewares, $this->getDeltaMiddleware()); |
|
109 | 4 | return $middlewares; |
|
110 | } |
||
111 | |||
112 | /** |
||
113 | * Get deltas for the given class |
||
114 | * |
||
115 | * @param string $class |
||
116 | * @return array |
||
117 | */ |
||
118 | 4 | public function getDeltas($class) |
|
119 | { |
||
120 | 4 | $classKey = strtolower($class); |
|
121 | 4 | return isset($this->deltas[$classKey]) |
|
122 | 4 | ? $this->deltas[$classKey] |
|
123 | 4 | : []; |
|
124 | } |
||
125 | |||
126 | /** |
||
127 | * Check if config should be completely reset before getting config |
||
128 | * |
||
129 | * @param string $class Class to check |
||
130 | * @return bool |
||
131 | */ |
||
132 | 4 | public function isDeltaReset($class = null) |
|
133 | { |
||
134 | // Global reset |
||
135 | 4 | if ($this->deltaReset) { |
|
136 | 1 | return true; |
|
137 | } |
||
138 | |||
139 | // Note: Deltas of the given type reset the prior config |
||
140 | 3 | $deltas = $this->getDeltas($class); |
|
141 | 3 | return isset($deltas[0]['type']) |
|
142 | 3 | && in_array( |
|
143 | 3 | $deltas[0]['type'], |
|
144 | 3 | [self::REPLACE, self::CLEAR] |
|
145 | 3 | ); |
|
146 | } |
||
147 | |||
148 | public function unserialize($serialized) |
||
149 | { |
||
150 | parent::unserialize($serialized); |
||
151 | $this->postInit(); |
||
152 | } |
||
153 | |||
154 | public function __clone() |
||
155 | { |
||
156 | $this->deltaMiddleware = clone $this->deltaMiddleware; |
||
157 | $this->postInit(); |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Restore back-links post-creation or unserialization |
||
162 | */ |
||
163 | 4 | protected function postInit() |
|
164 | { |
||
165 | // Ensure backlink to middleware |
||
166 | 4 | $this->getDeltaMiddleware()->setCollection($this); |
|
167 | 4 | } |
|
168 | |||
169 | 1 | public function set($class, $name, $data, $metadata = []) |
|
170 | { |
||
171 | // Check config to merge |
||
172 | 1 | $this->clearDeltas($class, $name); |
|
173 | 1 | View Code Duplication | if ($name) { |
0 ignored issues
–
show
|
|||
174 | 1 | $this->addDelta($class, [ |
|
175 | 1 | 'type' => self::SET, |
|
176 | 1 | 'config' => [$name => $data], |
|
177 | 1 | ]); |
|
178 | 1 | } else { |
|
179 | 1 | $this->addDelta($class, [ |
|
180 | 1 | 'type' => self::REPLACE, |
|
181 | 1 | 'config' => $data, |
|
182 | 1 | ]); |
|
183 | } |
||
184 | 1 | return $this; |
|
185 | } |
||
186 | |||
187 | 2 | public function remove($class, $name = null) |
|
188 | { |
||
189 | // Check config to merge |
||
190 | 2 | $this->clearDeltas($class, $name); |
|
191 | 2 | View Code Duplication | if ($name) { |
0 ignored issues
–
show
The expression
$name of type string|null is loosely compared to true ; 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
![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
192 | 2 | $this->addDelta($class, [ |
|
193 | 2 | 'type' => self::REMOVE, |
|
194 | 2 | 'config' => [$name => true], |
|
195 | 2 | ]); |
|
196 | 2 | } else { |
|
197 | 1 | $this->addDelta($class, [ |
|
198 | 1 | 'type' => self::CLEAR, |
|
199 | 1 | ]); |
|
200 | } |
||
201 | 2 | return $this; |
|
202 | } |
||
203 | |||
204 | 3 | public function merge($class, $name, $value) |
|
205 | { |
||
206 | // Check config to merge |
||
207 | 3 | if ($name) { |
|
208 | 3 | $config = [$name => $value]; |
|
209 | 3 | } else { |
|
210 | 1 | $config = $value; |
|
211 | } |
||
212 | 3 | $this->addDelta($class, [ |
|
213 | 3 | 'type' => self::MERGE, |
|
214 | 3 | 'config' => $config, |
|
215 | 3 | ]); |
|
216 | 3 | return $this; |
|
217 | } |
||
218 | |||
219 | 1 | public function removeAll() |
|
220 | { |
||
221 | 1 | $this->deltaReset = true; |
|
222 | 1 | $this->clearDeltas(); |
|
223 | 1 | } |
|
224 | |||
225 | /** |
||
226 | * Remove all deltas for the given class and/or key combination |
||
227 | * |
||
228 | * @param string $class Optional class to limit clear to |
||
229 | * @param string $key Optional field to limit clear to |
||
230 | */ |
||
231 | 3 | protected function clearDeltas($class = null, $key = null) |
|
232 | { |
||
233 | 3 | $this->callCache = []; |
|
234 | |||
235 | // Clear all classes |
||
236 | 3 | if (!$class) { |
|
0 ignored issues
–
show
The expression
$class 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
![]() |
|||
237 | 1 | $this->deltas = []; |
|
238 | 1 | return; |
|
239 | } |
||
240 | |||
241 | // Clear just one class |
||
242 | 3 | $classKey = strtolower($class); |
|
243 | 3 | if (!$key) { |
|
0 ignored issues
–
show
The expression
$key 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
![]() |
|||
244 | 2 | unset($this->deltas[$classKey]); |
|
245 | 2 | return; |
|
246 | } |
||
247 | |||
248 | // Filter deltas that would be ignored by this key.value replacement |
||
249 | 3 | if (!isset($this->deltas[$classKey])) { |
|
250 | return; |
||
251 | } |
||
252 | 3 | $this->deltas[$classKey] = array_filter( |
|
253 | 3 | $this->deltas[$classKey], |
|
254 | 3 | function ($delta) use ($key) { |
|
255 | // Clear if an array with exactly one element, with the key |
||
256 | // being the affected config property |
||
257 | 3 | return !isset($delta['config']) |
|
258 | 3 | || !is_array($delta['config']) |
|
259 | 3 | || (count($delta['config']) !== 1) |
|
260 | 3 | || !isset($delta['config'][$key]); |
|
261 | } |
||
262 | 3 | ); |
|
263 | 3 | } |
|
264 | |||
265 | /** |
||
266 | * Push new delta |
||
267 | * |
||
268 | * @param string $class |
||
269 | * @param array $delta |
||
270 | */ |
||
271 | 4 | protected function addDelta($class, $delta) |
|
272 | { |
||
273 | 4 | $classKey = strtolower($class); |
|
274 | 4 | if (!isset($this->deltas[$classKey])) { |
|
275 | 4 | $this->deltas[$classKey] = []; |
|
276 | 4 | } |
|
277 | 4 | $this->deltas[$classKey][] = $delta; |
|
278 | |||
279 | // Flush call cache |
||
280 | 4 | $this->callCache = []; |
|
281 | 4 | } |
|
282 | } |
||
283 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.