Merge pull request #156 from jaugustin/propel-param-converter-mapping-option
Add the mapping option for the PropelParamConverter,
This commit is contained in:
commit
64a6b0211e
|
@ -10,27 +10,75 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
|
||||
|
||||
/**
|
||||
* PropelConverter.
|
||||
* PropelParamConverter
|
||||
*
|
||||
* This convert action parameter to a Propel Object
|
||||
* there is two option for this converter:
|
||||
*
|
||||
* mapping : take an array of routeParam => column
|
||||
* exclude : take an array of routeParam to exclude from the conversion process
|
||||
*
|
||||
*
|
||||
* @author Jérémie Augustin <jeremie.augustin@pixel-cookers.com>
|
||||
*/
|
||||
class PropelParamConverter implements ParamConverterInterface
|
||||
{
|
||||
/**
|
||||
* the pk column (e.g. id)
|
||||
* @var string
|
||||
*/
|
||||
protected $pk;
|
||||
|
||||
/**
|
||||
* list of column/value to use with filterBy
|
||||
* @var array
|
||||
*/
|
||||
protected $filters = array();
|
||||
|
||||
/**
|
||||
* list of route parameters to exclude from the conversion process
|
||||
* @var array
|
||||
*/
|
||||
protected $exclude = array();
|
||||
|
||||
public function apply(Request $request, ConfigurationInterface $configuration)
|
||||
{
|
||||
$classQuery = $configuration->getClass() . 'Query';
|
||||
$classPeer = $configuration->getClass() . 'Peer';
|
||||
|
||||
if (!class_exists($classQuery)) {
|
||||
throw new \Exception(sprintf('The %s Query class does not exist', $classQuery));
|
||||
}
|
||||
|
||||
$tableMap = $classPeer::getTableMap();
|
||||
$pkColumns = $tableMap->getPrimaryKeyColumns();
|
||||
|
||||
if (count($pkColumns) == 1) {
|
||||
$this->pk = strtolower($pkColumns[0]->getName());
|
||||
}
|
||||
|
||||
$options = $configuration->getOptions();
|
||||
$exclude = isset($options['exclude'])? $options['exclude'] : array();
|
||||
|
||||
if (isset($options['mapping'])) {
|
||||
// We use the mapping for calling findPk or filterBy
|
||||
foreach ($options['mapping'] as $routeParam => $column) {
|
||||
if ($request->attributes->has($routeParam)) {
|
||||
if ($this->pk === $column) {
|
||||
$this->pk = $routeParam;
|
||||
} else {
|
||||
$this->filters[$column] = $request->attributes->get($routeParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->exclude = isset($options['exclude'])? $options['exclude'] : array();
|
||||
$this->filters = $request->attributes->all();
|
||||
}
|
||||
|
||||
// find by Pk
|
||||
if (in_array('id', $exclude) || false === $object = $this->findPk($classQuery, $request)) {
|
||||
if (false === $object = $this->findPk($classQuery, $request)) {
|
||||
// find by criteria
|
||||
if (false === $object = $this->findOneBy($classQuery, $request, $exclude)) {
|
||||
if (false === $object = $this->findOneBy($classQuery, $request)) {
|
||||
if ($configuration->isOptional()) {
|
||||
//we find nothing but the object is optional
|
||||
$object = null;
|
||||
|
@ -45,25 +93,27 @@ class PropelParamConverter implements ParamConverterInterface
|
|||
}
|
||||
|
||||
$request->attributes->set($configuration->getName(), $object);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function findPk($classQuery, Request $request)
|
||||
{
|
||||
if (!$request->attributes->has('id')) {
|
||||
if (in_array($this->pk, $this->exclude) || !$request->attributes->has($this->pk)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $classQuery::create()->findPk($request->attributes->get('id'));
|
||||
return $classQuery::create()->findPk($request->attributes->get($this->pk));
|
||||
}
|
||||
|
||||
protected function findOneBy($classQuery, Request $request, $exclude)
|
||||
protected function findOneBy($classQuery, Request $request)
|
||||
{
|
||||
$query = $classQuery::create();
|
||||
$hasCriteria = false;
|
||||
foreach ($request->attributes->all() as $key => $value) {
|
||||
if (!in_array($key, $exclude)) {
|
||||
foreach ($this->filters as $column => $value) {
|
||||
if (!in_array($column, $this->exclude)) {
|
||||
try {
|
||||
$query->{'filterBy' . PropelInflector::camelize($key)}($value);
|
||||
$query->{'filterBy' . PropelInflector::camelize($column)}($value);
|
||||
$hasCriteria = true;
|
||||
} catch (\PropelException $e) { }
|
||||
}
|
||||
|
|
|
@ -45,5 +45,23 @@ public function myAction(Post $post)
|
|||
}
|
||||
```
|
||||
|
||||
#### Custom mapping ####
|
||||
|
||||
You can map route parameters directly to model column to be use for filtering.
|
||||
|
||||
If you have a route like `/my-route/{postUniqueName}/{AuthorId}`
|
||||
Mapping option overwrite any other automatic mapping.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @ParamConverter("post", class="BlogBundle\Model\Post", options={"mapping"={"postUniqueName":"name"}})
|
||||
* @ParamConverter("author", class="BlogBundle\Model\Author", options={"mapping"={"AuthorId":"id"}})
|
||||
*/
|
||||
public function myAction(Post $post, $author)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
[Back to index](index.markdown)
|
||||
|
|
|
@ -152,4 +152,30 @@ class PropelParamConverterTest extends TestCase
|
|||
$this->assertNull($request->attributes->get('book'),
|
||||
'param "book" should be null if book is not found and the parameter is optional');
|
||||
}
|
||||
|
||||
public function testParamConverterFindWithMapping()
|
||||
{
|
||||
$paramConverter = new PropelParamConverter();
|
||||
$request = new Request(array(), array(), array('toto' => 1, 'book' => null));
|
||||
$configuration = new ParamConverter(array('class' => 'Propel\PropelBundle\Tests\Fixtures\Model\Book',
|
||||
'name' => 'book',
|
||||
'options' => array('mapping' => array('toto' => 'id'))
|
||||
));
|
||||
$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"');
|
||||
}
|
||||
|
||||
public function testParamConverterFindSlugWithMapping()
|
||||
{
|
||||
$paramConverter = new PropelParamConverter();
|
||||
$request = new Request(array(), array(), array('slugParam_special' => 'my-book', 'book' => null));
|
||||
$configuration = new ParamConverter(array('class' => 'Propel\PropelBundle\Tests\Fixtures\Model\Book',
|
||||
'name' => 'book',
|
||||
'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"');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue