Browse Source

Added support for numeric nested fields type, isRequired, val and attributes
Updated tests too

lilHermit 8 years ago
parent
commit
ebad0f2e51
2 changed files with 40 additions and 4 deletions
  1. 31 3
      src/View/Form/ArrayContext.php
  2. 9 1
      tests/TestCase/View/Form/ArrayContextTest.php

+ 31 - 3
src/View/Form/ArrayContext.php

@@ -177,7 +177,12 @@ class ArrayContext implements ContextInterface
             return null;
         }
 
-        return Hash::get($this->_context['defaults'], $field);
+        // Using Hash::check here incase the default value is actually null
+        if (Hash::check($this->_context['defaults'], $field)) {
+            return Hash::get($this->_context['defaults'], $field);
+        } else {
+            return Hash::get($this->_context['defaults'], $this->stripNesting($field));
+        }
     }
 
     /**
@@ -194,6 +199,9 @@ class ArrayContext implements ContextInterface
             return false;
         }
         $required = Hash::get($this->_context['required'], $field);
+        if ($required === null) {
+            $required = Hash::get($this->_context['required'], $this->stripNesting($field));
+        }
 
         return (bool)$required;
     }
@@ -221,7 +229,11 @@ class ArrayContext implements ContextInterface
         if (!is_array($this->_context['schema'])) {
             return null;
         }
+
         $schema = Hash::get($this->_context['schema'], $field);
+        if ($schema === null) {
+            $schema = Hash::get($this->_context['schema'], $this->stripNesting($field));
+        }
 
         return isset($schema['type']) ? $schema['type'] : null;
     }
@@ -237,10 +249,13 @@ class ArrayContext implements ContextInterface
         if (!is_array($this->_context['schema'])) {
             return [];
         }
-        $schema = (array)Hash::get($this->_context['schema'], $field);
+        $schema = Hash::get($this->_context['schema'], $field);
+        if ($schema === null) {
+            $schema = Hash::get($this->_context['schema'], $this->stripNesting($field));
+        }
         $whitelist = ['length' => null, 'precision' => null];
 
-        return array_intersect_key($schema, $whitelist);
+        return array_intersect_key((array)$schema, $whitelist);
     }
 
     /**
@@ -273,4 +288,17 @@ class ArrayContext implements ContextInterface
 
         return Hash::get($this->_context['errors'], $field);
     }
+
+    /**
+     * Strips out any numeric nesting like users.0.age
+     *
+     * @param string $field A dot separated path to check errors on
+     * @return string A string with stripped numeric nesting
+     */
+    protected function stripNesting($field)
+    {
+        return implode('.', array_filter(explode('.', $field), function ($val) {
+            return !is_numeric($val);
+        }));
+    }
 }

+ 9 - 1
tests/TestCase/View/Form/ArrayContextTest.php

@@ -176,10 +176,12 @@ class ArrayContextTest extends TestCase
         $context = new ArrayContext($this->request, [
             'defaults' => [
                 'title' => 'Default value',
+                'users' => ['tags' => 'common']
             ]
         ]);
 
         $this->assertEquals('Default value', $context->val('title'));
+        $this->assertEquals('common', $context->val('users.0.tags'));
         $result = $context->val('title', ['default' => 'explicit default']);
         $this->assertEquals('explicit default', $result);
     }
@@ -195,12 +197,14 @@ class ArrayContextTest extends TestCase
             'required' => [
                 'Comments' => [
                     'required' => true,
-                    'nope' => false
+                    'nope' => false,
+                    'tags' => true
                 ]
             ]
         ]);
         $this->assertTrue($context->isRequired('Comments.required'));
         $this->assertFalse($context->isRequired('Comments.nope'));
+        $this->assertTrue($context->isRequired('Comments.0.tags'));
         $this->assertFalse($context->isRequired('Articles.id'));
     }
 
@@ -226,12 +230,14 @@ class ArrayContextTest extends TestCase
             'schema' => [
                 'Comments' => [
                     'id' => ['type' => 'integer'],
+                    'tags' => ['type' => 'string'],
                     'comment' => ['length' => 255]
                 ]
             ]
         ]);
         $this->assertNull($context->type('Comments.undefined'));
         $this->assertEquals('integer', $context->type('Comments.id'));
+        $this->assertEquals('string', $context->type('Comments.0.tags'));
         $this->assertNull($context->type('Comments.comment'));
     }
 
@@ -260,10 +266,12 @@ class ArrayContextTest extends TestCase
                     'comment' => ['type' => 'string', 'length' => 255],
                     'decimal' => ['type' => 'decimal', 'precision' => 2, 'length' => 5],
                     'floaty' => ['type' => 'float', 'precision' => 2, 'length' => 5],
+                    'tags' => ['type' => 'string', 'length' => 25],
                 ]
             ]
         ]);
         $this->assertEquals([], $context->attributes('Comments.id'));
+        $this->assertEquals(['length' => 25], $context->attributes('Comments.0.tags'));
         $this->assertEquals(['length' => 255], $context->attributes('Comments.comment'));
         $this->assertEquals(['precision' => 2, 'length' => 5], $context->attributes('Comments.decimal'));
         $this->assertEquals(['precision' => 2, 'length' => 5], $context->attributes('Comments.floaty'));