Determine if the relationship is nested.

@param string $name
@param string $relation

@return bool
974927
protected function isNested(string $name, string $relation): bool
    {
        $dots = str_contains($name, '.');

        return $dots && starts_with($name, $relation.'.');
    }
1339506
public function addRelation(TableRelation $relation, string $name = null)
    {
        $name = $name ?? $relation->name;
        $relation->name = $name;
        $this->relations[$name] = $relation;
        return $this;
    }
1240899
public function isRelationLoaded($relationName)
    {
        if (!isset($this->loadedRelations[ $relationName ])) {
            throw new \OutOfBoundsException("Unknown relation: {$relationName}");
        }

        return $this->loadedRelations[ $relationName ];
    }
939263
private function checkBelongsToRelation($entity, $relation)
    {
        $varObjName = $relation->varObjectName();
        $varIdName  = $relation->varIdName();

        $currentRelation  = $this->getValue($entity, $varObjName);
        $originalRelation = $this->getValue($this->entityRegistry->getOriginal($entity), $varObjName);

        if (empty($currentRelation)) {
            // Current entity has no relation
            if (!empty($originalRelation)) {
                // Original had a relation, so relation was removed
                $this->setValue($entity, $varIdName, null);

                if ($relation->isRequired()) {
                    $this->scheduleForDeletion($entity);
                }
            }

            return;
        }

        // Current entity has a relation
        $currentRelationHash = $this->entityRegistry->getObjectHashId($currentRelation);

        if (empty($originalRelation)) {
            // Original had no relation, so relation was newly created
            $this->scheduleRelationForInsertion($currentRelation, $entity, $varIdName);

            return;
        }

        $originalRelationHash = $this->entityRegistry->getObjectHashId($originalRelation);

        if ($currentRelationHash != $originalRelationHash) {
            // Relation was exchanged
            $this->scheduleRelationForInsertion($currentRelation, $entity, $varIdName);
            $this->setValue($entity, $varIdName, null);
        }
    }
435468
public function getRelation($name)
    {
        // We want to run a relationship query without any constrains so that we will
        // not have to remove these where clauses manually which gets really hacky
        // and error prone. We don't want constraints because we add eager ones.
        $relation = Relation::noConstraints(function () use ($name) {
            $instance = $this->getModel()->newInstance();
            if (method_exists($instance, $name)) {
                return $instance->$name();
            }

            if ($relation = $instance->getRelationshipFromConfig($name)) {
                return $relation;
            }

            throw new RuntimeException("Call to undefined relationship [{$name}] on resource [{$this->getModel()->getTable()}].");
        });

        $nested = $this->relationsNestedUnder($name);

        // If there are nested relationships set on the query, we will put those onto
        // the query instances so that they can be handled after this relationship
        // is loaded. In this way they will all trickle down as they are loaded.
        if (count($nested) > 0) {
            $relation->getQuery()->with($nested);
        }

        return $relation;
    }
892652
public function getCmsSpecialRelationTranslated($relation)
    {
        if (    ! array_key_exists($relation, $this->relationsConfig)
            ||  ! array_key_exists('translated', $this->relationsConfig[$relation])
        ) {
            return false;
        }

        return (bool) $this->relationsConfig[ $relation ]['translated'];
    }
268045
public function getRelation($relation)
    {
        $query = Relation::noConstraints(
            function () use ($relation){
                /** @var BaseModel $model */
                $model = $this->getModel();
                $relationType = $model->getReferencingType($relation);

                if (RelationSchema::HAS_ONE === $relationType) {
                    return $model->getHasOneByRelationName($relation);
                } elseif (RelationSchema::HAS_MANY === $relationType) {
                    return $model->getHasManyByRelationName($relation);
                } elseif (RelationSchema::MANY_MANY === $relationType) {
                    return $model->getBelongsToManyByRelationName($relation);
                } elseif (RelationSchema::BELONGS_TO === $relationType) {
                    return $model->getBelongsToByRelationName($relation);
                }

                return null;
            }
        );

        if (!empty($query)) {
            return $query;
        }

        if (!method_exists($this->getModel(), $relation)) {
            throw new BadRequestException('Unknown relationship: ' . $relation);
        }

        return parent::getRelation($relation);
    }
