Generate Joins

@param array $joins
@param string $join
492848
public function generateJoin($joins, &$join)
    {
        $join = "";

        if (count($joins) == 0) return;

        foreach ($joins as $joinEntry) {
            $table = $joinEntry['table'];
            $on = $joinEntry['on'];
            $alias = $joinEntry['alias'];
            $type = $joinEntry['type'];

            $join .= "$type $table ";
            if ($alias !== null) $join .= " $alias ";
            $join .= " ON $on ";

            $join .= " ";
        }
    }
1079183
protected function buildJoins()
    {
        $builtJoins = [];
        foreach ($this->joins as $type => $joins) {
            if (count($joins) > 0) {
                foreach ($joins as $join) {
                    if ($type === self::JOIN_INNER) {
                        $builtJoins[] = 'INNER JOIN';
                    } elseif ($type === self::JOIN_LEFT) {
                        $builtJoins[] = 'LEFT JOIN';
                    } elseif ($type === self::JOIN_RIGHT) {
                        $builtJoins[] = 'RIGHT JOIN';
                    } elseif ($type === self::JOIN_FULL) {
                        $builtJoins[] = 'FULL JOIN';
                    }

                    $builtJoins[] = $this->quoteIdentifier($join->getJoinTableName()) . ' ON';

                    // Use a ConditionSet to build the joins
                    $conditionSet = new Query\Condition\AndSet($this, [$join]);
                    $builtJoins[] = $conditionSet->buildWithoutParentheses();
                }
            }
        }

        return implode(' ', $builtJoins);
    }
575158
protected function applyJoins($query)
    {
        foreach ($this->joins as $key => $join) {

            if (isset($this->joinTypes[$key])) {
                $joinMethod = $this->joinTypes[$key];
            } else {
                $joinMethod = 'leftJoin';
            }

            call_user_func_array([ $query, $joinMethod ], $join);
        }
    }
1023997
private function applyJoinsAndFilters(ClassMetadata $metadata, string $alias, InputObjectType $typeFields, array $joins, array $conditions): void
    {
        $this->applyJoins($metadata, $joins, $alias);
        $this->collectDqlConditions($metadata, $conditions, $typeFields, $alias);
    }
