浏览代码

Merge pull request #3687 from greg0ire/2.x

Backport 2.3 changes
Oskar Stark 9 年之前
父节点
当前提交
1bcdfcd4cc

+ 1 - 1
.travis.yml

@@ -7,7 +7,7 @@ sudo: false
 
 
 cache:
 cache:
   directories:
   directories:
-    - $HOME/.composer/cache
+    - $HOME/.composer/cache/files
     - $HOME/.cache/pip
     - $HOME/.cache/pip
 
 
 env:
 env:

+ 1 - 1
Admin/Admin.php

@@ -57,7 +57,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     const CONTEXT_MENU       = 'menu';
     const CONTEXT_MENU       = 'menu';
     const CONTEXT_DASHBOARD  = 'dashboard';
     const CONTEXT_DASHBOARD  = 'dashboard';
 
 
-    const CLASS_REGEX        = '@(?:([A-Za-z0-9]*)\\\)?(Bundle\\\)?([A-Za-z0-9]+)Bundle\\\(Entity|Document|Model|PHPCR|CouchDocument|Phpcr|Doctrine\\\Orm|Doctrine\\\Phpcr|Doctrine\\\MongoDB|Doctrine\\\CouchDB)\\\(.*)@';
+    const CLASS_REGEX        = '@(?:([A-Za-z0-9]*)\\\)?(Bundle\\\)?([A-Za-z0-9]+?)(?:Bundle)?\\\(Entity|Document|Model|PHPCR|CouchDocument|Phpcr|Doctrine\\\Orm|Doctrine\\\Phpcr|Doctrine\\\MongoDB|Doctrine\\\CouchDB)\\\(.*)@';
 
 
     /**
     /**
      * The class name managed by the admin class.
      * The class name managed by the admin class.

+ 8 - 8
Resources/doc/reference/security.rst

@@ -31,7 +31,7 @@ The install process is available on the dedicated
 Security handlers
 Security handlers
 -----------------
 -----------------
 
 
-The security part is managed by a ``SecurityHandler``, the bundle comes with 3 handlers
+The security part is managed by a ``SecurityHandler``, the bundle comes with 3 handlers:
 
 
 - ``sonata.admin.security.handler.role``: ROLES to handle permissions
 - ``sonata.admin.security.handler.role``: ROLES to handle permissions
 - ``sonata.admin.security.handler.acl``: ACL and ROLES to handle permissions
 - ``sonata.admin.security.handler.acl``: ACL and ROLES to handle permissions
@@ -104,7 +104,7 @@ Configuration
 
 
 First, activate the role security handler as described above.
 First, activate the role security handler as described above.
 
 
-Each time an user tries to do an action in the admin, Sonata checks if he is
+Each time a user tries to do an action in the admin, Sonata checks if he is
 either a super admin (``ROLE_SUPER_ADMIN``) **or** has the permission.
 either a super admin (``ROLE_SUPER_ADMIN``) **or** has the permission.
 
 
 The permissions are:
 The permissions are:
@@ -129,7 +129,7 @@ The role name will be based on the name of your admin service. For instance, ``a
 
 
     If your admin service is named like ``my.blog.admin.foo_bar`` (note the underscore ``_``) it will become: ``ROLE_MY_BLOG_ADMIN_FOO_BAR_{ACTION}``
     If your admin service is named like ``my.blog.admin.foo_bar`` (note the underscore ``_``) it will become: ``ROLE_MY_BLOG_ADMIN_FOO_BAR_{ACTION}``
 
 
-So our ``security.yml`` file may look to something like this:
+So our ``security.yml`` file may look something like this:
 
 
 .. configuration-block::
 .. configuration-block::
 
 
@@ -310,7 +310,7 @@ The following configuration for the SonataUserBundle defines:
 - the login form for authentication
 - the login form for authentication
 - the access control: resources with related required roles, the important
 - the access control: resources with related required roles, the important
   part is the admin configuration
   part is the admin configuration
-- the ``acl`` option to enable the ACL.
+- the ``acl`` option to enable the ACL
 - the ``AdminPermissionMap`` defines the permissions of the Admin class
 - the ``AdminPermissionMap`` defines the permissions of the Admin class
 
 
 .. configuration-block::
 .. configuration-block::
@@ -459,10 +459,10 @@ Owner:
 Vocabulary used for Access Control Lists:
 Vocabulary used for Access Control Lists:
 
 
 - **Role:** a user role;
 - **Role:** a user role;
-- **ACL:** a list of access rules, the Admin uses 2 types:
+- **ACL:** a list of access rules, the Admin uses 2 types;
 - **Admin ACL:** created from the Security information of the Admin class
 - **Admin ACL:** created from the Security information of the Admin class
   for  each admin and shares the Access Control Entries that specify what
   for  each admin and shares the Access Control Entries that specify what
-  the  user can do (permissions) with the admin
+  the  user can do (permissions) with the admin;
 - **Object ACL:** also created from the security information of the ``Admin``
 - **Object ACL:** also created from the security information of the ``Admin``
   class however created for each object, it uses 2 scopes:
   class however created for each object, it uses 2 scopes:
 
 
@@ -497,9 +497,9 @@ In the application the security context is asked if access is granted for a role
 or a permission (``admin.isGranted``):
 or a permission (``admin.isGranted``):
 
 
 - **Token:** a token identifies a user between requests;
 - **Token:** a token identifies a user between requests;
-- **Voter:** sort of judge that returns if access is granted of denied, if the
+- **Voter:** sort of judge that returns whether access is granted or denied, if the
   voter should not vote for a case, it returns abstain;
   voter should not vote for a case, it returns abstain;
-- **AccessDecisionManager:** decides if access is granted or denied according
+- **AccessDecisionManager:** decides whether access is granted or denied according
   a specific strategy. It grants access if at least one (affirmative strategy),
   a specific strategy. It grants access if at least one (affirmative strategy),
   all (unanimous strategy) or more then half (consensus strategy) of the
   all (unanimous strategy) or more then half (consensus strategy) of the
   counted votes granted access;
   counted votes granted access;

+ 1 - 1
Resources/views/empty_layout.html.twig

@@ -9,7 +9,7 @@ file that was distributed with this source code.
 
 
 #}
 #}
 
 
-{% extends 'SonataAdminBundle::standard_layout.html.twig' %}
+{% extends admin_pool.getTemplate('layout') %}
 
 
 {% block sonata_header %}{% endblock %}
 {% block sonata_header %}{% endblock %}
 {% block sonata_left_side %}{% endblock %}
 {% block sonata_left_side %}{% endblock %}

+ 22 - 8
Tests/Admin/AdminTest.php

@@ -442,6 +442,10 @@ class AdminTest extends \PHPUnit_Framework_TestCase
                 'AppBundle\Entity\User',
                 'AppBundle\Entity\User',
                 '/app/user',
                 '/app/user',
             ),
             ),
+            array(
+                'App\Entity\User',
+                '/app/user',
+            ),
         );
         );
     }
     }
 
 
@@ -454,13 +458,16 @@ class AdminTest extends \PHPUnit_Framework_TestCase
         $this->assertSame($expected, $admin->getBaseRoutePattern());
         $this->assertSame($expected, $admin->getBaseRoutePattern());
     }
     }
 
 
-    public function testGetBaseRoutePatternWithChildAdmin()
+    /**
+     * @dataProvider provideGetBaseRoutePattern
+     */
+    public function testGetBaseRoutePatternWithChildAdmin($objFqn, $expected)
     {
     {
-        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
+        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
         $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
         $commentAdmin = new CommentAdmin('sonata.post.admin.comment', 'Application\Sonata\NewsBundle\Entity\Comment', 'SonataNewsBundle:CommentAdmin');
         $commentAdmin->setParent($postAdmin);
         $commentAdmin->setParent($postAdmin);
 
 
-        $this->assertSame('/sonata/news/post/{id}/comment', $commentAdmin->getBaseRoutePattern());
+        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
     }
     }
 
 
     public function testGetBaseRoutePatternWithSpecifedPattern()
     public function testGetBaseRoutePatternWithSpecifedPattern()
