<?php

/**
 * Collection manager for Active Records in many-to-many relation
 *
 * @version DR1.6
 */
class ManyToManyRelation implements IteratorAggregate {



	protected $items = array();
	protected $map = array();
	protected $subject;
	protected $className;
	protected $mapName;
	protected $mapKey;
	protected $mapForeignKey;
	protected $orderKey;
	protected $dbAdapter;



	public function __construct(ActiveRecord $subject, $className, $mapName, $mapKey, $mapForeignKey, $orderKey = null) {
		$this->subject = $subject;
		$this->className = $className;
		$this->mapName = $mapName;
		$this->mapKey = $mapKey;
		$this->mapForeignKey = $mapForeignKey;
		$this->orderKey = $orderKey;
	}



	public function setDBAdapter(DBAdapter $dbAdapter) {
		$this->dbAdapter = $dbAdapter;
	}



	public function getIterator() {
		$items = new ArrayObject();
		if (!$this->subject->getPrimaryKeyValue()) {
			$this->subject->save();
		}
		$dialect = $this->dbAdapter->getDialect();
		$q = $dialect->getQuotes();
		$className = $this->className;
		$target = new $className();
		$sql = "
				SELECT * FROM {$q}{$this->mapName}{$q}
				WHERE {$q}{$this->mapKey}{$q} = '{$this->subject->getPrimaryKeyValue()}'
		";
		if ($this->orderKey) {
			$sql .= " ORDER BY {$this->orderKey} ASC ";
		}
		$this->dbAdapter->execute($sql);
		$this->items = array();
		$i = 0;
		foreach ($this->dbAdapter as $row) {
			$items[$i] = new $className();
			$items[$i]->loadById($row[$this->mapForeignKey]);
			++$i;
		}
		return $items->getIterator();
	}



	public function add(ActiveRecord $ar) {
		if (!$ar->getPrimaryKeyValue()) {
			$ar->save();
		}
		$dialect = $this->dbAdapter->getDialect();
		$sql = $dialect->getInsert(
			$this->mapName, array(
				$this->mapKey => $this->subject->getPrimaryKeyValue(),
				$this->mapForeignKey => $ar->getPrimaryKeyValue()
			)
		);
		$this->dbAdapter->execute($sql);
	}



	public function remove(ActiveRecord $ar) {
		$dialect = $this->dbAdapter->getDialect();
		$q = $dialect->getQuotes();
		$mapKey = $q . $this->mapKey . $q;
		$mapForeignKey = $q . $this->mapForeignKey . $q;
		$sql = "
				DELETE FROM {$this->mapName}
				WHERE $mapKey = '{$this->subject->getPrimaryKeyValue()}'
					AND $mapForeignKey = '{$ar->getPrimaryKeyValue()}'
		";
		$this->dbAdapter->execute($sql);
	}



} // class ManyToManyRelation

?>