/** * Finder Fluid Interface for Criteria::addJoin() * Infers $column1, $column2 and $operator from $relatedClass and some optional arguments * Uses the Propel column maps, based on the schema, to guess the related columns * Beware that the default JOIN operator is INNER JOIN, while Criteria defaults to WHERE * Examples: * $articleFinder->join('Comment') * => $c->addJoin(ArticlePeer::ID, CommentPeer::ARTICLE_ID, Criteria::INNER_JOIN) * $articleFinder->join('Category', 'RIGHT JOIN') * => $c->addJoin(ArticlePeer::CATEGORY_ID, CategoryPeer::ID, Criteria::RIGHT_JOIN) * $articleFinder->join('Article.CategoryId', 'Category.Id', 'RIGHT JOIN') * => $c->addJoin(ArticlePeer::CATEGORY_ID, CategoryPeer::ID, Criteria::RIGHT_JOIN) * * @param string $classOrColumn Class to join if 1 argument, first column of the join otherwise * @param string $column Second column of the join if more than 1 argument * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * * @return sfPropelFinder the current finder object */ public function join() { $args = func_get_args(); switch (count($args)) { case 0: throw new Exception('sfPropelFinder::join() expects at least one argument'); break; case 1: case 2: // $articleFinder->join('Comment') // $articleFinder->join('Comment co') // $articleFinder->join('Category', 'RIGHT JOIN') // $articleFinder->join('Category ca', 'RIGHT JOIN') list($class, $alias) = self::getClassAndAlias($args[0]); $relation = $this->getRelations()->addRelationFromClass($class, $alias); if (!$relation) { // There is already a relation on this table, so skip the join return $this; } if ($alias) { $table = constant(sfPropelFinderUtils::getPeerClassFromClass($class) . '::TABLE_NAME'); $this->criteria->addAlias($alias, $table); } $operator = isset($args[1]) ? $args[1] : Criteria::INNER_JOIN; break; case 3: // $articleFinder->join('Article.CategoryId', 'Category.Id', 'RIGHT JOIN') list($column1, $column2, $operator) = $args; list($peerClass1, $column1) = $this->getColName($column1, $peerClass = null, $withPeerClass = true, $autoAddJoin = false); $class1 = sfPropelFinderUtils::getClassFromPeerClass($peerClass1); list($peerClass2, $column2) = $this->getColName($column2, $peerClass = null, $withPeerClass = true, $autoAddJoin = false); $class2 = sfPropelFinderUtils::getClassFromPeerClass($peerClass2); $relation = $this->getRelations()->addRelationFromColumns($class1, $column1, $class2, $column2); if (!$relation) { // There is already a relation on this table, so skip the join return $this; } break; case 4: // $articleFinder->join('Category cat', 'Article.CategoryId', 'cat.Id', 'RIGHT JOIN') list($classAndAlias, $column1, $column2, $operator) = $args; list($peerClass1, $column1) = $this->getColName($column1, $peerClass = null, $withPeerClass = true, $autoAddJoin = false); $class1 = sfPropelFinderUtils::getClassFromPeerClass($peerClass1); list($class2, $alias) = self::getClassAndAlias($classAndAlias); list($alias2, $phpName2) = explode('.', $column2); if ($alias != $alias2) { throw new Exception('The second join member must be a column of the aliased table'); } list($peerClass2, $column2) = sfPropelFinderUtils::getColNameUsingAlias($alias2, $phpName2, $class2, true); $table = constant($peerClass2 . '::TABLE_NAME'); $relation = $this->getRelations()->addRelationFromColumns($class1, $column1, $class2, $column2, $alias); if (!$relation) { // There is already a relation on this table, so skip the join return $this; } $this->criteria->addAlias($alias, $table); break; } $operator = trim(str_replace('JOIN', '', strtoupper($operator))) . ' JOIN'; $this->criteria->addJoin($relation->getFromColumn(), $relation->getToColumn(), $operator); return $this; }
/** * Guess the relation to another class * * @param string $phpName Propel Class name (e.g. 'Article') * * @return array A list with the two columns member of the relationship */ public function getRelation($phpName) { foreach ($this->relations as $peerClass) { // try to find many to one or one to one relationship if ($relation = $this->findRelation($phpName, $peerClass)) { return $relation; } // try to find one to many relationship if ($relation = $this->findRelation(sfPropelFinderUtils::getClassFromPeerClass($peerClass), sfPropelFinderUtils::getPeerClassFromClass($phpName))) { return array_reverse($relation); } } throw new Exception(sprintf('sfPropelFinder: %s has no %s related table', $this->peerClass, $phpName)); }