Development

ApplyingCustomJoinsUsingHelper

You must first sign up to be able to contribute.

Applying custom joins using a helper class

Using the tips from ApplyingCustomJoinsInDoSelect can be painful if you found that there are a number of cases you want to apply custom joins. What if you want to add an extra join between "Book" and "Author"? So you write another similar method doJoinBookAndCategoryAndAuthor? Better not. Here offers a rather simple class to handle custom joins and relationships.

Below illustrates the same JoinBookAndCategory example, using the helper class sfPropelCustomJoinHelper.

	// Set up criteria
	$c = new Criteria();
	$c->addJoin(ArticlePeer::BOOK_ID, BookPeer::ID);
	$c->addJoin(BookPeer::CATEGORY_ID, CategoryPeer::ID);

	// Instead of calling ArticlePeer, we use a sfPropelCustomJoinHelper class
	$joinHelper = new sfPropelCustomJoinHelper('Article');

	// Tell the joiner to select fields from the following tables
	$joinHelper->addSelectTables('Book', 'Category');

	// Set up the relatoinship betweeen Book and Category.
	$joinHelper->setHas('Book', 'Category');

	$articles = $joinHelper->doSelect($c);

Then you can use the $articles array and its Article objects as if the selecting and object model getter method code have been written for you:

foreach ($articles as $article)
{
	echo $article->getTitle()."\n";
	$book = $article->getBook();
	echo $book->getName()."\n";
	$category = $book->getCategory();
	echo $category->getDescription()."\n";
}

To go in depth, sfPropelCustomJoin::doSelect() will automatically add the selecting columns (done via addSelectTables()) and set up the relationship between object classes (done via setHas()) for you.

The above seen $article, $book, and $category are not instances of Article, Book and Category. All of them are actually "proxies" to communicate with the underlying Article, Book and Category objects own by the respective instance, with one exception to return the object model when the proxy encounters an attempt to retrieve a known related model. You can retrieve the "real" object model by calling $realBook = $book->getDataObject().

Through this helper you can achieve the "JoinBookAndCategoryAndAuthor?" requirement with just a little code modification:

	$c = new Criteria();
	$c->addJoin(ArticlePeer::BOOK_ID, BookPeer::ID);
	$c->addJoin(BookPeer::CATEGORY_ID, CategoryPeer::ID);
	$c->addJoin(BookPeer::AUTHOR_ID, AuthorPeer::ID);

	$joinHelper = new sfPropelCustomJoinHelper('Article');

	$joinHelper->addSelectTables('Book', 'Category', 'Author');

	$joinHelper->setHas('Book', 'Category');
	$joinHelper->setHas('Book', 'Author');

	$articles = $joinHelper->doSelect($c);

Using a helper class with pager

By default, sfPropelPager always uses FooPeer::doSelect() once you configured it with class name "Foo", so you need to tweak its behavior by giving it a setClassPeer() method and override the original getClassPeer() method. Also you need to copy the init() method from sfPropelPager and modify it slightly:

class myPropelPager extends sfPropelPager 
{
	protected
		$classPeer  = false;

	public function getClassPeer()
	{
		if (!$this->classPeer)
			return $this->class.'Peer';
		return $this->classPeer;
	}

	public function setClassPeer($value)
	{
		$this->classPeer = $value;
	}

	public function init()
	{
		// .... copy the code from sfPropelPager::init(), and modify the following portion:

		// require the model class (because autoloading can crash under some conditions)
		if (is_string($this->getClassPeer())) //NEW
		{
			if (!$classPath = sfCore::getClassPath($this->getClassPeer()))
			{
				throw new sfException(sprintf('Unable to find path for class "%s".', $this->getClassPeer()));
			}
			require_once($classPath);
		}

		// modification end, remaining code goes below...
	}

}

Then you call $pager->setClassPeer($joinHelper); to assign the helper class to the pager.

how to give a good blow job blow jobs

Attachments