Applies filters Eloquent Query builder for relation

@param string  $relationName Relation name
@param string  $alias        SQL alias
@param Builder $query        Eloquent query builder

@return void
182649
public function applyRelationFilters(string $relationName, string $alias, Builder $query)
    {
        foreach ($this->getRelationFilters($relationName) as $filter) {
            $filter->apply($query, $alias);
        }
    }
765650
public function belongsTo($alias, $class, $foreignKey = null, Closure $conditions = null) {
        $relation = (new ManyToOne($alias, $class))
            ->setPrimaryForeignKey($foreignKey);

        if ($conditions) {
            $relation->setConditions($conditions);
        }

        return $this->addRelation($relation);
    }
428957
public function buildQuery($query)
	{
		foreach($this->children as $child)
		{
			if($child->master!==null)
				$child->_joined=true;
			elseif($child->relation instanceof CHasOneRelation || $child->relation instanceof CBelongsToRelation
				|| $this->_finder->joinAll || $child->relation->together || (!$this->_finder->baseLimited && $child->relation->together===null))
			{
				$child->_joined=true;
				$query->join($child);
				$child->buildQuery($query);
			}
		}
	}
902904
protected static function applyRelationFilter($query, $column, $searchValue)
    {
        if ($methodName = self::hasCustomSearch(str_replace('.', '_', $column))) {
            return self::$class::$methodName($query, $searchValue);
        }

        list($relationName, $relationColumnName) = getRelationDetails($column);
        $searchValue = '%'.$searchValue.'%';

        return $query->orWhereHas($relationName, function ($query) use ($relationColumnName, $searchValue) {
            $query->where($relationColumnName, 'like', "$searchValue");
        });
    }
656783
public function getRelations($use_alias = false)
    {
        if ($use_alias) {
            // re-index for alias usage, easier to find requested fields from client
            $relations = [];
            /** @var RelationSchema $column */
            foreach ($this->relations as $column) {
                $relations[strtolower($column->getName(true))] = $column;
            }

            return $relations;
        }

        return $this->relations;
    }
981004
protected function loadRelationOrder(Builder $query, $direction)
    {
        /** @var Relation $relationClass */
        $relations = collect(explode('.', $this->name));
        $loop = 0;
        if ($relations->count() >= 2) {
            $query->select($query->getModel()->getTable().'.*');

            do {
                $model = ! $loop++ ? $query->getModel() : $relationClass->getModel();
                $relation = $relations->shift();

                if (method_exists($model, $relation)) {
                    $relationClass = $model->{$relation}();
                    $relationModel = $relationClass->getRelated();

                    $loadRelationMethod = implode('', ['load', class_basename(get_class($relationClass))]);
                    call_user_func([$this, $loadRelationMethod],
                        $relations, $relationClass, $relationModel, $model, $query, $direction);
                } else {
                    break;
                }
            } while (true);

            if ($this->sortedColumnAlias) {
                $query->orderBy(DB::raw($this->sortedColumnAlias), $direction);
            }
        }
    }
634737
public function assignChild ($relationIdentifier, $id, $childId)
		{
			$relation = $this->getRelation($relationIdentifier);

			if (!$relation) {
				throw new RelationException('Invalid relation `' . $relationIdentifier);
			}

			if ($relation instanceof OneToMany) {
				$this->database->createQuery()
					->update()
					->table($relation->getRelatedTable())
					->set(
						array(
							$relation->getRelatedKey() => $id,
						)
					)
					->whereEqual($relation->getKey(), $childId)
					->execute();
			} else if ($relation instanceof ManyToMany) {
				if (! $this->getChild($relationIdentifier, $id, $childId)) {
					$this->database->createQuery()
						->insert()
						->into($relation->getRelationalTable())
						->set(
							array(
								$relation->getKey()         => $id,
								$relation->getRelatedKey()  => $childId,
							)
						)
						->execute();
				}
			} else {
				throw new RelationException('Invalid relation type `' . gettype($relation) . '`');
			}
		}
663737
public function unassignChild ($relationIdentifier, $id, $childId)
		{
			$relation = $this->getRelation($relationIdentifier);

			if (!$relation) {
				throw new RelationException('Invalid relation `' . $relationIdentifier);
			}

			if ($relation instanceof OneToMany) {
				$this->database->createQuery()
					->update()
					->table($relation->getRelatedTable())
					->set(
						array(
							$relation->getRelatedKey() => null,
						)
					)
					->whereEqual($relation->getRelatedKey(), $id)
					->whereEqual($relation->getKey(), $childId)
					->execute();
			} else if ($relation instanceof ManyToMany) {
				$this->database->createQuery()
					->delete()
					->from($relation->getRelationalTable())
					->whereEqual($relation->getKey(), $id)
					->whereEqual($relation->getRelatedKey(), $childId)
					->execute();
			} else {
				throw new RelationException('Invalid relation type `' . gettype($relation) . '`');
			}
		}
