Browse Source

Fix reading array values from associated entities.

Split out conditions into temporary variables as the conditions would be
a bit batty otherwise.

Refs #4083
mark_story 11 years ago
parent
commit
13210fa450
2 changed files with 35 additions and 6 deletions
  1. 11 6
      src/View/Form/EntityContext.php
  2. 24 0
      tests/TestCase/View/Form/EntityContextTest.php

+ 11 - 6
src/View/Form/EntityContext.php

@@ -260,18 +260,23 @@ class EntityContext implements ContextInterface {
 			$path = array_slice($path, 1);
 		}
 
-		foreach ($path as $prop) {
+		$len = count($path);
+		$last = $len - 1;
+		for ($i = 0; $i < $len; $i++) {
+			$prop = $path[$i];
 			$next = $this->_getProp($entity, $prop);
 
 			if ($next === null && $prop !== '_ids') {
 				return false;
 			}
 
-			if (
-				!is_array($next) &&
-				!($next instanceof Traversable) &&
-				!($next instanceof Entity)
-			) {
+			$isLast = ($i === $last && isset($next));
+			$isTraversable = (
+				is_array($next) ||
+				$next instanceof Traversable ||
+				$next instanceof Entity
+			);
+			if ($isLast || !$isTraversable) {
 				return $entity;
 			}
 			$entity = $next;

+ 24 - 0
tests/TestCase/View/Form/EntityContextTest.php

@@ -405,6 +405,30 @@ class EntityContextTest extends TestCase {
 	}
 
 /**
+ * Test reading array values from an entity.
+ *
+ * @return void
+ */
+	public function testValGetArrayValue() {
+		$row = new Article([
+			'title' => 'Test entity',
+			'types' => [1, 2, 3],
+			'author' => new Entity([
+				'roles' => ['admin', 'publisher']
+			])
+		]);
+		$context = new EntityContext($this->request, [
+			'entity' => $row,
+			'table' => 'Articles',
+		]);
+		$result = $context->val('types');
+		$this->assertEquals($row->types, $result);
+
+		$result = $context->val('author.roles');
+		$this->assertEquals($row->author->roles, $result);
+	}
+
+/**
  * Test that val() reads from the request.
  *
  * @return void