Check if all provied classes derive from ElementBase.
@param  array  $relation
@return array
199563
public static function validate_class_inheritance(array $relation): array
    {
        return array_filter($relation, function($className)
        {
            if (
                ClassInfo::exists($className)
                && (is_a(singleton($className), ElementBase::class))
            ) {
                return $className;
            }
            user_error('Your element needs to extend from ' . ElementBase::class, E_USER_WARNING);
        });
    }
800304
protected function hasOneOrManyDeepFromRelations(array $relations)
    {
        if (is_array($relations[0])) {
            $relations = $relations[0];
        }

        $related = null;
        $through = [];
        $foreignKeys = [];
        $localKeys = [];

        foreach ($relations as $i => $relation) {
            $method = $this->hasOneOrManyDeepRelationMethod($relation);

            [$through, $foreignKeys, $localKeys] = $this->$method($relation, $through, $foreignKeys, $localKeys);

            if ($i === count($relations) - 1) {
                $related = get_class($relation->getRelated());
            } else {
                $through[] = get_class($relation->getRelated());
            }
        }

        return [$related, $through, $foreignKeys, $localKeys];
    }
86577
public function with($relation)
    {
        $this->reset();

        if (func_num_args() > 1) {
            return $this->with(func_get_args());
        }

        if (is_array($relation)) {
            $this->related = array_merge($this->related, $relation);
        } else {
            $this->related[] = $relation;
        }

        $this->relatedCount = count($this->related);

        return $this;
    }
551715
public function has($relation, array $with = array())
    {
        $query = $this->make($with);

        return $query->has($relation)->get();
    }
701682
protected function getNonExistingFromRelation(string $relation): array
    {
        $nonExisting = [];

        foreach ($this->relationships[$relation] as $aggregate) {
            if (!$aggregate->exists()) {
                $nonExisting[] = $aggregate;
            }
        }

        return $nonExisting;
    }
1008598
public function addRelationSelectColumns($relation)
    {
        $join = $this->joins[$relation];
        call_user_func(array($join->getTableMap()->getPeerClassname(), 'addSelectColumns'), $this, $join->getRelationAlias());

        return $this;
    }
645976
protected function getRelations($relations)
    {
        $existingNames = [];
        $finalRelations = [];
        foreach ($relations as $relation) {
            $newRelation = ForeignRelationship::fromString($relation);
            if (is_null($newRelation)) {
                continue;
            }

            if (!empty($newRelation->name) && in_array($newRelation->name, $existingNames)) {
                continue;
            }

            $finalRelations[] = $newRelation;
            $existingNames[] = $newRelation->name;
        }

        return $finalRelations;
    }
724857
public function getLinks($relation = null)
    {
        $links = $this->getAllLinks();
        if (null === $relation) {
            return $links;
        }
        foreach ($links as $key => $link) {
            if ($link->getRelation() !== $relation) {
                unset($links[$key]);
            }
        }

        return $links;
    }
304032
protected function isCountableRelation($relation)
    {
        return is_a($relation, BelongsToMany::class)
            || is_a($relation, HasMany::class)
            || is_a($relation, HasManyThrough::class);
    }
1038836
public function getEmptyValueForRelationship(string $relation)
    {
        if ($this->isSingleRelationship($relation)) {
            return;
        }

        if ($this->isManyRelationship($relation)) {
            return new Collection();
        }

        throw new MappingException("Cannot determine default value of $relation");
    }
994955
protected function getJoinKeys(Relation $relation)
    {
        if ($relation instanceof MorphTo) {
            throw new LogicException("MorphTo relation cannot be joined.");
        }

        if ($relation instanceof HasOneOrMany) {
            return [$relation->getQualifiedForeignKeyName(), $relation->getQualifiedParentKeyName()];
        }

        if ($relation instanceof BelongsTo) {
            return [$relation->getQualifiedForeignKeyName(), $relation->getQualifiedOwnerKeyName()];
        }

        if ($relation instanceof BelongsToMany) {
            return [$relation->getQualifiedRelatedPivotKeyName(), $relation->getRelated()->getQualifiedKeyName()];
        }

        if ($relation instanceof HasManyThrough) {
            $fk = $relation->getQualifiedFarKeyName();

            return [$fk, $relation->getParent()->getQualifiedKeyName()];
        }
    }
261995
public static function validateToOneRelation($relation, $relationship)
    {
        if (
            !is_null($relation)
            && !$relation instanceof ResourceEntityInterface
        ) {
            $type = is_object($relation)
                ? get_class($relation) : gettype($relation);
            throw new \Exception(sprintf(
                self::ERROR_NOT_RESOURCE_ENTITY, $relationship, $type
            ));
        }
    }
390427
public static function findRelation($row, $relation): array
    {
        $model = $row->getTable()->getModel();

        /** @var \Bluz\Db\Table $relationTable */
        $relationTable = self::getModelClass($relation);
        $relationTable::getInstance();

        if (!$relations = self::getRelations($model, $relation)) {
            throw new RelationNotFoundException(
                "Relations between model `$model` and `$relation` is not defined"
            );
        }

        // check many-to-many relations
        if (\count($relations) === 1) {
            $relations = self::getRelations($model, current($relations));
        }

        $field = $relations[$model];
        $key = $row->{$field};

        return self::findRelations($model, $relation, [$key]);
    }
515693
public function getLocalKeys($relation)
    {
        return isset($this->localForeignKeys[$relation]) ? $this->localForeignKeys[$relation] : null;
    }
562837
public function getCmsSpecialRelationType($relation)
    {
        if (    ! array_key_exists($relation, $this->relationsConfig)
            ||  ! array_key_exists('type', $this->relationsConfig[$relation])
        ) {
            return null;
        }

        return $this->relationsConfig[ $relation ]['type'];
    }
1319114
protected function findEmbeddedObjectRelations(array $relations): array
    {
        $embeddedRelations = [];

        foreach ($relations as $relation) {
            if ($relation->getRelation() instanceof EmbeddedObjectRelation) {
                $embeddedRelations[] = $relation->getRelation();

                $embeddedRelations = array_merge(
                    $embeddedRelations,
                    $this->findEmbeddedObjectRelations($relation->getRelation()->getMapper()->getDefinition()->getToOneRelationMappings())
                );
            }
        }

        return $embeddedRelations;
    }
189102
protected function isActualRelationships(string $relation): bool
    {
        return array_key_exists($relation, $this->relationships)
            && count($this->relationships[$relation]) > 0;
    }