808282
public function countRel($key, $alias=null, $filter=null, $option=null) {
		if (!$alias)
			$alias = 'count_'.$key;
		$filter_bak = null;
		if ($filter || $option) {
			$filter_bak = isset($this->relFilter[$key]) ? $this->relFilter[$key] : false;
			$this->filter($key,$filter,$option);
		}
		if (isset($this->fieldConf[$key])){
			// one-to-one, one-to-many
			if ($this->fieldConf[$key]['relType'] == 'belongs-to-one') {
				if ($this->dbsType == 'sql') {
					$this->mapper->set($alias,'count('.$this->db->quotekey($key).')');
					$this->grp_stack=(!$this->grp_stack)?$key:$this->grp_stack.','.$key;
					if ($this->whitelist && !in_array($alias,$this->whitelist))
						$this->whitelist[] = $alias;
				} elseif ($this->dbsType == 'mongo')
					$this->_mongo_addGroup(array(
						'keys'=>array($key=>1),
						'reduce' => 'prev.'.$alias.'++;',
						"initial" => array($alias => 0)
					));
				else
					trigger_error('Cannot add direct relational counter.',E_USER_ERROR);
			} elseif($this->fieldConf[$key]['relType'] == 'has-many') {
				$relConf=$this->fieldConf[$key]['has-many'];
				if ($relConf['hasRel']=='has-many') {
					// many-to-many
					if ($this->dbsType == 'sql') {
						$mmTable = $this->mmTable($relConf,$key);
						$filter = array($mmTable.'.'.$relConf['relField']
							.' = '.$this->table.'.'.$this->primary);
						$from = $this->db->quotekey($mmTable);
						if (array_key_exists($key, $this->relFilter) &&
							!empty($this->relFilter[$key][0])) {
							$options=array();
							$from = $this->db->quotekey($mmTable).' '.
								$this->_sql_left_join($key,$mmTable,$relConf['relPK'],$relConf['relTable']);
							$relFilter = $this->relFilter[$key];
							$this->_sql_mergeRelCondition($relFilter,$relConf['relTable'],
								$filter,$options);
						}
						$filter = $this->queryParser->prepareFilter($filter,
							$this->dbsType, $this->db, $this->fieldConf);
						$crit = array_shift($filter);
						if (count($filter)>0)
							$this->preBinds=array_merge($this->preBinds,$filter);
						$this->mapper->set($alias,
							'(select count('.$this->db->quotekey($mmTable.'.'.$relConf['relField']).')'.
							' from '.$from.' where '.$crit.
							' group by '.$this->db->quotekey($mmTable.'.'.$relConf['relField']).')');
						if ($this->whitelist && !in_array($alias,$this->whitelist))
							$this->whitelist[] = $alias;
					} else {
						// count rel
						$this->countFields[]=$key;
					}
				} elseif($this->fieldConf[$key]['has-many']['hasRel']=='belongs-to-one') {
					// many-to-one
					if ($this->dbsType == 'sql') {
						$fConf=$relConf[0]::resolveConfiguration();
						$fTable=$fConf['table'];
						$fAlias=$fTable.'__count';
						$rKey=$relConf[1];
						$crit = $fAlias.'.'.$rKey.' = '.$this->table.'.'.$relConf['relField'];
						$filter = $this->mergeWithRelFilter($key,array($crit));
						$filter[0] = $this->queryParser->sql_prependTableToFields($filter[0],$fAlias);
						$filter = $this->queryParser->prepareFilter($filter,
							$this->dbsType, $this->db, $this->fieldConf);
						$crit = array_shift($filter);
						if (count($filter)>0)
							$this->preBinds=array_merge($this->preBinds,$filter);
						$this->mapper->set($alias,
							'(select count('.$this->db->quotekey($fAlias.'.'.$fConf['primary']).') from '.
							$this->db->quotekey($fTable).' AS '.$this->db->quotekey($fAlias).' where '.
							$crit.' group by '.$this->db->quotekey($fAlias.'.'.$rKey).')');
						if ($this->whitelist && !in_array($alias,$this->whitelist))
							$this->whitelist[] = $alias;
					} else {
						// count rel
						$this->countFields[]=$key;
					}
				}
			}
		}
		if ($filter_bak!==null) {
			if ($filter_bak)
				$this->relFilter[$key] = $filter_bak;
			else
				$this->clearFilter($key);
		}
	}
