Skip to content

Commit

Permalink
Merge pull request #26 from bpolaszek/master
Browse files Browse the repository at this point in the history
Added complex route parameters functionnality
  • Loading branch information
Petit Yoann committed Dec 16, 2015
2 parents 6f98e81 + 6d1044c commit 20754d5
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 12 deletions.
99 changes: 87 additions & 12 deletions BreadcrumbTrail/Trail.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,47 @@ public function add($breadcrumb_or_title, $routeName = null, $routeParameters =
$request = $this->container->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE);

if ($request !== null) {
preg_match_all('#\{(?P<variable>\w+).?(?P<function>\w*):?(?P<parameters>(\w|,| )*)\}#', $breadcrumb_or_title, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
preg_match_all('#\{(?P<variable>\w+).?(?P<function>([\w\.])*):?(?P<parameters>(\w|,| )*)\}#', $breadcrumb_or_title, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);

foreach ($matches as $match) {
$varName = $match['variable'][0];
$functionName = $match['function'][0];
$parameters = explode(',', $match['parameters'][0]);
$varName = $match['variable'][0];
$functions = $match['function'][0] ? explode('.', $match['function'][0]) : array();
$parameters = $match['parameters'][0] ? explode(',', $match['parameters'][0]) : array();
$nbCalls = count($functions);

if($request->attributes->has($varName)) {
$object = $request->attributes->get($varName);

if(empty($functionName)) {
if(empty($functions)) {
$objectValue = (string) $object;
}
elseif(is_callable(array($object, $fullFunctionName = 'get'.$functionName))
|| is_callable(array($object, $fullFunctionName = 'has'.$functionName))
|| is_callable(array($object, $fullFunctionName = 'is'.$functionName))) {
$objectValue = call_user_func_array(array($object, $fullFunctionName),$parameters);
}
else {
throw new \RuntimeException(sprintf('Function "%s" not found.', $functionName));
foreach ($functions AS $f => $function) {

# While this is not the last function, call the chain
if ($f < $nbCalls - 1) {
if(is_callable(array($object, $fullFunctionName = 'get'.$function))
|| is_callable(array($object, $fullFunctionName = 'has'.$function))
|| is_callable(array($object, $fullFunctionName = 'is'.$function))) {
$object = call_user_func(array($object, $fullFunctionName));
}
else {
throw new \RuntimeException(sprintf('"%s" is not callable.', join('.', array_merge([$varName], $functions))));
}
}

# End of the chain: call the method
else {
if(is_callable(array($object, $fullFunctionName = 'get'.$function))
|| is_callable(array($object, $fullFunctionName = 'has'.$function))
|| is_callable(array($object, $fullFunctionName = 'is'.$function))) {
$objectValue = call_user_func_array(array($object, $fullFunctionName),$parameters);
}
else {
throw new \RuntimeException(sprintf('"%s" is not callable.', join('.', array_merge([$varName], $functions))));
}
}
}
}

$breadcrumb_or_title = str_replace($match[0][0], $objectValue, $breadcrumb_or_title);
Expand All @@ -119,7 +141,60 @@ public function add($breadcrumb_or_title, $routeName = null, $routeParameters =
$routeParameters[$value] = $request->get($value);
unset($routeParameters[$key]);
} else {
if (preg_match('#^\{(?P<parameter>\w+)\}$#', $value, $matches)) {
if (preg_match_all('#\{(?P<variable>\w+).?(?P<function>([\w\.])*):?(?P<parameters>(\w|,| )*)\}#', $value, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {

foreach ($matches AS $match) {

$varName = $match['variable'][0];
$functions = $match['function'][0] ? explode('.', $match['function'][0]) : array();
$parameters = $match['parameters'][0] ? explode(',', $match['parameters'][0]) : array();
$nbCalls = count($functions);

if ($request->attributes->has($varName)) {
$object = $request->attributes->get($varName);

if (empty($functions)) {
$objectValue = (string) $object;
}
else {
foreach ($functions AS $f => $function) {

# While this is not the last function, call the chain
if ($f < $nbCalls - 1) {
if (is_callable(array($object, $fullFunctionName = 'get' . $function))
|| is_callable(array($object, $fullFunctionName = 'has' . $function))
|| is_callable(array($object, $fullFunctionName = 'is' . $function))
) {
$object = call_user_func(array($object, $fullFunctionName));
}
else {
throw new \RuntimeException(sprintf('"%s" is not callable.', join('.', array_merge([$varName], $functions))));
}
}

# End of the chain: call the method
else {

if (is_callable(array($object, $fullFunctionName = 'get' . $function))
|| is_callable(array($object, $fullFunctionName = 'has' . $function))
|| is_callable(array($object, $fullFunctionName = 'is' . $function))
) {
$objectValue = call_user_func_array(array($object, $fullFunctionName), $parameters);
}
else {
throw new \RuntimeException(sprintf('"%s" is not callable.', join('.', array_merge([$varName], $functions))));
}
}
}
}

$routeParameter = str_replace($match[0][0], $objectValue, $value);
$routeParameters[$key] = $routeParameter;
}


}
} elseif (preg_match('#^\{(?P<parameter>\w+)\}$#', $value, $matches)) {
$routeParameters[$key] = $request->get($matches['parameter']);
}
}
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#2015-11-10
- Allow complex expressions in breadcrumb names and route parameters

#2014-04-18
- Rewrite documentation

Expand Down
25 changes: 25 additions & 0 deletions Resources/doc/annotation_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,31 @@ The two following expressions are equivalents :
*/
```

### Complex parameters

Assume your controllers are designed like a REST API and you have a ManyToOne relationship on Book -> Author :

```php
/**
* @Route("/books/{book}", name="book", requirements={"book" = "\d+"}) // example: /book/53
* @Breadcrumb("{book.author.name}", route={"name"="author", "parameters"={"author"="{book.author.id}"}}) // example: /author/15
* @Breadcrumb("{book.title}", route={"name"="book", "parameters"={"book"="{book.id}"}})
*
* @param Request $request
* @param Book $book
* @return array
*/
public function indexAction(Request $request, Book $book) {
return [
'id' => $book->getId(),
'title' => $book->getTitle(),
'author' => $book->getAuthor()->getName(),
];
}
```



### Position

```php
Expand Down

0 comments on commit 20754d5

Please sign in to comment.