Browse Source

Add wildcard matcher to Hash::extract()

Port changes from #6447 from 2.7 into 3.0
Mark Story 11 years ago
parent
commit
7c8c540fb8
2 changed files with 37 additions and 9 deletions
  1. 10 9
      src/Utility/Hash.php
  2. 27 0
      tests/TestCase/Utility/HashTest.php

+ 10 - 9
src/Utility/Hash.php

@@ -89,6 +89,7 @@ class Hash
      *
      * - `{n}` Matches any numeric key, or integer.
      * - `{s}` Matches any string key.
+     * - `{*}` Matches any value.
      * - `Foo` Matches any key with the exact same value.
      *
      * There are a number of attribute operators:
@@ -191,16 +192,16 @@ class Hash
      */
     protected static function _matchToken($key, $token)
     {
-        if ($token === '{n}') {
-            return is_numeric($key);
+       switch ($token) {
+           case '{n}':
+               return is_numeric($key);
+           case '{s}':
+               return is_string($key);
+           case '{*}':
+               return true;
+           default:
+               return is_numeric($token) ? ($key == $token) : $key === $token;
         }
-        if ($token === '{s}') {
-            return is_string($key);
-        }
-        if (is_numeric($token)) {
-            return ($key == $token);
-        }
-        return ($key === $token);
     }
 
     /**

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

@@ -846,6 +846,33 @@ class HashTest extends TestCase
     }
 
     /**
+     * Test wildcard matcher
+     *
+     * @return void
+     */
+    public function testExtractWildcard()
+    {
+        $data = [
+            '02000009C5560001' => ['name' => 'Mr. Alphanumeric'],
+            '2300000918020101' => ['name' => 'Mr. Numeric'],
+            '390000096AB30001' => ['name' => 'Mrs. Alphanumeric'],
+            'stuff' => ['name' => 'Ms. Word'],
+            123 => ['name' => 'Mr. Number'],
+            true => ['name' => 'Ms. Bool'],
+        ];
+        $result = Hash::extract($data, '{*}.name');
+        $expected = [
+            'Mr. Alphanumeric',
+            'Mr. Numeric',
+            'Mrs. Alphanumeric',
+            'Ms. Word',
+            'Mr. Number',
+            'Ms. Bool',
+        ];
+        $this->assertEquals($expected, $result);
+   }
+
+    /**
      * Test the attribute presense selector.
      *
      * @return void