Browse Source

Fix entity route incorrectly handling placeholders

In addition to incorrectly handling `:` prefixed parameters EntityRoute
did not handle brace parameters at all. Instead of re-parsing the route,
we can compile the route template and use the extracted data to find
entity data.

Refs #12572
Mark Story 7 years ago
parent
commit
b85672a14f

+ 5 - 3
src/Routing/Route/EntityRoute.php

@@ -41,13 +41,15 @@ class EntityRoute extends Route
      */
      */
     public function match(array $url, array $context = [])
     public function match(array $url, array $context = [])
     {
     {
+        if (empty($this->_compiledRoute)) {
+            $this->compile();
+        }
+
         if (isset($url['_entity'])) {
         if (isset($url['_entity'])) {
             $entity = $url['_entity'];
             $entity = $url['_entity'];
             $this->_checkEntity($entity);
             $this->_checkEntity($entity);
 
 
-            preg_match_all('@:(\w+)@', $this->template, $matches);
-
-            foreach ($matches[1] as $field) {
+            foreach ($this->keys as $field) {
                 if (!isset($url[$field]) && isset($entity[$field])) {
                 if (!isset($url[$field]) && isset($entity[$field])) {
                     $url[$field] = $entity[$field];
                     $url[$field] = $entity[$field];
                 }
                 }

+ 27 - 0
tests/TestCase/Routing/Route/EntityRouteTest.php

@@ -83,6 +83,33 @@ class EntityRouteTest extends TestCase
      *
      *
      * @return void
      * @return void
      */
      */
+    public function testMatchUnderscoreBetweenVar()
+    {
+        $entity = new Article([
+            'category_id' => 2,
+            'slug' => 'article-slug'
+        ]);
+
+        $route = $route = new EntityRoute(
+            '/articles/:category_id_:slug',
+            [
+                '_name' => 'articlesView',
+            ]
+        );
+
+        $result = $route->match([
+            '_entity' => $entity,
+            '_name' => 'articlesView'
+        ]);
+
+        $this->assertEquals('/articles/2_article-slug', $result);
+    }
+
+    /**
+     * test that routes match their pattern.
+     *
+     * @return void
+     */
     public function testMatchingArray()
     public function testMatchingArray()
     {
     {
         $entity = [
         $entity = [