1104985
protected function returnRelation($relation, $entity, callable $callback = null, $alias = null)
    {
        if (is_string($entity)) {
            $entity = Reflect::create($entity, ['alias' => $alias]);
        }

        $relation = new $relation($this, $entity);

        if ($alias) {
            $relation->getRightEntity()->setAlias($alias);
        }

        if ($callback) {
            $callback($relation);
        }

        return $relation;
    }
656454
public function filterJoinedRelation($related)
    {
        // Apply any relation based scope to avoid method duplication
        $this->callRelatedLocalSetup($related, $this->query);

        foreach ($this->getLocalRelation($related) as $closure) {
            // If a relation is defined locally in a method AND is joined
            // Then we call those defined relation closures on this query
            $closure($this->query);
        }

        // Check if we have input we need to pass through a related Model's filter
        // Then filter by that related model's filter
        if (count($relatedFilterInput = $this->getRelatedFilterInput($related)) > 0) {
            $filterClass = $this->getRelatedFilter($related);

            // Disable querying joined relations on filters of joined tables.
            (new $filterClass($this->query, $relatedFilterInput, false))->handle();
        }
    }
1093066
protected function build_where($rules,$relation=false){
		$sql=array();
		for ($i=0; $i < sizeof($rules); $i++)
			if (is_string($rules[$i]))
				array_push($sql,"(".$rules[$i].")");
			else {
				$filtervalue = $rules[$i]["value"];
				$filteroperation = $rules[$i]["operation"];
				if ($filtervalue!=""){
					if (!$filteroperation)
						array_push($sql,$this->escape_name($rules[$i]["name"])." LIKE '%".$this->escape($filtervalue)."%'");
					else {
						if ($filteroperation != "IN") 
							$filtervalue = "'".$this->escape($filtervalue)."'";

						array_push($sql,$this->escape_name($rules[$i]["name"])." ".$filteroperation." ".$filtervalue);
					}
				}
			}

		if ($relation !== false && $relation !== ""){
			$relsql = $this->escape_name($this->config->relation_id["db_name"])." = '".$this->escape($relation)."'";
			if ($relation == "0")
				$relsql = "( ".$relsql." OR ".$this->escape_name($this->config->relation_id["db_name"])." IS NULL )";

			array_push($sql,$relsql);
		}
		return implode(" AND ",$sql);
	}
649894
private function _getJunctionTableColumns($relationName, $model)
    {
        $junctionTableColumns = [];
        if (array_key_exists($relationName, $this->_relationsExtraColumns)) {
            if (is_callable($this->_relationsExtraColumns[$relationName])) {
                $junctionTableColumns = $this->_relationsExtraColumns[$relationName]($model);
            } elseif (is_array($this->_relationsExtraColumns[$relationName])) {
                $junctionTableColumns = $this->_relationsExtraColumns[$relationName];
            }
            if (!is_array($junctionTableColumns)) {
                throw new RuntimeException(
                    'Junction table columns definition must return an array, got ' . gettype($junctionTableColumns)
                );
            }
        }
        return $junctionTableColumns;
    }
53580
public function ElementsByRelation(string $relationName)
    {
        $filter = [ 'RelationName' => $relationName ];
        if (
            $this->owner->hasExtension(ElementBase::FLUENT_CLASS)
            && !is_a(Controller::curr(), LeftAndMain::class)
        ) {
            $filter['Visible'] = true;
        }

        return $this->owner
            ->Elements()
            ->filter($filter)
        ;
    }
140906
public function createQueryBuilder($alias, $indexBy = null)
    {
        return $this->em->createQueryBuilder()
            ->select($alias)
            ->from($this->entityName, $alias, $indexBy);
    }
814170
protected function performJoin(Builder $query = null)
    {
        $query = $query ?: $this->query;

        $throughParents = array_reverse($this->throughParents);
        $foreignKeys = array_reverse($this->foreignKeys);
        $localKeys = array_reverse($this->localKeys);

        $segments = explode(' as ', $query->getQuery()->from);

        $alias = $segments[1] ?? null;

        foreach ($throughParents as $i => $throughParent) {
            $predecessor = $throughParents[$i - 1] ?? $this->related;

            $prefix = $i === 0 && $alias ? $alias.'.' : '';

            $this->joinThroughParent($query, $throughParent, $predecessor, $foreignKeys[$i], $localKeys[$i], $prefix);
        }
    }
1281430
private function getRelatedBuilder($alias) {
        foreach($this->getRelatedBuilders() as $key => $builder) {
            if($alias == $key) {
                return $builder;
            }
        }
        return null;
    }