From bf586d4f3337dcb427ed4bb6bfec6b12c398bad4 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Fri, 28 Sep 2012 12:21:03 -0500 Subject: [PATCH] Add priority support to partial matchers in a nested matcher. --- .../lib/Drupal/Core/Routing/NestedMatcher.php | 54 +++++++++++++++++-- .../Core/Routing/NestedMatcherInterface.php | 7 ++- .../Tests/Routing/NestedMatcherTest.php | 2 +- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/core/lib/Drupal/Core/Routing/NestedMatcher.php b/core/lib/Drupal/Core/Routing/NestedMatcher.php index d1bc91d66ff..ff53715426e 100644 --- a/core/lib/Drupal/Core/Routing/NestedMatcher.php +++ b/core/lib/Drupal/Core/Routing/NestedMatcher.php @@ -29,6 +29,13 @@ class NestedMatcher implements NestedMatcherInterface { */ protected $partialMatchers = array(); + /** + * Array of PartialMatcherInterface objects, sorted. + * + * @var type + */ + protected $sortedMatchers = array(); + /** * The initial matcher to match against. * @@ -50,14 +57,20 @@ class NestedMatcher implements NestedMatcherInterface { * * @param \Drupal\Core\Routing\PartialMatcherInterface $matcher * A partial matcher. + * @param int $priority + * (optional) The priority of the matcher. Higher number matchers will be checked + * first. Default to 0. * * @return NestedMatcherInterface * The current matcher. */ - public function addPartialMatcher(PartialMatcherInterface $matcher) { - $this->partialMatchers[] = $matcher; + public function addPartialMatcher(PartialMatcherInterface $matcher, $priority = 0) { + if (empty($this->matchers[$priority])) { + $this->matchers[$priority] = array(); + } - return $this; + $this->matchers[$priority][] = $matcher; + $this->sortedMatchers = array(); } /** @@ -114,7 +127,7 @@ class NestedMatcher implements NestedMatcherInterface { public function matchRequest(Request $request) { $collection = $this->initialMatcher->matchRequestPartial($request); - foreach ($this->partialMatchers as $matcher) { + foreach ($this->getPartialMatchers() as $matcher) { if ($collection) { $matcher->setCollection($collection); } @@ -126,6 +139,39 @@ class NestedMatcher implements NestedMatcherInterface { return $attributes; } + /** + * Sorts the matchers and flattens them. + * + * @return array + * An array of RequestMatcherInterface objects. + */ + public function getPartialMatchers() { + if (empty($this->sortedMatchers)) { + $this->sortedMatchers = $this->sortMatchers(); + } + + return $this->sortedMatchers; + } + + /** + * Sort matchers by priority. + * + * The highest priority number is the highest priority (reverse sorting). + * + * @return \Symfony\Component\Routing\RequestMatcherInterface[] + * An array of Matcher objects in the order they should be used. + */ + protected function sortMatchers() { + $sortedMatchers = array(); + krsort($this->matchers); + + foreach ($this->matchers as $matchers) { + $sortedMatchers = array_merge($sortedMatchers, $matchers); + } + + return $sortedMatchers; + } + /** * Sets the request context. * diff --git a/core/lib/Drupal/Core/Routing/NestedMatcherInterface.php b/core/lib/Drupal/Core/Routing/NestedMatcherInterface.php index 34018cc07f4..6ae09954af7 100644 --- a/core/lib/Drupal/Core/Routing/NestedMatcherInterface.php +++ b/core/lib/Drupal/Core/Routing/NestedMatcherInterface.php @@ -35,11 +35,14 @@ interface NestedMatcherInterface extends RequestMatcherInterface { * * @param \Drupal\Core\Routing\PartialMatcherInterface $matcher * A partial matcher. + * @param int $priority + * (optional) The priority of the matcher. Higher number matchers will be checked + * first. Default to 0. * - * @return \Drupal\Core\Routing\NestedMatcherInterface + * @return NestedMatcherInterface * The current matcher. */ - public function addPartialMatcher(PartialMatcherInterface $matcher); + public function addPartialMatcher(PartialMatcherInterface $matcher, $priority = 0); /** * Sets the final matcher for the matching plan. diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/NestedMatcherTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/NestedMatcherTest.php index ad17ea7c1a6..444785c49f0 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/NestedMatcherTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/NestedMatcherTest.php @@ -53,7 +53,7 @@ class NestedMatcherTest extends UnitTestBase { $matcher = new NestedMatcher(); $matcher->setInitialMatcher(new MockPathMatcher($this->fixtures->sampleRouteCollection())); - $matcher->addPartialMatcher(new HttpMethodMatcher()); + $matcher->addPartialMatcher(new HttpMethodMatcher(), 1); $matcher->setFinalMatcher(new FirstEntryFinalMatcher()); $request = Request::create('/path/one', 'GET');