@@ -484,7 +491,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
      */
      */
     public function testGetBaseRoutePatternWithUnreconizedClassname()
     public function testGetBaseRoutePatternWithUnreconizedClassname()
     {
     {
-        $admin = new PostAdmin('sonata.post.admin.post', 'News\Entity\Post', 'SonataNewsBundle:PostAdmin');
+        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'SonataNewsBundle:PostAdmin');
         $admin->getBaseRoutePattern();
         $admin->getBaseRoutePattern();
     }
     }
 
 
@@ -547,6 +554,10 @@ class AdminTest extends \PHPUnit_Framework_TestCase
                 'AppBundle\Entity\User',
                 'AppBundle\Entity\User',
                 'admin_app_user',
                 'admin_app_user',
             ),
             ),
+            array(
+                'App\Entity\User',
+                'admin_app_user',
+            ),
         );
         );
     }
     }
 
 
@@ -560,7 +571,10 @@ class AdminTest extends \PHPUnit_Framework_TestCase
         $this->assertSame($expected, $admin->getBaseRouteName());
         $this->assertSame($expected, $admin->getBaseRouteName());
     }
     }
 
 
-    public function testGetBaseRouteNameWithChildAdmin()
+    /**
+     * @dataProvider provideGetBaseRouteName
+     */
+    public function testGetBaseRouteNameWithChildAdmin($objFqn, $expected)
     {
     {
         $routeGenerator = new DefaultRouteGenerator(
         $routeGenerator = new DefaultRouteGenerator(
             $this->getMock('Symfony\Component\Routing\RouterInterface'),
             $this->getMock('Symfony\Component\Routing\RouterInterface'),
@@ -568,7 +582,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
         );
         );
 
 
         $pathInfo = new \Sonata\AdminBundle\Route\PathInfoBuilder($this->getMock('Sonata\AdminBundle\Model\AuditManagerInterface'));
         $pathInfo = new \Sonata\AdminBundle\Route\PathInfoBuilder($this->getMock('Sonata\AdminBundle\Model\AuditManagerInterface'));
-        $postAdmin = new PostAdmin('sonata.post.admin.post', 'Application\Sonata\NewsBundle\Entity\Post', 'SonataNewsBundle:PostAdmin');
+        $postAdmin = new PostAdmin('sonata.post.admin.post', $objFqn, 'SonataNewsBundle:PostAdmin');
         $postAdmin->setRouteBuilder($pathInfo);
         $postAdmin->setRouteBuilder($pathInfo);
         $postAdmin->setRouteGenerator($routeGenerator);
         $postAdmin->setRouteGenerator($routeGenerator);
         $postAdmin->initialize();
         $postAdmin->initialize();
@@ -580,7 +594,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
 
 
         $postAdmin->addChild($commentAdmin);
         $postAdmin->addChild($commentAdmin);
 
 
-        $this->assertSame('admin_sonata_news_post_comment', $commentAdmin->getBaseRouteName());
+        $this->assertSame($expected.'_comment', $commentAdmin->getBaseRouteName());
 
 
         $this->assertTrue($postAdmin->hasRoute('show'));
         $this->assertTrue($postAdmin->hasRoute('show'));
         $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
         $this->assertTrue($postAdmin->hasRoute('sonata.post.admin.post.show'));
@@ -595,7 +609,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
      */
      */
     public function testGetBaseRouteNameWithUnreconizedClassname()
     public function testGetBaseRouteNameWithUnreconizedClassname()
     {
     {
-        $admin = new PostAdmin('sonata.post.admin.post', 'News\Entity\Post', 'SonataNewsBundle:PostAdmin');
+        $admin = new PostAdmin('sonata.post.admin.post', 'News\Thing\Post', 'SonataNewsBundle:PostAdmin');
         $admin->getBaseRouteName();
         $admin->getBaseRouteName();
     }
     }
 
 

+ 22 - 0
Tests/Controller/CoreControllerTest.php

@@ -46,6 +46,17 @@ class CoreControllerTest extends \PHPUnit_Framework_TestCase
         $container->expects($this->any())->method('get')->will($this->returnCallback(function ($id) use ($values) {
         $container->expects($this->any())->method('get')->will($this->returnCallback(function ($id) use ($values) {
             return $values[$id];
             return $values[$id];
         }));
         }));
+
+        $container->expects($this->any())
+            ->method('has')
+            ->will($this->returnCallback(function ($id) {
+                if ($id == 'templating') {
+                    return true;
+                }
+
+                return false;
+            }));
+
         $container->expects($this->any())->method('getParameter')->will($this->returnCallback(function ($name) {
         $container->expects($this->any())->method('getParameter')->will($this->returnCallback(function ($name) {
             if ($name == 'sonata.admin.configuration.dashboard_blocks') {
             if ($name == 'sonata.admin.configuration.dashboard_blocks') {
                 return array();
                 return array();
@@ -96,6 +107,17 @@ class CoreControllerTest extends \PHPUnit_Framework_TestCase
         $container->expects($this->any())->method('get')->will($this->returnCallback(function ($id) use ($values) {
         $container->expects($this->any())->method('get')->will($this->returnCallback(function ($id) use ($values) {
             return $values[$id];
             return $values[$id];
         }));
         }));
+
+        $container->expects($this->any())
+            ->method('has')
+            ->will($this->returnCallback(function ($id) {
+                if ($id == 'templating') {
+                    return true;
+                }
+
+                return false;
+            }));
+
         $container->expects($this->any())->method('getParameter')->will($this->returnCallback(function ($name) {
         $container->expects($this->any())->method('getParameter')->will($this->returnCallback(function ($name) {
             if ($name == 'sonata.admin.configuration.dashboard_blocks') {
             if ($name == 'sonata.admin.configuration.dashboard_blocks') {
                 return array();
                 return array();

+ 2 - 0
Tests/DependencyInjection/Compiler/AnnotationCompilerPassTest.php

@@ -55,6 +55,8 @@ class AnnotationCompilerPassTest extends \PHPUnit_Framework_TestCase
             $meta->tags['sonata.admin'][0],
             $meta->tags['sonata.admin'][0],
             array(
             array(
                 'manager_type'      => 'orm',
                 'manager_type'      => 'orm',
+                'group'             => 'Admin',
+                'label'             => 'Tests\Fixtures\Foo',
                 'show_in_dashboard' => false,
                 'show_in_dashboard' => false,
             )
             )
         );
         );

+ 6 - 8
Tests/Twig/Extension/SonataAdminExtensionTest.php

@@ -116,8 +116,6 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
         $this->environment->addExtension(new RoutingExtension($urlGenerator));
         $this->environment->addExtension(new RoutingExtension($urlGenerator));
         $this->environment->addExtension(new \Twig_Extensions_Extension_Text());
         $this->environment->addExtension(new \Twig_Extensions_Extension_Text());
 
 
-        $this->twigExtension->initRuntime($this->environment);
-
         // initialize object
         // initialize object
         $this->object = new \stdClass();
         $this->object = new \stdClass();
 
 
@@ -247,7 +245,7 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
                 }
                 }
             }));
             }));
 
 
-        $this->assertSame($expected, trim(preg_replace('/\s+/', ' ', $this->twigExtension->renderListElement($this->object, $this->fieldDescription))));
+        $this->assertSame($expected, trim(preg_replace('/\s+/', ' ', $this->twigExtension->renderListElement($this->environment, $this->object, $this->fieldDescription))));
     }
     }
 
 
     public function getRenderListElementTests()
     public function getRenderListElementTests()
@@ -407,7 +405,7 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
             ->method('warning')
             ->method('warning')
             ->with(($this->stringStartsWith('An error occured trying to load the template "SonataAdminBundle:CRUD:list_nonexistent_template.html.twig" for the field "Foo_name", the default template "SonataAdminBundle:CRUD:base_list_field.html.twig" was used instead: "Unable to find template "list_nonexistent_template.html.twig')));
             ->with(($this->stringStartsWith('An error occured trying to load the template "SonataAdminBundle:CRUD:list_nonexistent_template.html.twig" for the field "Foo_name", the default template "SonataAdminBundle:CRUD:base_list_field.html.twig" was used instead: "Unable to find template "list_nonexistent_template.html.twig')));
 
 
-        $this->twigExtension->renderListElement($this->object, $this->fieldDescription);
+        $this->twigExtension->renderListElement($this->environment, $this->object, $this->fieldDescription);
     }
     }
 
 
     /**
     /**
@@ -425,7 +423,7 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
             ->method('getTemplate')
             ->method('getTemplate')
             ->will($this->returnValue('SonataAdminBundle:CRUD:list_nonexistent_template.html.twig'));
             ->will($this->returnValue('SonataAdminBundle:CRUD:list_nonexistent_template.html.twig'));
 
 
-        $this->twigExtension->renderListElement($this->object, $this->fieldDescription);
+        $this->twigExtension->renderListElement($this->environment, $this->object, $this->fieldDescription);
     }
     }
 
 
     /**
     /**
@@ -486,7 +484,7 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
                 }
                 }
             }));
             }));
 
 
-        $this->assertSame($expected, trim(preg_replace('/\s+/', ' ', $this->twigExtension->renderViewElement($this->fieldDescription, $this->object))));
+        $this->assertSame($expected, trim(preg_replace('/\s+/', ' ', $this->twigExtension->renderViewElement($this->environment, $this->fieldDescription, $this->object))));
     }
     }
 
 
     public function getRenderViewElementTests()
     public function getRenderViewElementTests()
@@ -702,11 +700,11 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
         $template = $this->environment->loadTemplate('SonataAdminBundle:CRUD:base_list_field.html.twig');
         $template = $this->environment->loadTemplate('SonataAdminBundle:CRUD:base_list_field.html.twig');
 
 
         $this->assertSame('<td class="sonata-ba-list-field sonata-ba-list-field-" objectId="12345"> foo </td>',
         $this->assertSame('<td class="sonata-ba-list-field sonata-ba-list-field-" objectId="12345"> foo </td>',
-                trim(preg_replace('/\s+/', ' ', $this->twigExtension->output($this->fieldDescription, $template, $parameters))));
+                trim(preg_replace('/\s+/', ' ', $this->twigExtension->output($this->fieldDescription, $template, $parameters, $this->environment))));
 
 
         $this->environment->enableDebug();
         $this->environment->enableDebug();
         $this->assertSame('<!-- START fieldName: fd_name template: SonataAdminBundle:CRUD:base_list_field.html.twig compiled template: SonataAdminBundle:CRUD:base_list_field.html.twig --> <td class="sonata-ba-list-field sonata-ba-list-field-" objectId="12345"> foo </td> <!-- END - fieldName: fd_name -->',
         $this->assertSame('<!-- START fieldName: fd_name template: SonataAdminBundle:CRUD:base_list_field.html.twig compiled template: SonataAdminBundle:CRUD:base_list_field.html.twig --> <td class="sonata-ba-list-field sonata-ba-list-field-" objectId="12345"> foo </td> <!-- END - fieldName: fd_name -->',
-                trim(preg_replace('/\s+/', ' ', $this->twigExtension->output($this->fieldDescription, $template, $parameters))));
+                trim(preg_replace('/\s+/', ' ', $this->twigExtension->output($this->fieldDescription, $template, $parameters, $this->environment))));
     }
     }
 
 
     public function testRenderRelationElementNoObject()
     public function testRenderRelationElementNoObject()

+ 17 - 29
Twig/Extension/SonataAdminExtension.php

@@ -17,6 +17,7 @@ use Sonata\AdminBundle\Admin\AdminInterface;
 use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
 use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
 use Sonata\AdminBundle\Admin\Pool;
 use Sonata\AdminBundle\Admin\Pool;
 use Sonata\AdminBundle\Exception\NoValueException;
 use Sonata\AdminBundle\Exception\NoValueException;
+use Twig_Environment;
 
 
 /**
 /**
  * Class SonataAdminExtension.
  * Class SonataAdminExtension.
@@ -25,11 +26,6 @@ use Sonata\AdminBundle\Exception\NoValueException;
  */
  */
 class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_InitRuntimeInterface
 class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_InitRuntimeInterface
 {
 {
-    /**
-     * @var \Twig_Environment
-     */
-    protected $environment;
-
     /**
     /**
      * @var Pool
      * @var Pool
      */
      */
@@ -50,22 +46,14 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
         $this->logger    = $logger;
         $this->logger    = $logger;
     }
     }
 
 
-    /**
-     * {@inheritdoc}
-     */
-    public function initRuntime(\Twig_Environment $environment)
-    {
-        $this->environment = $environment;
-    }
-
     /**
     /**
      * {@inheritdoc}
      * {@inheritdoc}
      */
      */
     public function getFilters()
     public function getFilters()
     {
     {
         return array(
         return array(
-            new \Twig_SimpleFilter('render_list_element', array($this, 'renderListElement'), array('is_safe' => array('html'))),
-            new \Twig_SimpleFilter('render_view_element', array($this, 'renderViewElement'), array('is_safe' => array('html'))),
+            new \Twig_SimpleFilter('render_list_element', array($this, 'renderListElement'), array('is_safe' => array('html'), 'needs_environment' => true)),
+            new \Twig_SimpleFilter('render_view_element', array($this, 'renderViewElement'), array('is_safe' => array('html'), 'needs_environment' => true)),
             new \Twig_SimpleFilter('render_view_element_compare', array($this, 'renderViewElementCompare'), array('is_safe' => array('html'))),
             new \Twig_SimpleFilter('render_view_element_compare', array($this, 'renderViewElementCompare'), array('is_safe' => array('html'))),
             new \Twig_SimpleFilter('render_relation_element', array($this, 'renderRelationElement')),
             new \Twig_SimpleFilter('render_relation_element', array($this, 'renderRelationElement')),
             new \Twig_SimpleFilter('sonata_urlsafeid', array($this, 'getUrlsafeIdentifier')),
             new \Twig_SimpleFilter('sonata_urlsafeid', array($this, 'getUrlsafeIdentifier')),
@@ -89,14 +77,14 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      *
      * @return \Twig_Template
      * @return \Twig_Template
      */
      */
-    protected function getTemplate(FieldDescriptionInterface $fieldDescription, $defaultTemplate)
+    protected function getTemplate(FieldDescriptionInterface $fieldDescription, $defaultTemplate, Twig_Environment $environment)
     {
     {
         $templateName = $fieldDescription->getTemplate() ?: $defaultTemplate;
         $templateName = $fieldDescription->getTemplate() ?: $defaultTemplate;
 
 
         try {
         try {
-            $template = $this->environment->loadTemplate($templateName);
+            $template = $environment->loadTemplate($templateName);
         } catch (\Twig_Error_Loader $e) {
         } catch (\Twig_Error_Loader $e) {
-            $template = $this->environment->loadTemplate($defaultTemplate);
+            $template = $environment->loadTemplate($defaultTemplate);
 
 
             if (null !== $this->logger) {
             if (null !== $this->logger) {
                 $this->logger->warning(sprintf('An error occured trying to load the template "%s" for the field "%s", the default template "%s" was used instead: "%s". ', $templateName, $fieldDescription->getFieldName(), $defaultTemplate, $e->getMessage()));
                 $this->logger->warning(sprintf('An error occured trying to load the template "%s" for the field "%s", the default template "%s" was used instead: "%s". ', $templateName, $fieldDescription->getFieldName(), $defaultTemplate, $e->getMessage()));
@@ -115,16 +103,16 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      *
      * @return string
      * @return string
      */
      */
-    public function renderListElement($object, FieldDescriptionInterface $fieldDescription, $params = array())
+    public function renderListElement(Twig_Environment $environment, $object, FieldDescriptionInterface $fieldDescription, $params = array())
     {
     {
-        $template = $this->getTemplate($fieldDescription, $fieldDescription->getAdmin()->getTemplate('base_list_field'));
+        $template = $this->getTemplate($fieldDescription, $fieldDescription->getAdmin()->getTemplate('base_list_field'), $environment);
 
 
         return $this->output($fieldDescription, $template, array_merge($params, array(
         return $this->output($fieldDescription, $template, array_merge($params, array(
             'admin'             => $fieldDescription->getAdmin(),
             'admin'             => $fieldDescription->getAdmin(),
             'object'            => $object,
             'object'            => $object,
             'value'             => $this->getValueFromFieldDescription($object, $fieldDescription),
             'value'             => $this->getValueFromFieldDescription($object, $fieldDescription),
             'field_description' => $fieldDescription,
             'field_description' => $fieldDescription,
-        )));
+        )), $environment);
     }
     }
 
 
     /**
     /**
@@ -134,11 +122,11 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      *
      * @return string
      * @return string
      */
      */
-    public function output(FieldDescriptionInterface $fieldDescription, \Twig_Template $template, array $parameters = array())
+    public function output(FieldDescriptionInterface $fieldDescription, \Twig_Template $template, array $parameters = array(), Twig_Environment $environment)
     {
     {
         $content = $template->render($parameters);
         $content = $template->render($parameters);
 
 
-        if ($this->environment->isDebug()) {
+        if ($environment->isDebug()) {
             return sprintf("\n<!-- START  \n  fieldName: %s\n  template: %s\n  compiled template: %s\n -->\n%s\n<!-- END - fieldName: %s -->",
             return sprintf("\n<!-- START  \n  fieldName: %s\n  template: %s\n  compiled template: %s\n -->\n%s\n<!-- END - fieldName: %s -->",
                 $fieldDescription->getFieldName(),
                 $fieldDescription->getFieldName(),
                 $fieldDescription->getTemplate(),
                 $fieldDescription->getTemplate(),
@@ -189,9 +177,9 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      *
      * @return string
      * @return string
      */
      */
-    public function renderViewElement(FieldDescriptionInterface $fieldDescription, $object)
+    public function renderViewElement(Twig_Environment $environment, FieldDescriptionInterface $fieldDescription, $object)
     {
     {
-        $template = $this->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_show_field.html.twig');
+        $template = $this->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_show_field.html.twig', $environment);
 
 
         try {
         try {
             $value = $fieldDescription->getValue($object);
             $value = $fieldDescription->getValue($object);
@@ -204,7 +192,7 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
             'object'            => $object,
             'object'            => $object,
             'value'             => $value,
             'value'             => $value,
             'admin'             => $fieldDescription->getAdmin(),
             'admin'             => $fieldDescription->getAdmin(),
-        ));
+        ), $environment);
     }
     }
 
 
     /**
     /**
@@ -216,9 +204,9 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      *
      * @return string
      * @return string
      */
      */
-    public function renderViewElementCompare(FieldDescriptionInterface $fieldDescription, $baseObject, $compareObject)
+    public function renderViewElementCompare(Twig_Environment $environment, FieldDescriptionInterface $fieldDescription, $baseObject, $compareObject)
     {
     {
-        $template = $this->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_show_field.html.twig');
+        $template = $this->getTemplate($fieldDescription, 'SonataAdminBundle:CRUD:base_show_field.html.twig', $environment);
 
 
         try {
         try {
             $baseValue = $fieldDescription->getValue($baseObject);
             $baseValue = $fieldDescription->getValue($baseObject);
@@ -253,7 +241,7 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
             'value_compare'     => $compareValue,
             'value_compare'     => $compareValue,
             'is_diff'           => $isDiff,
             'is_diff'           => $isDiff,
             'admin'             => $fieldDescription->getAdmin(),
             'admin'             => $fieldDescription->getAdmin(),
-        ));
+        ), $environment);
     }
     }
 
 
     /**
     /**