Jelajahi Sumber

Merge pull request #1378 from dantleech/ext_trans_domain_cascade

Added support for setting group translation_domain
Thomas 12 tahun lalu
induk
melakukan
c4c7333aea

+ 5 - 10
Admin/Admin.php

@@ -1469,7 +1469,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     }
 
     /**
-     * @return array
+     * {@inheritdoc}
      */
     public function getFormGroups()
     {
@@ -1477,7 +1477,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     }
 
     /**
-     * @param array $formGroups
+     * {@inheritdoc}
      */
     public function setFormGroups(array $formGroups)
     {
@@ -1615,12 +1615,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     }
 
     /**
-     * add a FieldDescription
-     *
-     * @param string                                              $name
-     * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription
-     *
-     * @return void
+     * {@inheritdoc}
      */
     public function addFormFieldDescription($name, FieldDescriptionInterface $fieldDescription)
     {
@@ -1841,7 +1836,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     }
 
     /**
-     * {@inheritDoc}
+     * {@inheritdoc}
      */
     public function setParent(AdminInterface $parent)
     {
@@ -1849,7 +1844,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     }
 
     /**
-     * {@inheritDoc}
+     * {@inheritdoc}
      */
     public function getParent()
     {

+ 24 - 0
Admin/AdminInterface.php

@@ -571,4 +571,28 @@ interface AdminInterface
      * @return string the translation domain
      */
     public function getTranslationDomain();
+
+    /**
+     * Return the form groups
+     *
+     * @return array
+     */
+    public function getFormGroups();
+
+    /**
+     * Set the form groups
+     *
+     * @param array $formGroups
+     */
+    public function setFormGroups(array $formGroups);
+
+    /**
+     * add a FieldDescription
+     *
+     * @param string                                              $name
+     * @param \Sonata\AdminBundle\Admin\FieldDescriptionInterface $fieldDescription
+     *
+     * @return void
+     */
+    public function addFormFieldDescription($name, FieldDescriptionInterface $fieldDescription);
 }

+ 5 - 2
Form/FormMapper.php

@@ -58,12 +58,16 @@ class FormMapper extends BaseGroupedMapper
     {
         $label = $name instanceof FormBuilder ? $name->getName() : $name;
 
-        $this->addFieldToCurrentGroup($label);
+        $group = $this->addFieldToCurrentGroup($label);
 
         if (!isset($fieldDescriptionOptions['type']) && is_string($type)) {
             $fieldDescriptionOptions['type'] = $type;
         }
 
+        if ($group['translation_domain'] && !isset($fieldDescriptionOptions['translation_domain'])) {
+            $fieldDescriptionOptions['translation_domain'] = $group['translation_domain'];
+        }
+
         $fieldDescription = $this->admin->getModelManager()->getNewFieldDescriptionInstance(
             $this->admin->getClass(),
             $name instanceof FormBuilder ? $name->getName() : $name,
@@ -185,5 +189,4 @@ class FormMapper extends BaseGroupedMapper
     {
         $this->admin->setFormGroups($groups);
     }
-    
 }

+ 8 - 5
Mapper/BaseGroupedMapper.php

@@ -38,9 +38,10 @@ abstract class BaseGroupedMapper extends BaseMapper
         }
 
         $groups[$name] = array_merge(array(
-            'collapsed'   => false,
-            'fields'      => array(),
-            'description' => false
+            'collapsed'          => false,
+            'fields'             => array(),
+            'description'        => false,
+            'translation_domain' => null,
         ), $groups[$name], $options);
         
         $this->setGroups($groups);
@@ -59,7 +60,7 @@ abstract class BaseGroupedMapper extends BaseMapper
 
         return $this;
     }
