Thomas Rabaix 11 년 전
부모
커밋
b65818ab47
3개의 변경된 파일68개의 추가작업 그리고 15개의 파일을 삭제
  1. 4 1
      Admin/BaseFieldDescription.php
  2. 47 10
      Tests/Twig/Extension/SonataAdminExtensionTest.php
  3. 17 4
      Twig/Extension/SonataAdminExtension.php

+ 4 - 1
Admin/BaseFieldDescription.php

@@ -33,7 +33,10 @@ use Symfony\Component\DependencyInjection\Container;
  *   - link_parameters (o) : add link parameter to the related Admin class when
  *                           the Admin.generateUrl is called
  *   - code : the method name to retrieve the related value
- *   - associated_tostring : the method to retrieve the "string" representation
+ *   - associated_tostring : (deprecated, use associated_property option)
+ *                           the method to retrieve the "string" representation
+ *                           of the collection element.
+ *   - associated_property : property path to retrieve the "string" representation
  *                           of the collection element.
  *
  * Form Field options :

+ 47 - 10
Tests/Twig/Extension/SonataAdminExtensionTest.php

@@ -530,10 +530,17 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
 
     public function testRenderRelationElementToString()
     {
-        $this->fieldDescription->expects($this->once())
+        $this->fieldDescription->expects($this->exactly(2))
             ->method('getOption')
-            ->with($this->identicalTo('associated_tostring'))
-            ->will($this->returnValue('__toString'));
+            ->will($this->returnCallback(function($value, $default = null) {
+                if ($value == 'associated_property') {
+                    return $default;
+                }
+
+                if ($value == 'associated_tostring') {
+                    return '__toString';
+                }
+            }));
 
        $element = $this->getMock('stdClass', array('__toString'));
        $element->expects($this->any())
@@ -545,10 +552,18 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
 
     public function testRenderRelationElementCustomToString()
     {
-        $this->fieldDescription->expects($this->any())
+        $this->fieldDescription->expects($this->exactly(2))
             ->method('getOption')
-            ->with($this->identicalTo('associated_tostring'))
-            ->will($this->returnValue('customToString'));
+            ->will($this->returnCallback(function($value, $default = null) {
+                if ($value == 'associated_property') {
+                    return $default;
+                }
+
+                if ($value == 'associated_tostring') {
+                    return 'customToString';
+                }
+            }));
+
 
        $element = $this->getMock('stdClass', array('customToString'));
        $element->expects($this->any())
@@ -560,17 +575,21 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
 
     public function testRenderRelationElementMethodNotExist()
     {
-        $this->fieldDescription->expects($this->any())
+        $this->fieldDescription->expects($this->exactly(2))
             ->method('getOption')
-            ->with($this->identicalTo('associated_tostring'))
-            ->will($this->returnValue('nonExistedMethod'));
+
+            ->will($this->returnCallback(function($value, $default = null) {
+                if ($value == 'associated_tostring') {
+                    return 'nonExistedMethod';
+                }
+            }));
 
         $element = new \stdClass();
 
         try {
             $this->twigExtension->renderRelationElement($element, $this->fieldDescription);
         } catch (\RuntimeException $e) {
-            $this->assertContains('You must define an `associated_tostring` option or create a `stdClass::__toString` method to the field option "fd_name" from service "xyz".', $e->getMessage());
+            $this->assertContains('You must define an `associated_property` option or create a `stdClass::__toString', $e->getMessage());
 
             return;
         }
@@ -578,6 +597,24 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
         $this->fail('Failed asserting that exception of type "\RuntimeException" is thrown.');
     }
 
+    public function testRenderRelationElementWithPropertyPath()
+    {
+        $this->fieldDescription->expects($this->exactly(1))
+            ->method('getOption')
+
+            ->will($this->returnCallback(function($value, $default = null) {
+                if ($value == 'associated_property') {
+                    return 'foo';
+                }
+            }));
+
+        $element = new \stdClass();
+        $element->foo = "bar";
+
+        $this->assertEquals('bar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
+
+    }
+
     public function testGetUrlsafeIdentifier()
     {
         $enitity = new \stdClass();

+ 17 - 4
Twig/Extension/SonataAdminExtension.php

@@ -15,6 +15,7 @@ use Doctrine\Common\Util\ClassUtils;
 use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
 use Sonata\AdminBundle\Exception\NoValueException;
 use Sonata\AdminBundle\Admin\Pool;
+use Symfony\Component\PropertyAccess\PropertyAccess;
 
 class SonataAdminExtension extends \Twig_Extension
 {
@@ -208,13 +209,25 @@ class SonataAdminExtension extends \Twig_Extension
             return $element;
         }
 
-        $method = $fieldDescription->getOption('associated_tostring', '__toString');
+        $propertyPath = $fieldDescription->getOption('associated_property');
 
-        if (!method_exists($element, $method)) {
-            throw new \RunTimeException(sprintf('You must define an `associated_tostring` option or create a `%s::__toString` method to the field option "%s" from service "%s".', get_class($element), $fieldDescription->getName(), $fieldDescription->getAdmin()->getCode()));
+        if (null === $propertyPath) {
+            // For BC kept associated_tostring option behavior
+            $method = $fieldDescription->getOption('associated_tostring', '__toString');
+
+            if (!method_exists($element, $method)) {
+                throw new \RuntimeException(sprintf(
+                    'You must define an `associated_property` option or create a `%s::__toString` method to the field option %s from service %s is ',
+                    get_class($element),
+                    $fieldDescription->getName(),
+                    $fieldDescription->getAdmin()->getCode()
+                ));
+            }
+
+            return call_user_func(array($element, $method));
         }
 
-        return call_user_func(array($element, $method));
+        return PropertyAccess::createPropertyAccessor()->getValue($element, $propertyPath);
     }
 
     /**