Browse Source

Fix #168 - AdminHelper underscore error

Thomas Rabaix 14 năm trước cách đây
mục cha
commit
841dc65915
2 tập tin đã thay đổi với 85 bổ sung15 xóa
  1. 7 15
      Admin/AdminHelper.php
  2. 78 0
      Util/FormBuilderIterator.php

+ 7 - 15
Admin/AdminHelper.php

@@ -11,6 +11,7 @@
 namespace Sonata\AdminBundle\Admin;
 
 use Symfony\Component\Form\FormBuilder;
+use Sonata\AdminBundle\Util\FormBuilderIterator;
 
 class AdminHelper
 {
@@ -26,28 +27,19 @@ class AdminHelper
 
     /**
      * @throws \RuntimeException
-     * @param \Symfony\Component\Form\FormBuilder $formBuider
+     * @param \Symfony\Component\Form\FormBuilder $formBuilder
      * @param  $elementId
      * @return \Symfony\Component\Form\FormBuilder
      */
-    public function getChildFormBuilder(FormBuilder $formBuider, $elementId)
+    public function getChildFormBuilder(FormBuilder $formBuilder, $elementId)
     {
-        // todo : warning this introduce a bug if the field name = 'field_name',
-        //        add a check to field will always be 'fieldName'
-        $elements = explode('_', $elementId);
-
-        // always remove the first element : form's name
-        array_shift($elements);
-
-        while ($elementName = array_shift($elements)) {
-            if (!$formBuider->has($elementName)) {
-                throw new \RuntimeException(sprintf('The element `%s` does not exists', $elementName));
+        foreach (new FormBuilderIterator($formBuilder) as $name => $formBuilder) {
+            if ($name == $elementId) {
+                return $formBuilder;
             }
-
-            $formBuider = $formBuider->get($elementName);
         }
 
-        return $formBuider;
+        return null;
     }
 
     /**

+ 78 - 0
Util/FormBuilderIterator.php

@@ -0,0 +1,78 @@
+<?php
+/*
+ * This file is part of the Sonata project.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\AdminBundle\Util;
+
+use Symfony\Component\Form\FormBuilder;
+
+class FormBuilderIterator extends \RecursiveArrayIterator
+{
+    static protected $reflection;
+
+    protected $formBuilder;
+
+    protected $keys = array();
+
+    protected $prefix;
+
+    public function __construct(FormBuilder $formBuilder, $prefix = false)
+    {
+        $this->formBuilder = $formBuilder;
+        $this->prefix      = $prefix ? $prefix : $formBuilder->getName();
+        $this->iterator    = new \ArrayIterator(self::getKeys($formBuilder));
+    }
+
+    private static function getKeys(FormBuilder $formBuilder)
+    {
+        if (!self::$reflection) {
+            self::$reflection = new \ReflectionProperty(get_class($formBuilder), 'children');
+            self::$reflection->setAccessible(true);
+        }
+
+        return array_keys(self::$reflection->getValue($formBuilder));
+    }
+
+    public function rewind()
+    {
+        return $this->iterator->rewind();
+    }
+
+    public function valid()
+    {
+        return $this->iterator->valid();
+    }
+
+    public function key()
+    {
+        $name = $this->iterator->current();
+
+        return sprintf('%s_%s', $this->prefix, $name);
+    }
+
+    public function next()
+    {
+        return $this->iterator->next();
+    }
+
+    public function current()
+    {
+        return $this->formBuilder->get($this->iterator->current());
+    }
+
+    public function getChildren()
+    {
+        return new self($this->formBuilder->get($this->iterator->current()), $this->current());
+    }
+
+    public function hasChildren()
+    {
+        return count(self::getKeys($this->current())) > 0;
+    }
+}