Procházet zdrojové kódy

Merge pull request #3687 from greg0ire/2.x

Backport 2.3 changes
Oskar Stark před 9 roky
rodič
revize
1bcdfcd4cc

+ 1 - 1
.travis.yml

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

+ 1 - 1
Admin/Admin.php

@@ -57,7 +57,7 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
     const CONTEXT_MENU       = 'menu';
     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.

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

@@ -31,7 +31,7 @@ The install process is available on the dedicated
 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.acl``: ACL and ROLES to handle permissions
@@ -104,7 +104,7 @@ Configuration
 
 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.
 
 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}``
 
-So our ``security.yml`` file may look to something like this:
+So our ``security.yml`` file may look something like this:
 
 .. configuration-block::
 
@@ -310,7 +310,7 @@ The following configuration for the SonataUserBundle defines:
 - the login form for authentication
 - the access control: resources with related required roles, the important
   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
 
 .. configuration-block::
@@ -459,10 +459,10 @@ Owner:
 Vocabulary used for Access Control Lists:
 
 - **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
   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``
   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``):
 
 - **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;
-- **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),
   all (unanimous strategy) or more then half (consensus strategy) of the
   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_left_side %}{% endblock %}

+ 22 - 8
Tests/Admin/AdminTest.php

@@ -442,6 +442,10 @@ class AdminTest extends \PHPUnit_Framework_TestCase
                 'AppBundle\Entity\User',
                 '/app/user',
             ),
+            array(
+                'App\Entity\User',
+                '/app/user',
+            ),
         );
     }
 
@@ -454,13 +458,16 @@ class AdminTest extends \PHPUnit_Framework_TestCase
         $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->setParent($postAdmin);
 
-        $this->assertSame('/sonata/news/post/{id}/comment', $commentAdmin->getBaseRoutePattern());
+        $this->assertSame($expected.'/{id}/comment', $commentAdmin->getBaseRoutePattern());
     }
 
     public function testGetBaseRoutePatternWithSpecifedPattern()
@@ -484,7 +491,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
      */
     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();
     }
 
@@ -547,6 +554,10 @@ class AdminTest extends \PHPUnit_Framework_TestCase
                 'AppBundle\Entity\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());
     }
 
-    public function testGetBaseRouteNameWithChildAdmin()
+    /**
+     * @dataProvider provideGetBaseRouteName
+     */
+    public function testGetBaseRouteNameWithChildAdmin($objFqn, $expected)
     {
         $routeGenerator = new DefaultRouteGenerator(
             $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'));
-        $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->setRouteGenerator($routeGenerator);
         $postAdmin->initialize();
@@ -580,7 +594,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
 
         $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('sonata.post.admin.post.show'));
@@ -595,7 +609,7 @@ class AdminTest extends \PHPUnit_Framework_TestCase
      */
     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();
     }
 

+ 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) {
             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) {
             if ($name == 'sonata.admin.configuration.dashboard_blocks') {
                 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) {
             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) {
             if ($name == 'sonata.admin.configuration.dashboard_blocks') {
                 return array();

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

@@ -55,6 +55,8 @@ class AnnotationCompilerPassTest extends \PHPUnit_Framework_TestCase
             $meta->tags['sonata.admin'][0],
             array(
                 'manager_type'      => 'orm',
+                'group'             => 'Admin',
+                'label'             => 'Tests\Fixtures\Foo',
                 '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 \Twig_Extensions_Extension_Text());
 
-        $this->twigExtension->initRuntime($this->environment);
-
         // initialize object
         $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()
@@ -407,7 +405,7 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
             ->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')));
 
-        $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')
             ->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()
@@ -702,11 +700,11 @@ class SonataAdminExtensionTest extends \PHPUnit_Framework_TestCase
         $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>',
-                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->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()

+ 17 - 29
Twig/Extension/SonataAdminExtension.php

@@ -17,6 +17,7 @@ use Sonata\AdminBundle\Admin\AdminInterface;
 use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
 use Sonata\AdminBundle\Admin\Pool;
 use Sonata\AdminBundle\Exception\NoValueException;
+use Twig_Environment;
 
 /**
  * Class SonataAdminExtension.
@@ -25,11 +26,6 @@ use Sonata\AdminBundle\Exception\NoValueException;
  */
 class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_InitRuntimeInterface
 {
-    /**
-     * @var \Twig_Environment
-     */
-    protected $environment;
-
     /**
      * @var Pool
      */
@@ -50,22 +46,14 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
         $this->logger    = $logger;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function initRuntime(\Twig_Environment $environment)
-    {
-        $this->environment = $environment;
-    }
-
     /**
      * {@inheritdoc}
      */
     public function getFilters()
     {
         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_relation_element', array($this, 'renderRelationElement')),
             new \Twig_SimpleFilter('sonata_urlsafeid', array($this, 'getUrlsafeIdentifier')),
@@ -89,14 +77,14 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      * @return \Twig_Template
      */
-    protected function getTemplate(FieldDescriptionInterface $fieldDescription, $defaultTemplate)
+    protected function getTemplate(FieldDescriptionInterface $fieldDescription, $defaultTemplate, Twig_Environment $environment)
     {
         $templateName = $fieldDescription->getTemplate() ?: $defaultTemplate;
 
         try {
-            $template = $this->environment->loadTemplate($templateName);
+            $template = $environment->loadTemplate($templateName);
         } catch (\Twig_Error_Loader $e) {
-            $template = $this->environment->loadTemplate($defaultTemplate);
+            $template = $environment->loadTemplate($defaultTemplate);
 
             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()));
@@ -115,16 +103,16 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      * @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(
             'admin'             => $fieldDescription->getAdmin(),
             'object'            => $object,
             'value'             => $this->getValueFromFieldDescription($object, $fieldDescription),
             'field_description' => $fieldDescription,
-        )));
+        )), $environment);
     }
 
     /**
@@ -134,11 +122,11 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      * @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);
 
-        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 -->",
                 $fieldDescription->getFieldName(),
                 $fieldDescription->getTemplate(),
@@ -189,9 +177,9 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      * @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 {
             $value = $fieldDescription->getValue($object);
@@ -204,7 +192,7 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
             'object'            => $object,
             'value'             => $value,
             'admin'             => $fieldDescription->getAdmin(),
-        ));
+        ), $environment);
     }
 
     /**
@@ -216,9 +204,9 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
      *
      * @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 {
             $baseValue = $fieldDescription->getValue($baseObject);
@@ -253,7 +241,7 @@ class SonataAdminExtension extends \Twig_Extension implements \Twig_Extension_In
             'value_compare'     => $compareValue,
             'is_diff'           => $isDiff,
             'admin'             => $fieldDescription->getAdmin(),
-        ));
+        ), $environment);
     }
 
     /**