diff --git a/core/lib/Drupal/Core/Controller/HtmlFormController.php b/core/lib/Drupal/Core/Controller/HtmlFormController.php index 7eb85f3..96530d5 100644 --- a/core/lib/Drupal/Core/Controller/HtmlFormController.php +++ b/core/lib/Drupal/Core/Controller/HtmlFormController.php @@ -50,15 +50,16 @@ public function content(Request $request, $_form) { // Using reflection, find all of the parameters needed by the form in the // request attributes, skipping $form and $form_state. - $attributes = $request->attributes->all(); - $reflection = new \ReflectionMethod($form_object, 'buildForm'); - $params = $reflection->getParameters(); - $args = array(); - foreach (array_splice($params, 2) as $param) { - if (array_key_exists($param->name, $attributes)) { - $args[] = $attributes[$param->name]; - } - } + + // At the form and form_state to trick the getArguments method of the + // controller resolver. + $form_state = array(); + $request->attributes->set('form', array()); + $request->attributes->set('form_state', $form_state); + $args = $this->container->get('controller_resolver')->getArguments($request, array($form_object, 'buildForm')); + unset($args[0], $args[1]); + $request->attributes->remove('form'); + $request->attributes->remove('form_state'); $form_state['build_info']['args'] = $args; $form_id = _drupal_form_id($form_object, $form_state); @@ -80,7 +81,7 @@ public function content(Request $request, $_form) { protected function getFormObject(Request $request, $form_arg) { // If this is a class, instantiate it. if (class_exists($form_arg)) { - if (in_array('Drupal\Core\ControllerInterface', class_implements($form_arg))) { + if (in_array('Drupal\Core\Controller\ControllerInterface', class_implements($form_arg))) { return $form_arg::create($this->container); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/FormObjectTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/FormObjectTest.php index 55dd739..13b54c8 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Form/FormObjectTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Form/FormObjectTest.php @@ -45,6 +45,8 @@ protected function setUp() { /** * Tests using an object as the form callback. + * + * @see \Drupal\form_test\EventSubscriber\FormTestEventSubscriber::onKernelRequest() */ function testObjectFormCallback() { $config_factory = $this->container->get('config.factory'); @@ -84,6 +86,8 @@ function testObjectFormCallback() { $this->assertText('The FormTestControllerObject::buildForm() method was used for this form.'); $elements = $this->xpath('//form[@id="form-test-form-test-controller-object"]'); $this->assertTrue(!empty($elements), 'The correct form ID was used.'); + $this->assertText('custom_value', 'Ensure parameters are injected from request attributes.'); + $this->assertText('request_value', 'Ensure the request object is injected.'); $this->drupalPost(NULL, array('bananas' => 'black'), t('Save')); $this->assertText('The FormTestControllerObject::validateForm() method was used for this form.'); $this->assertText('The FormTestControllerObject::submitForm() method was used for this form.'); diff --git a/core/modules/system/tests/modules/form_test/form_test.services.yml b/core/modules/system/tests/modules/form_test/form_test.services.yml index 42ae7a6..0201650 100644 --- a/core/modules/system/tests/modules/form_test/form_test.services.yml +++ b/core/modules/system/tests/modules/form_test/form_test.services.yml @@ -1,3 +1,7 @@ services: form_test.form.serviceform: class: Drupal\form_test\FormTestServiceObject + form_test.event_subscriber: + class: Drupal\form_test\EventSubscriber\FormTestEventSubscriber + tags: + - { name: event_subscriber } diff --git a/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/EventSubscriber/FormTestEventSubscriber.php b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/EventSubscriber/FormTestEventSubscriber.php new file mode 100644 index 0000000..7769bec --- /dev/null +++ b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/EventSubscriber/FormTestEventSubscriber.php @@ -0,0 +1,40 @@ +getRequest(); + $request->attributes->set('custom_attributes', 'custom_value'); + $request->attributes->set('request_attribute', 'request_value'); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[KernelEvents::REQUEST][] = array('onKernelRequest'); + + return $events; + } + +} diff --git a/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/FormTestControllerObject.php b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/FormTestControllerObject.php index 38a8fc7..aaa076f 100644 --- a/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/FormTestControllerObject.php +++ b/core/modules/system/tests/modules/form_test/lib/Drupal/form_test/FormTestControllerObject.php @@ -10,6 +10,7 @@ use Drupal\Core\Form\FormInterface; use Drupal\Core\ControllerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; /** * Provides a test form object. @@ -34,9 +35,12 @@ public static function create(ContainerInterface $container) { /** * Implements \Drupal\Core\Form\FormInterface::buildForm(). */ - public function buildForm(array $form, array &$form_state) { + public function buildForm(array $form, array &$form_state, $custom_attributes = NULL, Request $request = NULL) { $form['element'] = array('#markup' => 'The FormTestControllerObject::buildForm() method was used for this form.'); + $form['custom_attribute']['#markup'] = $custom_attributes; + $form['request_attribute']['#markup'] = $request->attributes->get('request_attribute'); + $form['bananas'] = array( '#type' => 'textfield', '#title' => t('Bananas'),