src/ObjectMapper.php
public function mapDataToObject($data, $targetClass)
    {
        $targetClass = preg_replace('~(\\\\){2,}~', '\\', $targetClass);

        // Check if the target object class exists, if not throw an exception
        if (!class_exists($targetClass)) {
            throw new ClassNotFoundException($targetClass);
        }

        // Create the target object
        $object = new $targetClass();

        // Reflecting the target object to extract properties etc.
        $class = new \ReflectionClass($targetClass);

        // Iterate over each class property to check if it's mapped
        foreach ($class->getProperties() as $property) {

            // Extract the Annotations
            $fields = $this->reader->getPropertyAnnotations($property);

            /** @var JsonField $field */
            foreach ($fields as $field) {
                if ($field instanceof JsonField == false) {
                    continue;
                }

                // Check if the property is public accessible or has a setter / adder
                $propertyName = $property->getName();
                $ucw = ucwords($propertyName);
                if (!$property->isPublic() && !($class->hasMethod('set' . $ucw) || $class->hasMethod('add' . $ucw))) {
                    throw new PropertyNotAccessibleException($propertyName);
                }

                if ($field->name == null) {
                    $field->name = $propertyName;
                }

                // Check if the current property is defined in the JSON
                if (!isset($data[$field->name])) continue;
                $val = null;

                $types = explode('|', $field->type);
                $typeKeys = array_keys($types);
                $lastTypeKey = end($typeKeys);

                if ($field->preTransformer !== null) {
                    /** @var TransformerInterface $preTransformer */
                    $preTransformer = $field->preTransformer;
                    $data[$field->name] = $preTransformer::transform($data[$field->name]);
                }

                if ($field->transformer !== null) {
                    /** @var TransformerInterface $transformer */
                    $transformer = $field->transformer;
                    $val = $transformer::transform($data[$field->name]);
                    $types = []; // Ignore type handler!
                }

                foreach ($types as $typeKey => $type) {
                    $isLastElement = ($typeKey == $lastTypeKey);

                    // Check the type of the field and set the val
                    if ($type == '') {
                        $val = $data[$field->name];
                    } elseif (in_array($type, $this->primitives)) {
                        $format = ($field instanceof DateTimeField && $field->format !== null
                            ? $field->format
                            : 'Y-m-d\TH:i:s');

                        $converted = null;
                        try {
                            $converted = $this->castType($data[$field->name], $type, $field->name, $format, true);
                        } catch (TypeMismatchException $ex) {
                            if ($isLastElement) {
                                throw  $ex;
                            }
                            continue;
                        }
                        $val = $converted;
                    } else {
                        // If none of the primitives match it is an custom object

                        // Check if it's an array of X
                        if (substr($type, -2) == '[]' && is_array($data[$field->name])) {
                            $t = substr($type, 0, -2);
                            $val = [];
                            foreach ($data[$field->name] as $entry) {
                                // Map the data recursive
                                $val[] = (object)$this->mapDataToObject($entry, $t);
                            }
                        } elseif (substr($type, -2) != '[]') {
                            // Map the data recursive
                            $val = (object)$this->mapDataToObject($data[$field->name], $type);
                        }
                    }

                    if ($field->postTransformer !== null) {
                        /** @var TransformerInterface $postTransformer */
                        $postTransformer = $field->postTransformer;
                        $val = $postTransformer::transform($val);
                    }

                    if ($val !== null) {
                        break;
                    }
                }

                // Assign the JSON data to the object property
                if ($val !== null) {
                    // If the property is public accessible, set the value directly
                    if ($property->isPublic()) {
                        $object->{$propertyName} = $val;
                    } else {
                        // If not, use the setter / adder
                        $ucw = ucwords($propertyName);
                        if ($class->hasMethod($method = 'set' . $ucw)) {
                            $object->$method($val);
                        } elseif ($class->hasMethod($method = 'add' . $ucw)) {
                            $object->$method($val);
                        }
                    }
                }
            }
        }
        return $object;
    }
