Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Routing] Simplified php matcher dumper (and optimized generated matc…
…her)
- Loading branch information
Showing
7 changed files
with
605 additions
and
161 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Routing\Matcher\Dumper; | ||
|
||
/** | ||
* Collection of routes. | ||
* | ||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com> | ||
*/ | ||
class DumperCollection implements \IteratorAggregate | ||
{ | ||
private $parent; | ||
private $children = array(); | ||
|
||
/** | ||
* Returns the children routes and collections. | ||
* | ||
* @return array Array of DumperCollection|DumperRoute | ||
*/ | ||
public function all() | ||
{ | ||
return $this->children; | ||
} | ||
|
||
/** | ||
* Adds a route or collection | ||
* | ||
* @param DumperRoute|DumperCollection The route or collection | ||
*/ | ||
public function add($child) | ||
{ | ||
if ($child instanceof DumperCollection) { | ||
$child->setParent($this); | ||
} | ||
$this->children[] = $child; | ||
} | ||
|
||
/** | ||
* Sets children | ||
* | ||
* @param array $children The children | ||
*/ | ||
public function setAll(array $children) | ||
{ | ||
foreach ($children as $child) { | ||
if ($child instanceof DumperCollection) { | ||
$child->setParent($this); | ||
} | ||
} | ||
$this->children = $children; | ||
} | ||
|
||
/** | ||
* Returns an iterator over the children. | ||
* | ||
* @return \Iterator The iterator | ||
*/ | ||
public function getIterator() | ||
{ | ||
return new \ArrayIterator($this->children); | ||
} | ||
|
||
/** | ||
* Returns the root of the collection. | ||
* | ||
* @return DumperCollection The root collection | ||
*/ | ||
public function getRoot() | ||
{ | ||
return (null !== $this->parent) ? $this->parent->getRoot() : $this; | ||
} | ||
|
||
/** | ||
* Returns the parent collection. | ||
* | ||
* @return DumperCollection|null The parent collection or null if the collection has no parent | ||
*/ | ||
protected function getParent() | ||
{ | ||
return $this->parent; | ||
} | ||
|
||
/** | ||
* Sets the parent collection. | ||
* | ||
* @param DumperCollection $parent The parent collection | ||
*/ | ||
protected function setParent(DumperCollection $parent) | ||
{ | ||
$this->parent = $parent; | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
src/Symfony/Component/Routing/Matcher/Dumper/DumperPrefixCollection.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Routing\Matcher\Dumper; | ||
|
||
/** | ||
* Prefix tree of routes preserving routes order. | ||
* | ||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com> | ||
*/ | ||
class DumperPrefixCollection extends DumperCollection | ||
{ | ||
private $prefix = ''; | ||
|
||
/** | ||
* Returns the prefix. | ||
* | ||
* @return string The prefix | ||
*/ | ||
public function getPrefix() | ||
{ | ||
return $this->prefix; | ||
} | ||
|
||
/** | ||
* Sets the prefix. | ||
* | ||
* @param string $prefix The prefix | ||
*/ | ||
public function setPrefix($prefix) | ||
{ | ||
$this->prefix = $prefix; | ||
} | ||
|
||
/** | ||
* Adds a route in the tree. | ||
* | ||
* @param DumperRoute $route The route | ||
* | ||
* @return DumperPrefixCollection The node the route was added to | ||
*/ | ||
public function addPrefixRoute(DumperRoute $route) | ||
{ | ||
$prefix = $route->getRoute()->compile()->getStaticPrefix(); | ||
|
||
// Same prefix, add to current leave | ||
if ($this->prefix === $prefix) { | ||
$this->add($route); | ||
|
||
return $this; | ||
} | ||
|
||
// Prefix starts with route's prefix | ||
if ('' === $this->prefix || 0 === strpos($prefix, $this->prefix)) { | ||
$collection = new DumperPrefixCollection(); | ||
$collection->setPrefix(substr($prefix, 0, strlen($this->prefix)+1)); | ||
$this->add($collection); | ||
|
||
return $collection->addPrefixRoute($route); | ||
} | ||
|
||
// No match, fallback to parent (recursively) | ||
|
||
if (null === $parent = $this->getParent()) { | ||
throw new \LogicException("The collection root must not have a prefix"); | ||
} | ||
|
||
return $parent->addPrefixRoute($route); | ||
} | ||
|
||
/** | ||
* Merges nodes whose prefix ends with a slash | ||
* | ||
* Children of a node whose prefix ends with a slash are moved to the parent node | ||
*/ | ||
public function mergeSlashNodes() | ||
{ | ||
$children = array(); | ||
|
||
foreach ($this as $child) { | ||
if ($child instanceof self) { | ||
$child->mergeSlashNodes(); | ||
if ('/' === substr($child->prefix, -1)) { | ||
$children = array_merge($children, $child->all()); | ||
} else { | ||
$children[] = $child; | ||
} | ||
} else { | ||
$children[] = $child; | ||
} | ||
} | ||
|
||
$this->setAll($children); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/Symfony/Component/Routing/Matcher/Dumper/DumperRoute.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Routing\Matcher\Dumper; | ||
|
||
use Symfony\Component\Routing\Route; | ||
use Symfony\Component\Routing\RouteCollection; | ||
|
||
/** | ||
* Container for a Route. | ||
* | ||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com> | ||
*/ | ||
class DumperRoute | ||
{ | ||
private $name; | ||
private $route; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param string $name The route name | ||
* @param Route $route The route | ||
*/ | ||
public function __construct($name, Route $route) | ||
{ | ||
$this->name = $name; | ||
$this->route = $route; | ||
} | ||
|
||
/** | ||
* Returns the route name. | ||
* | ||
* @return string The route name | ||
*/ | ||
public function getName() | ||
{ | ||
return $this->name; | ||
} | ||
|
||
/** | ||
* Returns the route. | ||
* | ||
* @return Route The route | ||
*/ | ||
public function getRoute() | ||
{ | ||
return $this->route; | ||
} | ||
} |
Oops, something went wrong.