Get nested context array.

@param  string $class
@param  array  $attributes
@return array
546174
protected function getNestedContext($class, $attributes = null)
    {
        // Must be an array
        if (is_array($attributes) === false) return $attributes;

        // Create nested context
        $context = new $class($attributes);

        // Return context attributes
        return $this->filterNestedContext($context->getProperties());
    }
1032529
public function createFromArray($class, array $attributes)
    {
        $entity = new $class();
        foreach ($attributes as $name => $value) {
            if (property_exists($entity, $name)) {
                $methodName = $this->getSetterName($entity, $name);
                if ($methodName) {
                    $entity->{$methodName}($value);
                } else {
                    throw new InvalidPropertyException('Add/Setter method for property '.$name.' not found');
                }
            }
        }

        return $entity;
    }
200357
protected function getMappableFieldsForClass($class)
    {
        $singleton = singleton($class);
        $fields = (array)$singleton->fieldLabels(false);
        foreach ($fields as $field => $label) {
            if (!$singleton->hasField($field)) {
                unset($fields[$field]);
            }
        }
        return $fields;
    }
712559
public static function toObjectArray(array $items, $class, UserContext $context)
    {
        return array_combine($items, array_map(function ($item) use ($class, $context) {
            return new $class($item, $context);
        }, $items));
    }
80809
public static function getClassProperties($class)
    {
        if (is_string($class)) {
            if (isset(self::$classPropertyes[$class])) {
                return self::$classPropertyes[$class];
            }

            $class = new \ReflectionClass($class);
        }

        if (!$class instanceof \ReflectionClass) {
            throw new \InvalidArgumentException('The arguments must be a valid class name or reflection');
        }

        if (isset(self::$classPropertyes[$class->getName()])) {
            return self::$classPropertyes[$class->getName()];
        }

        $props = $class->getProperties();
        $props_arr = [];
        foreach ($props as $prop) {
            $f = $prop->getName();

            $props_arr[$f] = $prop;
        }
        if ($parentClass = $class->getParentClass()) {
            $parent_props_arr = static::getClassProperties($parentClass);//RECURSION
            if (count($parent_props_arr) > 0) {
                $props_arr = array_merge($parent_props_arr, $props_arr);
            }
        }

        self::$classPropertyes[$class->getName()] = $props_arr;

        return $props_arr;
    }
258712
public function getAttributes(array $attribute_names = [], array $types = [])
    {
        $attribute_map = [];

        if (empty($attribute_names)) {
            $attribute_map = $this->attribute_map->getItems();
        } else {
            foreach ($attribute_names as $attribute_name) {
                $attribute_map[$attribute_name] = $this->getAttribute($attribute_name);
            }
        }

        if (!empty($types)) {
            $attribute_map = array_filter(
                $attribute_map,
                function ($attribute) use ($types) {
                    return in_array(get_class($attribute), $types);
                }
            );
        }

        return new AttributeMap($attribute_map);
    }
892573
public function getImplements($class)
    {
        $interfaces = [];
        $classId = $this->getClassId($class);
        if (isset($classId)) {
            if (isset($this->implements[$classId])) {
                foreach ($this->implements[$classId] as $interfaceId) {
                    $interfaces[$this->interfaces[$interfaceId]] = 1;
                }
            }
            foreach ($this->getAncestors($class) as $parent) {
                foreach ($this->getImplements($parent) as $interface) {
                    $interfaces[$interface] = 1;
                }
            }
        }
        return array_keys($interfaces);
    }
247464
protected function findModel($modelClass, $attributes = [])
    {
        $query = $this->buildQuery($modelClass, $attributes);

        return $query->first();
    }
597109
protected function getBatchesForAttributes(array $attributes)
    {
        $batches = [];

        $lcAttributes = array_map('strtolower', $attributes);
        foreach ($this->batches as $index => $batch) {
            /** @var Batch $batch */
            if (in_array(strtolower($batch->getAttribute()), $lcAttributes)) {
                $batches[$index] = $batch;
            }
        }

        return $batches;
    }
