Symfony\Component\PropertyAccess\PropertyAccessor::readPropertiesUntil PHP Method

readPropertiesUntil() private method

Reads the path from an object up to a given path index.
private readPropertiesUntil ( array $zval, Symfony\Component\PropertyAccess\PropertyPathInterface $propertyPath, integer $lastIndex, boolean $ignoreInvalidIndices = true ) : array
$zval array The array containing the object or array to read from
$propertyPath Symfony\Component\PropertyAccess\PropertyPathInterface The property path to read
$lastIndex integer The index up to which should be read
$ignoreInvalidIndices boolean Whether to ignore invalid indices or throw an exception
return array The values read in the path
    private function readPropertiesUntil($zval, PropertyPathInterface $propertyPath, $lastIndex, $ignoreInvalidIndices = true)
    {
        if (!is_object($zval[self::VALUE]) && !is_array($zval[self::VALUE])) {
            throw new UnexpectedTypeException($zval[self::VALUE], $propertyPath, 0);
        }

        // Add the root object to the list
        $propertyValues = array($zval);

        for ($i = 0; $i < $lastIndex; ++$i) {
            $property = $propertyPath->getElement($i);
            $isIndex = $propertyPath->isIndex($i);

            if ($isIndex) {
                // Create missing nested arrays on demand
                if (($zval[self::VALUE] instanceof \ArrayAccess && !$zval[self::VALUE]->offsetExists($property)) ||
                    (is_array($zval[self::VALUE]) && !isset($zval[self::VALUE][$property]) && !array_key_exists($property, $zval[self::VALUE]))
                ) {
                    if (!$ignoreInvalidIndices) {
                        if (!is_array($zval[self::VALUE])) {
                            if (!$zval[self::VALUE] instanceof \Traversable) {
                                throw new NoSuchIndexException(sprintf(
                                    'Cannot read index "%s" while trying to traverse path "%s".',
                                    $property,
                                    (string) $propertyPath
                                ));
                            }

                            $zval[self::VALUE] = iterator_to_array($zval[self::VALUE]);
                        }

                        throw new NoSuchIndexException(sprintf(
                            'Cannot read index "%s" while trying to traverse path "%s". Available indices are "%s".',
                            $property,
                            (string) $propertyPath,
                            print_r(array_keys($zval[self::VALUE]), true)
                        ));
                    }

                    if ($i + 1 < $propertyPath->getLength()) {
                        if (isset($zval[self::REF])) {
                            $zval[self::VALUE][$property] = array();
                            $zval[self::REF] = $zval[self::VALUE];
                        } else {
                            $zval[self::VALUE] = array($property => array());
                        }
                    }
                }

                $zval = $this->readIndex($zval, $property);
            } else {
                $zval = $this->readProperty($zval, $property);
            }

            // the final value of the path must not be validated
            if ($i + 1 < $propertyPath->getLength() && !is_object($zval[self::VALUE]) && !is_array($zval[self::VALUE])) {
                throw new UnexpectedTypeException($zval[self::VALUE], $propertyPath, $i + 1);
            }

            if (isset($zval[self::REF]) && (0 === $i || isset($propertyValues[$i - 1][self::IS_REF_CHAINED]))) {
                // Set the IS_REF_CHAINED flag to true if:
                // current property is passed by reference and
                // it is the first element in the property path or
                // the IS_REF_CHAINED flag of its parent element is true
                // Basically, this flag is true only when the reference chain from the top element to current element is not broken
                $zval[self::IS_REF_CHAINED] = true;
            }

            $propertyValues[] = $zval;
        }

        return $propertyValues;
    }