diff --git a/src/JsonMapper.php b/src/JsonMapper.php index 25534d0a6..b372f9967 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -176,10 +176,13 @@ public function map($json, $object) // again for subsequent objects of the same type if (!isset($this->arInspectedClasses[$strClassName][$key])) { $this->arInspectedClasses[$strClassName][$key] - = $this->inspectProperty($rc, $key); + = $this->inspectBuildProperty($rc, $key); } - list($hasProperty, $accessor, $type, $isNullable) + /** + * @var array{isSimpleType: bool, hasVariadicArrayType: bool, isFlatType: bool, isArrayOfType: bool, isParenthesesEnd: bool} $typeAttribute + */ + list($hasProperty, $accessor, $type, $isNullable, $typeAttribute) = $this->arInspectedClasses[$strClassName][$key]; if (!$hasProperty) { @@ -195,8 +198,8 @@ public function map($json, $object) ); if (is_string($undefinedPropertyKey)) { - list($hasProperty, $accessor, $type, $isNullable) - = $this->inspectProperty($rc, $undefinedPropertyKey); + list($hasProperty, $accessor, $type, $isNullable, $typeAttribute) + = $this->inspectBuildProperty($rc, $undefinedPropertyKey); } } else { $this->log( @@ -231,7 +234,6 @@ public function map($json, $object) $this->setProperty($object, $accessor, null); continue; } - $type = $this->removeNullable($type); } else if ($jvalue === null) { throw new JsonMapper_Exception( 'JSON property "' . $key . '" in class "' @@ -239,9 +241,6 @@ public function map($json, $object) ); } - $type = $this->getFullNamespace($type, $strNs); - $type = $this->getMappedType($type, $jvalue); - if ($type === null || $type === 'mixed') { //no given type - simply set the json data $this->setProperty($object, $accessor, $jvalue); @@ -249,10 +248,10 @@ public function map($json, $object) } else if ($this->isObjectOfSameType($type, $jvalue)) { $this->setProperty($object, $accessor, $jvalue); continue; - } else if ($this->isSimpleType($type) - && !(is_array($jvalue) && $this->hasVariadicArrayType($accessor)) + } else if ($typeAttribute['isSimpleType'] + && !($typeAttribute['hasVariadicArrayType'] && is_array($jvalue)) ) { - if ($this->isFlatType($type) + if ($typeAttribute['isFlatType'] && !$this->isFlatType(gettype($jvalue)) ) { throw new JsonMapper_Exception( @@ -282,18 +281,18 @@ public function map($json, $object) $array = null; $subtype = null; - if ($this->isArrayOfType($type)) { + if ($typeAttribute['isArrayOfType']) { //array $array = array(); $subtype = substr($type, 0, -2); - } else if (substr($type, -1) == ']') { + } else if ($typeAttribute['isParenthesesEnd']) { list($proptype, $subtype) = explode('[', substr($type, 0, -1)); if ($proptype == 'array') { $array = array(); } else { $array = $this->createInstance($proptype, false, $jvalue); } - } else if (is_array($jvalue) && $this->hasVariadicArrayType($accessor)) { + } else if ($typeAttribute['hasVariadicArrayType'] && is_array($jvalue)) { $array = array(); $subtype = $type; } else { @@ -512,6 +511,29 @@ public function mapArray($json, $array, $class = null, $parent_key = '') return $array; } + protected function inspectBuildProperty(ReflectionClass $rc, $name) + { + list($hasProperty, $accessor, $type, $isNullable) = $this->inspectProperty($rc, $name); + $typeAttribute = [ + 'isArrayOfType' => false, + 'isParenthesesEnd' => false, + ]; + if ($isNullable || !$this->bStrictNullTypes) { + $type = $this->removeNullable($type); + } + $strNs = $rc->getNamespaceName(); + $type = $this->getFullNamespace($type, $strNs); + $typeAttribute['isSimpleType'] = $this->isSimpleType($type); + $typeAttribute['hasVariadicArrayType'] = $this->hasVariadicArrayType($accessor); + $typeAttribute['isFlatType'] = $this->isFlatType($type); + + if (is_string($type)) { + $typeAttribute['isArrayOfType'] = $this->isArrayOfType($type); + $typeAttribute['isParenthesesEnd'] = substr($type, -1) == ']'; + } + + return array($hasProperty, $accessor, $type, $isNullable, $typeAttribute); + } /** * Try to find out if a property exists in a given class. * Checks property first, falls back to setter method.