894762
protected function nestedRelations( $relation )
	{
		$nested = [];

		// We are basically looking for any relationships that are nested deeper than
		// the given top-level relationship. We will just check for any relations
		// that start with the given top relations and adds them to our arrays.
		foreach ( $this->eagerLoad as $name => $constraints )
		{
			if ( $this->isNested( $name, $relation ) )
			{
				$nested[substr( $name, strlen( $relation . '.' ) )] = $constraints;
			}
		}

		return $nested;
	}
325575
protected function parseForCommonValues($relation)
    {
        if (!$this->hasAttribute($relation)) {
            // If no attribute exists for this relationships
            // we'll make it a simple empty array. This will
            // save us from constantly checking for the attributes
            // actual existence.
            $this->relationships[$relation] = [];

            return false;
        }

        $value = $this->getRelationshipValue($relation);

        if (is_null($value)) {
            $this->relationships[$relation] = [];

            // If the relationship's content is the null value
            // and the Entity's exist in DB, we'll interpret this
            // as the need to detach all related Entities,
            // therefore a sync operation is needed.
            $this->needSync[] = $relation;

            return false;
        }

        return $value;
    }
1030198
protected function checkRelationName($sRelationName) : bool
    {
        $sCheckedRelationName = $this->getRelationName();
        if (empty($sCheckedRelationName)) {
            return true;
        }

        if (is_array($sCheckedRelationName) && in_array($sRelationName, $sCheckedRelationName)) {
            return true;
        }

        $bResult = $sRelationName == $sCheckedRelationName;

        return $bResult;
    }
1091179
public static function related_class($relation)
	{
		$class = get_called_class();

		foreach (static::$_valid_relations as $rel_name => $rel_class)
		{
			if (property_exists($class, '_'.$rel_name))
			{
				if (isset(static::${'_'.$rel_name}[$relation]))
				{
					return static::${'_'.$rel_name}[$relation]['model_to'];
				}
			}
		}

		return null;
	}
367487
public function nestedTypes($name)
    {
        if (!is_string($name)) {
            throw new InvalidArgumentException('nestedTypes name must string.');
        }
        $matches = [];

        if (preg_match_all('/(\[[0-9]*\])/', $name, $matches, PREG_PATTERN_ORDER) >= 1) {
            return $matches[0];
        }
        return false;
    }
1347427
public function has($relation)
    {
        $query = $this->make();
        return $query->has($relation)->get( $this->getParameters );
    }
1073636
public function relation($name)
    {
        if (isset($this->_relationships[$name])) {
            return $this->_relationships[$name];
        }
        if (!isset($this->_relations[$name])) {
            throw new ORMException("Relationship `{$name}` not found.");
        }
        $config = $this->_relations[$name];
        $relationship = $config['relation'];
        unset($config['relation']);

        $relation = $this->_classes[$relationship];
        return $this->_relationships[$name] = new $relation($config + [
            'name'        => $name,
            'conventions' => $this->_conventions
        ]);
    }
293667
protected function relationsNestedUnder($relation)
    {
        $nested = [];

        // We are basically looking for any relationships that are nested deeper than
        // the given top-level relationship. We will just check for any relations
        // that start with the given top relations and adds them to our arrays.
        foreach ($this->eagerLoad as $name => $constraints) {
            if ($this->isNestedUnder($relation, $name)) {
                $nested[substr($name, strlen($relation.'.'))] = $constraints;
            }
        }

        return $nested;
    }
540843
protected function isNestedUnder($relation, $name)
    {
        return (mb_strpos($name, '.') !== false) && (substr($name, 0, strlen($relation.'.')) === $relation.'.');
    }
37289
public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null)
    {
        if (strpos($relation, '.') !== false) {
            return $this->hasNested($relation, $operator, $count, $boolean, $callback);
        }

        $relation = $this->getHasRelationQuery($relation);

        $query = $relation->getRelationCountQuery($relation->getRelated()->newQuery(), $this);

        if ($callback) call_user_func($callback, $query);

        return $this->addHasWhere($query, $relation, $operator, $count, $boolean);
    }