176864
private function getArrayWithNestedObjects($useAttributesAppend = true)
    {
        $result = [];
        $multipleNestedEntities = $this->getMultipleNestedEntities();

        foreach ($this->attributes as $attributeName => $attributeValue) {
            if (! is_object($attributeValue)) {
                $result[$attributeName] = $attributeValue;
            }

            if (array_key_exists($attributeName, $this->getSingleNestedEntities())) {
                $result[$attributeName] = $attributeValue->attributes;
            }

            if (array_key_exists($attributeName, $multipleNestedEntities)) {
                if ($useAttributesAppend) {
                    $attributeNameToUse = $attributeName . '_attributes';
                } else {
                    $attributeNameToUse = $attributeName;
                }

                $result[$attributeNameToUse] = [];
                foreach ($attributeValue as $attributeEntity) {
                    $result[$attributeNameToUse][] = $attributeEntity->attributes;

                    if ($multipleNestedEntities[$attributeName]['type'] === self::NESTING_TYPE_NESTED_OBJECTS) {
                        $result[$attributeNameToUse] = (object) $result[$attributeNameToUse];
                    }
                }

                if (
                    $multipleNestedEntities[$attributeName]['type'] === self::NESTING_TYPE_NESTED_OBJECTS
                    && empty($result[$attributeNameToUse])
                ) {
                    $result[$attributeNameToUse] = new \StdClass();
                }
            }
        }

        return $result;
    }
1091463
public function parse(RefClass $class)
    {
        $result = [];

        $annotations = $this->parseComment($class->docComment);
        foreach ($annotations as $annotation) {
            $annotation->originClass = $class->name;
            $result[]                = $annotation;
        }

        foreach ($class->constants as $constant) {
            foreach ($this->parseComment($constant->docComment) as $annotation) {
                $annotation->originClass    = $class->name;
                $annotation->originConstant = $constant->name;
                $result[]                   = $annotation;
            }
        }

        foreach ($class->properties as $property) {
            foreach ($this->parseComment($property->docComment) as $annotation) {
                $annotation->originClass    = $class->name;
                $annotation->originProperty = $property->name;
                $result[]                   = $annotation;
            }
        }

        foreach ($class->methods as $method) {
            foreach ($this->parseComment($method->docComment) as $annotation) {
                $annotation->originClass  = $class->name;
                $annotation->originMethod = $method->name;
                $result[]                 = $annotation;
            }
        }

        return $result;
    }
1052593
protected function getAttributes($object, $format = null, array $context)
    {
        $class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
        $key = $class.'-'.$context['cache_key'];

        if (isset($this->attributesCache[$key])) {
            return $this->attributesCache[$key];
        }

        $allowedAttributes = $this->getAllowedAttributes($object, $context, true);

        if (false !== $allowedAttributes) {
            if ($context['cache_key']) {
                $this->attributesCache[$key] = $allowedAttributes;
            }

            return $allowedAttributes;
        }

        $attributes = $this->extractAttributes($object, $format, $context);

        if ($this->classDiscriminatorResolver && $mapping = $this->classDiscriminatorResolver->getMappingForMappedObject($object)) {
            array_unshift($attributes, $mapping->getTypeProperty());
        }

        if ($context['cache_key']) {
            $this->attributesCache[$key] = $attributes;
        }

        return $attributes;
    }
887280
public function addAttributeClass($classes)
    {
        if (is_string($classes)) {
            $classes = explode(',', $classes);
        }

        $classes = array_map('trim', $classes);
        $classes = array_filter($classes);

        if ( ! $this->offsetExists('class')) {
            $this->storage[ 'class' ] = [];
        }

        $this->storage[ 'class' ] = array_merge($this->storage[ 'class' ], $classes);
        $this->storage[ 'class' ] = array_unique($this->storage[ 'class' ]);

        if (in_array('disabled', $this->storage[ 'class' ])) {
            $this->removeAttributeClass('active');
        }

        return $this;
    }
