Browse Source

Fix Hash::extract() to not array cast objects.

dereuromark 9 years ago
parent
commit
1c3de4aea5
2 changed files with 33 additions and 1 deletions
  1. 6 1
      src/Utility/Hash.php
  2. 27 0
      tests/TestCase/Utility/HashTest.php

+ 6 - 1
src/Utility/Hash.php

@@ -135,7 +135,12 @@ class Hash
 
         // Simple paths.
         if (!preg_match('/[{\[]/', $path)) {
-            return (array)static::get($data, $path);
+            $data = static::get($data, $path);
+            if ($data !== null && !(is_array($data) || $data instanceof ArrayAccess)) {
+                return [$data];
+            }
+
+            return $data !== null ? (array)$data : [];
         }
 
         if (strpos($path, '[') === false) {

+ 27 - 0
tests/TestCase/Utility/HashTest.php

@@ -15,6 +15,7 @@
 namespace Cake\Test\TestCase\Utility;
 
 use ArrayObject;
+use Cake\I18n\Time;
 use Cake\ORM\Entity;
 use Cake\TestSuite\TestCase;
 use Cake\Utility\Hash;
@@ -1489,6 +1490,32 @@ class HashTest extends TestCase
     }
 
     /**
+     * Tests that objects as values handled correctly.
+     *
+     * @return void
+     */
+    public function testExtractObjects()
+    {
+        $data = [
+            'root' => [
+                'array' => new ArrayObject([
+                    'foo' => 'bar',
+                ]),
+                'created' => new Time('2010-01-05'),
+            ],
+        ];
+
+        $result = Hash::extract($data, 'root.created');
+        $this->assertSame([$data['root']['created']], $result);
+
+        $result = Hash::extract($data, 'root.array');
+        $this->assertSame(['foo' => 'bar'], $result);
+
+        $result = Hash::extract($data, 'root.array.foo');
+        $this->assertSame(['bar'], $result);
+    }
+
+    /**
      * testSort method
      *
      * @return void