summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwebchick2013-11-14 04:57:56 (GMT)
committerwebchick2013-11-14 04:57:56 (GMT)
commit4217221f94b1c01f5d3cecc18360952e42ba4bc8 (patch)
tree30384bb15e8de9a94ac082ec3cec1f3a79df7700
parent30e56c5d84e824565812949eb330c69d74915240 (diff)
Issue #2110953 by Xano, dawehner: Convert views_forms() to a classed form.
-rw-r--r--core/modules/views/lib/Drupal/views/Form/ViewsForm.php184
-rw-r--r--core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php152
-rw-r--r--core/modules/views/views.module196
-rw-r--r--core/modules/views/views.theme.inc6
4 files changed, 341 insertions, 197 deletions
diff --git a/core/modules/views/lib/Drupal/views/Form/ViewsForm.php b/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
new file mode 100644
index 0000000..6c06250
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
@@ -0,0 +1,184 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Form\ViewsForm.
+ */
+
+namespace Drupal\views\Form;
+
+use Drupal\Component\Utility\Url;
+use Drupal\Core\Controller\ControllerResolverInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Form\FormInterface;
+use Drupal\Core\Routing\UrlGeneratorInterface;
+use Drupal\views\ViewExecutable;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Provides a base class for single- or multistep view forms.
+ *
+ * This class only dispatches logic to the form for the current step. The form
+ * is always assumed to be multistep, even if it has only one step (which by
+ * default is \Drupal\views\Form\ViewsFormMainForm). That way it is actually
+ * possible for modules to have a multistep form if they need to.
+ */
+class ViewsForm implements FormInterface, ContainerInjectionInterface {
+
+ /**
+ * The controller resolver to get the subform form objects.
+ *
+ * @var \Drupal\Core\Controller\ControllerResolverInterface
+ */
+ protected $controllerResolver;
+
+ /**
+ * The current request.
+ *
+ * @var \Symfony\Component\HttpFoundation\Request
+ */
+ protected $request;
+
+ /**
+ * The url generator to generate the form action.
+ *
+ * @var \Drupal\Core\Routing\UrlGeneratorInterface
+ */
+ protected $urlGenerator;
+
+ /**
+ * The ID of the view.
+ *
+ * @var string
+ */
+ protected $viewId;
+
+ /**
+ * The ID of the active view's display.
+ *
+ * @var string
+ */
+ protected $viewDisplayId;
+
+ /**
+ * Constructs a ViewsForm object.
+ *
+ * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
+ * The controller resolver to get the subform form objects.
+ * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+ * The url generator to generate the form action.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * The current request.
+ * @param string $view_id
+ * The ID of the view.
+ * @param string $view_display_id
+ * The ID of the active view's display.
+ */
+ public function __construct(ControllerResolverInterface $controller_resolver, UrlGeneratorInterface $url_generator, Request $request, $view_id, $view_display_id) {
+ $this->controllerResolver = $controller_resolver;
+ $this->urlGenerator = $url_generator;
+ $this->request = $request;
+ $this->viewId = $view_id;
+ $this->viewDisplayId = $view_display_id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, $view_id = NULL, $view_display_id = NULL) {
+ return new static(
+ $container->get('controller_resolver'),
+ $container->get('url_generator'),
+ $container->get('request'),
+ $view_id,
+ $view_display_id
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ $parts = array(
+ 'views_form',
+ $this->viewId,
+ $this->viewDisplayId,
+ );
+
+ return implode('_', $parts);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state, ViewExecutable $view = NULL, $output = NULL) {
+ $form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 'views_form_views_form';
+ $form_state['step_controller']['views_form_views_form'] = 'Drupal\views\Form\ViewsFormMainForm';
+
+ // Cache the built form to prevent it from being rebuilt prior to validation
+ // and submission, which could lead to data being processed incorrectly,
+ // because the views rows (and thus, the form elements as well) have changed
+ // in the meantime.
+ $form_state['cache'] = TRUE;
+
+ $form = array();
+
+ $query = $this->request->query->all();
+ $query = Url::filterQueryParameters($query, array(), '');
+
+ $form['#action'] = $this->urlGenerator->generateFromPath($view->getUrl(), array('query' => $query));
+ // Tell the preprocessor whether it should hide the header, footer, pager...
+ $form['show_view_elements'] = array(
+ '#type' => 'value',
+ '#value' => ($form_state['step'] == 'views_form_views_form') ? TRUE : FALSE,
+ );
+
+ $form_object = $this->getFormObject($form_state);
+ $form += $form_object->buildForm($form, $form_state, $view, $output);
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ $form_object = $this->getFormObject($form_state);
+ $form_object->validateForm($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $form_object = $this->getFormObject($form_state);
+ $form_object->submitForm($form, $form_state);
+ }
+
+ /**
+ * Returns the object used to build the step form.
+ *
+ * @param array $form_state
+ * The form_state of the current form.
+ *
+ * @return \Drupal\Core\Form\FormInterface
+ * The form object to use.
+ */
+ protected function getFormObject(array $form_state) {
+ // If this is a class, instantiate it.
+ $form_step_class = isset($form_state['step_controller'][$form_state['step']]) ? $form_state['step_controller'][$form_state['step']] : 'Drupal\views\Form\ViewsFormMainForm';
+ $container = \Drupal::getContainer();
+ if (class_exists($form_step_class)) {
+ if (in_array('Drupal\Core\DependencyInjection\ContainerInjectionInterface', class_implements($form_step_class))) {
+ return $form_step_class::create($container);
+ }
+
+ return new $form_step_class();
+ }
+
+ // Otherwise, it is a service.
+ return $container->get($form_step_class);
+ }
+
+}
diff --git a/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php b/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php
new file mode 100644
index 0000000..a5dbd15
--- /dev/null
+++ b/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Form\ViewsFormMainForm.
+ */
+
+namespace Drupal\views\Form;
+
+use Drupal\Core\Form\FormInterface;
+use Drupal\views\ViewExecutable;
+
+class ViewsFormMainForm implements FormInterface {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state, ViewExecutable $view = NULL, $output = NULL) {
+ $form['#prefix'] = '<div class="views-form">';
+ $form['#suffix'] = '</div>';
+ $form['#theme'] = 'form';
+ $form['#pre_render'][] = 'views_pre_render_views_form_views_form';
+
+ // Add the output markup to the form array so that it's included when the form
+ // array is passed to the theme function.
+ $form['output'] = array(
+ '#markup' => $output,
+ // This way any additional form elements will go before the view
+ // (below the exposed widgets).
+ '#weight' => 50,
+ );
+
+ $form['actions'] = array(
+ '#type' => 'actions',
+ );
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ );
+
+ $substitutions = array();
+ foreach ($view->field as $field_name => $field) {
+ $form_element_name = $field_name;
+ if (method_exists($field, 'form_element_name')) {
+ $form_element_name = $field->form_element_name();
+ }
+ $method_form_element_row_id_exists = FALSE;
+ if (method_exists($field, 'form_element_row_id')) {
+ $method_form_element_row_id_exists = TRUE;
+ }
+
+ // If the field provides a views form, allow it to modify the $form array.
+ $has_form = FALSE;
+ if (property_exists($field, 'views_form_callback')) {
+ $callback = $field->views_form_callback;
+ $callback($view, $field, $form, $form_state);
+ $has_form = TRUE;
+ }
+ elseif (method_exists($field, 'views_form')) {
+ $field->views_form($form, $form_state);
+ $has_form = TRUE;
+ }
+
+ // Build the substitutions array for use in the theme function.
+ if ($has_form) {
+ foreach ($view->result as $row_id => $row) {
+ if ($method_form_element_row_id_exists) {
+ $form_element_row_id = $field->form_element_row_id($row_id);
+ }
+ else {
+ $form_element_row_id = $row_id;
+ }
+
+ $substitutions[] = array(
+ 'placeholder' => '<!--form-item-' . $form_element_name . '--' . $form_element_row_id . '-->',
+ 'field_name' => $form_element_name,
+ 'row_id' => $form_element_row_id,
+ );
+ }
+ }
+ }
+
+ // Give the area handlers a chance to extend the form.
+ $area_handlers = array_merge(array_values($view->header), array_values($view->footer));
+ $empty = empty($view->result);
+ foreach ($area_handlers as $area) {
+ if (method_exists($area, 'views_form') && !$area->views_form_empty($empty)) {
+ $area->views_form($form, $form_state);
+ }
+ }
+
+ $form['#substitutions'] = array(
+ '#type' => 'value',
+ '#value' => $substitutions,
+ );
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ $view = $form_state['build_info']['args'][0];
+
+ // Call the validation method on every field handler that has it.
+ foreach ($view->field as $field) {
+ if (method_exists($field, 'views_form_validate')) {
+ $field->views_form_validate($form, $form_state);
+ }
+ }
+
+ // Call the validate method on every area handler that has it.
+ foreach (array('header', 'footer') as $area) {
+ foreach ($view->{$area} as $area_handler) {
+ if (method_exists($area_handler, 'views_form_validate')) {
+ $area_handler->views_form_validate($form, $form_state);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $view = $form_state['build_info']['args'][0];
+
+ // Call the submit method on every field handler that has it.
+ foreach ($view->field as $field) {
+ if (method_exists($field, 'views_form_submit')) {
+ $field->views_form_submit($form, $form_state);
+ }
+ }
+
+ // Call the submit method on every area handler that has it.
+ foreach (array('header', 'footer') as $area) {
+ foreach ($view->{$area} as $area_handler) {
+ if (method_exists($area_handler, 'views_form_submit')) {
+ $area_handler->views_form_submit($form, $form_state);
+ }
+ }
+ }
+ }
+
+}
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 615ac6f..5bea350 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -19,37 +19,6 @@ use Drupal\views\Views;
use Drupal\field\FieldInstanceInterface;
/**
- * Implements hook_forms().
- *
- * To provide distinct form IDs for Views forms, the View name and
- * specific display name are appended to the base ID,
- * views_form_views_form. When such a form is built or submitted, this
- * function will return the proper callback function to use for the given form.
- */
-function views_forms($form_id, $args) {
- if (strpos($form_id, 'views_form_') === 0) {
- return array(
- $form_id => array(
- 'callback' => 'views_form',
- ),
- );
- }
-}
-
-/**
- * Returns a form ID for a Views form using the name and display of the View.
- */
-function views_form_id($view) {
- $parts = array(
- 'views_form',
- $view->storage->id(),
- $view->current_display,
- );
-
- return implode('_', $parts);
-}
-
-/**
* Implements hook_element_info().
*/
function views_element_info() {
@@ -1036,171 +1005,6 @@ function views_view_has_form_elements($view) {
}
/**
- * This is the entry function. Just gets the form for the current step.
- * The form is always assumed to be multistep, even if it has only one
- * step (the default 'views_form_views_form' step). That way it is actually
- * possible for modules to have a multistep form if they need to.
- */
-function views_form($form, &$form_state, ViewExecutable $view, $output) {
- $form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 'views_form_views_form';
- // Cache the built form to prevent it from being rebuilt prior to validation
- // and submission, which could lead to data being processed incorrectly,
- // because the views rows (and thus, the form elements as well) have changed
- // in the meantime.
- $form_state['cache'] = TRUE;
-
- $form = array();
- $query = drupal_get_query_parameters();
- $form['#action'] = url($view->getUrl(), array('query' => $query));
- // Tell the preprocessor whether it should hide the header, footer, pager...
- $form['show_view_elements'] = array(
- '#type' => 'value',
- '#value' => ($form_state['step'] == 'views_form_views_form') ? TRUE : FALSE,
- );
-
- $form = $form_state['step']($form, $form_state, $view, $output);
- return $form;
-}
-
-/**
- * Callback for the main step of a Views form.
- * Invoked by views_form().
- */
-function views_form_views_form($form, &$form_state, ViewExecutable $view, $output) {
- $form['#prefix'] = '<div class="views-form">';
- $form['#suffix'] = '</div>';
- $form['#theme'] = 'form';
- $form['#pre_render'][] = 'views_pre_render_views_form_views_form';
- $form['#validate'][] = 'views_form_views_form_validate';
- $form['#submit'][] = 'views_form_views_form_submit';
-
- // Add the output markup to the form array so that it's included when the form
- // array is passed to the theme function.
- $form['output'] = array(
- '#markup' => $output,
- // This way any additional form elements will go before the view
- // (below the exposed widgets).
- '#weight' => 50,
- );
-
- $form['actions'] = array(
- '#type' => 'actions',
- );
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save'),
- );
-
- $substitutions = array();
- foreach ($view->field as $field_name => $field) {
- $form_element_name = $field_name;
- if (method_exists($field, 'form_element_name')) {
- $form_element_name = $field->form_element_name();
- }
- $method_form_element_row_id_exists = FALSE;
- if (method_exists($field, 'form_element_row_id')) {
- $method_form_element_row_id_exists = TRUE;
- }
-
- // If the field provides a views form, allow it to modify the $form array.
- $has_form = FALSE;
- if (property_exists($field, 'views_form_callback')) {
- $callback = $field->views_form_callback;
- $callback($view, $field, $form, $form_state);
- $has_form = TRUE;
- }
- elseif (method_exists($field, 'views_form')) {
- $field->views_form($form, $form_state);
- $has_form = TRUE;
- }
-
- // Build the substitutions array for use in the theme function.
- if ($has_form) {
- foreach ($view->result as $row_id => $row) {
- if ($method_form_element_row_id_exists) {
- $form_element_row_id = $field->form_element_row_id($row_id);
- }
- else {
- $form_element_row_id = $row_id;
- }
-
- $substitutions[] = array(
- 'placeholder' => '<!--form-item-' . $form_element_name . '--' . $form_element_row_id . '-->',
- 'field_name' => $form_element_name,
- 'row_id' => $form_element_row_id,
- );
- }
- }
- }
-
- // Give the area handlers a chance to extend the form.
- $area_handlers = array_merge(array_values($view->header), array_values($view->footer));
- $empty = empty($view->result);
- foreach ($area_handlers as $area) {
- if (method_exists($area, 'views_form') && !$area->views_form_empty($empty)) {
- $area->views_form($form, $form_state);
- }
- }
-
- $form['#substitutions'] = array(
- '#type' => 'value',
- '#value' => $substitutions,
- );
-
- return $form;
-}
-
-/**
- * Validate handler for the first step of the views form.
- * Calls any existing views_form_validate functions located
- * on the views fields.
- */
-function views_form_views_form_validate($form, &$form_state) {
- $view = $form_state['build_info']['args'][0];
-
- // Call the validation method on every field handler that has it.
- foreach ($view->field as $field) {
- if (method_exists($field, 'views_form_validate')) {
- $field->views_form_validate($form, $form_state);
- }
- }
-
- // Call the validate method on every area handler that has it.
- foreach (array('header', 'footer') as $area) {
- foreach ($view->{$area} as $area_handler) {
- if (method_exists($area_handler, 'views_form_validate')) {
- $area_handler->views_form_validate($form, $form_state);
- }
- }
- }
-}
-
-/**
- * Submit handler for the first step of the views form.
- * Calls any existing views_form_submit functions located
- * on the views fields.
- */
-function views_form_views_form_submit($form, &$form_state) {
- $view = $form_state['build_info']['args'][0];
-
- // Call the submit method on every field handler that has it.
- foreach ($view->field as $field) {
- if (method_exists($field, 'views_form_submit')) {
- $field->views_form_submit($form, $form_state);
- }
- }
-
- // Call the submit method on every area handler that has it.
- foreach (array('header', 'footer') as $area) {
- foreach ($view->{$area} as $area_handler) {
- if (method_exists($area_handler, 'views_form_submit')) {
- $area_handler->views_form_submit($form, $form_state);
- }
- }
- }
-}
-
-/**
* Replaces views substitution placeholders.
*
* @param array $element
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 084b87d..6c6cd0a 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -8,6 +8,7 @@
use Drupal\Component\Utility\Xss;
use Drupal\Core\Language\Language;
use Drupal\Core\Template\Attribute;
+use Drupal\views\Form\ViewsForm;
use Drupal\views\ViewExecutable;
/**
@@ -134,7 +135,10 @@ function template_preprocess_views_view(&$variables) {
$rows = $variables['rows'];
$rows = drupal_render($rows);
$output = !empty($rows) ? $rows : $variables['empty'];
- $form = drupal_get_form(views_form_id($view), $view, $output);
+
+ $container = \Drupal::getContainer();
+ $form_object = new ViewsForm($container->get('controller_resolver'), $container->get('url_generator'), $container->get('request'), $view->storage->id(), $view->current_display);
+ $form = \Drupal::formBuilder()->getForm($form_object, $view, $output);
// The form is requesting that all non-essential views elements be hidden,
// usually because the rendered step is not a view result.
if ($form['show_view_elements']['#value'] == FALSE) {