<?php

/*
 *  $Id: PHP5ComplexPeerBuilder.php 536 2007-01-10 14:30:38Z heltem $
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information please see
 * <http://propel.phpdb.org>.
 */

require_once 'propel/engine/builder/om/php5/PHP5BasicPeerBuilder.php';

/**
 * Generates a PHP5 base Peer class with complex object model methods.
 *
 * This class extends the basic peer builder by adding on the doSelectJoin*()
 * methods and other complex object model methods.
 *
 * @author     Hans Lellelid <hans@xmpl.org>
 * @package    propel.engine.builder.om.php5
 */
class PHP5ComplexPeerBuilder extends PHP5BasicPeerBuilder {

	/**
	 * Adds the complex OM methods to the base addSelectMethods() function.
	 * @param      string &$script The script will be modified in this method.
	 * @see        PeerBuilder::addSelectMethods()
	 */
	protected function addSelectMethods(&$script)
	{
		$table = $this->getTable();

		parent::addSelectMethods($script);

		$this->addDoCountJoin($script);
		$this->addDoSelectJoin($script);

		$countFK = count($table->getForeignKeys());

		$includeJoinAll = true;

		foreach ($this->getTable()->getForeignKeys() as $fk) {
			$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
			if ($tblFK->isForReferenceOnly()) {
			   $includeJoinAll = false;
			}
		}

		if ($includeJoinAll) {
			if($countFK > 0) {
				$this->addDoCountJoinAll($script);
				$this->addDoSelectJoinAll($script);
			}
			if ($countFK > 1) {
				$this->addDoCountJoinAllExcept($script);
				$this->addDoSelectJoinAllExcept($script);
			}
		}

	}

	/**
	 * Adds the doSelectJoin*() methods.
	 * @param      string &$script The script will be modified in this method.
	 */
	protected function addDoSelectJoin(&$script)
	{
		$table = $this->getTable();
		$className = $table->getPhpName();
		$countFK = count($table->getForeignKeys());

		if ($countFK >= 1) {

			foreach ($table->getForeignKeys() as $fk) {

				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());

				if (!$joinTable->isForReferenceOnly()) {

					// FIXME - look into removing this next condition; it may not
					// be necessary:
					// --- IT is necessary because there needs to be a system for
					// aliasing the table if it is the same table.
					if ( $fk->getForeignTableName() != $table->getName() ) {

						/*
						REPLACED BY USING THE ObjectBuilder objects below

						// check to see if we need to add something to the method name.
						// For example if there are multiple columns that reference the same
						// table, then we have to have a methd name like doSelectJoinBooksByBookId
						$partJoinName = "";
						foreach ($fk->getLocalColumns() as $columnName ) {
							$column = $table->getColumn($columnName);
								//							this second part is not currently ever true (right?)
							if ($column->isMultipleFK() || $fk->getForeignTableName() == $table->getName()) {
								$partJoinName = $partJoinName . $column->getPhpName();
							}
						}


						$joinClassName = $joinTable->getPhpName();

						if ($joinTable->getInterface()) {
						   $interfaceName = $joinTable->getInterface();
						} else {
							$interfaceName = $joinTable->getPhpName();
						}

						if ($partJoinName == "") {
							$joinColumnId = $joinClassName;
							$joinInterface = $interfaceName;
							$collThisTable = $className . "s";
							$collThisTableMs = $className;
						} else {
							$joinColumnId = $joinClassName . "RelatedBy" . $partJoinName;
							$joinInterface = $interfaceName . "RelatedBy" . $partJoinName;
							$collThisTable = $className . "sRelatedBy" . $partJoinName;
							$collThisTableMs = $className . "RelatedBy" . $partJoinName;
						}
						*/

						$joinClassName = $joinTable->getPhpName();

						$thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
						$joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable);
						$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

						$script .= "

	/**
	 * Selects a collection of $className objects pre-filled with their $joinClassName objects.
	 *
	 * @return     array Array of $className objects.
	 * @throws     PropelException Any exceptions caught during processing will be
	 *		 rethrown wrapped into a PropelException.
	 */
	public static function doSelectJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$c, \$con = null)
	{
		\$c = clone \$c;

		// Set the correct dbName if it has not been overridden
		if (\$c->getDbName() == Propel::getDefaultDB()) {
			\$c->setDbName(self::DATABASE_NAME);
		}

		".$this->getPeerClassname()."::addSelectColumns(\$c);
		\$startcol = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1;
		".$joinedTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c);
";

						$lfMap = $fk->getLocalForeignMapping();
						foreach ($fk->getLocalColumns() as $columnName ) {
							$column = $table->getColumn($columnName);
							$columnFk = $joinTable->getColumn( $lfMap[$columnName] );
							$script .= "
		\$c->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk).");"; //CHECKME
						}
						$script .= "
		\$rs = ".$this->basePeerClassname."::doSelect(\$c, \$con);
		\$results = array();

		while(\$rs->next()) {
";
						if ($table->getChildrenColumn()) {
							$script .= "
			\$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1);
";
						} else {
							$script .= "
			\$omClass = ".$this->getPeerClassname()."::getOMClass();
";
						}
						$script .= "
			\$cls = Propel::import(\$omClass);
			\$obj1 = new \$cls();
			\$obj1->hydrate(\$rs);
";
						if ($joinTable->getChildrenColumn()) {
							$script .= "
			\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol);
";
						} else {
							$script .= "
			\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass();
";
						}

						$script .= "
			\$cls = Propel::import(\$omClass);
			\$obj2 = new \$cls();
			\$obj2->hydrate(\$rs, \$startcol);

			\$newObject = true;
			foreach(\$results as \$temp_obj1) {
				\$temp_obj2 = \$temp_obj1->get".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(); //CHECKME
				if (\$temp_obj2->getPrimaryKey() === \$obj2->getPrimaryKey()) {
					\$newObject = false;
					// e.g. \$author->addBookRelatedByBookId()
					\$temp_obj2->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); //CHECKME
					break;
				}
			}
			if (\$newObject) {
				\$obj2->init".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = true)."();
				\$obj2->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); //CHECKME
			}
			\$results[] = \$obj1;
		}
		return \$results;
	}