-    
+
     /**
      * Add the fieldname to the current group
      * 
@@ -73,8 +74,10 @@ abstract class BaseGroupedMapper extends BaseMapper
         $groups = $this->getGroups();
         $groups[$currentGroup]['fields'][$fieldName] = $fieldName;
         $this->setGroups($groups);
+
+        return $groups[$currentGroup];
     }
-    
+
     /**
      * Return the name of the currently selected group. The method also makes 
      * sure a valid group name is currently selected

+ 24 - 9
Resources/doc/reference/translation.rst

@@ -64,28 +64,43 @@ The Admin bundle comes with a customized form field template. The most notable
 change from the original one is the use of the translation domain provided by
 either the Admin instance or the field description to translate labels.
 
-Setting the translation domain
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Overriding the translation domain
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-The translation domain of the Admin instance is used by default, however this
-can be overridden when defining new form fields:
+The translation domain (message catalog) can be overridden at either the form
+group or individual field level.
+
+If a translation domain is set at the group level it will cascade down to all
+fields within the group.
+
+Overriding the translation domain is of particular use when using
+:doc:`extensions <extensions>`, where the extension and the translations would
+be defined in one bundle, but implemented in many different admin instances.
+
+The following example sets the translation domain on a form group:
 
 .. code-block:: php
 
-        $formMapper->with('form.my_group')
+        $formMapper->with('form.my_group', array(
+            'translation_domain' => 'MyTranslationDomain'
+            ))
             ->add('publishable', 'checkbox', array(), array(
                 // ...
                 'translation_domain' => 'MyTranslationDomain',
             ))
             ->add('start_date', 'date', array(), array(
+            ));
+
+Setting the translation domain on an individual field:
+
+.. code-block:: php
+
+        $formMapper->with('form.my_group')
+            ->add('publishable', 'checkbox', array(), array(
                 // ...
                 'translation_domain' => 'MyTranslationDomain',
             ));
 
-This is of particular use when using admin :doc:`extensions <extensions>`,
-where the extension and the translations would be defined in one bundle, but
-implemented in many different admin instances.
-
 Setting the label name
 ^^^^^^^^^^^^^^^^^^^^^^
 

+ 1 - 1
Resources/views/CRUD/base_edit_form.html.twig

@@ -20,7 +20,7 @@
                             <li class="{% if loop.first %}active{% endif %}">
                                 <a href="#{{ admin.uniqid }}_{{ loop.index }}" data-toggle="tab">
                                     <i class="icon-exclamation-sign has-errors hide"></i>
-                                    {{ admin.trans(name) }}
+                                    {{ admin.trans(name, {}, form_group.translation_domain) }}
                                 </a>
                             </li>
                         {% endfor %}

+ 2 - 2
Resources/views/Form/form_admin_fields.html.twig

@@ -42,7 +42,7 @@ file that was distributed with this source code.
                 {% if not sonata_admin.admin%}
                     {{- label|trans({}, translation_domain) -}}
                 {% else %}
-                {{ sonata_admin.admin.trans(label, {}, sonata_admin.field_description.translationDomain) }}
+                    {{ sonata_admin.admin.trans(label, {}, sonata_admin.field_description.translationDomain) }}
                 {% endif %}
                 {{ required ? '*' : '' }}
             </label>
@@ -135,7 +135,7 @@ file that was distributed with this source code.
                 {% endif %}
 
                 {% if sonata_admin.field_description.help %}
-                    <span class="help-block sonata-ba-field-help">{{ sonata_admin.admin.trans(sonata_admin.field_description.help)|raw }}</span>
+                    <span class="help-block sonata-ba-field-help">{{ sonata_admin.admin.trans(sonata_admin.field_description.help, {}, sonata_admin.field_description.translationDomain)|raw }}</span>
                 {% endif %}
             </div>
         </div>

+ 116 - 0
Tests/Form/FormMapperTest.php

@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of the Sonata package.
+ *
+ * (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\Tests\Form;
+
+use Sonata\AdminBundle\Form\FormMapper;
+
+class FormMapperTest extends \PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        $this->contractor = $this->getMock('Sonata\AdminBundle\Builder\FormContractorInterface');
+        $this->builder = $this->getMockBuilder('Symfony\Component\Form\FormBuilder')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->admin = $this->getMock('Sonata\AdminBundle\Admin\AdminInterface');
+        $this->modelManager = $this->getMock('Sonata\AdminBundle\Model\ModelManagerInterface');
+        $this->fieldDescription = $this->getMock('Sonata\AdminBundle\Admin\FieldDescriptionInterface');
+        $this->labelTranslatorStrategy = $this->getMock('Sonata\AdminBundle\Translator\LabelTranslatorStrategyInterface');
+
+        $this->formMapper = new FormMapper(
+            $this->contractor,
+            $this->builder,
+            $this->admin
+        );
+    }
+
+    public function testWithNoOptions()
+    {
+        $this->admin->expects($this->once())
+            ->method('setFormGroups')
+            ->with(array(
+                'foobar' => array(
+                    'collapsed' => false,
+                    'fields' => array(),
+                    'description' => false,
+                    'translation_domain' => null,
+                )));
+
+        $this->formMapper->with('foobar');
+    }
+
+    public function testWithOptions()
+    {
+        $this->admin->expects($this->once())
+            ->method('setFormGroups')
+            ->with(array(
+                'foobar' => array(
+                    'collapsed' => false,
+                    'fields' => array(),
+                    'description' => false,
+                    'translation_domain' => 'Foobar',
+                )));
+
+        $this->formMapper->with('foobar', array(
+            'translation_domain' => 'Foobar',
+        ));
+    }
+
+    public function testWithFieldsCascadeTranslationDomain()
+    {
+        $formGroups = array(
+            'foobar' => array(
+                'collapsed' => false,
+                'fields' => array(),
+                'description' => false,
+                'translation_domain' => 'Foobar',
+            )
+        );
+
+        $this->admin->expects($this->exactly(2))
+            ->method('setFormGroups');
+
+        $this->admin->expects($this->any())
+            ->method('getFormGroups')
+            ->will($this->returnValue($formGroups));
+
+        $this->admin->expects($this->once())
+            ->method('getModelManager')
+            ->will($this->returnValue($this->modelManager));
+
+        $this->modelManager->expects($this->once())
+            ->method('getNewFieldDescriptionInstance')
+            ->with(
+                null, // mock admin ->getClass returns null
+                'foo',
+                array(
+                    'translation_domain' => 'Foobar',
+                    'type' => 'bar',
+                )
+            )
+            ->will($this->returnValue($this->fieldDescription));
+
+        $this->contractor->expects($this->once())
+            ->method('getDefaultOptions')
+            ->will($this->returnValue(array()));
+
+        $this->admin->expects($this->once())
+            ->method('getLabelTranslatorStrategy')
+            ->will($this->returnValue($this->labelTranslatorStrategy));
+
+        $this->formMapper->with('foobar', array(
+            'translation_domain' => 'Foobar'
+        ))
+        ->add('foo', 'bar')
+        ->end();
+    }
+}