[WIP] rebase, refactor code, add tests, add doc

This commit is contained in:
jaugustin 2012-05-24 00:03:56 +02:00 committed by William DURAND
parent e1f18fbdf2
commit 1b5b18237c
3 changed files with 175 additions and 5 deletions

View file

@ -47,6 +47,8 @@ class PropelParamConverter implements ParamConverterInterface
*/
protected $withs;
protected $hasWith = false;
public function apply(Request $request, ConfigurationInterface $configuration)
{
$classQuery = $configuration->getClass() . 'Query';
@ -134,7 +136,11 @@ class PropelParamConverter implements ParamConverterInterface
return false;
}
return $this->getQuery($classQuery)->findPk($request->attributes->get($this->pk));
if (!$this->hasWith) {
return $this->getQuery($classQuery)->findPk($request->attributes->get($this->pk));
} else {
return reset($this->getQuery($classQuery)->filterByPrimaryKey($request->attributes->get($this->pk))->find());
}
}
/**
@ -161,7 +167,11 @@ class PropelParamConverter implements ParamConverterInterface
return false;
}
return $query->findOne();
if (!$this->hasWith) {
return $query->findOne();
} else {
return reset($query->find());
}
}
/**
@ -178,6 +188,7 @@ class PropelParamConverter implements ParamConverterInterface
if (is_array($with)) {
if (2 == count($with)) {
$query->joinWith($with[0], $this->getValidJoin($with));
$this->hasWith = true;
} else {
throw new \Exception(sprintf('ParamConverter : "with" parameter "%s" is invalid,
only string relation name (e.g. "Book") or an array with two keys (e.g. {"Book", "LEFT_JOIN"}) are allowed',
@ -185,6 +196,7 @@ class PropelParamConverter implements ParamConverterInterface
}
} else {
$query->joinWith($with);
$this->hasWith = true;
}
}
@ -199,7 +211,7 @@ class PropelParamConverter implements ParamConverterInterface
*/
protected function getValidJoin($with)
{
switch (str_replace(array('_', 'JOIN'),'', strtoupper($with[1]))) {
switch (trim(str_replace(array('_', 'JOIN'), '', strtoupper($with[1])))) {
case 'LEFT':
return \Criteria::LEFT_JOIN;
case 'RIGHT':

View file

@ -64,4 +64,39 @@ public function myAction(Post $post, $author)
}
```
#### Hydrate related object ####
You could hydrate related object with the "with" option:
``` php
<?php
/**
* @ParamConverter("post", class="BlogBundle\Model\Post", options={"with"={"Comments"}})
*/
public function myAction(Post $post)
{
}
```
You can set multiple with ```"with"={"Comments", "Author", "RelatedPosts"}```.
The default join is an "inner join" but you can configure it to be a left join, right join or inner join :
``` php
<?php
/**
* @ParamConverter("post", class="BlogBundle\Model\Post", options={"with"={ {"Comments", "left join" } }})
*/
public function myAction(Post $post)
{
}
```
Accepted parmeters for join :
left, LEFT, left join, LEFT JOIN, left_join, LEFT_JOIN
right, RIGHT, right join, RIGHT JOIN, right_join, RIGHT_JOIN
inner, INNER, inner join, INNER JOIN, inner_join, INNER_JOIN
[Back to index](index.markdown)

View file

@ -12,6 +12,8 @@ use Propel\PropelBundle\Tests\TestCase;
class PropelParamConverterTest extends TestCase
{
protected $con;
public function setUp()
{
parent::setUp();
@ -20,6 +22,14 @@ class PropelParamConverterTest extends TestCase
}
}
public function tearDown()
{
\Propel::enableInstancePooling();
if ($this->con) {
$this->con->useDebug(false);
}
}
public function testParamConverterSupport()
{
$paramConverter = new PropelParamConverter();
@ -175,7 +185,120 @@ class PropelParamConverterTest extends TestCase
'options' => array('mapping' => array('slugParam_special' => 'slug'))
));
$paramConverter->apply($request, $configuration);
$this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\Model\Book',$request->attributes->get('book'),
'param "book" should be an instance of "Propel\PropelBundle\Tests\Fixtures\Model\Book"');
$this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\Model\Book',$request->attributes->get('book'),
'param "book" should be an instance of "Propel\PropelBundle\Tests\Fixtures\Model\Book"');
}
public function testParamConvertWithOptionWith()
{
$this->loadFixture();
\Propel::disableInstancePooling();
$paramConverter = new PropelParamConverter();
$request = new Request(array(), array(), array('id' => 1, 'book' => null));
$configuration = new ParamConverter(array(
'class' => 'Propel\PropelBundle\Tests\Request\ParamConverter\MyBook',
'name' => 'book',
'options' => array(
'with' => 'MyAuthor'
)
));
$nb = $this->con->getQueryCount();
$paramConverter->apply($request, $configuration);
$book = $request->attributes->get('book');
$this->assertInstanceOf('Propel\PropelBundle\Tests\Request\ParamConverter\MyBook', $book,
'param "book" should be an instance of "Propel\PropelBundle\Tests\Request\ParamConverter\MyBook"');
$this->assertEquals($nb +1, $this->con->getQueryCount(), 'only one query to get the book');
$this->assertInstanceOf('Propel\PropelBundle\Tests\Request\ParamConverter\MyAuthor', $book->getMyAuthor(),
'param "book" should be an instance of "Propel\PropelBundle\Tests\Request\ParamConverter\MyAuthor"');
$this->assertEquals($nb +1, $this->con->getQueryCount(), 'no new query to get the author');
\Propel::enableInstancePooling();
}
public function testParamConvertWithOptionWithLeftJoin()
{
$this->loadFixture();
\Propel::disableInstancePooling();
$paramConverter = new PropelParamConverter();
$request = new Request(array(), array(), array('param1' => 10, 'author' => null));
$configuration = new ParamConverter(array(
'class' => 'Propel\PropelBundle\Tests\Request\ParamConverter\MyAuthor',
'name' => 'author',
'options' => array(
'with' => array(array('MyBook', 'left join')),
'mapping' => array('param1' => 'id'),
)
));
$nb = $this->con->getQueryCount();
$paramConverter->apply($request, $configuration);
$author = $request->attributes->get('author');
$this->assertInstanceOf('Propel\PropelBundle\Tests\Request\ParamConverter\MyAuthor', $author,
'param "author" should be an instance of "Propel\PropelBundle\Tests\Request\ParamConverter\MyAuthor"');
$this->assertEquals($nb +1, $this->con->getQueryCount(), 'only one query to get the book');
$books = $author->getMyBooks();
$this->assertInstanceOf('PropelObjectCollection', $books);
$this->assertCount(2, $books, 'Author should have two books');
$this->assertEquals($nb +1, $this->con->getQueryCount(), 'no new query to get the books');
}
protected function loadFixture()
{
$this->loadPropelQuickBuilder();
$schema = <<<XML
<database name="default" package="vendor.bundles.Propel.PropelBundle.Tests.Request.DataFixtures.Loader" namespace="Propel\PropelBundle\Tests\Request\ParamConverter" defaultIdMethod="native">
<table name="my_book">
<column name="id" type="integer" primaryKey="true" />
<column name="name" type="varchar" size="255" />
<column name="my_author_id" type="integer" />
<foreign-key foreignTable="my_author" onDelete="CASCADE" onUpdate="CASCADE">
<reference local="my_author_id" foreign="id" />
</foreign-key>
</table>
<table name="my_author">
<column name="id" type="integer" primaryKey="true" />
<column name="name" type="varchar" size="255" />
</table>
</database>
XML;
$builder = new \PropelQuickBuilder();
$builder->setSchema($schema);
if (class_exists('Propel\PropelBundle\Tests\Request\ParamConverter\MyAuthor')) {
$builder->setClassTargets(array());
}
$this->con = $builder->build();
$this->con->useDebug(true);
MyBookQuery::create()->deleteAll($this->con);
MyAuthorQuery::create()->deleteAll($this->con);
$author = new MyAuthor();
$author->setId(10);
$author->setName('Will');
$book = new MyBook();
$book->setId(1);
$book->setName('PropelBook');
$book->setMyAuthor($author);
$book2 = new MyBook();
$book2->setId(2);
$book2->setName('sf2lBook');
$book2->setMyAuthor($author);
$author->save($this->con);
}
}