Example #1
0
 /**
  * Joins with another join element
  * @param CJoinElement $element the element to be joined
  */
 public function join($element)
 {
     if ($element->slave !== null) {
         $this->join($element->slave);
     }
     if (!empty($element->relation->select)) {
         $this->selects[] = $element->getColumnSelect($element->relation->select);
     }
     $this->conditions[] = $element->relation->condition;
     $this->orders[] = $element->relation->order;
     $this->joins[] = $element->getJoinCondition();
     $this->joins[] = $element->relation->join;
     $this->groups[] = $element->relation->group;
     $this->havings[] = $element->relation->having;
     if (is_array($element->relation->params)) {
         if (is_array($this->params)) {
             $this->params = array_merge($this->params, $element->relation->params);
         } else {
             $this->params = $element->relation->params;
         }
     }
     $this->elements[$element->id] = true;
 }
 /**
  * Generates the join statement for many-many relationship.
  * @param CDbTableSchema $joinTable the join table
  * @param array $fks the foreign keys
  * @param CJoinElement $parent the parent join element
  * @return string the join statement
  * @throws CDbException if a foreign key is invalid
  */
 private function joinManyMany($joinTable, $fks, $parent)
 {
     $schema = $this->_builder->getSchema();
     $joinAlias = $schema->quoteTableName($this->relation->name . '_' . $this->tableAlias);
     $parentCondition = array();
     $childCondition = array();
     $fkDefined = true;
     foreach ($fks as $i => $fk) {
         if (!is_int($i)) {
             $pk = $fk;
             $fk = $i;
         }
         if (!isset($joinTable->columns[$fk])) {
             throw new CDbException(Yii::t('yii', 'The relation "{relation}" in active record class "{class}" is specified with an invalid foreign key "{key}". There is no such column in the table "{table}".', array('{class}' => get_class($parent->model), '{relation}' => $this->relation->name, '{key}' => $fk, '{table}' => $joinTable->name)));
         }
         if (is_int($i) && isset($joinTable->foreignKeys[$fk])) {
             list($tableName, $pk) = $joinTable->foreignKeys[$fk];
             if (!isset($parentCondition[$pk]) && $schema->compareTableNames($parent->_table->rawName, $tableName)) {
                 $parentCondition[$pk] = $parent->getColumnPrefix() . $schema->quoteColumnName($pk) . '=' . $joinAlias . '.' . $schema->quoteColumnName($fk);
             } elseif (!isset($childCondition[$pk]) && $schema->compareTableNames($this->_table->rawName, $tableName)) {
                 $childCondition[$pk] = $this->getColumnPrefix() . $schema->quoteColumnName($pk) . '=' . $joinAlias . '.' . $schema->quoteColumnName($fk);
             } else {
                 $fkDefined = false;
                 break;
             }
         } else {
             $fkDefined = false;
             break;
         }
     }
     if (!$fkDefined) {
         $parentCondition = array();
         $childCondition = array();
         $fkNumber = 0;
         foreach ($fks as $i => $fk) {
             if (!is_int($i)) {
                 $pk = $fk;
                 $fk = $i;
             }
             if ($fkNumber < count($parent->_table->primaryKey)) {
                 if (is_int($i)) {
                     $pk = is_array($parent->_table->primaryKey) ? $parent->_table->primaryKey[$fkNumber] : $parent->_table->primaryKey;
                 }
                 $parentCondition[$pk] = $parent->getColumnPrefix() . $schema->quoteColumnName($pk) . '=' . $joinAlias . '.' . $schema->quoteColumnName($fk);
             } else {
                 if (is_int($i)) {
                     $j = $fkNumber - count($parent->_table->primaryKey);
                     $pk = is_array($this->_table->primaryKey) ? $this->_table->primaryKey[$j] : $this->_table->primaryKey;
                 }
                 $childCondition[$pk] = $this->getColumnPrefix() . $schema->quoteColumnName($pk) . '=' . $joinAlias . '.' . $schema->quoteColumnName($fk);
             }
             $fkNumber++;
         }
     }
     if ($parentCondition !== array() && $childCondition !== array()) {
         $join = $this->relation->joinType . ' ' . $joinTable->rawName . ' ' . $joinAlias;
         $join .= ' ON (' . implode(') AND (', $parentCondition) . ')';
         $join .= ' ' . $this->relation->joinType . ' ' . $this->getTableNameWithAlias();
         $join .= ' ON (' . implode(') AND (', $childCondition) . ')';
         if (!empty($this->relation->on)) {
             $join .= ' AND (' . $this->relation->on . ')';
         }
         return $join;
     } else {
         throw new CDbException(Yii::t('yii', 'The relation "{relation}" in active record class "{class}" is specified with an incomplete foreign key. The foreign key must consist of columns referencing both joining tables.', array('{class}' => get_class($parent->model), '{relation}' => $this->relation->name)));
     }
 }