Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #156 from jaugustin/propel-param-converter-mapping…

…-option

Add the mapping option for the PropelParamConverter,
  • Loading branch information...
commit 64a6b0211e760841719233a375e92c24c40797b4 2 parents f675e39 + b03f6a5
@willdurand willdurand authored
View
70 Request/ParamConverter/PropelParamConverter.php
@@ -10,27 +10,75 @@
/**
- * 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 @@ public function apply(Request $request, ConfigurationInterface $configuration)
}
$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) { }
}
View
18 Resources/doc/param_converter.markdown
@@ -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)
View
26 Tests/Request/ParamConverter/PropelParamConverterTest.php
@@ -152,4 +152,30 @@ public function testParamConverterFindWithOptionalParam()
$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"');
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.