";
					} // if fk table name != this table name
				} // if ! is reference only
			} // foreach column
		} // if count(fk) > 1

	} // addDoSelectJoin()

	/**
	 * Adds the doCountJoin*() methods.
	 * @param      string &$script The script will be modified in this method.
	 */
	protected function addDoCountJoin(&$script)
	{
		$table = $this->getTable();
		$className = $table->getPhpName();
		$countFK = count($table->getForeignKeys());

		if ($countFK >= 1) {

			foreach ($table->getForeignKeys() as $fk) {

				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());

				if (!$joinTable->isForReferenceOnly()) {

					if ( $fk->getForeignTableName() != $table->getName() ) {

						$joinClassName = $joinTable->getPhpName();

						$thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
						$joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable);
						$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

						$script .= "

	/**
	 * Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table
	 *
	 * @param      Criteria \$c
	 * @param      boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria).
	 * @param      Connection \$con
	 * @return     int Number of matching rows.
	 */
	public static function doCountJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, \$con = null)
	{
		// we're going to modify criteria, so copy it first
		\$criteria = clone \$criteria;

		// clear out anything that might confuse the ORDER BY clause
		\$criteria->clearSelectColumns()->clearOrderByColumns();
		if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
			\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT);
		} else {
			\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT);
		}

		// just in case we're grouping: add those columns to the select statement
		foreach(\$criteria->getGroupByColumns() as \$column)
		{
			\$criteria->addSelectColumn(\$column);
		}
";
						$lfMap = $fk->getLocalForeignMapping();
						foreach ($fk->getLocalColumns() as $columnName ) {
							$column = $table->getColumn($columnName);
							$columnFk = $joinTable->getColumn( $lfMap[$columnName] );
							$script .= "
		\$criteria->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk).");
";
						}
						$script .= "
		\$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con);
		if (\$rs->next()) {
			return \$rs->getInt(1);
		} else {
			// no rows returned; we infer that means 0 matches.
			return 0;
		}
	}
";
					} // if fk table name != this table name
				} // if ! is reference only
			} // foreach column
		} // if count(fk) > 1

	} // addDoCountJoin()

	/**
	 * Adds the doSelectJoinAll() method.
	 * @param      string &$script The script will be modified in this method.
	 */
	protected function addDoSelectJoinAll(&$script)
	{
		$table = $this->getTable();
		$className = $table->getPhpName();

		$script .= "

	/**
	 * Selects a collection of $className objects pre-filled with all related objects.
	 *
	 * @return     array Array of $className objects.
	 * @throws     PropelException Any exceptions caught during processing will be
	 *		 rethrown wrapped into a PropelException.
	 */
	public static function doSelectJoinAll(Criteria \$c, \$con = null)
	{
		\$c = clone \$c;

		// Set the correct dbName if it has not been overridden
		if (\$c->getDbName() == Propel::getDefaultDB()) {
			\$c->setDbName(self::DATABASE_NAME);
		}

		".$this->getPeerClassname()."::addSelectColumns(\$c);
		\$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1;
";
		$index = 2;
		foreach ($table->getForeignKeys() as $fk) {
			// want to cover this case, but the code is not there yet.
			// FIXME: why "is the code not there yet" ?
			if ( $fk->getForeignTableName() != $table->getName() ) {
				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
				$joinClassName = $joinTable->getPhpName();
				$new_index = $index + 1;

				$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

				$script .= "
		".$joinedTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c);
		\$startcol$new_index = \$startcol$index + ".$joinedTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS;
";
			$index = $new_index;

			} // if fk->getForeignTableName != table->getName
		} // foreach [sub] foreign keys


		foreach ($table->getForeignKeys() as $fk) {
			// want to cover this case, but the code is not there yet.
			if ( $fk->getForeignTableName() != $table->getName() ) {
				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
				$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

				$joinClassName = $joinTable->getPhpName();
				$lfMap = $fk->getLocalForeignMapping();
				foreach ($fk->getLocalColumns() as $columnName ) {
					$column = $table->getColumn($columnName);
					$columnFk = $joinTable->getColumn( $lfMap[$columnName]);
					$script .= "
		\$c->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk).");
";
	  			}
			}
		}

		$script .= "
		\$rs = ".$this->basePeerClassname."::doSelect(\$c, \$con);
		\$results = array();

		while(\$rs->next()) {
";

		if ($table->getChildrenColumn()) {
			$script .= "
			\$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1);
";
		} else {
			$script .= "
			\$omClass = ".$this->getPeerClassname()."::getOMClass();
";
		}

		$script .= "

			\$cls = Propel::import(\$omClass);
			\$obj1 = new \$cls();
			\$obj1->hydrate(\$rs);
";

		$index = 1;
		foreach ($table->getForeignKeys() as $fk ) {

			// want to cover this case, but the code is not there yet.
			// FIXME -- why not? -because we'd have to alias the tables in the JOIN
			if ( $fk->getForeignTableName() != $table->getName() ) {

				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
				$joinClassName = $joinTable->getPhpName();
				$interfaceName = $joinTable->getPhpName();
				if($joinTable->getInterface()) {
					$interfaceName = $joinTable->getInterface();
				}

				/*
				$partJoinName = "";
				foreach ($fk->getLocalColumns() as $columnName ) {
					$column = $table->getColumn($columnName);
					if ($column->isMultipleFK()) {
						$partJoinName .= $column->getPhpName();
					}
				}

				if ($partJoinName == "") {
					$joinString = $interfaceName;
					$collThisTable = "${className}s";
					$collThisTableMs = $className;
				} else {
					$joinString= $interfaceName."RelatedBy" . $partJoinName;
					$collThisTable= $className . "sRelatedBy" . $partJoinName;
					$collThisTableMs= $className . "RelatedBy" . $partJoinName;
				}
				*/

				$thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
				$joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable);
				$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);


				$index++;

				$script .= "

				// Add objects for joined $joinClassName rows
	";
				if ($joinTable->getChildrenColumn()) {
					$script .= "
			\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol$index);
";
				} else {
					$script .= "
			\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass();
";
				} /* $joinTable->getChildrenColumn() */

				$script .= "

			\$cls = Propel::import(\$omClass);
			\$obj".$index." = new \$cls();
			\$obj".$index."->hydrate(\$rs, \$startcol$index);

			\$newObject = true;
			for (\$j=0, \$resCount=count(\$results); \$j < \$resCount; \$j++) {
				\$temp_obj1 = \$results[\$j];
				\$temp_obj$index = \$temp_obj1->get".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(); // CHECKME
				if (\$temp_obj".$index."->getPrimaryKey() === \$obj".$index."->getPrimaryKey()) {
					\$newObject = false;
					\$temp_obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1); // CHECKME
					break;
				}
			}

			if (\$newObject) {
				\$obj".$index."->init".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = true)."();
				\$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1);
			}
";

			} // $fk->getForeignTableName() != $table->getName()
		} //foreach foreign key

		$script .= "
			\$results[] = \$obj1;
		}
		return \$results;
	}
";

	} // end addDoSelectJoinAll()

	/**
	 * Adds the doCountJoinAll() method.
	 * @param      string &$script The script will be modified in this method.
	 */
	protected function addDoCountJoinAll(&$script)
	{
		$table = $this->getTable();
		$className = $table->getPhpName();

		$script .= "

	/**
	 * Returns the number of rows matching criteria, joining all related tables
	 *
	 * @param      Criteria \$c
	 * @param      boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria).
	 * @param      Connection \$con
	 * @return     int Number of matching rows.
	 */
	public static function doCountJoinAll(Criteria \$criteria, \$distinct = false, \$con = null)
	{
		\$criteria = clone \$criteria;

		// clear out anything that might confuse the ORDER BY clause
		\$criteria->clearSelectColumns()->clearOrderByColumns();
		if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
			\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT);
		} else {
			\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT);
		}

		// just in case we're grouping: add those columns to the select statement
		foreach(\$criteria->getGroupByColumns() as \$column)
		{
			\$criteria->addSelectColumn(\$column);
		}
";

		foreach ($table->getForeignKeys() as $fk) {
			// want to cover this case, but the code is not there yet.
			if ( $fk->getForeignTableName() != $table->getName() ) {
				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
				$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

				$joinClassName = $joinTable->getPhpName();
				$lfMap = $fk->getLocalForeignMapping();
				foreach ($fk->getLocalColumns() as $columnName ) {
					$column = $table->getColumn($columnName);
					$columnFk = $joinTable->getColumn( $lfMap[$columnName]);
					$script .= "
		\$criteria->addJoin(".$this->getColumnConstant($column).", ".$joinedTablePeerBuilder->getColumnConstant($columnFk).");
";
				}
			} // if fk->getForeignTableName != table->getName
		} // foreach [sub] foreign keys

		$script .= "
		\$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con);
		if (\$rs->next()) {
			return \$rs->getInt(1);
		} else {
			// no rows returned; we infer that means 0 matches.
			return 0;
		}
	}
";
	} // end addDoCountJoinAll()

	/**
	 * Adds the doSelectJoinAllExcept*() methods.
	 * @param      string &$script The script will be modified in this method.
	 */
	protected function addDoSelectJoinAllExcept(&$script)
	{
		$table = $this->getTable();

		// ------------------------------------------------------------------------
		// doSelectJoinAllExcept*()
		// ------------------------------------------------------------------------

		// 2) create a bunch of doSelectJoinAllExcept*() methods
		// -- these were existing in original Torque, so we should keep them for compatibility

		$fkeys = $table->getForeignKeys();  // this sep assignment is necessary otherwise sub-loops over
											// getForeignKeys() will cause this to only execute one time.
		foreach ($fkeys as $fk ) {

			$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());

			$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
			$excludedClassName = $excludedTable->getPhpName();

			/*
			$relatedByCol = "";
			foreach ($fk->getLocalColumns() as $columnName) {
				$column = $table->getColumn($columnName);
				if ($column->isMultipleFK()) {
					$relatedByCol .= $column->getPhpName();
				}
			}

			if ($relatedByCol == "") {
				$excludeString = $excludedClassName;
				$collThisTable = "${className}s";
				$collThisTableMs = $className;
			} else {
				$excludeString = $excludedClassName . "RelatedBy" . $relatedByCol;
				$collThisTable = $className . "sRelatedBy" . $relatedByCol;
				$collThisTableMs = $className . "RelatedBy" . $relatedByCol;
			}
			*/

			$thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
			$excludedTableObjectBuilder = OMBuilder::getNewObjectBuilder($excludedTable);
			$excludedTablePeerBuilder = OMBuilder::getNewPeerBuilder($excludedTable);

		$script .= "

	/**
	 * Selects a collection of ".$table->getPhpName()." objects pre-filled with all related objects except ".$thisTableObjectBuilder->getFKPhpNameAffix($fk).".
	 *
	 * @return     array Array of ".$table->getPhpName()." objects.
	 * @throws     PropelException Any exceptions caught during processing will be
	 *		 rethrown wrapped into a PropelException.
	 */
	public static function doSelectJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$c, \$con = null)
	{
		\$c = clone \$c;

		// Set the correct dbName if it has not been overridden
		// \$c->getDbName() will return the same object if not set to another value
		// so == check is okay and faster
		if (\$c->getDbName() == Propel::getDefaultDB()) {
			\$c->setDbName(self::DATABASE_NAME);
		}

		".$this->getPeerClassname()."::addSelectColumns(\$c);
		\$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1;
";
			$index = 2;
			foreach ($table->getForeignKeys() as $subfk) {
				// want to cover this case, but the code is not there yet.
				// FIXME - why not?
				if ( !($subfk->getForeignTableName() == $table->getName())) {
					$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
					$joinClassName = $joinTable->getPhpName();
					$joinTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

					if ($joinClassName != $excludedClassName) {
						$new_index = $index + 1;
						$script .= "
		".$joinTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c);
		\$startcol$new_index = \$startcol$index + ".$joinTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS;
";
					$index = $new_index;
					} // if joinClassName not excludeClassName
				} // if subfk is not curr table
			} // foreach [sub] foreign keys

			foreach ($table->getForeignKeys() as $subfk) {
				// want to cover this case, but the code is not there yet.
				if ( $subfk->getForeignTableName() != $table->getName() ) {
					$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
					$joinClassName = $joinTable->getPhpName();
					$joinTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

					if($joinClassName != $excludedClassName)
					{
						$lfMap = $subfk->getLocalForeignMapping();
						foreach ($subfk->getLocalColumns() as $columnName ) {
							$column = $table->getColumn($columnName);
							$columnFk = $joinTable->getColumn( $lfMap[$columnName]);
							$script .= "
		\$c->addJoin(".$this->getColumnConstant($column).", ".$joinTablePeerBuilder->getColumnConstant($columnFk).");
";
						}
					}
				}
			} // foreach fkeys
			$script .= "

		\$rs = ".$this->basePeerClassname ."::doSelect(\$c, \$con);
		\$results = array();

		while(\$rs->next()) {
";
			if ($table->getChildrenColumn()) {
				$script .= "
			\$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1);
";
			} else {
				$script .= "
			\$omClass = ".$this->getPeerClassname()."::getOMClass();
";
			}

			$script .= "
			\$cls = Propel::import(\$omClass);
			\$obj1 = new \$cls();
			\$obj1->hydrate(\$rs);
";

		$index = 1;
		foreach ($table->getForeignKeys() as $subfk ) {
		  // want to cover this case, but the code is not there yet.
		  if ( $subfk->getForeignTableName() != $table->getName() ) {

				$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
				$joinClassName = $joinTable->getPhpName();
				$interfaceName = $joinTable->getPhpName();
				if($joinTable->getInterface()) {
					$interfaceName = $joinTable->getInterface();
				}

				if ($joinClassName != $excludedClassName) {

					/*
					$partJoinName = "";
					foreach ($subfk->getLocalColumns() as $columnName ) {
						$column = $table->getColumn($columnName);
						if ($column->isMultipleFK()) {
							$partJoinName .= $column->getPhpName();
						}
					}

					if ($partJoinName == "") {
						$joinString = $interfaceName;
						$collThisTable = "${className}s";
						$collThisTableMs = $className;
					} else {
						$joinString= $interfaceName."RelatedBy" . $partJoinName;
						$collThisTable= $className . "sRelatedBy" . $partJoinName;
						$collThisTableMs= $className . "RelatedBy" . $partJoinName;
					}
					*/

					$joinedTableObjectBuilder = OMBuilder::getNewObjectBuilder($joinTable);
					$joinedTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

					$index++;

					if ($joinTable->getChildrenColumn()) {
						$script .= "
			\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol$index);
";
					} else {
						$script .= "
			\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass();
";
					} /* $joinTable->getChildrenColumn() */

					$script .= "

			\$cls = Propel::import(\$omClass);
			\$obj$index  = new \$cls();
			\$obj".$index."->hydrate(\$rs, \$startcol$index);

			\$newObject = true;
			for (\$j=0, \$resCount=count(\$results); \$j < \$resCount; \$j++) {
				\$temp_obj1 = \$results[\$j];
				\$temp_obj$index = \$temp_obj1->get".$thisTableObjectBuilder->getFKPhpNameAffix($subfk, $plural=false)."(); //CHECKME
				if (\$temp_obj".$index."->getPrimaryKey() === \$obj".$index."->getPrimaryKey()) {
					\$newObject = false;
					\$temp_obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, $plural=false)."(\$obj1);
					break;
				}
			}

			if (\$newObject) {
				\$obj".$index."->init".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, $plural=true)."();
				\$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($subfk, $plural=false)."(\$obj1);
			}
";
					} // if ($joinClassName != $excludedClassName) {
			} // $subfk->getForeignTableName() != $table->getName()
		} // foreach
		$script .= "
			\$results[] = \$obj1;
		}
		return \$results;
	}
