/** * Builds the join query with all descendant HAS_ONE and BELONGS_TO nodes. * @param CJoinQuery $query the query being built up */ public function buildQuery($query) { foreach ($this->children as $child) { if ($child->master !== null) { $child->_joined = true; } else { if ($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); } } } }
/** * Performs the recursive finding with the criteria. * @param CDbCriteria the query criteria */ public function find($criteria = null) { if ($this->_parent === null) { $query = new CJoinQuery($this, $criteria); $this->_finder->baseLimited = $criteria->offset >= 0 || $criteria->limit >= 0; $this->buildQuery($query); $this->_finder->baseLimited = false; $this->runQuery($query); } else { if (!$this->_joined && !empty($this->_parent->records)) { $query = new CJoinQuery($this->_parent); $this->_joined = true; $query->join($this); $this->buildQuery($query); $this->_parent->runQuery($query); } } foreach ($this->children as $child) { // find recursively $child->find(); } foreach ($this->stats as $stat) { $stat->query(); } }
/** * Performs lazy find with the specified base record. * @param CActiveRecord the active record whose related object is to be fetched. */ public function lazyFind($baseRecord) { if (is_string($this->_table->primaryKey)) { $this->records[$baseRecord->{$this->_table->primaryKey}] = $baseRecord; } else { $pk = array(); foreach ($this->_table->primaryKey as $name) { $pk[$name] = $baseRecord->{$name}; } $this->records[serialize($pk)] = $baseRecord; } foreach ($this->stats as $stat) { $stat->query(); } if (empty($this->children)) { return; } $child = reset($this->children); $query = new CJoinQuery($this); $this->_joined = true; $child->_joined = true; $query->join($child); if ($child->relation instanceof CHasManyRelation) { $query->limit = $child->relation->limit; $query->offset = $child->relation->offset; if ($this->_finder->baseLimited === null) { $this->_finder->baseLimited = $query->offset >= 0 || $query->limit >= 0; } $query->groups[] = str_replace($child->relation->aliasToken . '.', $child->tableAlias . '.', $child->relation->group); $query->havings[] = str_replace($child->relation->aliasToken . '.', $child->tableAlias . '.', $child->relation->having); } $child->buildQuery($query); $this->runQuery($query); foreach ($child->children as $c) { $c->find(); } }