You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							173 lines
						
					
					
						
							4.8 KiB
						
					
					
				
			
		
		
	
	
							173 lines
						
					
					
						
							4.8 KiB
						
					
					
				<?php | 
						|
/** | 
						|
 * JoinElement class file. | 
						|
 * | 
						|
 * @author Qiang Xue <qiang.xue@gmail.com> | 
						|
 * @link http://www.yiiframework.com/ | 
						|
 * @copyright Copyright © 2008-2012 Yii Software LLC | 
						|
 * @license http://www.yiiframework.com/license/ | 
						|
 */ | 
						|
 | 
						|
namespace yii\db\ar; | 
						|
 | 
						|
use yii\base\VectorIterator; | 
						|
use yii\db\dao\Query; | 
						|
use yii\db\Exception; | 
						|
 | 
						|
 | 
						|
class JoinElement | 
						|
{ | 
						|
	/** | 
						|
	 * @var integer ID of this join element | 
						|
	 */ | 
						|
	public $id; | 
						|
	/** | 
						|
	 * @var BaseActiveQuery | 
						|
	 */ | 
						|
	public $query; | 
						|
	/** | 
						|
	 * @var JoinElement the parent element that this element needs to join with | 
						|
	 */ | 
						|
	public $parent; | 
						|
	public $container; | 
						|
	/** | 
						|
	 * @var JoinElement[] the child elements that need to join with this element | 
						|
	 */ | 
						|
	public $children = array(); | 
						|
	/** | 
						|
	 * @var JoinElement[] the child elements that have corresponding relations declared in the AR class of this element | 
						|
	 */ | 
						|
	public $relations = array(); | 
						|
	/** | 
						|
	 * @var array column aliases (alias => original name) | 
						|
	 */ | 
						|
	public $columnAliases = array(); | 
						|
	/** | 
						|
	 * @var array primary key column aliases (original name => alias) | 
						|
	 */ | 
						|
	public $pkAlias = array(); | 
						|
	/** | 
						|
	 * @var string|array the column(s) used for index the query results | 
						|
	 */ | 
						|
	public $key; | 
						|
	/** | 
						|
	 * @var array query results for this element (PK value => AR instance or data array) | 
						|
	 */ | 
						|
	public $records = array(); | 
						|
	public $related = array(); | 
						|
 | 
						|
	/** | 
						|
	 * @param integer $id | 
						|
	 * @param ActiveRelation|ActiveQuery $query | 
						|
	 * @param null|JoinElement $parent | 
						|
	 * @param null|JoinElement $container | 
						|
	 */ | 
						|
	public function __construct($id, $query, $parent, $container) | 
						|
	{ | 
						|
		$this->id = $id; | 
						|
		$this->query = $query; | 
						|
		if ($parent !== null) { | 
						|
			$this->parent = $parent; | 
						|
			$this->container = $container; | 
						|
			$parent->children[$query->name] = $this; | 
						|
			if ($query->select !== false) { | 
						|
				$container->relations[$query->name] = $this; | 
						|
			} | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	public function populateData($rows) | 
						|
	{ | 
						|
		if ($this->container === null) { | 
						|
			foreach ($rows as $row) { | 
						|
				if (($key = $this->getKeyValue($row)) !== null && !isset($this->records[$key])) { | 
						|
					$this->records[$key] = $this->createRecord($row); | 
						|
				} | 
						|
			} | 
						|
		} else { | 
						|
			foreach ($rows as $row) { | 
						|
				$key = $this->getKeyValue($row); | 
						|
				$containerKey = $this->container->getKeyValue($row); | 
						|
				if ($key === null || $containerKey === null || isset($this->related[$containerKey][$key])) { | 
						|
					continue; | 
						|
				} | 
						|
				$this->related[$containerKey][$key] = true; | 
						|
				if ($this->query->asArray) { | 
						|
					if (isset($this->records[$key])) { | 
						|
						if ($this->query->hasMany) { | 
						|
							if ($this->query->index !== null) { | 
						|
								$this->container->records[$containerKey][$this->query->name][$key] =& $this->records[$key]; | 
						|
							} else { | 
						|
								$this->container->records[$containerKey][$this->query->name][] =& $this->records[$key]; | 
						|
							} | 
						|
						} else { | 
						|
							$this->container->records[$containerKey][$this->query->name] =& $this->records[$key]; | 
						|
						} | 
						|
					} else { | 
						|
						$record = $this->createRecord($row); | 
						|
						if ($this->query->hasMany) { | 
						|
							if ($this->query->index !== null) { | 
						|
								$this->container->records[$containerKey][$this->query->name][$key] = $record; | 
						|
								$this->records[$key] =& $this->container->records[$containerKey][$this->query->name][$key]; | 
						|
							} else { | 
						|
								$count = count($this->container->records[$containerKey][$this->query->name]); | 
						|
								$this->container->records[$containerKey][$this->query->name][] = $record; | 
						|
								$this->records[$key] =& $this->container->records[$containerKey][$this->query->name][$count]; | 
						|
							} | 
						|
						} else { | 
						|
							$this->container->records[$containerKey][$this->query->name] = $record; | 
						|
							$this->records[$key] =& $this->container->records[$containerKey][$this->query->name]; | 
						|
						} | 
						|
					} | 
						|
				} else { | 
						|
					if (isset($this->records[$key])) { | 
						|
						$record = $this->records[$key]; | 
						|
					} else { | 
						|
						$this->records[$key] = $record = $this->createRecord($row); | 
						|
					} | 
						|
					$this->container->records[$containerKey]->addRelatedRecord($this->query, $record); | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		foreach ($this->relations as $child) { | 
						|
			$child->populateData($rows); | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	protected function getKeyValue($row) | 
						|
	{ | 
						|
		if (is_array($this->key)) { | 
						|
			$key = array(); | 
						|
			foreach ($this->key as $alias) { | 
						|
				if (!isset($row[$alias])) { | 
						|
					return null; | 
						|
				} | 
						|
				$key[] = $row[$alias]; | 
						|
			} | 
						|
			return serialize($key); | 
						|
		} else { | 
						|
			return $row[$this->key]; | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	protected function createRecord($row) | 
						|
	{ | 
						|
		$record = array(); | 
						|
		foreach ($this->columnAliases as $alias => $name) { | 
						|
			$record[$name] = $row[$alias]; | 
						|
		} | 
						|
		if ($this->query->asArray) { | 
						|
			foreach ($this->relations as $child) { | 
						|
				$record[$child->query->name] = $child->query->hasMany ? array() : null; | 
						|
			} | 
						|
		} else { | 
						|
			$modelClass = $this->query->modelClass; | 
						|
			$record = $modelClass::create($record); | 
						|
			foreach ($this->relations as $child) { | 
						|
				$record->{$child->query->name} = $child->query->hasMany ? array() : null; | 
						|
			} | 
						|
		} | 
						|
		return $record; | 
						|
	} | 
						|
} |