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 | declare(strict_types=1); |
||
4 | |||
5 | /* |
||
6 | * This file is part of the Sonata Project package. |
||
7 | * |
||
8 | * (c) Thomas Rabaix <[email protected]> |
||
9 | * |
||
10 | * For the full copyright and license information, please view the LICENSE |
||
11 | * file that was distributed with this source code. |
||
12 | */ |
||
13 | |||
14 | namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Model; |
||
15 | |||
16 | use Doctrine\Common\Collections\ArrayCollection; |
||
17 | use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory; |
||
18 | use Doctrine\Common\Persistence\ObjectManager; |
||
19 | use Doctrine\ODM\MongoDB\DocumentManager; |
||
20 | use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; |
||
21 | use PHPUnit\Framework\MockObject\Stub; |
||
22 | use PHPUnit\Framework\TestCase; |
||
23 | use Sonata\AdminBundle\Admin\FieldDescriptionInterface; |
||
24 | use Sonata\AdminBundle\Datagrid\Datagrid; |
||
25 | use Sonata\AdminBundle\Datagrid\DatagridInterface; |
||
26 | use Sonata\DoctrineMongoDBAdminBundle\Admin\FieldDescription; |
||
27 | use Sonata\DoctrineMongoDBAdminBundle\Model\ModelManager; |
||
28 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\AbstractDocument; |
||
29 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\AssociatedDocument; |
||
30 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\ContainerDocument; |
||
31 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\EmbeddedDocument; |
||
32 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\ProtectedDocument; |
||
33 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\SimpleDocument; |
||
34 | use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\SimpleDocumentWithPrivateSetter; |
||
35 | use Symfony\Bridge\Doctrine\ManagerRegistry; |
||
36 | use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException; |
||
37 | use Symfony\Component\PropertyAccess\PropertyAccess; |
||
38 | use Symfony\Component\PropertyAccess\PropertyAccessor; |
||
39 | |||
40 | final class ModelManagerTest extends TestCase |
||
41 | { |
||
42 | /** |
||
43 | * @var PropertyAccessor |
||
44 | */ |
||
45 | private $propertyAccessor; |
||
46 | |||
47 | /** |
||
48 | * @var Stub&ManagerRegistry |
||
49 | */ |
||
50 | private $registry; |
||
51 | |||
52 | protected function setUp(): void |
||
53 | { |
||
54 | parent::setUp(); |
||
55 | |||
56 | $this->registry = $this->createStub(ManagerRegistry::class); |
||
57 | $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * @dataProvider getWrongDocuments |
||
62 | * |
||
63 | * @param mixed $document |
||
64 | */ |
||
65 | public function testNormalizedIdentifierException($document): void |
||
66 | { |
||
67 | $manager = new ModelManager($this->registry, $this->propertyAccessor); |
||
68 | |||
69 | $this->expectException(\RuntimeException::class); |
||
70 | |||
71 | $manager->getNormalizedIdentifier($document); |
||
72 | } |
||
73 | |||
74 | public function getWrongDocuments(): iterable |
||
75 | { |
||
76 | yield [0]; |
||
77 | yield [1]; |
||
78 | yield [false]; |
||
79 | yield [true]; |
||
80 | yield [[]]; |
||
81 | yield ['']; |
||
82 | yield ['sonata-project']; |
||
83 | } |
||
84 | |||
85 | public function testGetNormalizedIdentifierNull(): void |
||
86 | { |
||
87 | $manager = new ModelManager($this->registry, $this->propertyAccessor); |
||
88 | |||
89 | $this->assertNull($manager->getNormalizedIdentifier(null)); |
||
0 ignored issues
–
show
|
|||
90 | } |
||
91 | |||
92 | public function testSortParameters(): void |
||
93 | { |
||
94 | $manager = new ModelManager($this->registry, $this->propertyAccessor); |
||
95 | |||
96 | $datagrid1 = $this->createStub(Datagrid::class); |
||
97 | $datagrid2 = $this->createStub(Datagrid::class); |
||
98 | |||
99 | $field1 = new FieldDescription(); |
||
100 | $field1->setName('field1'); |
||
101 | |||
102 | $field2 = new FieldDescription(); |
||
103 | $field2->setName('field2'); |
||
104 | |||
105 | $field3 = new FieldDescription(); |
||
106 | $field3->setName('field3'); |
||
107 | $field3->setOption('sortable', 'field3sortBy'); |
||
108 | |||
109 | $datagrid1 |
||
110 | ->method('getValues') |
||
111 | ->willReturn([ |
||
112 | '_sort_by' => $field1, |
||
113 | '_sort_order' => 'ASC', |
||
114 | ]); |
||
115 | |||
116 | $datagrid2 |
||
117 | ->method('getValues') |
||
118 | ->willReturn([ |
||
119 | '_sort_by' => $field3, |
||
120 | '_sort_order' => 'ASC', |
||
121 | ]); |
||
122 | |||
123 | $parameters = $manager->getSortParameters($field1, $datagrid1); |
||
124 | |||
125 | $this->assertSame('DESC', $parameters['filter']['_sort_order']); |
||
126 | $this->assertSame('field1', $parameters['filter']['_sort_by']); |
||
127 | |||
128 | $parameters = $manager->getSortParameters($field2, $datagrid1); |
||
129 | |||
130 | $this->assertSame('ASC', $parameters['filter']['_sort_order']); |
||
131 | $this->assertSame('field2', $parameters['filter']['_sort_by']); |
||
132 | |||
133 | $parameters = $manager->getSortParameters($field3, $datagrid1); |
||
134 | |||
135 | $this->assertSame('ASC', $parameters['filter']['_sort_order']); |
||
136 | $this->assertSame('field3sortBy', $parameters['filter']['_sort_by']); |
||
137 | |||
138 | $parameters = $manager->getSortParameters($field3, $datagrid2); |
||
139 | |||
140 | $this->assertSame('DESC', $parameters['filter']['_sort_order']); |
||
141 | $this->assertSame('field3sortBy', $parameters['filter']['_sort_by']); |
||
142 | } |
||
143 | |||
144 | public function testGetParentMetadataForProperty(): void |
||
145 | { |
||
146 | $containerDocumentClass = ContainerDocument::class; |
||
147 | $associatedDocumentClass = AssociatedDocument::class; |
||
148 | $embeddedDocumentClass = EmbeddedDocument::class; |
||
149 | |||
150 | $dm = $this->createStub(DocumentManager::class); |
||
151 | |||
152 | $modelManager = new ModelManager($this->registry, $this->propertyAccessor); |
||
153 | |||
154 | $this->registry |
||
155 | ->method('getManagerForClass') |
||
156 | ->willReturn($dm); |
||
157 | |||
158 | $metadataFactory = $this->createStub(ClassMetadataFactory::class); |
||
159 | |||
160 | $dm |
||
161 | ->method('getMetadataFactory') |
||
162 | ->willReturn($metadataFactory); |
||
163 | |||
164 | $containerDocumentMetadata = $this->getMetadataForContainerDocument(); |
||
165 | $associatedDocumentMetadata = $this->getMetadataForAssociatedDocument(); |
||
166 | $embeddedDocumentMetadata = $this->getMetadataForEmbeddedDocument(); |
||
167 | |||
168 | $metadataFactory->method('getMetadataFor') |
||
169 | ->willReturnMap( |
||
170 | [ |
||
171 | [$containerDocumentClass, $containerDocumentMetadata], |
||
172 | [$embeddedDocumentClass, $embeddedDocumentMetadata], |
||
173 | [$associatedDocumentClass, $associatedDocumentMetadata], |
||
174 | ] |
||
175 | ); |
||
176 | |||
177 | /** @var ClassMetadata $metadata */ |
||
178 | [$metadata, $lastPropertyName] = $modelManager |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
The variable
$lastPropertyName does not exist. Did you forget to declare it?
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.
Loading history...
|
|||
179 | ->getParentMetadataForProperty($containerDocumentClass, 'plainField'); |
||
180 | $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'integer'); |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
|
|||
181 | |||
182 | [$metadata, $lastPropertyName] = $modelManager |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
|
|||
183 | ->getParentMetadataForProperty($containerDocumentClass, 'associatedDocument.plainField'); |
||
184 | $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'string'); |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
|
|||
185 | |||
186 | [$metadata, $lastPropertyName] = $modelManager |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
|
|||
187 | ->getParentMetadataForProperty($containerDocumentClass, 'embeddedDocument.plainField'); |
||
188 | $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean'); |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
|
|||
189 | |||
190 | $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean'); |
||
0 ignored issues
–
show
The variable
$metadata does not exist. Did you mean $metadataFactory ?
This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name. The variable may have been renamed without also renaming all references.
Loading history...
|
|||
191 | } |
||
192 | |||
193 | public function testModelReverseTransformWithSetter(): void |
||
194 | { |
||
195 | $class = SimpleDocument::class; |
||
196 | |||
197 | $manager = $this->createModelManagerForClass($class); |
||
198 | $object = $manager->modelReverseTransform( |
||
199 | $class, |
||
200 | [ |
||
201 | 'schmeckles' => 42, |
||
202 | 'multi_word_property' => 'hello', |
||
203 | 'schwifty' => true, |
||
204 | ] |
||
205 | ); |
||
206 | $this->assertInstanceOf($class, $object); |
||
207 | $this->assertSame(42, $object->getSchmeckles()); |
||
208 | $this->assertSame('hello', $object->getMultiWordProperty()); |
||
209 | $this->assertTrue($object->schwifty); |
||
210 | } |
||
211 | |||
212 | public function testModelReverseTransformFailsWithPrivateSetter(): void |
||
213 | { |
||
214 | $class = SimpleDocumentWithPrivateSetter::class; |
||
215 | $manager = $this->createModelManagerForClass($class); |
||
216 | |||
217 | $this->expectException(NoSuchPropertyException::class); |
||
218 | |||
219 | $manager->modelReverseTransform($class, ['schmeckles' => 42]); |
||
220 | } |
||
221 | |||
222 | public function testModelReverseTransformFailsWithPrivateProperties(): void |
||
223 | { |
||
224 | $class = SimpleDocument::class; |
||
225 | $manager = $this->createModelManagerForClass($class); |
||
226 | |||
227 | $this->expectException(NoSuchPropertyException::class); |
||
228 | |||
229 | $manager->modelReverseTransform($class, ['plumbus' => 42]); |
||
230 | } |
||
231 | |||
232 | public function testModelReverseTransformFailsWithPrivateProperties2(): void |
||
233 | { |
||
234 | $class = SimpleDocument::class; |
||
235 | $manager = $this->createModelManagerForClass($class); |
||
236 | |||
237 | $this->expectException(NoSuchPropertyException::class); |
||
238 | |||
239 | $manager->modelReverseTransform($class, ['plumbus' => 42]); |
||
240 | } |
||
241 | |||
242 | public function testCollections(): void |
||
243 | { |
||
244 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
245 | |||
246 | $collection = $model->getModelCollectionInstance('whyDoWeEvenHaveThisParameter'); |
||
247 | $this->assertInstanceOf(ArrayCollection::class, $collection); |
||
248 | |||
249 | $item1 = new \stdClass(); |
||
250 | $item2 = new \stdClass(); |
||
251 | $model->collectionAddElement($collection, $item1); |
||
0 ignored issues
–
show
It seems like
$collection defined by $model->getModelCollecti...EvenHaveThisParameter') on line 246 can also be of type object<ArrayAccess> ; however, Sonata\DoctrineMongoDBAd...:collectionAddElement() does only seem to accept array , 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.
Loading history...
|
|||
252 | $model->collectionAddElement($collection, $item2); |
||
253 | |||
254 | $this->assertTrue($model->collectionHasElement($collection, $item1)); |
||
255 | |||
256 | $model->collectionRemoveElement($collection, $item1); |
||
257 | |||
258 | $this->assertFalse($model->collectionHasElement($collection, $item1)); |
||
259 | |||
260 | $model->collectionClear($collection); |
||
261 | |||
262 | $this->assertTrue($collection->isEmpty()); |
||
0 ignored issues
–
show
|
|||
263 | } |
||
264 | |||
265 | public function testModelTransform(): void |
||
266 | { |
||
267 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
268 | |||
269 | $instance = new \stdClass(); |
||
270 | $result = $model->modelTransform('thisIsNotUsed', $instance); |
||
271 | |||
272 | $this->assertSame($instance, $result); |
||
273 | } |
||
274 | |||
275 | public function testGetPaginationParameters(): void |
||
276 | { |
||
277 | $datagrid = $this->createMock(DatagridInterface::class); |
||
278 | $fieldDescription = $this->createMock(FieldDescriptionInterface::class); |
||
279 | |||
280 | $datagrid->expects($this->once()) |
||
281 | ->method('getValues') |
||
282 | ->willReturn(['_sort_by' => $fieldDescription]); |
||
283 | |||
284 | $fieldDescription->expects($this->once()) |
||
285 | ->method('getName') |
||
286 | ->willReturn($name = 'test'); |
||
287 | |||
288 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
289 | |||
290 | $result = $model->getPaginationParameters($datagrid, $page = 5); |
||
291 | |||
292 | $this->assertSame($page, $result['filter']['_page']); |
||
293 | $this->assertSame($name, $result['filter']['_sort_by']); |
||
294 | } |
||
295 | |||
296 | public function testGetModelInstanceException(): void |
||
297 | { |
||
298 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
299 | |||
300 | $this->expectException(\InvalidArgumentException::class); |
||
301 | |||
302 | $model->getModelInstance(AbstractDocument::class); |
||
303 | } |
||
304 | |||
305 | public function testGetModelInstanceForProtectedDocument(): void |
||
306 | { |
||
307 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
308 | |||
309 | $this->assertInstanceOf(ProtectedDocument::class, $model->getModelInstance(ProtectedDocument::class)); |
||
310 | } |
||
311 | |||
312 | public function testFindBadId(): void |
||
313 | { |
||
314 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
315 | |||
316 | $this->assertNull($model->find('notImportant', null)); |
||
317 | } |
||
318 | |||
319 | public function testGetUrlSafeIdentifierException(): void |
||
320 | { |
||
321 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
322 | |||
323 | $this->expectException(\RuntimeException::class); |
||
324 | |||
325 | $model->getNormalizedIdentifier(new \stdClass()); |
||
326 | } |
||
327 | |||
328 | public function testGetUrlSafeIdentifierNull(): void |
||
329 | { |
||
330 | $model = new ModelManager($this->registry, $this->propertyAccessor); |
||
331 | |||
332 | $this->assertNull($model->getNormalizedIdentifier(null)); |
||
0 ignored issues
–
show
null is of type null , but the function expects a object .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
333 | } |
||
334 | |||
335 | public function testGetNewFieldDescriptionInstanceCreatesAFieldDescription(): void |
||
336 | { |
||
337 | $dm = $this->createStub(DocumentManager::class); |
||
338 | |||
339 | $this->registry |
||
340 | ->method('getManagerForClass') |
||
341 | ->willReturn($dm); |
||
342 | |||
343 | $metadataFactory = $this->createStub(ClassMetadataFactory::class); |
||
344 | |||
345 | $dm |
||
346 | ->method('getMetadataFactory') |
||
347 | ->willReturn($metadataFactory); |
||
348 | |||
349 | $containerDocumentClass = ContainerDocument::class; |
||
350 | $containerDocumentMetadata = $this->getMetadataForContainerDocument(); |
||
351 | |||
352 | $metadataFactory->method('getMetadataFor') |
||
353 | ->willReturnMap( |
||
354 | [ |
||
355 | [$containerDocumentClass, $containerDocumentMetadata], |
||
356 | ] |
||
357 | ); |
||
358 | |||
359 | $modelManager = new ModelManager($this->registry, $this->propertyAccessor); |
||
360 | |||
361 | $fieldDescription = $modelManager->getNewFieldDescriptionInstance($containerDocumentClass, 'plainField'); |
||
362 | |||
363 | $this->assertSame('edit', $fieldDescription->getOption('route')['name']); |
||
364 | $this->assertSame(['fieldName' => 'plainField', |
||
365 | 'name' => 'plainField', |
||
366 | 'columnName' => 'plainField', |
||
367 | 'type' => 'integer', ], $fieldDescription->getFieldMapping()); |
||
368 | } |
||
369 | |||
370 | private function createModelManagerForClass(string $class): ModelManager |
||
371 | { |
||
372 | $metadataFactory = $this->createMock(ClassMetadataFactory::class); |
||
373 | $modelManager = $this->createMock(ObjectManager::class); |
||
374 | $registry = $this->createMock(ManagerRegistry::class); |
||
375 | |||
376 | $classMetadata = new ClassMetadata($class); |
||
377 | $classMetadata->reflClass = new \ReflectionClass($class); |
||
378 | |||
379 | $modelManager->expects($this->once()) |
||
380 | ->method('getMetadataFactory') |
||
381 | ->willReturn($metadataFactory); |
||
382 | $metadataFactory->expects($this->once()) |
||
383 | ->method('getMetadataFor') |
||
384 | ->with($class) |
||
385 | ->willReturn($classMetadata); |
||
386 | $registry->expects($this->once()) |
||
387 | ->method('getManagerForClass') |
||
388 | ->with($class) |
||
389 | ->willReturn($modelManager); |
||
390 | |||
391 | return new ModelManager($registry, $this->propertyAccessor); |
||
392 | } |
||
393 | |||
394 | private function getMetadataForEmbeddedDocument(): ClassMetadata |
||
395 | { |
||
396 | $metadata = new ClassMetadata(EmbeddedDocument::class); |
||
397 | |||
398 | $metadata->fieldMappings = [ |
||
399 | 'plainField' => [ |
||
400 | 'fieldName' => 'plainField', |
||
401 | 'columnName' => 'plainField', |
||
402 | 'type' => 'boolean', |
||
403 | ], |
||
404 | ]; |
||
405 | |||
406 | return $metadata; |
||
407 | } |
||
408 | |||
409 | private function getMetadataForAssociatedDocument(): ClassMetadata |
||
410 | { |
||
411 | $embeddedDocumentClass = EmbeddedDocument::class; |
||
412 | |||
413 | $metadata = new ClassMetadata(AssociatedDocument::class); |
||
414 | |||
415 | $metadata->fieldMappings = [ |
||
416 | 'plainField' => [ |
||
417 | 'fieldName' => 'plainField', |
||
418 | 'name' => 'plainField', |
||
419 | 'columnName' => 'plainField', |
||
420 | 'type' => 'string', |
||
421 | ], |
||
422 | ]; |
||
423 | |||
424 | $metadata->mapOneEmbedded([ |
||
425 | 'fieldName' => 'embeddedDocument', |
||
426 | 'name' => 'embeddedDocument', |
||
427 | 'targetDocument' => $embeddedDocumentClass, |
||
428 | ]); |
||
429 | |||
430 | return $metadata; |
||
431 | } |
||
432 | |||
433 | private function getMetadataForContainerDocument(): ClassMetadata |
||
434 | { |
||
435 | $containerDocumentClass = ContainerDocument::class; |
||
436 | $associatedDocumentClass = AssociatedDocument::class; |
||
437 | $embeddedDocumentClass = EmbeddedDocument::class; |
||
438 | |||
439 | $metadata = new ClassMetadata($containerDocumentClass); |
||
440 | |||
441 | $metadata->fieldMappings = [ |
||
442 | 'plainField' => [ |
||
443 | 'fieldName' => 'plainField', |
||
444 | 'name' => 'plainField', |
||
445 | 'columnName' => 'plainField', |
||
446 | 'type' => 'integer', |
||
447 | ], |
||
448 | ]; |
||
449 | |||
450 | $metadata->associationMappings['associatedDocument'] = [ |
||
451 | 'fieldName' => 'associatedDocument', |
||
452 | 'name' => 'associatedDocument', |
||
453 | 'targetDocument' => $associatedDocumentClass, |
||
454 | 'sourceDocument' => $containerDocumentClass, |
||
455 | ]; |
||
456 | |||
457 | $metadata->mapOneEmbedded([ |
||
458 | 'fieldName' => 'embeddedDocument', |
||
459 | 'name' => 'embeddedDocument', |
||
460 | 'targetDocument' => $embeddedDocumentClass, |
||
461 | ]); |
||
462 | |||
463 | return $metadata; |
||
464 | } |
||
465 | } |
||
466 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: