Changeset 10132
- Timestamp:
- 07/05/08 11:34:47 (5 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/sfPropelFinderPlugin/lib/sfPropelFinder.php
r10123 r10132 258 258 $this->criteria->setLimit($limit); 259 259 } 260 $ret = $this->doFind($ this->getCriteria(), $con);260 $ret = $this->doFind($con); 261 261 $this->updateLatestQuery($con); 262 262 if($reinitCriteria) … … 271 271 { 272 272 $this->criteria->setLimit(1); 273 $ret = $this->doFind($ this->getCriteria(), $con);273 $ret = $this->doFind($con); 274 274 $this->updateLatestQuery($con); 275 275 if($reinitCriteria) … … 455 455 } 456 456 457 public function doFind($criteria, $con = null) 458 { 457 public function doFind($con = null) 458 { 459 $this->addMissingJoins(); 459 460 if($this->getWithClasses() || $this->getWithColumns()) 460 461 { 461 $c = $this->prepareCompositeCriteria( $criteria);462 $c = $this->prepareCompositeCriteria(); 462 463 if(method_exists($this->getPeerClass(), 'doSelectRS')) 463 464 { … … 527 528 } 528 529 } 529 sfPropelFinderUtils::relateObjects($withObj, $objectsInJoin, $isNewObject); 530 if(strpos(get_class($withObj), 'I18n') !== false) 531 { 532 sfPropelFinderUtils::relateI18nObjects($withObj, $objectsInJoin, $this->culture); 533 } 534 else 535 { 536 sfPropelFinderUtils::relateObjects($withObj, $objectsInJoin, $isNewObject); 537 } 530 538 $objectsInJoin []= $withObj; 531 539 if ($isNewObject) … … 566 574 { 567 575 // No 'with', so we use the native Propel doSelect() 568 return call_user_func(array($this->getPeerClass(), 'doSelect'), $criteria, $con); 569 } 576 return call_user_func(array($this->getPeerClass(), 'doSelect'), $this->buildCriteria(), $con); 577 } 578 } 579 580 /** 581 * Adds missing Joins from with() and withColumn() 582 */ 583 protected function addMissingJoins() 584 { 585 foreach ($this->getWithClasses() as $className) 586 { 587 if(!in_array(sfPropelFinderUtils::getPeerClassFromClass($className), $this->relations)) 588 { 589 $this->join($className); 590 } 591 } 592 foreach($this->getWithColumns() as $alias => $column) 593 { 594 $peerClass = $column['peerClass']; 595 if($peerClass && !in_array($peerClass, $this->relations)) 596 { 597 $this->join(sfPropelFinderUtils::getClassFromPeerClass($peerClass)); 598 } 599 } 600 601 return $this; 570 602 } 571 603 … … 573 605 * Prepare the select columns and add the missing joins 574 606 */ 575 protected function prepareCompositeCriteria($criteria) 576 { 607 protected function prepareCompositeCriteria() 608 { 609 $criteria = $this->buildCriteria(); 577 610 $c = clone $criteria; 578 611 $c->clearSelectColumns(); … … 582 615 foreach ($this->getWithClasses() as $className) 583 616 { 584 $tempClass = new $className(); 585 call_user_func(array($tempClass->getPeer(), 'addSelectColumns'), $c); 586 // if join() wasn't called previously on this class, do a simple join 587 if(!in_array(sfPropelFinderUtils::getPeerClassFromClass($className), $this->relations)) 588 { 589 list($column1, $column2) = $this->getRelation($className); 590 $c->addJoin($column1, $column2); 591 $this->relations[]= sfPropelFinderUtils::getPeerClassFromClass($className); 592 } 617 call_user_func(array(sfPropelFinderUtils::getPeerClassFromClass($className), 'addSelectColumns'), $c); 593 618 } 594 619 // Then the columns added one by one by way of 'withColumn' 595 620 foreach($this->getWithColumns() as $alias => $column) 596 621 { 597 // if the column is on a related object property598 // and if join() wasn't called previously on this object, do a simple join599 $peerClass = $column['peerClass'];600 if($peerClass && !in_array($peerClass, $this->relations))601 {602 list($column1, $column2) = $this->getRelation(sfPropelFinderUtils::getClassFromPeerClass($peerClass));603 $c->addJoin($column1, $column2);604 $this->relations[]= $peerClass;605 }606 622 $c->addAsColumn('\''.$alias.'\'', $column['column']); 607 623 } … … 636 652 { 637 653 $i18nClass = $this->class.'I18n'; 638 $tmp = new $i18nClass(); 639 $i18nPeerClass = get_class($tmp->getPeer()); 640 if(is_null($culture)) $culture = sfContext::getInstance()->getUser()->getCulture(); 641 $this->addWithClass($this->class.'I18n'); 642 $this->criteria->add(constant($i18nPeerClass.'::CULTURE'), $culture); 643 $this->culture = $culture; 654 $this->addWithClass($i18nClass); 655 $this->culture = is_null($culture) ? sfContext::getInstance()->getUser()->getCulture() : $culture; 656 $this->criteria->add(constant(sfPropelFinderUtils::getPeerClassFromClass($i18nClass).'::CULTURE'), $this->culture); 644 657 645 658 return $this; plugins/sfPropelFinderPlugin/lib/sfPropelFinderUtils.php
r10118 r10132 25 25 } 26 26 call_user_func(array($new, $methodName), $existingObject); 27 break; 28 } 29 } 30 } 31 32 public static function relateI18nObjects($new, $existingObjects, $culture) 33 { 34 // brute force (to be optimized later) 35 foreach ($existingObjects as $existingObject) 36 { 37 $methodName = 'set'.get_class($new).'ForCulture'; 38 if(method_exists($existingObject, $methodName)) 39 { 40 call_user_func(array($existingObject, $methodName), $new, $culture); 41 call_user_func(array($new, 'set'.get_class($existingObject)), $existingObject); 27 42 break; 28 43 } plugins/sfPropelFinderPlugin/test/unit/sfPropelFinderRelationsTest.php
r10122 r10132 79 79 $con = Propel::getConnection(); 80 80 81 $t = new lime_test(7 1, new lime_output_color());81 $t = new lime_test(72, new lime_output_color()); 82 82 83 83 $t->diag('findRelation()'); … … 274 274 $article1->setCategory($category1); 275 275 $article1->save(); 276 $sql = 'SELECT article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article, category WHERE article.CATEGORY_ID=category.ID LIMIT 1'; 276 277 $finder = sfPropelFinder::from('Article')->join('Category')->with('Category'); 277 278 $article = $finder->findOne(); 278 $sql = 'SELECT article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, category.ID, category.NAME FROM article, category WHERE article.CATEGORY_ID=category.ID LIMIT 1';279 279 $t->is($finder->getLatestQuery(), $sql, 'with() gets the columns of the with class in addition to the columns of the current class'); 280 $article->getCategory(); 281 $t->is(Propel::getConnection()->getLastExecutedQuery(), $sql, 'with() hydrates the related classes and avoids subsequent queries'); 282 280 283 $finder = sfPropelFinder::from('Article')->with('Category'); 281 284 $article = $finder->findOne(); 282 285 $t->is($finder->getLatestQuery(), $sql, 'with() adds a join if not already added'); 283 286 $t->is($article->getTitle(), 'aaaaa', 'fetching objects with a with() returns the correct main object'); 284 $category = $article->getCategory(); 285 $t->is($category->getName(), 'cat1', 'fetching objects with a with() returns the correct related object'); 286 $con = Propel::getConnection(); 287 $latestQuery = $con->getLastExecutedQuery(); 288 $t->is($latestQuery, $sql, 'calling a FK getter on an object hydrated with with() does not issue a new query'); 287 $t->is($article->getCategory()->getName(), 'cat1', 'fetching objects with a with() returns the correct related object'); 288 $t->is(Propel::getConnection()->getLastExecutedQuery(), $sql, 'with() called without a join() hydrates the related classes and avoids subsequent queries'); 289 289 290 290 ArticlePeer::doDeleteAll(); … … 305 305 $finder = sfPropelFinder::from('Comment')->with('Article')->with('Author'); 306 306 $comment = $finder->findOne(); 307 $sql = 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, author.ID, author.NAME FROM comment, article, author WHERE comment.ARTICLE_ID=article.ID AND comment.AUTHOR_ID=author.ID LIMIT 1'; 308 $t->is($finder->getLatestQuery(), $sql, 'you can call with() several times to hydrate more than one related object'); 307 309 $t->is($comment->getContent(), 'foo', 'you can call with() several times to hydrate more than one related object'); 308 310 $t->is($comment->getArticle()->getTitle(), 'bbbbb', 'you can call with() several times to hydrate more than one related object'); 309 311 $t->is($comment->getAuthor()->getName(), 'John', 'you can call with() several times to hydrate more than one related object'); 310 $t->is( $finder->getLatestQuery(), 'SELECT comment.ID, comment.CONTENT, comment.ARTICLE_ID, comment.AUTHOR_ID, article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, author.ID, author.NAME FROM comment, article, author WHERE comment.ARTICLE_ID=article.ID AND comment.AUTHOR_ID=author.ID LIMIT 1', 'you can call with() several times to hydrate more than one related object');312 $t->is(Propel::getConnection()->getLastExecutedQuery(), $sql, 'with() called several tims hydrates the related classes and avoids subsequent queries'); 311 313 312 314 $finder = sfPropelFinder::from('Comment')->with('Article')->with('Category'); … … 333 335 $finder = sfPropelFinder::from('Article')->withI18n(); 334 336 $article = $finder->findOne(); 335 336 $t->is($ finder->getLatestQuery(), 'SELECT article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article, article_i18n WHERE article_i18n.CULTURE=\'en\' AND article.ID=article_i18n.ID LIMIT 1', 'withI18n() hydrates the related I18n object with a culture taken from the user object');337 $query = $finder->getLatestQuery(); 338 $t->is($query, 'SELECT article.ID, article.VERSION, article.TITLE, article.CATEGORY_ID, article_i18n.CONTENT, article_i18n.ID, article_i18n.CULTURE FROM article, article_i18n WHERE article_i18n.CULTURE=\'en\' AND article.ID=article_i18n.ID LIMIT 1', 'withI18n() hydrates the related I18n object with a culture taken from the user object'); 337 339 $t->is($article->getContent(), 'english content', 'withI18n() considers the current user culture for hydration'); 340 $t->is(Propel::getConnection()->getLastExecutedQuery(), $query, 'withI18n() hydrates the i18n object so that no further query is necessary'); 338 341 339 342 sfContext::getInstance()->getUser()->setCulture('fr');