public function mapDataToObject($data, $targetClass)
    {
        $targetClass = preg_replace('~(\\\\){2,}~', '\\', $targetClass);

        // Check if the target object class exists, if not throw an exception
        if (!class_exists($targetClass)) {
            throw new ClassNotFoundException($targetClass);
        }

        // Create the target object
        $object = new $targetClass();

        // Reflecting the target object to extract properties etc.
        $class = new \ReflectionClass($targetClass);

        // Iterate over each class property to check if it's mapped
        foreach ($class->getProperties() as $property) {

            // Extract the Annotations
            $fields = $this->reader->getPropertyAnnotations($property);

            /** @var JsonField $field */
            foreach ($fields as $field) {
                if ($field instanceof JsonField == false) {
                    continue;
                }

                // Check if the property is public accessible or has a setter / adder
                $propertyName = $property->getName();
                $ucw = ucwords($propertyName);
                if (!$property->isPublic() && !($class->hasMethod('set' . $ucw) || $class->hasMethod('add' . $ucw))) {
                    throw new PropertyNotAccessibleException($propertyName);
                }

                if ($field->name == null) {
                    $field->name = $propertyName;
                }

                // Check if the current property is defined in the JSON
                if (!isset($data[$field->name])) continue;
                $val = null;

                $types = explode('|', $field->type);
                $typeKeys = array_keys($types);
                $lastTypeKey = end($typeKeys);

                if ($field->preTransformer !== null) {
                    /** @var TransformerInterface $preTransformer */
                    $preTransformer = $field->preTransformer;
                    $data[$field->name] = $preTransformer::transform($data[$field->name]);
                }

                if ($field->transformer !== null) {
                    /** @var TransformerInterface $transformer */
                    $transformer = $field->transformer;
                    $val = $transformer::transform($data[$field->name]);
                    $types = []; // Ignore type handler!
                }

                foreach ($types as $typeKey => $type) {
                    $isLastElement = ($typeKey == $lastTypeKey);

                    // Check the type of the field and set the val
                    if ($type == '') {
                        $val = $data[$field->name];
                    } elseif (in_array($type, $this->primitives)) {
                        $format = ($field instanceof DateTimeField && $field->format !== null
                            ? $field->format
                            : 'Y-m-d\TH:i:s');

                        $converted = null;
                        try {
                            $converted = $this->castType($data[$field->name], $type, $field->name, $format, true);
                        } catch (TypeMismatchException $ex) {
                            if ($isLastElement) {
                                throw  $ex;
                            }
                            continue;
                        }
                        $val = $converted;
                    } else {
                        // If none of the primitives match it is an custom object

                        // Check if it's an array of X
                        if (substr($type, -2) == '[]' && is_array($data[$field->name])) {
                            $t = substr($type, 0, -2);
                            $val = [];
                            foreach ($data[$field->name] as $entry) {
                                // Map the data recursive
                                $val[] = (object)$this->mapDataToObject($entry, $t);
                            }
                        } elseif (substr($type, -2) != '[]') {
                            // Map the data recursive
                            $val = (object)$this->mapDataToObject($data[$field->name], $type);
                        }
                    }

                    if ($field->postTransformer !== null) {
                        /** @var TransformerInterface $postTransformer */
                        $postTransformer = $field->postTransformer;
                        $val = $postTransformer::transform($val);
                    }

                    if ($val !== null) {
                        break;
                    }
                }

                // Assign the JSON data to the object property
                if ($val !== null) {
                    // If the property is public accessible, set the value directly
                    if ($property->isPublic()) {
                        $object->{$propertyName} = $val;
                    } else {
                        // If not, use the setter / adder
                        $ucw = ucwords($propertyName);
                        if ($class->hasMethod($method = 'set' . $ucw)) {
                            $object->$method($val);
                        } elseif ($class->hasMethod($method = 'add' . $ucw)) {
                            $object->$method($val);
                        }
                    }
                }
            }
        }
        return $object;
    }
Maps the  current entry to the property of the object

@param array $data The array of data
@param string $targetClass The current object class

@return mixed The mapped object

@throws ClassNotFoundException If the target class does not exist
@throws PropertyNotAccessibleException If the mapped property is not accessible
@throws TypeMismatchException If the given type in json does not match with the expected type
@throws \ReflectionException If the class does not exist.