<?php

/**
 * Collection manager for Active Records in one-to-many relation
 *
 * Manages adding and removing records. Caches relations for objects already in use.
 *
 * @version DR1.6
 */
class OneToManyRelation implements IteratorAggregate {



	protected $one;
	protected $className;
	protected $mappedKey;
	protected $dbAdapter;

	protected static $cache;



	protected function __construct(ActiveRecord $one, $className, $mappedKey) {
		$this->one = $one;
		$this->className = $className;
		$this->mappedKey = $mappedKey;
	}



	public static function getInstance(ActiveRecord $one, $className, $mappedKey, DBAdapter $dbAdapter) {
		$cachedRelation = &self::$cache[$one->getTableName()][$one->getPrimaryKeyValue()][$className];
		if (!$cachedRelation) {
			$cachedRelation = new OneToManyRelation($one, $className, $mappedKey);
			$cachedRelation->dbAdapter = $dbAdapter;
		}
		return $cachedRelation;
	}



	public function getIterator() {
		$dialect = $this->dbAdapter->getDialect();
		$q = $dialect->getQuotes();
		$className = $this->className;
		$target = new $className();
		$targetPrimaryKeyName = $target->getPrimaryKeyName();
		$sql = "
				SELECT {$q}{$targetPrimaryKeyName}{$q} FROM {$q}{$target->getTableName()}{$q}
				WHERE {$q}{$this->mappedKey}{$q} = '{$this->one->getPrimaryKeyValue()}'
		";
		$this->dbAdapter->execute($sql);
		$i = 0;
		$many = new ArrayObject();
		foreach ($this->dbAdapter as $row) {
			if ($i) {
				$many[$i] = new $className();
			} else {
				$many[$i] = $target; // reuse previously intantiated object
			}
			$many[$i]->loadById($row[$targetPrimaryKeyName]); // this is cached by ActiveRecord
			++$i;
		}
		return $many->getIterator();
	}



	public function add(ActiveRecord $ar) {
		if (!$this->one->getPrimaryKeyValue()) {
			$this->one->save();
		}
		$ar->{$this->mappedKey} = $this->one->getPrimaryKeyValue();
		$ar->save();
	}



	public function remove(ActiveRecord $ar) {
		if ($ar->{$this->mappedKey} == $this->one->getPrimaryKeyValue()) {
			$ar->{$this->mappedKey} = null;
			$ar->save();
		}
	}



} // class OneToManyRelation

?>