diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index ecd541e..63d3ba1 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -433,4 +433,13 @@ public function isInstallable() {
return (bool) \Drupal::service('views.views_data')->get($this->base_table);
}
+ /**
+ * {@inheritdoc}
+ */
+ public function __sleep() {
+ $keys = parent::__sleep();
+ unset($keys[array_search('executable', $keys)]);
+ return $keys;
+ }
+
}
diff --git a/core/modules/views/src/Form/ViewsExposedForm.php b/core/modules/views/src/Form/ViewsExposedForm.php
index 5e2eee9..0fdd2ea 100644
--- a/core/modules/views/src/Form/ViewsExposedForm.php
+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -121,7 +121,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$form['#id'] = Html::cleanCssIdentifier('views_exposed_form-' . String::checkPlain($view->storage->id()) . '-' . String::checkPlain($display['id']));
/** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
- $exposed_form_plugin = $form_state->get('exposed_form_plugin');
+ $exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
$exposed_form_plugin->exposedFormAlter($form, $form_state);
// Save the form.
@@ -134,15 +134,17 @@ public function buildForm(array $form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
+ $view = $form_state->get('view');
+
foreach (array('field', 'filter') as $type) {
/** @var \Drupal\views\Plugin\views\ViewsHandlerInterface[] $handlers */
- $handlers = &$form_state->get('view')->$type;
+ $handlers = &$view->$type;
foreach ($handlers as $key => $handler) {
$handlers[$key]->validateExposed($form, $form_state);
}
}
/** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
- $exposed_form_plugin = $form_state->get('exposed_form_plugin');
+ $exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
$exposed_form_plugin->exposedFormValidate($form, $form_state);
}
@@ -157,13 +159,14 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
$handlers[$key]->submitExposed($form, $form_state);
}
}
+
$view = $form_state->get('view');
$view->exposed_data = $form_state->getValues();
$view->exposed_raw_input = [];
- $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', '', 'reset');
+ $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset');
/** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
- $exposed_form_plugin = $form_state->get('exposed_form_plugin');
+ $exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
$exposed_form_plugin->exposedFormSubmit($form, $form_state, $exclude);
foreach ($form_state->getValues() as $key => $value) {
diff --git a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
index 3652e8b..16f86a8 100644
--- a/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
+++ b/core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php
@@ -150,7 +150,6 @@ public function renderExposedForm($block = FALSE) {
$form_state->set('ajax', TRUE);
}
- $form_state->set('exposed_form_plugin', $this);
$form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state);
if (!$this->view->display_handler->displaysExposed() || (!$block && $this->view->display_handler->getOption('exposed_block'))) {
diff --git a/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php b/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php
index bb6b803..34a2a9a 100644
--- a/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php
+++ b/core/modules/views/src/Plugin/views/relationship/RelationshipPluginBase.php
@@ -55,6 +55,13 @@
abstract class RelationshipPluginBase extends HandlerBase {
/**
+ * The relationship alias.
+ *
+ * @var string
+ */
+ public $alias;
+
+ /**
* Overrides \Drupal\views\Plugin\views\HandlerBase::init().
*
* Init handler to let relationships live on tables other than
diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php
index db01ad8..3d38a98 100644
--- a/core/modules/views/src/ViewExecutable.php
+++ b/core/modules/views/src/ViewExecutable.php
@@ -17,6 +17,7 @@
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewEntityInterface;
use Drupal\Component\Utility\Tags;
+use Drupal\views_ui\ViewUI;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -26,7 +27,7 @@
* An object to contain all of the data to generate a view, plus the member
* functions to build the view query, execute the query and render the output.
*/
-class ViewExecutable {
+class ViewExecutable implements \Serializable {
use DependencySerializationTrait;
/**
@@ -2284,4 +2285,55 @@ public function calculateDependencies() {
return $this->storage->calculateDependencies();
}
+ /**
+ * {@inheritdoc}
+ */
+ public function serialize() {
+ if ($this->storage instanceof ViewUI) {
+ $storage = $this->storage;
+ }
+ else {
+ $storage = $this->storage->id();
+ }
+
+ return serialize([
+ $storage,
+ $this->current_display,
+ $this->args,
+ $this->current_page,
+ $this->exposed_input,
+ $this->exposed_raw_input,
+ $this->exposed_data,
+ $this->dom_id,
+ $this->executed,
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized) {
+ list($storage, $current_display, $args, $current_page, $exposed_input, $exposed_raw_input, $exposed_data, $dom_id, $executed) = unserialize($serialized);
+
+ $this->setRequest(\Drupal::request());
+ $this->user = \Drupal::currentUser();
+
+ $this->storage = is_object($storage) ? $storage : \Drupal::entityManager()->getStorage('view')->load($storage);
+
+ $this->setDisplay($current_display);
+ $this->setArguments($args);
+ $this->setCurrentPage($current_page);
+ $this->setExposedInput($exposed_input);
+ $this->exposed_data = $exposed_data;
+ $this->exposed_raw_input = $exposed_raw_input;
+ $this->dom_id = $dom_id;
+
+ $this->initHandlers();
+
+ // If the display was previously executed, execute it now.
+ if ($executed) {
+ $this->execute($this->current_display);
+ }
+ }
+
}
diff --git a/core/modules/views/tests/src/Unit/ViewExecutableTest.php b/core/modules/views/tests/src/Unit/ViewExecutableTest.php
index 85b545c..51de164 100644
--- a/core/modules/views/tests/src/Unit/ViewExecutableTest.php
+++ b/core/modules/views/tests/src/Unit/ViewExecutableTest.php
@@ -465,4 +465,11 @@ protected function setupBaseViewAndDisplay() {
return array($view, $display);
}
+ /**
+ * Tests serialization of the ViewExecutable object.
+ */
+ public function testSerialization() {
+ // @todo
+ }
+
}
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index 5d27d30..28b1175 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -266,6 +266,7 @@ public function validate(array $form, FormStateInterface $form_state) {
public function save(array $form, FormStateInterface $form_state) {
$view = $this->entity;
$executable = $view->getExecutable();
+ $executable->initDisplay();
// Go through and remove displayed scheduled for removal.
$displays = $view->get('display');
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 5d00c80..6a41d9b 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -173,10 +173,10 @@ class ViewUI implements ViewEntityInterface {
public function __construct(ViewEntityInterface $storage, ViewExecutable $executable = NULL) {
$this->entityType = 'view';
$this->storage = $storage;
- if (!isset($executable)) {
- $executable = Views::executableFactory()->get($this);
+
+ if (isset($executable)) {
+ $this->executable = $executable;
}
- $this->executable = $executable;
}
/**
@@ -259,7 +259,7 @@ public function standardSubmit($form, FormStateInterface $form_state) {
$display_id = $form_state->get('display_id');
if ($revert) {
// If it's revert just change the override and return.
- $display = &$this->executable->displayHandlers->get($display_id);
+ $display = &$this->getExecutable()->displayHandlers->get($display_id);
$display->optionsOverride($form, $form_state);
// Don't execute the normal submit handling but still store the changed view into cache.
@@ -273,7 +273,7 @@ public function standardSubmit($form, FormStateInterface $form_state) {
elseif ($was_defaulted && !$is_defaulted) {
// We were using the default display's values, but we're now overriding
// the default display and saving values specific to this display.
- $display = &$this->executable->displayHandlers->get($display_id);
+ $display = &$this->getExecutable()->displayHandlers->get($display_id);
// optionsOverride toggles the override of this section.
$display->optionsOverride($form, $form_state);
$display->submitOptionsForm($form, $form_state);
@@ -283,7 +283,7 @@ public function standardSubmit($form, FormStateInterface $form_state) {
// to go back to the default display.
// Overwrite the default display with the current form values, and make
// the current display use the new default values.
- $display = &$this->executable->displayHandlers->get($display_id);
+ $display = &$this->getExecutable()->displayHandlers->get($display_id);
// optionsOverride toggles the override of this section.
$display->optionsOverride($form, $form_state);
$display->submitOptionsForm($form, $form_state);
@@ -481,7 +481,7 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
if ($was_defaulted && !$is_defaulted) {
// We were using the default display's values, but we're now overriding
// the default display and saving values specific to this display.
- $display = &$this->executable->displayHandlers->get($display_id);
+ $display = &$this->getExecutable()->displayHandlers->get($display_id);
// setOverride toggles the override of this section.
$display->setOverride($section);
}
@@ -490,7 +490,7 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
// to go back to the default display.
// Overwrite the default display with the current form values, and make
// the current display use the new default values.
- $display = &$this->executable->displayHandlers->get($display_id);
+ $display = &$this->getExecutable()->displayHandlers->get($display_id);
// optionsOverride toggles the override of this section.
$display->setOverride($section);
}
@@ -503,7 +503,7 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
if ($cut = strpos($field, '$')) {
$field = substr($field, 0, $cut);
}
- $id = $this->executable->addHandler($display_id, $type, $table, $field);
+ $id = $this->getExecutable()->addHandler($display_id, $type, $table, $field);
// check to see if we have group by settings
$key = $type;
@@ -516,7 +516,7 @@ public function submitItemAdd($form, FormStateInterface $form_state) {
'field' => $field,
);
$handler = Views::handlerManager($key)->getHandler($item);
- if ($this->executable->displayHandlers->get('default')->useGroupBy() && $handler->usesGroupBy()) {
+ if ($this->getExecutable()->displayHandlers->get('default')->useGroupBy() && $handler->usesGroupBy()) {
$this->addFormToStack('handler-group', $display_id, $type, $id);
}
@@ -580,11 +580,11 @@ public function renderPreview($display_id, $args = array()) {
$rows = array('query' => array(), 'statistics' => array());
- $errors = $this->executable->validate();
- $this->executable->destroy();
+ $errors = $this->getExecutable()->validate();
+ $this->getExecutable()->destroy();
if (empty($errors)) {
$this->ajax = TRUE;
- $this->executable->live_preview = TRUE;
+ $this->getExecutable()->live_preview = TRUE;
// AJAX happens via HTTP POST but everything expects exposed data to
// be in GET. Copy stuff but remove ajax-framework specific keys.
@@ -597,19 +597,19 @@ public function renderPreview($display_id, $args = array()) {
unset($exposed_input[$key]);
}
}
- $this->executable->setExposedInput($exposed_input);
+ $this->getExecutable()->setExposedInput($exposed_input);
- if (!$this->executable->setDisplay($display_id)) {
+ if (!$this->getExecutable()->setDisplay($display_id)) {
return [
'#markup' => t('Invalid display id @display', array('@display' => $display_id)),
];
}
- $this->executable->setArguments($args);
+ $this->getExecutable()->setArguments($args);
// Store the current view URL for later use:
- if ($this->executable->display_handler->getOption('path')) {
- $path = $this->executable->getUrl();
+ if ($this->getExecutable()->display_handler->getOption('path')) {
+ $path = $this->getExecutable()->getUrl();
}
// Make view links come back to preview.
@@ -646,7 +646,7 @@ public function renderPreview($display_id, $args = array()) {
}
// Execute/get the view preview.
- $preview = $this->executable->preview($display_id, $args);
+ $preview = $this->getExecutable()->preview($display_id, $args);
if ($show_additional_queries) {
$this->endQueryCapture();
@@ -660,13 +660,13 @@ public function renderPreview($display_id, $args = array()) {
// below the view preview.
if ($show_info || $show_query || $show_stats) {
// Get information from the preview for display.
- if (!empty($this->executable->build_info['query'])) {
+ if (!empty($this->getExecutable()->build_info['query'])) {
if ($show_query) {
- $query_string = $this->executable->build_info['query'];
+ $query_string = $this->getExecutable()->build_info['query'];
// Only the sql default class has a method getArguments.
$quoted = array();
- if ($this->executable->query instanceof Sql) {
+ if ($this->getExecutable()->query instanceof Sql) {
$quoted = $query_string->getArguments();
$connection = Database::getConnection();
foreach ($quoted as $key => $val) {
@@ -722,7 +722,7 @@ public function renderPreview($display_id, $args = array()) {
'#template' => "{% trans 'Title' %}",
),
),
- Xss::filterAdmin($this->executable->getTitle()),
+ Xss::filterAdmin($this->getExecutable()->getTitle()),
);
if (isset($path)) {
// @todo Views should expect and store a leading /. See:
@@ -743,7 +743,7 @@ public function renderPreview($display_id, $args = array()) {
'#template' => "{% trans 'Query build time' %}",
),
),
- t('@time ms', array('@time' => intval($this->executable->build_time * 100000) / 100)),
+ t('@time ms', array('@time' => intval($this->getExecutable()->build_time * 100000) / 100)),
);
$rows['statistics'][] = array(
@@ -753,7 +753,7 @@ public function renderPreview($display_id, $args = array()) {
'#template' => "{% trans 'Query execute time' %}",
),
),
- t('@time ms', array('@time' => intval($this->executable->execute_time * 100000) / 100)),
+ t('@time ms', array('@time' => intval($this->getExecutable()->execute_time * 100000) / 100)),
);
$rows['statistics'][] = array(
@@ -763,7 +763,7 @@ public function renderPreview($display_id, $args = array()) {
'#template' => "{% trans 'View render time' %}",
),
),
- t('@time ms', array('@time' => intval($this->executable->render_time * 100000) / 100)),
+ t('@time ms', array('@time' => intval($this->getExecutable()->render_time * 100000) / 100)),
);
}
\Drupal::moduleHandler()->alter('views_preview_info', $rows, $this->executable);
@@ -873,14 +873,14 @@ public function cacheSet() {
if (isset($executable->current_display)) {
// Add the knowledge of the changed display, too.
$this->changed_display[$executable->current_display] = TRUE;
- unset($executable->current_display);
+ $executable->current_display = NULL;
}
- // Unset handlers; we don't want to write these into the cache.
- unset($executable->display_handler);
- unset($executable->default_display);
+ // Unset handlers. We don't want to write these into the cache.
+ $executable->display_handler = NULL;
+ $executable->default_display = NULL;
$executable->query = NULL;
- unset($executable->displayHandlers);
+ $executable->displayHandlers = NULL;
\Drupal::service('user.shared_tempstore')->get('views')->set($this->id(), $this);
}
@@ -1132,7 +1132,11 @@ public static function postLoad(EntityStorageInterface $storage, array &$entitie
* {@inheritdoc}
*/
public function getExecutable() {
- return $this->storage->getExecutable();
+ if (!isset($this->executable)) {
+ $this->executable = Views::executableFactory()->get($this);
+ }
+
+ return $this->executable;
}
/**
@@ -1242,13 +1246,6 @@ public function addDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
/**
* {@inheritdoc}
*/
- public function getViewExecutable() {
- return $this->storage->getViewExecutable();
- }
-
- /**
- * {@inheritdoc}
- */
public function isInstallable() {
return $this->storage->isInstallable();
}
@@ -1287,4 +1284,11 @@ public function unsetThirdPartySetting($module, $key) {
public function getThirdPartyProviders() {
return $this->storage->getThirdPartyProviders();
}
+
+ public function __sleep() {
+ $vars = get_object_vars($this);
+ unset($vars['executable']);
+ return array_keys($vars);
+ }
+
}