diff --git a/core/lib/Drupal/Core/Controller/HtmlFormController.php b/core/lib/Drupal/Core/Controller/HtmlFormController.php
index 7eb85f3..82397aa 100644
--- a/core/lib/Drupal/Core/Controller/HtmlFormController.php
+++ b/core/lib/Drupal/Core/Controller/HtmlFormController.php
@@ -50,15 +50,13 @@ 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'));
$form_state['build_info']['args'] = $args;
$form_id = _drupal_form_id($form_object, $form_state);
@@ -80,7 +78,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'),