Browse Source

Allow url data to overwrite Entity data.

When a routing parameter is defined in the URL array it should overwrite
the entity data. This gives us a way to explicitly overwrite the entity
data if necessary.

Refs #11455
Mark Story 8 years ago
parent
commit
933681be3b

+ 7 - 2
src/Routing/Route/EntityRoute.php

@@ -28,7 +28,10 @@ class EntityRoute extends Route
 {
     /**
      * Match by entity and map its fields to the URL pattern by comparing the
-     * field names with the template vars
+     * field names with the template vars.
+     *
+     * If a routing key is defined in both `$url` and the entity, the value defined
+     * in `$url` will be preferred.
      *
      * @param array $url Array of parameters to convert to a string.
      * @param array $context An array of the current request context.
@@ -45,7 +48,9 @@ class EntityRoute extends Route
             preg_match_all('@:(\w+)@', $this->template, $matches);
 
             foreach ($matches[1] as $field) {
-                $url[$field] = $entity[$field];
+                if (!isset($url[$field]) && isset($entity[$field])) {
+                    $url[$field] = $entity[$field];
+                }
             }
         }
 

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

@@ -24,6 +24,34 @@ use TestApp\Model\Entity\Article;
 class EntityRouteTest extends TestCase
 {
     /**
+     * test that route keys take precedence to object properties.
+     *
+     * @return void
+     */
+    public function testMatchRouteKeyPrecedence()
+    {
+        $entity = new Article([
+            'category_id' => 2,
+            'slug' => 'article-slug'
+        ]);
+
+        $route = $route = new EntityRoute(
+            '/articles/:category_id/:slug',
+            [
+                '_name' => 'articlesView',
+            ]
+        );
+
+        $result = $route->match([
+            'slug' => 'other-slug',
+            '_entity' => $entity,
+            '_name' => 'articlesView'
+        ]);
+
+        $this->assertEquals('/articles/2/other-slug', $result);
+    }
+
+    /**
      * test that routes match their pattern.
      *
      * @return void