Issue #2368275 by martin107, dawehner, znerol, Crell, Wim Leers: EntityRouteEnhancer and ContentFormControllerSubscriber implicitly depend on too many services
parent
58480ee670
commit
07a6a686a1
|
@ -639,7 +639,6 @@ services:
|
|||
arguments: ['@authentication', '@current_user']
|
||||
route_enhancer.entity:
|
||||
class: Drupal\Core\Entity\Enhancer\EntityRouteEnhancer
|
||||
arguments: ['@controller_resolver', '@entity.manager', '@form_builder']
|
||||
tags:
|
||||
- { name: route_enhancer, priority: 20 }
|
||||
route_content_controller_subscriber:
|
||||
|
@ -647,12 +646,6 @@ services:
|
|||
arguments: ['@content_negotiation']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
route_content_form_controller_subscriber:
|
||||
class: Drupal\Core\EventSubscriber\ContentFormControllerSubscriber
|
||||
arguments: ['@class_resolver', '@controller_resolver', '@form_builder']
|
||||
parent: container.trait
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
route_special_attributes_subscriber:
|
||||
class: Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
|
||||
tags:
|
||||
|
@ -688,7 +681,12 @@ services:
|
|||
arguments: ['@title_resolver']
|
||||
tags:
|
||||
- { name: render.main_content_renderer, format: drupal_modal }
|
||||
|
||||
controller.form:
|
||||
class: Drupal\Core\Controller\HtmlFormController
|
||||
arguments: ['@controller_resolver', '@form_builder', '@class_resolver']
|
||||
controller.entity_form:
|
||||
class: Drupal\Core\Entity\HtmlEntityFormController
|
||||
arguments: ['@controller_resolver', '@form_builder', '@entity.manager']
|
||||
router_listener:
|
||||
class: Symfony\Component\HttpKernel\EventListener\RouterListener
|
||||
tags:
|
||||
|
|
|
@ -19,12 +19,6 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
*/
|
||||
abstract class FormController {
|
||||
use DependencySerializationTrait;
|
||||
/**
|
||||
* The form definition. The format may vary depending on the child class.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $formDefinition;
|
||||
|
||||
/**
|
||||
* The controller resolver.
|
||||
|
@ -63,14 +57,15 @@ abstract class FormController {
|
|||
* The render array that results from invoking the controller.
|
||||
*/
|
||||
public function getContentResult(Request $request) {
|
||||
$form_object = $this->getFormObject($request, $this->formDefinition);
|
||||
$form_arg = $this->getFormArgument($request);
|
||||
$form_object = $this->getFormObject($request, $form_arg);
|
||||
|
||||
// Add the form and form_state to trick the getArguments method of the
|
||||
// controller resolver.
|
||||
$form_state = new FormState();
|
||||
$request->attributes->set('form', array());
|
||||
$request->attributes->set('form', []);
|
||||
$request->attributes->set('form_state', $form_state);
|
||||
$args = $this->controllerResolver->getArguments($request, array($form_object, 'buildForm'));
|
||||
$args = $this->controllerResolver->getArguments($request, [$form_object, 'buildForm']);
|
||||
$request->attributes->remove('form');
|
||||
$request->attributes->remove('form_state');
|
||||
|
||||
|
@ -81,6 +76,26 @@ abstract class FormController {
|
|||
return $this->formBuilder->buildForm($form_object, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the form argument string from a request.
|
||||
*
|
||||
* Depending on the type of form the argument string may be stored in a
|
||||
* different request attribute.
|
||||
*
|
||||
* One example of a route definition is given below.
|
||||
* @code
|
||||
* defaults:
|
||||
* _form: Drupal\example\Form\ExampleForm
|
||||
* @endcode
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object from which to extract a form definition string.
|
||||
*
|
||||
* @return string
|
||||
* The form definition string.
|
||||
*/
|
||||
abstract protected function getFormArgument(Request $request);
|
||||
|
||||
/**
|
||||
* Returns the object used to build the form.
|
||||
*
|
||||
|
|
|
@ -9,29 +9,13 @@ namespace Drupal\Core\Controller;
|
|||
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\DependencyInjection\ClassResolverInterface;
|
||||
use Drupal\Core\Controller\ControllerResolverInterface;
|
||||
|
||||
/**
|
||||
* Wrapping controller for forms that serve as the main page body.
|
||||
*/
|
||||
class HtmlFormController extends FormController {
|
||||
|
||||
/**
|
||||
* The injection container for this object.
|
||||
*
|
||||
* @var \Symfony\Component\DependencyInjection\ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* The name of a class implementing FormInterface that defines a form.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $formClass;
|
||||
|
||||
/**
|
||||
* The class resolver.
|
||||
*
|
||||
|
@ -41,12 +25,24 @@ class HtmlFormController extends FormController {
|
|||
|
||||
/**
|
||||
* Constructs a new \Drupal\Core\Routing\Enhancer\FormEnhancer object.
|
||||
*
|
||||
* @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
|
||||
* The controller resolver.
|
||||
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
|
||||
* The form builder.
|
||||
* @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
|
||||
* The class resolver.
|
||||
*/
|
||||
public function __construct(ClassResolverInterface $class_resolver, ControllerResolverInterface $controller_resolver, ContainerInterface $container, $class, FormBuilderInterface $form_builder) {
|
||||
public function __construct(ControllerResolverInterface $controller_resolver, FormBuilderInterface $form_builder, ClassResolverInterface $class_resolver) {
|
||||
parent::__construct($controller_resolver, $form_builder);
|
||||
$this->classResolver = $class_resolver;
|
||||
$this->container = $container;
|
||||
$this->formDefinition = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @{inheritDoc}
|
||||
*/
|
||||
protected function getFormArgument(Request $request) {
|
||||
return $request->attributes->get('_form');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
|
||||
namespace Drupal\Core\Entity\Enhancer;
|
||||
|
||||
use Drupal\Core\Controller\ControllerResolverInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\HtmlEntityFormController;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
|
||||
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||
|
@ -20,51 +16,13 @@ use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
|||
*/
|
||||
class EntityRouteEnhancer implements RouteEnhancerInterface {
|
||||
|
||||
/**
|
||||
* The controller resolver.
|
||||
*
|
||||
* @var \Drupal\Core\Controller\ControllerResolverInterface
|
||||
*/
|
||||
protected $resolver;
|
||||
|
||||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* The form builder.
|
||||
*
|
||||
* @var \Drupal\Core\Form\FormBuilderInterface
|
||||
*/
|
||||
protected $formBuilder;
|
||||
|
||||
/**
|
||||
* Constructs a new EntityRouteEnhancer object.
|
||||
*
|
||||
* @param \Drupal\Core\Controller\ControllerResolverInterface $resolver
|
||||
* The controller resolver.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
|
||||
* The form builder.
|
||||
*/
|
||||
public function __construct(ControllerResolverInterface $resolver, EntityManagerInterface $manager, FormBuilderInterface $form_builder) {
|
||||
$this->resolver = $resolver;
|
||||
$this->manager = $manager;
|
||||
$this->formBuilder = $form_builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function enhance(array $defaults, Request $request) {
|
||||
if (empty($defaults['_controller'])) {
|
||||
if (!empty($defaults['_entity_form'])) {
|
||||
$wrapper = new HtmlEntityFormController($this->resolver, $this->manager, $this->formBuilder, $defaults['_entity_form']);
|
||||
$defaults['_controller'] = array($wrapper, 'getContentResult');
|
||||
$defaults['_controller'] = 'controller.entity_form:getContentResult';
|
||||
}
|
||||
elseif (!empty($defaults['_entity_list'])) {
|
||||
$defaults['_controller'] = '\Drupal\Core\Entity\Controller\EntityListController::listing';
|
||||
|
|
|
@ -29,17 +29,21 @@ class HtmlEntityFormController extends FormController {
|
|||
*
|
||||
* @param \Drupal\Core\Controller\ControllerResolverInterface $resolver
|
||||
* The controller resolver.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
|
||||
* The form builder.
|
||||
* @param string $form_definition
|
||||
* The definition of this form, usually found in $defaults['_entity_form'].
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
|
||||
* The entity manager.
|
||||
*/
|
||||
public function __construct(ControllerResolverInterface $resolver, EntityManagerInterface $manager, FormBuilderInterface $form_builder, $form_definition) {
|
||||
public function __construct(ControllerResolverInterface $resolver, FormBuilderInterface $form_builder, EntityManagerInterface $manager) {
|
||||
parent::__construct($resolver, $form_builder);
|
||||
$this->manager = $manager;
|
||||
$this->formDefinition = $form_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @{inheritDoc}
|
||||
*/
|
||||
protected function getFormArgument(Request $request) {
|
||||
return $request->attributes->get('_entity_form');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +75,7 @@ class HtmlEntityFormController extends FormController {
|
|||
$entity = $request->attributes->get($entity_type);
|
||||
}
|
||||
else {
|
||||
$entity = $this->manager->getStorage($entity_type)->create(array());
|
||||
$entity = $this->manager->getStorage($entity_type)->create([]);
|
||||
}
|
||||
|
||||
return $this->manager->getFormObject($entity_type, $operation)->setEntity($entity);
|
||||
|
|
|
@ -53,6 +53,20 @@ class ContentControllerSubscriber implements EventSubscriberInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the _controller on a request when a _form is defined.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
|
||||
* The event to process.
|
||||
*/
|
||||
public function onRequestDeriveFormWrapper(GetResponseEvent $event) {
|
||||
$request = $event->getRequest();
|
||||
|
||||
if ($request->attributes->has('_form')) {
|
||||
$request->attributes->set('_controller', 'controller.form:getContentResult');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the methods in this class that should be listeners.
|
||||
*
|
||||
|
@ -61,6 +75,7 @@ class ContentControllerSubscriber implements EventSubscriberInterface {
|
|||
*/
|
||||
static function getSubscribedEvents() {
|
||||
$events[KernelEvents::REQUEST][] = array('onRequestDeriveFormat', 31);
|
||||
$events[KernelEvents::REQUEST][] = array('onRequestDeriveFormWrapper', 29);
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,7 @@ class EntityRouteEnhancerTest extends UnitTestCase {
|
|||
* @see \Drupal\Core\Entity\Enhancer\EntityRouteEnhancer::enhancer()
|
||||
*/
|
||||
public function testEnhancer() {
|
||||
$controller_resolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
|
||||
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
|
||||
$form_builder = $this->getMock('Drupal\Core\Form\FormBuilderInterface');
|
||||
|
||||
$route_enhancer = new EntityRouteEnhancer($controller_resolver, $entity_manager, $form_builder);
|
||||
$route_enhancer = new EntityRouteEnhancer();
|
||||
|
||||
// Set a controller to ensure it is not overridden.
|
||||
$request = new Request();
|
||||
|
@ -43,9 +39,7 @@ class EntityRouteEnhancerTest extends UnitTestCase {
|
|||
$defaults = array();
|
||||
$defaults['_entity_form'] = 'entity_test.default';
|
||||
$new_defaults = $route_enhancer->enhance($defaults, $request);
|
||||
$this->assertTrue(is_callable($new_defaults['_controller']));
|
||||
$this->assertInstanceOf('\Drupal\Core\Entity\HtmlEntityFormController', $new_defaults['_controller'][0]);
|
||||
$this->assertEquals($new_defaults['_controller'][1], 'getContentResult');
|
||||
$this->assertEquals('controller.entity_form:getContentResult', $new_defaults['_controller']);
|
||||
|
||||
// Set _entity_list and ensure that the entity list controller is set.
|
||||
$defaults = array();
|
||||
|
|
Loading…
Reference in New Issue