protected function getListParentInformation(
        Model $model,
        $relation,
        $key,
        ModelInformationInterface $info,
        $recurse = false
    ) {
        // Don't attempt to load relation methods if the parent relation is not configured
        if (    empty($info->list->parents)
            ||  ! count(
                    array_filter(
                        $info->list->parents,
                        function ($parent) use ($relation) { return $parent->relation == $relation; }
                    )
                )
        ) {
            return [];
        }

        /** @var Relation $relationInstance */
        $relationInstance = $model->{$relation}();

        // For MorphTo relations, we cannot know the related model from the relation
        // instance, it being polymorphic. We have to trust the record 'key' to contain the model.
        if ($relationInstance instanceof MorphTo) {

            $separator = $this->getListParentMorphKeySeparator();

            // If parent record indicator $key does not contain class/key separator symbol, ignore
            if (false === strpos($key, $separator)) {
                return [];
            }

            list($parentType, $parentKey) = explode($separator, $key, 2);

            $parentModelClass = $this->getRelationMappedMorphClass($parentType);

            if ( ! is_a($parentModelClass, Model::class, true)) {
                // @codeCoverageIgnoreStart
                throw new UnexpectedValueException(
                    "Parent record indicator {$key} does not refer to usable Eloquent model parent."
                );
                // @codeCoverageIgnoreEnd
            }

            $parentModel = new $parentModelClass;
            $key         = $parentKey;

        } else {
            $parentModel = $relationInstance->getRelated();
        }

        $parentModel = $this->getModelByKey($parentModel, $key);

        if ( ! $parentModel) {
            return [];
        }

        $parentInfo = $this->getModelInformationForModel($parentModel);

        $list = [];

        // Check for another link in the chain and recurse if there is
        if ($recurse && ! empty($parentInfo->list->parents)) {

            // When switching from one model to another, use the global subcontext,
            // otherwise, use the subcontext that contains the next step
            // Look up session data for list parent

            $parentListParent = $this->getListParentDataFromMemory(
                get_class($model) != get_class($parentModel) ? $this->globalSubContext() : $relation . ':' . $key,
                $this->getModelSessionKey($this->getModuleHelper()->modelSlug($parentModel))
            );

            if (is_array($parentListParent)) {
                $list = $this->getListParentInformation(
                    $parentModel,
                    array_get($parentListParent, 'relation'),
                    array_get($parentListParent, 'key'),
                    $parentInfo,
                    true
                );
            }
        }

        $module = $this->getModuleByModel($parentModel);

        if ( ! $module) {
            return [];
        }

        /** @var RouteHelperInterface $routeHelper */
        $routeHelper = app(RouteHelperInterface::class);

        $list[] = new ListParentData([
            'relation'          => $relation,
            'key'               => $key,
            'model'             => $parentModel,
            'information'       => $parentInfo,
            'module_key'        => $module->getKey(),
            'route_prefix'      => $routeHelper->getRouteNameForModelClass(get_class($parentModel), true),
            'permission_prefix' => $routeHelper->getPermissionPrefixForModelSlug(
                $this->getModuleHelper()->modelInformationKeyForModel($parentModel)
            ),
        ]);

        return $list;
    }
protected function getListParentInformation(
        Model $model,
        $relation,
        $key,
        ModelInformationInterface $info,
        $recurse = false
    ) {
        // Don't attempt to load relation methods if the parent relation is not configured
        if (    empty($info->list->parents)
            ||  ! count(
                    array_filter(
                        $info->list->parents,
                        function ($parent) use ($relation) { return $parent->relation == $relation; }
                    )
                )
        ) {
            return [];
        }

        /** @var Relation $relationInstance */
        $relationInstance = $model->{$relation}();

        // For MorphTo relations, we cannot know the related model from the relation
        // instance, it being polymorphic. We have to trust the record 'key' to contain the model.
        if ($relationInstance instanceof MorphTo) {

            $separator = $this->getListParentMorphKeySeparator();

            // If parent record indicator $key does not contain class/key separator symbol, ignore
            if (false === strpos($key, $separator)) {
                return [];
            }

            list($parentType, $parentKey) = explode($separator, $key, 2);

            $parentModelClass = $this->getRelationMappedMorphClass($parentType);

            if ( ! is_a($parentModelClass, Model::class, true)) {
                // @codeCoverageIgnoreStart
                throw new UnexpectedValueException(
                    "Parent record indicator {$key} does not refer to usable Eloquent model parent."
                );
                // @codeCoverageIgnoreEnd
            }

            $parentModel = new $parentModelClass;
            $key         = $parentKey;

        } else {
            $parentModel = $relationInstance->getRelated();
        }

        $parentModel = $this->getModelByKey($parentModel, $key);

        if ( ! $parentModel) {
            return [];
        }

        $parentInfo = $this->getModelInformationForModel($parentModel);

        $list = [];

        // Check for another link in the chain and recurse if there is
        if ($recurse && ! empty($parentInfo->list->parents)) {

            // When switching from one model to another, use the global subcontext,
            // otherwise, use the subcontext that contains the next step
            // Look up session data for list parent

            $parentListParent = $this->getListParentDataFromMemory(
                get_class($model) != get_class($parentModel) ? $this->globalSubContext() : $relation . ':' . $key,
                $this->getModelSessionKey($this->getModuleHelper()->modelSlug($parentModel))
            );

            if (is_array($parentListParent)) {
                $list = $this->getListParentInformation(
                    $parentModel,
                    array_get($parentListParent, 'relation'),
                    array_get($parentListParent, 'key'),
                    $parentInfo,
                    true
                );
            }
        }

        $module = $this->getModuleByModel($parentModel);

        if ( ! $module) {
            return [];
        }

        /** @var RouteHelperInterface $routeHelper */
        $routeHelper = app(RouteHelperInterface::class);

        $list[] = new ListParentData([
            'relation'          => $relation,
            'key'               => $key,
            'model'             => $parentModel,
            'information'       => $parentInfo,
            'module_key'        => $module->getKey(),
            'route_prefix'      => $routeHelper->getRouteNameForModelClass(get_class($parentModel), true),
            'permission_prefix' => $routeHelper->getPermissionPrefixForModelSlug(
                $this->getModuleHelper()->modelInformationKeyForModel($parentModel)
            ),
        ]);

        return $list;
    }