557814
protected function doJoins($source, $joins, &$dest, $from, $contextAlias, $buildImpactIndex=true)
    {
        // expand sequences before doing any joins...
        $this->expandSequence($joins,$source);

        foreach ($joins as $predicate=>$ruleset) {
            if ($predicate=='followSequence') {
                continue;
            }

            if (isset($source[$predicate]))
            {
                // todo: perhaps we can get better performance by detecting whether or not
                // the uri to join on is already in the impact index, and if so not attempting
                // to join on it. However, we need to think about different combinations of
                // nested joins in different points of the view spec and see if this would
                // complicate things. Needs a unit test or two.
                $joinUris = [];
                if (isset($source[$predicate][VALUE_URI]))
                {
                    // single value for join
                    $joinUris[] = array(_ID_RESOURCE=>$source[$predicate][VALUE_URI],_ID_CONTEXT=>$contextAlias);
                }
                else
                {
                    // multiple values for join
                    $joinsPushed = 0;
                    foreach ($source[$predicate] as $v)
                    {
                        if (isset($ruleset['maxJoins']) && !$joinsPushed<$ruleset['maxJoins'])
                        {
                            break; // maxJoins reached
                        }
                        $joinUris[] = array(_ID_RESOURCE=>$v[VALUE_URI],_ID_CONTEXT=>$contextAlias);
                        $joinsPushed++;
                    }
                }

                $recursiveJoins = [];
                $collection = (
                isset($ruleset['from'])
                    ? $this->config->getCollectionForCBD($this->storeName, $ruleset['from'])
                    : $this->config->getCollectionForCBD($this->storeName, $from)
                );

                $cursor = $collection->find(array('_id'=>array('$in'=>$joinUris)), array(
                    'maxTimeMS' => $this->getConfigInstance()->getMongoCursorTimeout()
                ));

                $this->addIdToImpactIndex($joinUris, $dest, $buildImpactIndex);
                foreach($cursor as $linkMatch) {
                    // if there is a condition, check it...
                    if (isset($ruleset['condition']))
                    {
                        $ruleset['condition']['._id'] = $linkMatch['_id'];
                    }
                    if (!(isset($ruleset['condition']) && $collection->count($ruleset['condition'])==0))
                    {
                        // make sure any sequences are expanded before extracting properties
                        if (isset($ruleset['joins'])) $this->expandSequence($ruleset['joins'],$linkMatch);
                        if (isset($ruleset['filter']))
                        {
                            foreach($ruleset['filter'] as $filterPredicate => $filter)
                            {
                                foreach($filter as $filterType => $filterMatch)
                                {
                                    if (isset($linkMatch[$filterPredicate]))
                                    {
                                        foreach($linkMatch[$filterPredicate] as $linkMatchType => $linkMatchValues)
                                        {
                                            if (is_array($linkMatchValues) == false)
                                            {
                                                $linkMatchValues = array($linkMatchType => $linkMatchValues);
                                            }
                                            foreach($linkMatchValues as $linkMatchType => $linkMatchValue)
                                            {
                                                if ($this->matchesFilter($linkMatchType, $linkMatchValue, $filterType, $filterMatch))
                                                {
                                                    $dest[_GRAPHS][] = $this->extractProperties($linkMatch,$ruleset,$from);
                                                }
                                            }

                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            $dest[_GRAPHS][] = $this->extractProperties($linkMatch,$ruleset,$from);
                        }

                        if (isset($ruleset['joins']))
                        {
                            // recursive joins must be done after this cursor has completed, otherwise things get messy
                            $recursiveJoins[] = array('data'=>$linkMatch, 'ruleset'=>$ruleset['joins']);
                        }
                    }
                }
                if (count($recursiveJoins)>0)
                {
                    foreach ($recursiveJoins as $r)
                    {
                        $this->doJoins($r['data'],$r['ruleset'],$dest,$from,$contextAlias,$buildImpactIndex);
                    }
                }
            }
        }
        return;
    }
223328
public function toSql(?JoinClauseStrategy $join = null, bool $useClause = true): array
    {
        return $this->fromToSql($join, $useClause);
    }
1251675
private function build_join( $join ) {
		$sql = '';
		if ( ! empty( $join ) ) {
			$items = [];
			foreach ( $join as $data ) {
				if ( ! is_array( $data ) || count( $data ) < 3 ) {
					continue;
				}
				$table = $data[0];
				$rule  = $data[1];
				$rule  = strtoupper( $rule );
				if ( ! in_array( $rule, [
					'JOIN',
					'INNER JOIN',
					'LEFT JOIN',
					'RIGHT JOIN',
				] ) ) {
					continue;
				}

				$conditions = $data[2];
				if ( empty( $conditions ) ) {
					continue;
				}
				$check = reset( $conditions );
				if ( ! is_array( $check ) ) {
					$conditions = [ $conditions ];
				}
				$values = [];
				foreach ( $conditions as $condition ) {
					if ( ! is_array( $condition ) || count( $condition ) < 3 ) {
						continue;
					}
					$left     = $condition[0];
					$op       = $condition[1];
					$right    = $condition[2];
					$values[] = $this->get_field_name( $left, null ) . " $op " . $this->get_field_name( $right, null );
				}
				if ( ! empty( $values ) ) {
					$as = null;
					if ( is_array( $table ) && count( $table ) > 1 ) {
						$as    = $table[1];
						$table = $table[0];
					}
					$items[] = $rule . ' ' . $this->get_table( $table ) . ( isset( $as ) ? " AS $as" : '' ) . ' ON ' . implode( ' AND ', $values );
				}
			}
			if ( ! empty( $items ) ) {
				$sql .= ' ' . implode( ' ', $items );
			}
		}

		return $sql;
	}
111479
protected function getJoins()
    {
        $joins = [];
        $fields = array_merge($this->sortFields, $this->selectFields, $this->searchFields, $this->expressionFields);

        foreach ($fields as $field) {
            $joins = array_merge($joins, $field->getJoins());
        }

        return $joins;
    }
1013378
public function addJoinObject(Join $join, $name = null)
    {
        if (!in_array($join, $this->joins)) { // compare equality, NOT identity
            if (null === $name) {
                $this->joins[] = $join;
            } else {
                $this->joins[$name] = $join;
            }
        }

        return $this;
    }
663767
public static function select(array $columns = ['*'], ...$joinsColumns)
    {
        $query               = new static(Query\Type::SELECT);
        $query->columns['t'] = $columns;

        $alias = 'j1';
        foreach ($joinsColumns as $joinColumns) {
            $query->columns[$alias] = (array)$joinColumns;
            $alias++;
        }

        return $query;
    }
855856
public function addJoinObject(Join $join)
    {
        $isAlreadyAdded = false;
        foreach ($this->joins as $alreadyAddedJoin) {
            if ($join->equals($alreadyAddedJoin)) {
                $isAlreadyAdded = true;
                break;
            }
        }

        if (!$isAlreadyAdded) {
            $this->joins[] = $join;
        }

        return $this;
    }
1183423
protected function assignJoins(QueryBuilder $queryBuilder, array $joins = null)
    {
        if (null === $joins) {
            $joins = $this->getJoins();
        }

        foreach ($joins as $entity => $join) {
            switch ($join->getJoinMethod()) {
                case DoctrineJoinDescriptor::JOIN_METHOD_LEFT:
                    $queryBuilder->leftJoin(
                        $join->getJoin() ?: $entity,
                        $this->encodeAlias($entity),
                        $join->getJoinConditionMethod(),
                        $join->getJoinCondition()
                    );
                    break;
                case DoctrineJoinDescriptor::JOIN_METHOD_INNER:
                    $queryBuilder->innerJoin(
                        $join->getJoin() ?: $entity,
                        $this->encodeAlias($entity),
                        $join->getJoinConditionMethod(),
                        $join->getJoinCondition()
                    );
                    break;
            }
        }
    }
680124
public function join($join = [])
    {
        $this->string['join'] = $this->useBuilder('join')->join($join, $this->getBase()->getTable());
        return $this;
    }
1161637
public function buildJoin()
	{
		$joins = [];

		foreach ($this->join as $join)
		{
			if (isset($join['raw']))
			{
				$joins[] = strtoupper($join['type']) . ' JOIN ' . $join['table'] . ' ON ' . $join['raw'];
			}
			else
			{
				$joins[] = strtoupper($join['type']) . ' JOIN ' . $join['table'] . ' ON ' . $join['left'] . ' = ' . $join['right'];
			}
		}

		return implode("\n", $joins);
	}
422119
public static function render(SQL\Join $join)
    {
        $condition = $join->getCondition();
        $table = $join->getTable();

        return Compiler::expression(array(
            $join->getType(),
            'JOIN',
            $table instanceof SQL\Aliased ? Aliased::render($table) : $table,
            is_array($condition) ? self::renderArrayCondition($condition) : $condition,
        ));
    }
880598
public static function flatten(array $array, $prefix = '', $join = '.')
    {
        $flat = array();

        foreach ($array as $key => $value) {
            $key = $prefix ? $prefix . $join . $key : $key;

            if (is_array($value)) {
                $flat = array_merge(
                    $flat,
                    self::flatten($value, $key, $join)
                );
            } else {
                $flat[$key] = $value;
            }
        }

        return $flat;
    }
839428
public function addJoins(Join ...$joins): MutableQuery
    {
        $cloned = clone $this;

        $activeJoins = iterator_to_array($this->joins);
        $activeJoins = array_merge($activeJoins, $joins);

        $cloned->joins = new JoinCollection(...$activeJoins);

        return $cloned;
    }