Skip to content

Commit 75c54d9

Browse files
committed
Allow iterating only arrays and objects
1 parent e00322a commit 75c54d9

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

phpstan-baseline.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
parameters:
22
ignoreErrors:
3+
-
4+
message: "#^Argument of an invalid type array\\|object supplied for foreach, only iterables are supported\\.$#"
5+
count: 2
6+
path: src/JsonMapper.php
7+
38
-
49
message: "#^Method MagicSunday\\\\JsonMapper\\:\\:makeInstance\\(\\) has parameter \\$constructorArguments with no value type specified in iterable type array\\.$#"
510
count: 1

src/JsonMapper.php

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public function map($json, ?string $className = null, ?string $collectionClassNa
166166
$collectionClassName = $this->getMappedClassName($collectionClassName, $json);
167167
}
168168

169-
// Assert that classes exists
169+
// Assert that the given classes exist
170170
$this->assertClassesExists($className, $collectionClassName);
171171

172172
// Handle collections
@@ -195,7 +195,13 @@ public function map($json, ?string $className = null, ?string $collectionClassNa
195195
$properties = $this->getProperties($className);
196196
$entity = $this->makeInstance($className);
197197

198+
// Return entity if JSON is not an array or object (is_iterable won't work here)
199+
if (!is_array($json) && !is_object($json)) {
200+
return $entity;
201+
}
202+
198203
// Process all children
204+
199205
/** @var string $propertyName */
200206
foreach ($json as $propertyName => $propertyValue) {
201207
// Replaces the property name with another one
@@ -413,7 +419,7 @@ private function hasClassAnnotation(string $className, string $annotationName):
413419
*
414420
* @return mixed|null
415421
*/
416-
private function getDefaultValue(string $className, string $propertyName)
422+
private function getDefaultValue(string $className, string $propertyName): mixed
417423
{
418424
$reflectionProperty = $this->getReflectionProperty($className, $propertyName);
419425

@@ -431,7 +437,7 @@ private function getDefaultValue(string $className, string $propertyName)
431437
*
432438
* @return bool
433439
*/
434-
private function isNumericIndexArray($json): bool
440+
private function isNumericIndexArray(mixed $json): bool
435441
{
436442
foreach ($json as $propertyName => $propertyValue) {
437443
if (is_int($propertyName)) {
@@ -449,8 +455,13 @@ private function isNumericIndexArray($json): bool
449455
*
450456
* @return bool
451457
*/
452-
private function isIterableWithArraysOrObjects($json): bool
458+
private function isIterableWithArraysOrObjects(mixed $json): bool
453459
{
460+
// Return false if JSON is not an array or object (is_iterable won't work here)
461+
if (!is_array($json) && !is_object($json)) {
462+
return false;
463+
}
464+
454465
foreach ($json as $propertyValue) {
455466
if (is_array($propertyValue)) {
456467
continue;
@@ -467,7 +478,7 @@ private function isIterableWithArraysOrObjects($json): bool
467478
}
468479

469480
/**
470-
* Assert that the given classes exists.
481+
* Assert that the given classes exist.
471482
*
472483
* @param class-string $className The class name of the initial element
473484
* @param class-string|null $collectionClassName The class name of a collection used to
@@ -499,7 +510,7 @@ private function assertClassesExists(string $className, ?string $collectionClass
499510
* @param string $name
500511
* @param mixed $value
501512
*/
502-
private function setProperty(object $entity, string $name, $value): void
513+
private function setProperty(object $entity, string $name, mixed $value): void
503514
{
504515
// Handle variadic setters
505516
if (is_array($value)) {
@@ -559,7 +570,7 @@ private function getType(string $className, string $propertyName): Type
559570
*
560571
* @throws DomainException
561572
*/
562-
private function getValue($json, Type $type)
573+
private function getValue(mixed $json, Type $type): mixed
563574
{
564575
if ((is_array($json) || is_object($json)) && $type->isCollection()) {
565576
$collectionType = $this->getCollectionValueType($type);
@@ -641,7 +652,7 @@ private function getClassNameFromType(Type $type): string
641652
*
642653
* @throws DomainException
643654
*/
644-
private function getMappedClassName(string $className, $json): string
655+
private function getMappedClassName(string $className, mixed $json): string
645656
{
646657
if (array_key_exists($className, $this->classMap)) {
647658
$classNameOrClosure = $this->classMap[$className];
@@ -669,7 +680,7 @@ private function getMappedClassName(string $className, $json): string
669680
*
670681
* @throws DomainException
671682
*/
672-
private function getClassName($json, Type $type): string
683+
private function getClassName(mixed $json, Type $type): string
673684
{
674685
return $this->getMappedClassName(
675686
$this->getClassNameFromType($type),
@@ -678,7 +689,7 @@ private function getClassName($json, Type $type): string
678689
}
679690

680691
/**
681-
* Cast node to collection.
692+
* Cast node to a collection.
682693
*
683694
* @param mixed $json
684695
* @param Type $type
@@ -687,7 +698,7 @@ private function getClassName($json, Type $type): string
687698
*
688699
* @throws DomainException
689700
*/
690-
private function asCollection($json, Type $type): ?array
701+
private function asCollection(mixed $json, Type $type): ?array
691702
{
692703
if ($json === null) {
693704
return null;
@@ -712,7 +723,7 @@ private function asCollection($json, Type $type): ?array
712723
*
713724
* @throws DomainException
714725
*/
715-
private function asObject($json, Type $type)
726+
private function asObject(mixed $json, Type $type): mixed
716727
{
717728
/** @var class-string<TEntity> $className */
718729
$className = $this->getClassName($json, $type);
@@ -748,7 +759,7 @@ private function isCustomType(string $typeClassName): bool
748759
*
749760
* @return mixed
750761
*/
751-
private function callCustomClosure($json, string $typeClassName)
762+
private function callCustomClosure(mixed $json, string $typeClassName): mixed
752763
{
753764
$callback = $this->types[$typeClassName];
754765

0 commit comments

Comments
 (0)