protected function getListParentInformation ( Model $ model , $ relation , $ key , ModelInformationInterface $ info , $ recurse = false ) { // Don't attempt to load relation methods if the parent relation is not configured if ( empty ( $ info -> list -> parents ) || ! count ( array_filter ( $ info -> list -> parents , function ( $ parent ) use ( $ relation ) { return $ parent -> relation == $ relation ; } ) ) ) { return [ ] ; } /** @var Relation $relationInstance */ $ relationInstance = $ model -> { $ relation } ( ) ; // For MorphTo relations, we cannot know the related model from the relation // instance, it being polymorphic. We have to trust the record 'key' to contain the model. if ( $ relationInstance instanceof MorphTo ) { $ separator = $ this -> getListParentMorphKeySeparator ( ) ; // If parent record indicator $key does not contain class/key separator symbol, ignore if ( false === strpos ( $ key , $ separator ) ) { return [ ] ; } list ( $ parentType , $ parentKey ) = explode ( $ separator , $ key , 2 ) ; $ parentModelClass = $ this -> getRelationMappedMorphClass ( $ parentType ) ; if ( ! is_a ( $ parentModelClass , Model :: class , true ) ) { // @codeCoverageIgnoreStart throw new UnexpectedValueException ( "Parent record indicator {$key} does not refer to usable Eloquent model parent." ) ; // @codeCoverageIgnoreEnd } $ parentModel = new $ parentModelClass ; $ key = $ parentKey ; } else { $ parentModel = $ relationInstance -> getRelated ( ) ; } $ parentModel = $ this -> getModelByKey ( $ parentModel , $ key ) ; if ( ! $ parentModel ) { return [ ] ; } $ parentInfo = $ this -> getModelInformationForModel ( $ parentModel ) ; $ list = [ ] ; // Check for another link in the chain and recurse if there is if ( $ recurse && ! empty ( $ parentInfo -> list -> parents ) ) { // When switching from one model to another, use the global subcontext, // otherwise, use the subcontext that contains the next step // Look up session data for list parent $ parentListParent = $ this -> getListParentDataFromMemory ( get_class ( $ model ) != get_class ( $ parentModel ) ? $ this -> globalSubContext ( ) : $ relation . ':' . $ key , $ this -> getModelSessionKey ( $ this -> getModuleHelper ( ) -> modelSlug ( $ parentModel ) ) ) ; if ( is_array ( $ parentListParent ) ) { $ list = $ this -> getListParentInformation ( $ parentModel , array_get ( $ parentListParent , 'relation' ) , array_get ( $ parentListParent , 'key' ) , $ parentInfo , true ) ; } } $ module = $ this -> getModuleByModel ( $ parentModel ) ; if ( ! $ module ) { return [ ] ; } /** @var RouteHelperInterface $routeHelper */ $ routeHelper = app ( RouteHelperInterface :: class ) ; $ list [ ] = new ListParentData ( [ 'relation' => $ relation , 'key' => $ key , 'model' => $ parentModel , 'information' => $ parentInfo , 'module_key' => $ module -> getKey ( ) , 'route_prefix' => $ routeHelper -> getRouteNameForModelClass ( get_class ( $ parentModel ) , true ) , 'permission_prefix' => $ routeHelper -> getPermissionPrefixForModelSlug ( $ this -> getModuleHelper ( ) -> modelInformationKeyForModel ( $ parentModel ) ) , ] ) ; return $ list ; }
Returns information about a list parent, or all list parents in the chain.

Exceptions will be thrown if there are logical problems with the chain.

@param Model                                      $model
@param string                                     $relation
@param mixed                                      $key
@param ModelInformationInterface|ModelInformation $info
@param bool                                       $recurse   if true, looks up entire chain
@return ListParentData[]
Returns information about a list parent or all list parents in the chain .