884367
protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
    {
        if (
            isset($context['object_to_populate']) &&
            is_object($context['object_to_populate']) &&
            $class === get_class($context['object_to_populate'])
        ) {
            return $context['object_to_populate'];
        }

        $format = null;
        if (isset($context['format'])) {
            $format = $context['format'];
        }

        $constructor = $reflectionClass->getConstructor();
        if (!$constructor) {
            return new $class();
        }

        $constructorParameters = $constructor->getParameters();

        $params = array();
        foreach ($constructorParameters as $constructorParameter) {
            $paramName = $constructorParameter->name;
            $key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName;

            $allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes);
            $ignored = in_array($paramName, $this->ignoredAttributes);

            if (!$allowed || $ignored) {
                continue;
            }

            $missing = !isset($data[$key]) && !array_key_exists($key, $data);
            $variadic = method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic();

            if ($variadic && !$missing && !is_array($data[$paramName])) {
                $message = 'Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.';
                throw new RuntimeException(sprintf($message, $class, $constructorParameter->name));
            }

            if ($variadic && !$missing) {
                $params = array_merge($params, $data[$paramName]);

                continue;
            }

            if ($missing && !$variadic && !$constructorParameter->isDefaultValueAvailable()) {
                $message = 'Cannot create an instance of %s from serialized data because its constructor requires parameter "%s" to be present.';
                throw new RuntimeException(sprintf($message, $class, $constructorParameter->name));
            }

            if ($missing && $constructorParameter->isDefaultValueAvailable()) {
                $params[] = $constructorParameter->getDefaultValue();

                continue;
            }

            if (!$missing) {
                $params[] = $this->denormalizeProperty($data[$key], $class, $key, $format, $context);

                unset($data[$key]);
            }
        }

        return $reflectionClass->newInstanceArgs($params);
    }
1020445
protected function getModelColumns($class)
    {
        $attributes = [];

        $classNamespace = $this->getModelNamespace($class);

        if ($class) {
            if (class_exists($classNamespace)) {
                $model = new \ReflectionClass($classNamespace);

                if ($model->isSubclassOf('Illuminate\Database\Eloquent\Model')) {
                    $mdl = $this->app->make($classNamespace);
                    $table = $mdl->getTable();

                    if (is_array($table)) {
                        $table = array_first($table);
                    }

                    $table = $mdl->getConnection()->getTablePrefix().$table;
                    $schema = $mdl->getConnection()->getDoctrineSchemaManager($table);

                    $database = null;
                    if (strpos($table, '.')) {
                        list($database, $table) = explode('.', $table);
                    }

                    $columns = Arr::except($schema->listTableColumns($table, $database), $mdl->getHidden());

                    foreach ($columns as $column) {
                        if ($column->getType() instanceof \Doctrine\DBAL\Types\JsonArrayType) {
                            continue;
                        }

                        $castTo = $this->getCasting($column->getType());

                        $attributes[] = ['column' => $column->getName(), 'casts' => $castTo];
                    }

                    return $attributes;
                }
            } else {
                $this->error("Your model {$class} was not found in {$this->config->get('fractal.model_namespace')}\\ \r\nIf this is the first time you get this message, try to update /config/fractal.php to make changes to model_namespace accordingly.");
                exit();
            }
        }

        // use as a default attribute
        return [
            ['column' => 'id', 'casts' => null],
        ];
    }
1300925
private static function getMethods($methods, $class): array
    {
        $methods[] = \array_fill_keys(\get_class_methods($class), 0);
        $parent = \get_parent_class($class);
        if ($parent) {
            \array_merge($methods, self::getMethods($methods, $parent));
        }
        return $methods[0];
    }
112392
private function collectCacheMethods(ReflectionClass $class)
    {
        $methods = [];
        foreach ($class->getMethods() as $method) {
            $annotations = $this->collectMethodCacheAnnotations($method);
            if ($annotations->count()) {
                $methods[$method->getName()] = $annotations;
            }
        }

        return $methods;
    }