summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2014-05-14 20:18:01 (GMT)
committerNathaniel Catchpole2014-05-14 20:18:01 (GMT)
commit120a1da34c131282960dd993fc5bd2eb1036d924 (patch)
tree6a2956744605f93f87860af6e20f2e9028db68a4
parent5f79a75cbcfc29992402c1c717f1c627c44329df (diff)
Issue #2257835 by tim.plunkett, sun, Jalandhar: Move form submission logic out of FormBuilder into a new class.
-rw-r--r--core/core.services.yml5
-rw-r--r--core/includes/form.inc12
-rw-r--r--core/lib/Drupal/Core/Form/FormBuilder.php197
-rw-r--r--core/lib/Drupal/Core/Form/FormBuilderInterface.php77
-rw-r--r--core/lib/Drupal/Core/Form/FormSubmitter.php232
-rw-r--r--core/lib/Drupal/Core/Form/FormSubmitterInterface.php106
-rw-r--r--core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php151
-rw-r--r--core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php291
-rw-r--r--core/tests/Drupal/Tests/Core/Form/FormTestBase.php55
9 files changed, 686 insertions, 440 deletions
diff --git a/core/core.services.yml b/core/core.services.yml
index bb65f34..dc55af1 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -119,10 +119,13 @@ services:
arguments: [default]
form_builder:
class: Drupal\Core\Form\FormBuilder
- arguments: ['@form_validator', '@module_handler', '@keyvalue.expirable', '@event_dispatcher', '@url_generator', '@request_stack', '@?csrf_token', '@?http_kernel']
+ arguments: ['@form_validator', '@form_submitter', '@module_handler', '@keyvalue.expirable', '@event_dispatcher', '@request_stack', '@?csrf_token', '@?http_kernel']
form_validator:
class: Drupal\Core\Form\FormValidator
arguments: ['@request_stack', '@string_translation', '@csrf_token']
+ form_submitter:
+ class: Drupal\Core\Form\FormSubmitter
+ arguments: ['@request_stack', '@url_generator']
keyvalue:
class: Drupal\Core\KeyValueStore\KeyValueFactory
arguments: ['@service_container', '@settings']
diff --git a/core/includes/form.inc b/core/includes/form.inc
index c037ce1..42206a4 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -334,27 +334,27 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
* Redirects the user to a URL after a form has been processed.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
- * Use \Drupal::formBuilder()->redirectForm().
+ * Use \Drupal::service('form_submitter')->redirectForm().
*
- * @see \Drupal\Core\Form\FormBuilderInterface::redirectForm().
+ * @see \Drupal\Core\Form\FormSubmitterInterface::redirectForm().
*/
function drupal_redirect_form($form_state) {
- return \Drupal::formBuilder()->redirectForm($form_state);
+ return \Drupal::service('form_submitter')->redirectForm($form_state);
}
/**
* Executes custom validation and submission handlers for a given form.
*
* @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
- * Use either \Drupal::formBuilder()->executeSubmitHandlers() or
+ * Use either \Drupal::service('form_submitter')->executeSubmitHandlers() or
* \Drupal::service('form_validator')->executeValidateHandlers().
*
- * @see \Drupal\Core\Form\FormBuilderInterface::executeSubmitHandlers()
+ * @see \Drupal\Core\Form\FormSubmitterInterface::executeSubmitHandlers()
* @see \Drupal\Core\Form\FormValidatorInterface::executeValidateHandlers()
*/
function form_execute_handlers($type, &$form, &$form_state) {
if ($type == 'submit') {
- \Drupal::formBuilder()->executeSubmitHandlers($form, $form_state);
+ \Drupal::service('form_submitter')->executeSubmitHandlers($form, $form_state);
}
elseif ($type == 'validate') {
\Drupal::service('form_validator')->executeValidateHandlers($form, $form_state);
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 3efa1f2..ebaf19b 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -15,11 +15,8 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\HttpKernel;
use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
use Drupal\Core\Render\Element;
-use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Site\Settings;
-use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
@@ -29,7 +26,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
/**
* Provides form building and processing.
*/
-class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
+class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormSubmitterInterface {
/**
* The module handler.
@@ -53,13 +50,6 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
protected $eventDispatcher;
/**
- * The URL generator.
- *
- * @var \Drupal\Core\Routing\UrlGeneratorInterface
- */
- protected $urlGenerator;
-
- /**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
@@ -93,18 +83,23 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
protected $formValidator;
/**
+ * @var \Drupal\Core\Form\FormSubmitterInterface
+ */
+ protected $formSubmitter;
+
+ /**
* Constructs a new FormBuilder.
*
* @param \Drupal\Core\Form\FormValidatorInterface $form_validator
* The form validator.
+ * @param \Drupal\Core\Form\FormSubmitterInterface $form_submitter
+ * The form submission processor.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_expirable_factory
* The keyvalue expirable factory.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
- * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
- * The URL generator.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
@@ -112,12 +107,12 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
* @param \Drupal\Core\HttpKernel $http_kernel
* The HTTP kernel.
*/
- public function __construct(FormValidatorInterface $form_validator, ModuleHandlerInterface $module_handler, KeyValueExpirableFactoryInterface $key_value_expirable_factory, EventDispatcherInterface $event_dispatcher, UrlGeneratorInterface $url_generator, RequestStack $request_stack, CsrfTokenGenerator $csrf_token = NULL, HttpKernel $http_kernel = NULL) {
+ public function __construct(FormValidatorInterface $form_validator, FormSubmitterInterface $form_submitter, ModuleHandlerInterface $module_handler, KeyValueExpirableFactoryInterface $key_value_expirable_factory, EventDispatcherInterface $event_dispatcher, RequestStack $request_stack, CsrfTokenGenerator $csrf_token = NULL, HttpKernel $http_kernel = NULL) {
$this->formValidator = $form_validator;
+ $this->formSubmitter = $form_submitter;
$this->moduleHandler = $module_handler;
$this->keyValueExpirableFactory = $key_value_expirable_factory;
$this->eventDispatcher = $event_dispatcher;
- $this->urlGenerator = $url_generator;
$this->requestStack = $request_stack;
$this->csrfToken = $csrf_token;
$this->httpKernel = $http_kernel;
@@ -555,53 +550,9 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
$this->drupalStaticReset('drupal_html_id');
}
- // @todo Move into a dedicated class in https://drupal.org/node/2257835.
- if ($form_state['submitted'] && !$this->getAnyErrors() && !$form_state['rebuild']) {
- // Execute form submit handlers.
- $this->executeSubmitHandlers($form, $form_state);
-
- // If batches were set in the submit handlers, we process them now,
- // possibly ending execution. We make sure we do not react to the batch
- // that is already being processed (if a batch operation performs a
- // self::submitForm).
- if ($batch = &$this->batchGet() && !isset($batch['current_set'])) {
- // Store $form_state information in the batch definition.
- // We need the full $form_state when either:
- // - Some submit handlers were saved to be called during batch
- // processing. See self::executeSubmitHandlers().
- // - The form is multistep.
- // In other cases, we only need the information expected by
- // self::redirectForm().
- if ($batch['has_form_submits'] || !empty($form_state['rebuild'])) {
- $batch['form_state'] = $form_state;
- }
- else {
- $batch['form_state'] = array_intersect_key($form_state, array_flip(array('programmed', 'rebuild', 'storage', 'no_redirect', 'redirect', 'redirect_route')));
- }
-
- $batch['progressive'] = !$form_state['programmed'];
- $response = batch_process();
- if ($batch['progressive']) {
- return $response;
- }
-
- // Execution continues only for programmatic forms.
- // For 'regular' forms, we get redirected to the batch processing
- // page. Form redirection will be handled in _batch_finished(),
- // after the batch is processed.
- }
-
- // Set a flag to indicate the the form has been processed and executed.
- $form_state['executed'] = TRUE;
-
- // If no response has been set, process the form redirect.
- if (!isset($form_state['response']) && $redirect = $this->redirectForm($form_state)) {
- $form_state['response'] = $redirect;
- }
-
- // If there is a response was set, return it instead of continuing.
- if (isset($form_state['response']) && $form_state['response'] instanceof Response) {
- return $form_state['response'];
+ if (!$form_state['rebuild'] && !$this->formValidator->getAnyErrors()) {
+ if ($submit_response = $this->formSubmitter->doSubmitForm($form, $form_state)) {
+ return $submit_response;
}
}
@@ -793,78 +744,7 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
* {@inheritdoc}
*/
public function redirectForm($form_state) {
- // Skip redirection for form submissions invoked via self::submitForm().
- if (!empty($form_state['programmed'])) {
- return;
- }
- // Skip redirection if rebuild is activated.
- if (!empty($form_state['rebuild'])) {
- return;
- }
- // Skip redirection if it was explicitly disallowed.
- if (!empty($form_state['no_redirect'])) {
- return;
- }
-
- // Allow using redirect responses directly if needed.
- if (isset($form_state['redirect']) && $form_state['redirect'] instanceof RedirectResponse) {
- return $form_state['redirect'];
- }
-
- // Check for a route-based redirection.
- if (isset($form_state['redirect_route'])) {
- // @todo Remove once all redirects are converted to Url.
- if (!($form_state['redirect_route'] instanceof Url)) {
- $form_state['redirect_route'] += array(
- 'route_parameters' => array(),
- 'options' => array(),
- );
- $form_state['redirect_route'] = new Url($form_state['redirect_route']['route_name'], $form_state['redirect_route']['route_parameters'], $form_state['redirect_route']['options']);
- }
-
- $form_state['redirect_route']->setAbsolute();
- return new RedirectResponse($form_state['redirect_route']->toString());
- }
-
- // Only invoke a redirection if redirect value was not set to FALSE.
- if (!isset($form_state['redirect']) || $form_state['redirect'] !== FALSE) {
- if (isset($form_state['redirect'])) {
- if (is_array($form_state['redirect'])) {
- if (isset($form_state['redirect'][1])) {
- $options = $form_state['redirect'][1];
- }
- else {
- $options = array();
- }
- // Redirections should always use absolute URLs.
- $options['absolute'] = TRUE;
- if (isset($form_state['redirect'][2])) {
- $status_code = $form_state['redirect'][2];
- }
- else {
- $status_code = 302;
- }
- return new RedirectResponse($this->urlGenerator->generateFromPath($form_state['redirect'][0], $options), $status_code);
- }
- else {
- // This function can be called from the installer, which guarantees
- // that $redirect will always be a string, so catch that case here
- // and use the appropriate redirect function.
- if ($this->drupalInstallationAttempted()) {
- install_goto($form_state['redirect']);
- }
- else {
- return new RedirectResponse($this->urlGenerator->generateFromPath($form_state['redirect'], array('absolute' => TRUE)));
- }
- }
- }
- $request = $this->requestStack->getCurrentRequest();
- $url = $this->urlGenerator->generateFromPath($request->attributes->get('_system_path'), array(
- 'query' => $request->query->all(),
- 'absolute' => TRUE,
- ));
- return new RedirectResponse($url);
- }
+ return $this->formSubmitter->redirectForm($form_state);
}
/**
@@ -878,33 +758,14 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
* {@inheritdoc}
*/
public function executeSubmitHandlers(&$form, &$form_state) {
- // If there was a button pressed, use its handlers.
- if (isset($form_state['submit_handlers'])) {
- $handlers = $form_state['submit_handlers'];
- }
- // Otherwise, check for a form-level handler.
- elseif (isset($form['#submit'])) {
- $handlers = $form['#submit'];
- }
- else {
- $handlers = array();
- }
+ $this->formSubmitter->executeSubmitHandlers($form, $form_state);
+ }
- foreach ($handlers as $function) {
- // Check if a previous _submit handler has set a batch, but make sure we
- // do not react to a batch that is already being processed (for instance
- // if a batch operation performs a self::submitForm()).
- if (($batch = &$this->batchGet()) && !isset($batch['id'])) {
- // Some previous submit handler has set a batch. To ensure correct
- // execution order, store the call in a special 'control' batch set.
- // See _batch_next_set().
- $batch['sets'][] = array('form_submit' => $function);
- $batch['has_form_submits'] = TRUE;
- }
- else {
- call_user_func_array($function, array(&$form, &$form_state));
- }
- }
+ /**
+ * {@inheritdoc}
+ */
+ public function doSubmitForm(&$form, &$form_state) {
+ throw new \LogicException('Use FormBuilderInterface::processForm() instead.');
}
/**
@@ -1379,15 +1240,6 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
}
/**
- * Wraps drupal_installation_attempted().
- *
- * @return bool
- */
- protected function drupalInstallationAttempted() {
- return drupal_installation_attempted();
- }
-
- /**
* Wraps drupal_html_class().
*
* @return string
@@ -1430,11 +1282,4 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface {
return $this->currentUser;
}
- /**
- * Wraps batch_get().
- */
- protected function &batchGet() {
- return batch_get();
- }
-
}
diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
index 1e43984..bf00f50 100644
--- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php
+++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
@@ -386,83 +386,6 @@ interface FormBuilderInterface extends FormErrorInterface {
public function prepareForm($form_id, &$form, &$form_state);
/**
- * Redirects the user to a URL after a form has been processed.
- *
- * After a form is submitted and processed, normally the user should be
- * redirected to a new destination page. This function figures out what that
- * destination should be, based on the $form_state array and the 'destination'
- * query string in the request URL, and redirects the user there.
- *
- * Usually (for exceptions, see below) $form_state['redirect'] determines
- * where to redirect the user. This can be set either to a string (the path to
- * redirect to), or an array of arguments for url(). If
- * $form_state['redirect'] is missing, the user is usually (again, see below
- * for exceptions) redirected back to the page they came from, where they
- * should see a fresh, unpopulated copy of the form.
- *
- * Here is an example of how to set up a form to redirect to the path 'node':
- * @code
- * $form_state['redirect'] = 'node';
- * @endcode
- * And here is an example of how to redirect to 'node/123?foo=bar#baz':
- * @code
- * $form_state['redirect'] = array(
- * 'node/123',
- * array(
- * 'query' => array(
- * 'foo' => 'bar',
- * ),
- * 'fragment' => 'baz',
- * ),
- * );
- * @endcode
- *
- * There are several exceptions to the "usual" behavior described above:
- * - If $form_state['programmed'] is TRUE, the form submission was usually
- * invoked via self::submitForm(), so any redirection would break the script
- * that invoked self::submitForm() and no redirection is done.
- * - If $form_state['rebuild'] is TRUE, the form is being rebuilt, and no
- * redirection is done.
- * - If $form_state['no_redirect'] is TRUE, redirection is disabled. This is
- * set, for instance, by \Drupal\system\FormAjaxController::getForm() to
- * prevent redirection in Ajax callbacks. $form_state['no_redirect'] should
- * never be set or altered by form builder functions or form validation
- * or submit handlers.
- * - If $form_state['redirect'] is set to FALSE, redirection is disabled.
- * - If none of the above conditions has prevented redirection, then the
- * redirect is accomplished by returning a RedirectResponse, passing in the
- * value of $form_state['redirect'] if it is set, or the current path if it
- * is not. RedirectResponse preferentially uses the value of
- * \Drupal::request->query->get('destination') (the 'destination' URL query
- * string) if it is present, so this will override any values set by
- * $form_state['redirect'].
- *
- * @param $form_state
- * An associative array containing the current state of the form.
- *
- * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
- *
- * @see self::processForm()
- * @see self::buildForm()
- */
- public function redirectForm($form_state);
-
- /**
- * Executes custom submission handlers for a given form.
- *
- * Button-specific handlers are checked first. If none exist, the function
- * falls back to form-level handlers.
- *
- * @param $form
- * An associative array containing the structure of the form.
- * @param $form_state
- * A keyed array containing the current state of the form. If the user
- * submitted the form by clicking a button with custom handler functions
- * defined, those handlers will be stored here.
- */
- public function executeSubmitHandlers(&$form, &$form_state);
-
- /**
* Builds and processes all elements in the structured form array.
*
* Adds any required properties to each element, maps the incoming input data
diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php
new file mode 100644
index 0000000..fea8f54
--- /dev/null
+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -0,0 +1,232 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Form\FormSubmitter.
+ */
+
+namespace Drupal\Core\Form;
+
+use Drupal\Core\Url;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Response;
+use Drupal\Core\Routing\UrlGeneratorInterface;
+
+/**
+ * Provides submission processing for forms.
+ */
+class FormSubmitter implements FormSubmitterInterface {
+
+ /**
+ * The URL generator.
+ *
+ * @var \Drupal\Core\Routing\UrlGeneratorInterface
+ */
+ protected $urlGenerator;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * Constructs a new FormValidator.
+ *
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * The request stack.
+ * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+ */
+ public function __construct(RequestStack $request_stack, UrlGeneratorInterface $url_generator) {
+ $this->requestStack = $request_stack;
+ $this->urlGenerator = $url_generator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function doSubmitForm(&$form, &$form_state) {
+ if (!$form_state['submitted']) {
+ return;
+ }
+
+ // Execute form submit handlers.
+ $this->executeSubmitHandlers($form, $form_state);
+
+ // If batches were set in the submit handlers, we process them now,
+ // possibly ending execution. We make sure we do not react to the batch
+ // that is already being processed (if a batch operation performs a
+ // \Drupal\Core\Form\FormBuilderInterface::submitForm).
+ if ($batch = &$this->batchGet() && !isset($batch['current_set'])) {
+ // Store $form_state information in the batch definition.
+ // We need the full $form_state when either:
+ // - Some submit handlers were saved to be called during batch
+ // processing. See self::executeSubmitHandlers().
+ // - The form is multistep.
+ // In other cases, we only need the information expected by
+ // self::redirectForm().
+ if ($batch['has_form_submits'] || !empty($form_state['rebuild'])) {
+ $batch['form_state'] = $form_state;
+ }
+ else {
+ $batch['form_state'] = array_intersect_key($form_state, array_flip(array('programmed', 'rebuild', 'storage', 'no_redirect', 'redirect', 'redirect_route')));
+ }
+
+ $batch['progressive'] = !$form_state['programmed'];
+ $response = batch_process();
+ if ($batch['progressive']) {
+ return $response;
+ }
+
+ // Execution continues only for programmatic forms.
+ // For 'regular' forms, we get redirected to the batch processing
+ // page. Form redirection will be handled in _batch_finished(),
+ // after the batch is processed.
+ }
+
+ // Set a flag to indicate the the form has been processed and executed.
+ $form_state['executed'] = TRUE;
+
+ // If no response has been set, process the form redirect.
+ if (!isset($form_state['response']) && $redirect = $this->redirectForm($form_state)) {
+ $form_state['response'] = $redirect;
+ }
+
+ // If there is a response was set, return it instead of continuing.
+ if (isset($form_state['response']) && $form_state['response'] instanceof Response) {
+ return $form_state['response'];
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function executeSubmitHandlers(&$form, &$form_state) {
+ // If there was a button pressed, use its handlers.
+ if (isset($form_state['submit_handlers'])) {
+ $handlers = $form_state['submit_handlers'];
+ }
+ // Otherwise, check for a form-level handler.
+ elseif (isset($form['#submit'])) {
+ $handlers = $form['#submit'];
+ }
+ else {
+ $handlers = array();
+ }
+
+ foreach ($handlers as $function) {
+ // Check if a previous _submit handler has set a batch, but make sure we
+ // do not react to a batch that is already being processed (for instance
+ // if a batch operation performs a
+ // \Drupal\Core\Form\FormBuilderInterface::submitForm()).
+ if (($batch = &$this->batchGet()) && !isset($batch['id'])) {
+ // Some previous submit handler has set a batch. To ensure correct
+ // execution order, store the call in a special 'control' batch set.
+ // See _batch_next_set().
+ $batch['sets'][] = array('form_submit' => $function);
+ $batch['has_form_submits'] = TRUE;
+ }
+ else {
+ call_user_func_array($function, array(&$form, &$form_state));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function redirectForm($form_state) {
+ // Skip redirection for form submissions invoked via
+ // \Drupal\Core\Form\FormBuilderInterface::submitForm().
+ if (!empty($form_state['programmed'])) {
+ return;
+ }
+ // Skip redirection if rebuild is activated.
+ if (!empty($form_state['rebuild'])) {
+ return;
+ }
+ // Skip redirection if it was explicitly disallowed.
+ if (!empty($form_state['no_redirect'])) {
+ return;
+ }
+
+ // Allow using redirect responses directly if needed.
+ if (isset($form_state['redirect']) && $form_state['redirect'] instanceof RedirectResponse) {
+ return $form_state['redirect'];
+ }
+
+ // Check for a route-based redirection.
+ if (isset($form_state['redirect_route'])) {
+ // @todo Remove once all redirects are converted to Url.
+ if (!($form_state['redirect_route'] instanceof Url)) {
+ $form_state['redirect_route'] += array(
+ 'route_parameters' => array(),
+ 'options' => array(),
+ );
+ $form_state['redirect_route'] = new Url($form_state['redirect_route']['route_name'], $form_state['redirect_route']['route_parameters'], $form_state['redirect_route']['options']);
+ }
+
+ $form_state['redirect_route']->setAbsolute();
+ return new RedirectResponse($form_state['redirect_route']->toString());
+ }
+
+ // Only invoke a redirection if redirect value was not set to FALSE.
+ if (!isset($form_state['redirect']) || $form_state['redirect'] !== FALSE) {
+ if (isset($form_state['redirect'])) {
+ if (is_array($form_state['redirect'])) {
+ if (isset($form_state['redirect'][1])) {
+ $options = $form_state['redirect'][1];
+ }
+ else {
+ $options = array();
+ }
+ // Redirections should always use absolute URLs.
+ $options['absolute'] = TRUE;
+ if (isset($form_state['redirect'][2])) {
+ $status_code = $form_state['redirect'][2];
+ }
+ else {
+ $status_code = 302;
+ }
+ return new RedirectResponse($this->urlGenerator->generateFromPath($form_state['redirect'][0], $options), $status_code);
+ }
+ else {
+ // This function can be called from the installer, which guarantees
+ // that $redirect will always be a string, so catch that case here
+ // and use the appropriate redirect function.
+ if ($this->drupalInstallationAttempted()) {
+ install_goto($form_state['redirect']);
+ }
+ else {
+ return new RedirectResponse($this->urlGenerator->generateFromPath($form_state['redirect'], array('absolute' => TRUE)));
+ }
+ }
+ }
+ $request = $this->requestStack->getCurrentRequest();
+ $url = $this->urlGenerator->generateFromPath($request->attributes->get('_system_path'), array(
+ 'query' => $request->query->all(),
+ 'absolute' => TRUE,
+ ));
+ return new RedirectResponse($url);
+ }
+ }
+
+ /**
+ * Wraps drupal_installation_attempted().
+ *
+ * @return bool
+ */
+ protected function drupalInstallationAttempted() {
+ return drupal_installation_attempted();
+ }
+
+ /**
+ * Wraps batch_get().
+ */
+ protected function &batchGet() {
+ return batch_get();
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Form/FormSubmitterInterface.php b/core/lib/Drupal/Core/Form/FormSubmitterInterface.php
new file mode 100644
index 0000000..8ae8b08
--- /dev/null
+++ b/core/lib/Drupal/Core/Form/FormSubmitterInterface.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Form\FormSubmitterInterface.
+ */
+
+namespace Drupal\Core\Form;
+
+/**
+ * Provides an interface for processing form submissions.
+ */
+interface FormSubmitterInterface {
+
+ /**
+ * Handles the submitted form, executing callbacks and processing responses.
+ *
+ * @param array $form
+ * An associative array containing the structure of the form.
+ * @param array $form_state
+ * An associative array containing the current state of the form.
+ *
+ * @return null|\Symfony\Component\HttpFoundation\Response
+ * If a response was set by a submit handler, or if the form needs to
+ * redirect, a Response object will be returned.
+ */
+ public function doSubmitForm(&$form, &$form_state);
+
+ /**
+ * Executes custom submission handlers for a given form.
+ *
+ * Button-specific handlers are checked first. If none exist, the function
+ * falls back to form-level handlers.
+ *
+ * @param $form
+ * An associative array containing the structure of the form.
+ * @param $form_state
+ * A keyed array containing the current state of the form. If the user
+ * submitted the form by clicking a button with custom handler functions
+ * defined, those handlers will be stored here.
+ */
+ public function executeSubmitHandlers(&$form, &$form_state);
+
+ /**
+ * Redirects the user to a URL after a form has been processed.
+ *
+ * After a form is submitted and processed, normally the user should be
+ * redirected to a new destination page. This function figures out what that
+ * destination should be, based on the $form_state array and the 'destination'
+ * query string in the request URL, and redirects the user there.
+ *
+ * Usually (for exceptions, see below) $form_state['redirect'] determines
+ * where to redirect the user. This can be set either to a string (the path to
+ * redirect to), or an array of arguments for url(). If
+ * $form_state['redirect'] is missing, the user is usually (again, see below
+ * for exceptions) redirected back to the page they came from, where they
+ * should see a fresh, unpopulated copy of the form.
+ *
+ * Here is an example of how to set up a form to redirect to the path 'node':
+ * @code
+ * $form_state['redirect'] = 'node';
+ * @endcode
+ * And here is an example of how to redirect to 'node/123?foo=bar#baz':
+ * @code
+ * $form_state['redirect'] = array(
+ * 'node/123',
+ * array(
+ * 'query' => array(
+ * 'foo' => 'bar',
+ * ),
+ * 'fragment' => 'baz',
+ * ),
+ * );
+ * @endcode
+ *
+ * There are several exceptions to the "usual" behavior described above:
+ * - If $form_state['programmed'] is TRUE, the form submission was usually
+ * invoked via self::submitForm(), so any redirection would break the script
+ * that invoked self::submitForm() and no redirection is done.
+ * - If $form_state['rebuild'] is TRUE, the form is being rebuilt, and no
+ * redirection is done.
+ * - If $form_state['no_redirect'] is TRUE, redirection is disabled. This is
+ * set, for instance, by \Drupal\system\FormAjaxController::getForm() to
+ * prevent redirection in Ajax callbacks. $form_state['no_redirect'] should
+ * never be set or altered by form builder functions or form validation
+ * or submit handlers.
+ * - If $form_state['redirect'] is set to FALSE, redirection is disabled.
+ * - If none of the above conditions has prevented redirection, then the
+ * redirect is accomplished by returning a RedirectResponse, passing in the
+ * value of $form_state['redirect'] if it is set, or the current path if it
+ * is not. RedirectResponse preferentially uses the value of
+ * \Drupal::request->query->get('destination') (the 'destination' URL query
+ * string) if it is present, so this will override any values set by
+ * $form_state['redirect'].
+ *
+ * @param $form_state
+ * An associative array containing the current state of the form.
+ *
+ * @return \Symfony\Component\HttpFoundation\RedirectResponse|null
+ *
+ * @see \Drupal\Core\Form\FormBuilderInterface::processForm()
+ * @see \Drupal\Core\Form\FormBuilderInterface::buildForm()
+ */
+ public function redirectForm($form_state);
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index f7c94ed..8b09681 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -7,12 +7,9 @@
namespace Drupal\Tests\Core\Form {
-use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormInterface;
-use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Tests the form builder.
@@ -36,17 +33,6 @@ class FormBuilderTest extends FormTestBase {
}
/**
- * {@inheritdoc}
- */
- public function setUp() {
- parent::setUp();
-
- $container = new ContainerBuilder();
- $container->set('url_generator', $this->urlGenerator);
- \Drupal::setContainer($container);
- }
-
- /**
* Tests the getFormId() method with a string based form ID.
*/
public function testGetFormIdWithString() {
@@ -219,140 +205,6 @@ class FormBuilderTest extends FormTestBase {
}
$this->assertSame($response, $form_state['response']);
}
-
- /**
- * Tests the redirectForm() method when a redirect is expected.
- *
- * @param array $form_state
- * An array of form state data to use for the redirect.
- * @param string $result
- * The URL the redirect is targeting.
- * @param int $status
- * (optional) The HTTP status code for the redirect.
- *
- * @dataProvider providerTestRedirectWithResult
- */
- public function testRedirectWithResult($form_state, $result, $status = 302) {
- $this->urlGenerator->expects($this->once())
- ->method('generateFromPath')
- ->will($this->returnValueMap(array(
- array(NULL, array('query' => array(), 'absolute' => TRUE), '<front>'),
- array('foo', array('absolute' => TRUE), 'foo'),
- array('bar', array('query' => array('foo' => 'baz'), 'absolute' => TRUE), 'bar'),
- array('baz', array('absolute' => TRUE), 'baz'),
- ))
- );
-
- $form_state += $this->formBuilder->getFormStateDefaults();
- $redirect = $this->formBuilder->redirectForm($form_state);
- $this->assertSame($result, $redirect->getTargetUrl());
- $this->assertSame($status, $redirect->getStatusCode());
- }
-
- /**
- * Tests the redirectForm() with redirect_route when a redirect is expected.
- *
- * @param array $form_state
- * An array of form state data to use for the redirect.
- * @param string $result
- * The URL the redirect is targeting.
- * @param int $status
- * (optional) The HTTP status code for the redirect.
- *
- * @dataProvider providerTestRedirectWithRouteWithResult
- */
- public function testRedirectWithRouteWithResult($form_state, $result, $status = 302) {
- $this->urlGenerator->expects($this->once())
- ->method('generateFromRoute')
- ->will($this->returnValueMap(array(
- array('test_route_a', array(), array('absolute' => TRUE), 'test-route'),
- array('test_route_b', array('key' => 'value'), array('absolute' => TRUE), 'test-route/value'),
- ))
- );
-
- $form_state += $this->formBuilder->getFormStateDefaults();
- $redirect = $this->formBuilder->redirectForm($form_state);
- $this->assertSame($result, $redirect->getTargetUrl());
- $this->assertSame($status, $redirect->getStatusCode());
- }
-
- /**
- * Tests the redirectForm() method with a response object.
- */
- public function testRedirectWithResponseObject() {
- $redirect = new RedirectResponse('/example');
- $form_state['redirect'] = $redirect;
-
- $form_state += $this->formBuilder->getFormStateDefaults();
- $result_redirect = $this->formBuilder->redirectForm($form_state);
-
- $this->assertSame($redirect, $result_redirect);
- }
-
- /**
- * Tests the redirectForm() method when no redirect is expected.
- *
- * @param array $form_state
- * An array of form state data to use for the redirect.
- *
- * @dataProvider providerTestRedirectWithoutResult
- */
- public function testRedirectWithoutResult($form_state) {
- $this->urlGenerator->expects($this->never())
- ->method('generateFromPath');
- $this->urlGenerator->expects($this->never())
- ->method('generateFromRoute');
- $form_state += $this->formBuilder->getFormStateDefaults();
- $redirect = $this->formBuilder->redirectForm($form_state);
- $this->assertNull($redirect);
- }
-
- /**
- * Provides test data for testing the redirectForm() method with a redirect.
- *
- * @return array
- * Returns some test data.
- */
- public function providerTestRedirectWithResult() {
- return array(
- array(array(), '<front>'),
- array(array('redirect' => 'foo'), 'foo'),
- array(array('redirect' => array('foo')), 'foo'),
- array(array('redirect' => array('foo')), 'foo'),
- array(array('redirect' => array('bar', array('query' => array('foo' => 'baz')))), 'bar'),
- array(array('redirect' => array('baz', array(), 301)), 'baz', 301),
- );
- }
-
- /**
- * Provides test data for testing the redirectForm() method with a route name.
- *
- * @return array
- * Returns some test data.
- */
- public function providerTestRedirectWithRouteWithResult() {
- return array(
- array(array('redirect_route' => array('route_name' => 'test_route_a')), 'test-route'),
- array(array('redirect_route' => array('route_name' => 'test_route_b', 'route_parameters' => array('key' => 'value'))), 'test-route/value'),
- array(array('redirect_route' => new Url('test_route_b', array('key' => 'value'))), 'test-route/value'),
- );
- }
-
- /**
- * Provides test data for testing the redirectForm() method with no redirect.
- *
- * @return array
- * Returns some test data.
- */
- public function providerTestRedirectWithoutResult() {
- return array(
- array(array('programmed' => TRUE)),
- array(array('rebuild' => TRUE)),
- array(array('no_redirect' => TRUE)),
- array(array('redirect' => FALSE)),
- );
- }
-
/**
* Tests the getForm() method with a string based form ID.
*/
@@ -554,9 +406,6 @@ class FormBuilderTest extends FormTestBase {
$form_id = 'test_form_id';
$expected_form = $form_id();
$expected_form['test']['#required'] = TRUE;
- $this->formValidator->expects($this->exactly(4))
- ->method('getAnyErrors')
- ->will($this->returnValue(TRUE));
// Mock a form object that will be built two times.
$form_arg = $this->getMock('Drupal\Core\Form\FormInterface');
diff --git a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
new file mode 100644
index 0000000..5dcc668
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
@@ -0,0 +1,291 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Form\FormSubmitterTest.
+ */
+
+namespace Drupal\Tests\Core\Form;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Url;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Tests the form submission handler.
+ *
+ * @coversDefaultClass \Drupal\Core\Form\FormSubmitter
+ *
+ * @group Drupal
+ * @group Form
+ */
+class FormSubmitterTest extends UnitTestCase {
+
+ /**
+ * The mocked URL generator.
+ *
+ * @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Routing\UrlGeneratorInterface
+ */
+ protected $urlGenerator;
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getInfo() {
+ return array(
+ 'name' => 'Form submission test',
+ 'description' => 'Tests the form submission handler.',
+ 'group' => 'Form API',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
+ }
+
+ /**
+ * @covers ::doSubmitForm
+ */
+ public function testHandleFormSubmissionNotSubmitted() {
+ $form_submitter = $this->getFormSubmitter();
+ $form = array();
+ $form_state = $this->getFormStateDefaults();
+
+ $return = $form_submitter->doSubmitForm($form, $form_state);
+ $this->assertFalse($form_state['executed']);
+ $this->assertNull($return);
+ }
+
+ /**
+ * @covers ::doSubmitForm
+ */
+ public function testHandleFormSubmissionNoRedirect() {
+ $form_submitter = $this->getFormSubmitter();
+ $form = array();
+ $form_state = $this->getFormStateDefaults();
+ $form_state['submitted'] = TRUE;
+ $form_state['no_redirect'] = TRUE;
+
+ $return = $form_submitter->doSubmitForm($form, $form_state);
+ $this->assertTrue($form_state['executed']);
+ $this->assertNull($return);
+ }
+
+ /**
+ * @covers ::doSubmitForm
+ *
+ * @dataProvider providerTestHandleFormSubmissionWithResponses
+ */
+ public function testHandleFormSubmissionWithResponses($class, $form_state_key) {
+ $response = $this->getMockBuilder($class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $response->expects($this->any())
+ ->method('prepare')
+ ->will($this->returnValue($response));
+
+ $form_state = $this->getFormStateDefaults();
+ $form_state['submitted'] = TRUE;
+ $form_state[$form_state_key] = $response;
+
+ $form_submitter = $this->getFormSubmitter();
+ $form = array();
+ $return = $form_submitter->doSubmitForm($form, $form_state);
+
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $return);
+ }
+
+ public function providerTestHandleFormSubmissionWithResponses() {
+ return array(
+ array('Symfony\Component\HttpFoundation\Response', 'response'),
+ array('Symfony\Component\HttpFoundation\RedirectResponse', 'redirect'),
+ );
+ }
+
+ /**
+ * Tests the redirectForm() method when a redirect is expected.
+ *
+ * @covers ::redirectForm
+ *
+ * @dataProvider providerTestRedirectWithResult
+ */
+ public function testRedirectWithResult($form_state, $result, $status = 302) {
+ $form_submitter = $this->getFormSubmitter();
+ $this->urlGenerator->expects($this->once())
+ ->method('generateFromPath')
+ ->will($this->returnValueMap(array(
+ array(NULL, array('query' => array(), 'absolute' => TRUE), '<front>'),
+ array('foo', array('absolute' => TRUE), 'foo'),
+ array('bar', array('query' => array('foo' => 'baz'), 'absolute' => TRUE), 'bar'),
+ array('baz', array('absolute' => TRUE), 'baz'),
+ ))
+ );
+
+ $form_state += $this->getFormStateDefaults();
+ $redirect = $form_submitter->redirectForm($form_state);
+ $this->assertSame($result, $redirect->getTargetUrl());
+ $this->assertSame($status, $redirect->getStatusCode());
+ }
+
+ /**
+ * Tests the redirectForm() with redirect_route when a redirect is expected.
+ *
+ * @covers ::redirectForm
+ *
+ * @dataProvider providerTestRedirectWithRouteWithResult
+ */
+ public function testRedirectWithRouteWithResult($form_state, $result, $status = 302) {
+ $container = new ContainerBuilder();
+ $container->set('url_generator', $this->urlGenerator);
+ \Drupal::setContainer($container);
+ $form_submitter = $this->getFormSubmitter();
+ $this->urlGenerator->expects($this->once())
+ ->method('generateFromRoute')
+ ->will($this->returnValueMap(array(
+ array('test_route_a', array(), array('absolute' => TRUE), 'test-route'),
+ array('test_route_b', array('key' => 'value'), array('absolute' => TRUE), 'test-route/value'),
+ ))
+ );
+
+ $form_state += $this->getFormStateDefaults();
+ $redirect = $form_submitter->redirectForm($form_state);
+ $this->assertSame($result, $redirect->getTargetUrl());
+ $this->assertSame($status, $redirect->getStatusCode());
+ }
+
+ /**
+ * Tests the redirectForm() method with a response object.
+ *
+ * @covers ::redirectForm
+ */
+ public function testRedirectWithResponseObject() {
+ $form_submitter = $this->getFormSubmitter();
+ $redirect = new RedirectResponse('/example');
+ $form_state['redirect'] = $redirect;
+
+ $form_state += $this->getFormStateDefaults();
+ $result_redirect = $form_submitter->redirectForm($form_state);
+
+ $this->assertSame($redirect, $result_redirect);
+ }
+
+ /**
+ * Tests the redirectForm() method when no redirect is expected.
+ *
+ * @covers ::redirectForm
+ *
+ * @dataProvider providerTestRedirectWithoutResult
+ */
+ public function testRedirectWithoutResult($form_state) {
+ $form_submitter = $this->getFormSubmitter();
+ $this->urlGenerator->expects($this->never())
+ ->method('generateFromPath');
+ $this->urlGenerator->expects($this->never())
+ ->method('generateFromRoute');
+ $form_state += $this->getFormStateDefaults();
+ $redirect = $form_submitter->redirectForm($form_state);
+ $this->assertNull($redirect);
+ }
+
+ /**
+ * Provides test data for testing the redirectForm() method with a redirect.
+ *
+ * @return array
+ * Returns some test data.
+ */
+ public function providerTestRedirectWithResult() {
+ return array(
+ array(array(), '<front>'),
+ array(array('redirect' => 'foo'), 'foo'),
+ array(array('redirect' => array('foo')), 'foo'),
+ array(array('redirect' => array('foo')), 'foo'),
+ array(array('redirect' => array('bar', array('query' => array('foo' => 'baz')))), 'bar'),
+ array(array('redirect' => array('baz', array(), 301)), 'baz', 301),
+ );
+ }
+
+ /**
+ * Provides test data for testing the redirectForm() method with a route name.
+ *
+ * @return array
+ * Returns some test data.
+ */
+ public function providerTestRedirectWithRouteWithResult() {
+ return array(
+ array(array('redirect_route' => array('route_name' => 'test_route_a')), 'test-route'),
+ array(array('redirect_route' => array('route_name' => 'test_route_b', 'route_parameters' => array('key' => 'value'))), 'test-route/value'),
+ array(array('redirect_route' => new Url('test_route_b', array('key' => 'value'))), 'test-route/value'),
+ );
+ }
+
+ /**
+ * Provides test data for testing the redirectForm() method with no redirect.
+ *
+ * @return array
+ * Returns some test data.
+ */
+ public function providerTestRedirectWithoutResult() {
+ return array(
+ array(array('programmed' => TRUE)),
+ array(array('rebuild' => TRUE)),
+ array(array('no_redirect' => TRUE)),
+ array(array('redirect' => FALSE)),
+ );
+ }
+
+ /**
+ * @covers ::executeSubmitHandlers
+ */
+ public function testExecuteSubmitHandlers() {
+ $form_submitter = $this->getFormSubmitter();
+ $mock = $this->getMock('stdClass', array('submit_handler', 'hash_submit'));
+ $mock->expects($this->once())
+ ->method('submit_handler')
+ ->with($this->isType('array'), $this->isType('array'));
+ $mock->expects($this->once())
+ ->method('hash_submit')
+ ->with($this->isType('array'), $this->isType('array'));
+
+ $form = array();
+ $form_state = $this->getFormStateDefaults();
+ $form_submitter->executeSubmitHandlers($form, $form_state);
+
+ $form['#submit'][] = array($mock, 'hash_submit');
+ $form_submitter->executeSubmitHandlers($form, $form_state);
+
+ // $form_state submit handlers will supersede $form handlers.
+ $form_state['submit_handlers'][] = array($mock, 'submit_handler');
+ $form_submitter->executeSubmitHandlers($form, $form_state);
+ }
+
+ /**
+ * @return array()
+ */
+ protected function getFormStateDefaults() {
+ $form_builder = $this->getMockBuilder('Drupal\Core\Form\FormBuilder')
+ ->disableOriginalConstructor()
+ ->setMethods(NULL)
+ ->getMock();
+ return $form_builder->getFormStateDefaults();
+ }
+
+ /**
+ * @return \Drupal\Core\Form\FormSubmitterInterface
+ */
+ protected function getFormSubmitter() {
+ $request_stack = new RequestStack();
+ $request_stack->push(new Request());
+ return $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
+ ->setConstructorArgs(array($request_stack, $this->urlGenerator))
+ ->setMethods(array('batchGet', 'drupalInstallationAttempted'))
+ ->getMock();
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
index 1a8b61f..280e54e 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
@@ -35,6 +35,11 @@ abstract class FormTestBase extends UnitTestCase {
protected $formValidator;
/**
+ * @var \Drupal\Core\Form\FormSubmitterInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $formSubmitter;
+
+ /**
* The mocked URL generator.
*
* @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Routing\UrlGeneratorInterface
@@ -84,6 +89,13 @@ abstract class FormTestBase extends UnitTestCase {
protected $request;
/**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
* The event dispatcher.
*
* @var \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\EventDispatcher\EventDispatcherInterface
@@ -117,8 +129,6 @@ abstract class FormTestBase extends UnitTestCase {
array('form_state', $this->formStateCache),
)));
- $this->eventDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
- $this->formValidator = $this->getMock('Drupal\Core\Form\FormValidatorInterface');
$this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
$this->csrfToken = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator')
->disableOriginalConstructor()
@@ -126,10 +136,22 @@ abstract class FormTestBase extends UnitTestCase {
$this->httpKernel = $this->getMockBuilder('Drupal\Core\HttpKernel')
->disableOriginalConstructor()
->getMock();
- $this->request = new Request();
$this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
+ $this->request = new Request();
+ $this->eventDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ $this->requestStack = new RequestStack();
+ $this->requestStack->push($this->request);
+ $this->formValidator = $this->getMockBuilder('Drupal\Core\Form\FormValidator')
+ ->setConstructorArgs(array($this->requestStack, $this->getStringTranslationStub(), $this->csrfToken))
+ ->setMethods(array('drupalSetMessage'))
+ ->getMock();
+ $this->formSubmitter = $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
+ ->setConstructorArgs(array($this->requestStack, $this->urlGenerator))
+ ->setMethods(array('batchGet', 'drupalInstallationAttempted'))
+ ->getMock();
- $this->setupFormBuilder();
+ $this->formBuilder = new TestFormBuilder($this->formValidator, $this->formSubmitter, $this->moduleHandler, $this->keyValueExpirableFactory, $this->eventDispatcher, $this->requestStack, $this->csrfToken, $this->httpKernel);
+ $this->formBuilder->setCurrentUser($this->account);
}
/**
@@ -140,16 +162,6 @@ abstract class FormTestBase extends UnitTestCase {
}
/**
- * Sets up a new form builder object to test.
- */
- protected function setupFormBuilder() {
- $request_stack = new RequestStack();
- $request_stack->push($this->request);
- $this->formBuilder = new TestFormBuilder($this->formValidator, $this->moduleHandler, $this->keyValueExpirableFactory, $this->eventDispatcher, $this->urlGenerator, $request_stack, $this->csrfToken, $this->httpKernel);
- $this->formBuilder->setCurrentUser($this->account);
- }
-
- /**
* Provides a mocked form object.
*
* @param string $form_id
@@ -279,13 +291,6 @@ class TestFormBuilder extends FormBuilder {
/**
* {@inheritdoc}
*/
- protected function drupalInstallationAttempted() {
- return FALSE;
- }
-
- /**
- * {@inheritdoc}
- */
protected function drupalHtmlClass($class) {
return $class;
}
@@ -310,14 +315,6 @@ class TestFormBuilder extends FormBuilder {
static::$seenIds = array();
}
- /**
- * {@inheritdoc}
- */
- protected function &batchGet() {
- $batch = array();
- return $batch;
- }
-
}
}