";
		} // foreach fk

	} // addDoSelectJoinAllExcept

	/**
	 * Adds the doCountJoinAllExcept*() methods.
	 * @param      string &$script The script will be modified in this method.
	 */
	protected function addDoCountJoinAllExcept(&$script)
	{
		$table = $this->getTable();

		$fkeys = $table->getForeignKeys();  // this sep assignment is necessary otherwise sub-loops over
											// getForeignKeys() will cause this to only execute one time.
		foreach ($fkeys as $fk ) {

			$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());

			$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
			$excludedClassName = $excludedTable->getPhpName();

			$thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
			$excludedTableObjectBuilder = OMBuilder::getNewObjectBuilder($excludedTable);
			$excludedTablePeerBuilder = OMBuilder::getNewPeerBuilder($excludedTable);

		$script .= "

	/**
	 * Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table
	 *
	 * @param      Criteria \$c
	 * @param      boolean \$distinct Whether to select only distinct columns (You can also set DISTINCT modifier in Criteria).
	 * @param      Connection \$con
	 * @return     int Number of matching rows.
	 */
	public static function doCountJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, \$con = null)
	{
		// we're going to modify criteria, so copy it first
		\$criteria = clone \$criteria;

		// clear out anything that might confuse the ORDER BY clause
		\$criteria->clearSelectColumns()->clearOrderByColumns();
		if (\$distinct || in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
			\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT_DISTINCT);
		} else {
			\$criteria->addSelectColumn(".$this->getPeerClassname()."::COUNT);
		}

		// just in case we're grouping: add those columns to the select statement
		foreach(\$criteria->getGroupByColumns() as \$column)
		{
			\$criteria->addSelectColumn(\$column);
		}
";

			foreach ($table->getForeignKeys() as $subfk) {
				// want to cover this case, but the code is not there yet.
				if ( $subfk->getForeignTableName() != $table->getName() ) {
					$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
					$joinClassName = $joinTable->getPhpName();
					$joinTablePeerBuilder = OMBuilder::getNewPeerBuilder($joinTable);

					if($joinClassName != $excludedClassName)
					{
						$lfMap = $subfk->getLocalForeignMapping();
						foreach ($subfk->getLocalColumns() as $columnName ) {
							$column = $table->getColumn($columnName);
							$columnFk = $joinTable->getColumn( $lfMap[$columnName]);
							$script .= "
		\$criteria->addJoin(".$this->getColumnConstant($column).", ".$joinTablePeerBuilder->getColumnConstant($columnFk).");
";
						}
					}
				}
			} // foreach fkeys
			$script .= "
		\$rs = ".$this->getPeerClassname()."::doSelectRS(\$criteria, \$con);
		if (\$rs->next()) {
			return \$rs->getInt(1);
		} else {
			// no rows returned; we infer that means 0 matches.
			return 0;
		}
	}
";
		} // foreach fk

	} // addDoCountJoinAllExcept

} // PHP5ComplexPeerBuilder
