From ad514aea2f53572fd0585209429ada725541ae43 Mon Sep 17 00:00:00 2001
From: dereine <dereine@99340.no-reply.drupal.org>
Date: Tue, 18 Sep 2012 15:41:58 -0400
Subject: [PATCH] Issue #1751358 by dawehner: Split up View class into
 ViewStorage and ViewExecutable.

---
 includes/admin.inc                            |  36 +--
 lib/Drupal/views/Analyzer.php                 |   8 +-
 lib/Drupal/views/Plugin/views/HandlerBase.php |   8 +-
 lib/Drupal/views/Plugin/views/PluginBase.php  |   2 +-
 .../views/display/DisplayPluginBase.php       |  10 +-
 .../views/relationship/GroupwiseMax.php       |   2 +-
 .../Plugin/views/wizard/WizardInterface.php   |   2 +-
 .../Plugin/views/wizard/WizardPluginBase.php  |  12 +-
 lib/Drupal/views/Tests/Plugin/CacheTest.php   |   4 +-
 .../views/Tests/Plugin/StyleMappingTest.php   |   2 +-
 lib/Drupal/views/Tests/ViewExecutableTest.php |  76 ++++++
 lib/Drupal/views/Tests/ViewStorageTest.php    |   9 +-
 lib/Drupal/views/Tests/ViewTest.php           |   6 +-
 lib/Drupal/views/Tests/ViewTestBase.php       |  10 +-
 .../views/{View.php => ViewExecutable.php}    | 246 ++++++------------
 lib/Drupal/views/ViewStorage.php              | 168 +++++++++++-
 lib/Drupal/views/ViewsBundle.php              |   4 +-
 modules/node.views_template.inc               |   2 +-
 tests/views_test_data/views_test_data.module  |   2 +-
 views.api.php                                 |   2 +-
 views.module                                  |  27 +-
 views_ui.module                               |   4 +-
 22 files changed, 392 insertions(+), 250 deletions(-)
 create mode 100644 lib/Drupal/views/Tests/ViewExecutableTest.php
 rename lib/Drupal/views/{View.php => ViewExecutable.php} (94%)

diff --git a/includes/admin.inc b/includes/admin.inc
index f8194c9a4c1a..bd0b169b9a4f 100644
--- a/includes/admin.inc
+++ b/includes/admin.inc
@@ -7,7 +7,7 @@
 
 use Drupal\Core\Database\Database;
 use Drupal\views\TempStore\UserTempStore;
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 use Drupal\views\Analyzer;
 use Drupal\views\Plugin\views\wizard\WizardException;
 
@@ -2001,7 +2001,7 @@ function views_ui_import_validate($form, &$form_state) {
         }
       }
 
-      foreach (View::viewsHandlerTypes() as $type => $info) {
+      foreach (ViewExecutable::viewsHandlerTypes() as $type => $info) {
         $handlers = $display->handler->getHandlers($type);
         if ($handlers) {
           foreach ($handlers as $id => $handler) {
@@ -2129,7 +2129,7 @@ function views_ui_edit_form_get_bucket($type, $view, $display) {
   $build = array(
     '#theme_wrappers' => array('views_ui_display_tab_bucket'),
   );
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
 
   $build['#overridden'] = FALSE;
   $build['#defaulted'] = FALSE;
@@ -3247,7 +3247,7 @@ function views_ui_config_type_form($form, &$form_state) {
   $display_id = $form_state['display_id'];
   $type = $form_state['type'];
 
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   if (!$view->setDisplay($display_id)) {
     views_ajax_error(t('Invalid display id @display', array('@display' => $display_id)));
   }
@@ -3279,7 +3279,7 @@ function views_ui_config_type_form($form, &$form_state) {
  * Submit handler for type configuration form
  */
 function views_ui_config_type_form_submit($form, &$form_state) {
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   $display = &$form_state['view']->display[$form_state['display_id']];
 
   // Store in cache
@@ -3294,7 +3294,7 @@ function views_ui_rearrange_form($form, &$form_state) {
   $display_id = $form_state['display_id'];
   $type = $form_state['type'];
 
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   if (!$view->setDisplay($display_id)) {
     views_ajax_error(t('Invalid display id @display', array('@display' => $display_id)));
   }
@@ -3519,7 +3519,7 @@ function theme_views_ui_build_group_filter_form($variables) {
  * Submit handler for rearranging form.
  */
 function views_ui_rearrange_form_submit($form, &$form_state) {
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   $display = &$form_state['view']->display[$form_state['display_id']];
 
   $old_fields = $display->handler->getOption($types[$form_state['type']]['plural']);
@@ -3555,7 +3555,7 @@ function views_ui_rearrange_filter_form($form, &$form_state) {
   $display_id = $form_state['display_id'];
   $type = $form_state['type'];
 
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   if (!$view->setDisplay($display_id)) {
     views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
   }
@@ -3821,7 +3821,7 @@ function theme_views_ui_rearrange_filter_form(&$vars) {
  * Submit handler for rearranging form
  */
 function views_ui_rearrange_filter_form_submit($form, &$form_state) {
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   $display = &$form_state['view']->display[$form_state['display_id']];
   $remember_groups = array();
 
@@ -3944,7 +3944,7 @@ function views_ui_add_item_form($form, &$form_state) {
   }
   $display = &$view->display[$display_id];
 
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   $ltitle = $types[$type]['ltitle'];
   $section = $types[$type]['plural'];
 
@@ -4060,7 +4060,7 @@ function views_ui_add_item_form($form, &$form_state) {
  */
 function views_ui_add_item_form_submit($form, &$form_state) {
   $type = $form_state['type'];
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   $section = $types[$type]['plural'];
 
   // Handle the override select.
@@ -4187,7 +4187,7 @@ function views_ui_config_item_form($form, &$form_state) {
       $form['markup'] = array('#markup' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field'])));
     }
     else {
-      $types = View::viewsHandlerTypes();
+      $types = ViewExecutable::viewsHandlerTypes();
 
       // If this item can come from the default display, show a dropdown
       // that lets the user choose which display the changes should apply to.
@@ -4307,7 +4307,7 @@ function views_ui_config_item_form_submit_temporary($form, &$form_state) {
   // Run it through the handler's submit function.
   $form_state['handler']->submitOptionsForm($form['options'], $form_state);
   $item = $form_state['handler']->options;
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
 
   // For footer/header $handler_type is area but $type is footer/header.
   // For all other handle types it's the same.
@@ -4361,7 +4361,7 @@ function views_ui_config_item_form_submit($form, &$form_state) {
   // Run it through the handler's submit function.
   $form_state['handler']->submitOptionsForm($form['options'], $form_state);
   $item = $form_state['handler']->options;
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
 
   // For footer/header $handler_type is area but $type is footer/header.
   // For all other handle types it's the same.
@@ -4437,7 +4437,7 @@ function views_ui_config_item_group_form($type, &$form_state) {
     }
     else {
       $handler->init($view, $item);
-      $types = View::viewsHandlerTypes();
+      $types = ViewExecutable::viewsHandlerTypes();
 
       $form['#title'] = t('Configure group settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel()));
 
@@ -4538,7 +4538,7 @@ function views_ui_config_item_extra_form($form, &$form_state) {
     }
     else {
       $handler->init($view, $item);
-      $types = View::viewsHandlerTypes();
+      $types = ViewExecutable::viewsHandlerTypes();
 
       $form['#title'] = t('Configure extra settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel()));
 
@@ -4609,7 +4609,7 @@ function views_ui_config_style_form($form, &$form_state) {
     }
     else {
       $handler->init($view, $item);
-      $types = View::viewsHandlerTypes();
+      $types = ViewExecutable::viewsHandlerTypes();
 
       $form['#title'] = t('Configure summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->adminLabel()));
 
@@ -5321,7 +5321,7 @@ function views_ui_field_list() {
   foreach ($views as $view) {
     foreach ($view->display as $display_id => $display) {
       if ($view->setDisplay($display_id)) {
-        foreach (View::viewsHandlerTypes() as $type => $info) {
+        foreach (ViewExecutable::viewsHandlerTypes() as $type => $info) {
           foreach ($view->getItems($type, $display_id) as $item) {
             $data = views_fetch_data($item['table']);
             if (isset($data[$item['field']]) && isset($data[$item['field']][$type])
diff --git a/lib/Drupal/views/Analyzer.php b/lib/Drupal/views/Analyzer.php
index d8611c4b7a05..2c6263977a66 100644
--- a/lib/Drupal/views/Analyzer.php
+++ b/lib/Drupal/views/Analyzer.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views;
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 /**
  * This tool is a small plugin manager to perform analysis on a view and
@@ -22,14 +22,14 @@ class Analyzer {
   /**
    * The view to analyze.
    *
-   * @var Drupal\views\View.
+   * @var Drupal\views\ViewExecutable.
    */
   protected $view;
 
   /**
    * Constructs the analyzer object.
    *
-   * @param Drupal\views\View $view
+   * @param Drupal\views\ViewExecutable $view
    *   (optional) The view to analyze.
    */
   function __construct(View $view = NULL) {
@@ -41,7 +41,7 @@ function __construct(View $view = NULL) {
   /**
    * Sets the view which is analyzed by this analyzer.
    *
-   * @param Drupal\views\View
+   * @param Drupal\views\ViewExecutable
    *   The view to analyze.
    */
   public function setView(View $view = NULL) {
diff --git a/lib/Drupal/views/Plugin/views/HandlerBase.php b/lib/Drupal/views/Plugin/views/HandlerBase.php
index 40e2616c0fd2..c40b4eae9a66 100644
--- a/lib/Drupal/views/Plugin/views/HandlerBase.php
+++ b/lib/Drupal/views/Plugin/views/HandlerBase.php
@@ -9,7 +9,7 @@
 
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\views\Plugin\views\PluginBase;
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 abstract class HandlerBase extends PluginBase {
 
@@ -81,7 +81,7 @@ public function __construct(array $configuration, $plugin_id, DiscoveryInterface
   /**
    * Init the handler with necessary data.
    *
-   * @param Drupal\views\View $view
+   * @param Drupal\views\ViewExecutable $view
    *   The $view object this handler is attached to.
    * @param array $options
    *   The item from the database; the actual contents of this will vary
@@ -104,7 +104,7 @@ public function init(&$view, &$options) {
       $options['field'] = $this->actualField;
     }
 
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     $plural = $this->definition['plugin_type'];
     if (isset($types[$plural]['plural'])) {
       $plural = $types[$plural]['plural'];
@@ -317,7 +317,7 @@ public function usesGroupBy() {
   public function buildGroupByForm(&$form, &$form_state) {
     $view = &$form_state['view'];
     $display_id = $form_state['display_id'];
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     $type = $form_state['type'];
     $id = $form_state['id'];
 
diff --git a/lib/Drupal/views/Plugin/views/PluginBase.php b/lib/Drupal/views/Plugin/views/PluginBase.php
index 826241279741..69ed8ebd7351 100644
--- a/lib/Drupal/views/Plugin/views/PluginBase.php
+++ b/lib/Drupal/views/Plugin/views/PluginBase.php
@@ -22,7 +22,7 @@ abstract class PluginBase extends ComponentPluginBase {
   /**
    * The top object of a view.
    *
-   * @var Drupal\views\View
+   * @var Drupal\views\ViewExecutable
    */
   public $view = NULL;
 
diff --git a/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
index 1d851b28c295..7cfdbff1c3f6 100644
--- a/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
+++ b/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Plugin\views\display;
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\PluginBase;
 
 /**
@@ -32,7 +32,7 @@ abstract class DisplayPluginBase extends PluginBase {
   /**
    * The top object of a view.
    *
-   * @var Drupal\views\View
+   * @var Drupal\views\ViewExecutable
    */
   var $view = NULL;
 
@@ -840,7 +840,7 @@ public function &getHandler($type, $id) {
   public function getHandlers($type) {
     if (!isset($this->handlers[$type])) {
       $this->handlers[$type] = array();
-      $types = View::viewsHandlerTypes();
+      $types = ViewExecutable::viewsHandlerTypes();
       $plural = $types[$type]['plural'];
 
       foreach ($this->getOption($plural) as $id => $info) {
@@ -2639,7 +2639,7 @@ public function validate() {
     }
 
     // Validate handlers
-    foreach (View::viewsHandlerTypes() as $type => $info) {
+    foreach (ViewExecutable::viewsHandlerTypes() as $type => $info) {
       foreach ($this->getHandlers($type) as $handler) {
         $result = $handler->validate();
         if (!empty($result) && is_array($result)) {
@@ -2664,7 +2664,7 @@ public function validate() {
    *
    */
   public function isIdentifierUnique($id, $identifier) {
-    foreach (View::viewsHandlerTypes() as $type => $info) {
+    foreach (ViewExecutable::viewsHandlerTypes() as $type => $info) {
       foreach ($this->getHandlers($type) as $key => $handler) {
         if ($handler->canExpose() && $handler->isExposed()) {
           if ($handler->isAGroup()) {
diff --git a/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php b/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php
index 945f8e7b5eee..e27dcc1d52bc 100644
--- a/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php
+++ b/lib/Drupal/views/Plugin/views/relationship/GroupwiseMax.php
@@ -8,7 +8,7 @@
 namespace Drupal\views\Plugin\views\relationship;
 
 use Drupal\Core\Database\Query\AlterableInterface;
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 use Drupal\Core\Annotation\Plugin;
 
 /**
diff --git a/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php b/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php
index 3f7cc7bf40aa..cd340fbe4d3a 100644
--- a/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php
+++ b/lib/Drupal/views/Plugin/views/wizard/WizardInterface.php
@@ -50,7 +50,7 @@ public function validateView(array $form, array &$form_state);
    * @param array $form_state
    *   The current state of the wizard form.
    *
-   * @return Drupal\views\View
+   * @return Drupal\views\ViewExecutable
    *   The created view object.
    *
    * @throws Drupal\views\Plugin\views\wizard\WizardException
diff --git a/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
index 6949f483d53a..1af446bb199e 100644
--- a/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
+++ b/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Plugin\views\wizard;
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\PluginBase;
 use Drupal\views\Plugin\views\wizard\WizardInterface;
@@ -542,7 +542,7 @@ protected function build_sorts(&$form, &$form_state) {
   /**
    * Instantiates a view object from form values.
    *
-   * @return
+   * @return Drupal\views\ViewExecutable
    *   The instantiated view object.
    */
   protected function instantiate_view($form, &$form_state) {
@@ -565,7 +565,9 @@ protected function instantiate_view($form, &$form_state) {
 
     $this->addDisplays($view, $display_options, $form, $form_state);
 
-    return $view;
+    $executable = new ViewExecutable($view);
+
+    return $executable;
   }
 
   /**
@@ -1035,7 +1037,7 @@ protected function set_override_options(array $options, DisplayPluginBase $displ
    * @param bool $unset
    *   Should the view be removed from the list of validated views.
    *
-   * @return Drupal\views\View $view
+   * @return Drupal\views\ViewExecutable $view
    *   The validated view object.
    */
   protected function retrieve_validated_view(array $form, array &$form_state, $unset = TRUE) {
@@ -1056,7 +1058,7 @@ protected function retrieve_validated_view(array $form, array &$form_state, $uns
    *   The full wizard form array.
    * @param array $form_state
    *   The current state of the wizard form.
-   * @param Drupal\views\View $view
+   * @param Drupal\views\ViewExecutable $view
    *   The validated view object.
    */
   protected function set_validated_view(array $form, array &$form_state, View $view) {
diff --git a/lib/Drupal/views/Tests/Plugin/CacheTest.php b/lib/Drupal/views/Tests/Plugin/CacheTest.php
index a16c3e02ea60..cf2e61966d12 100644
--- a/lib/Drupal/views/Tests/Plugin/CacheTest.php
+++ b/lib/Drupal/views/Tests/Plugin/CacheTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Tests\Plugin;
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 /**
  * Basic test for pluggable caching.
@@ -33,7 +33,7 @@ protected function setUp() {
   /**
    * Build and return a basic view of the views_test_data table.
    *
-   * @return Drupal\views\View
+   * @return Drupal\views\ViewExecutable
    */
   protected function getBasicView() {
     // Create the basic view.
diff --git a/lib/Drupal/views/Tests/Plugin/StyleMappingTest.php b/lib/Drupal/views/Tests/Plugin/StyleMappingTest.php
index e34102283a35..dea64539ae4c 100644
--- a/lib/Drupal/views/Tests/Plugin/StyleMappingTest.php
+++ b/lib/Drupal/views/Tests/Plugin/StyleMappingTest.php
@@ -44,7 +44,7 @@ public function testMappedOutput() {
   /**
    * Tests the mapping of fields.
    *
-   * @param Drupal\views\View $view
+   * @param Drupal\views\ViewExecutable $view
    *   The view to test.
    *
    * @return string
diff --git a/lib/Drupal/views/Tests/ViewExecutableTest.php b/lib/Drupal/views/Tests/ViewExecutableTest.php
new file mode 100644
index 000000000000..cb6c03743a24
--- /dev/null
+++ b/lib/Drupal/views/Tests/ViewExecutableTest.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * Definition of Drupal\views\Tests\ViewExecutable.
+ */
+
+namespace Drupal\views\Tests;
+
+/**
+ * Tests the ViewExecutable class.
+ *
+ * @see Drupal\views\ViewExecutableExecutable
+ */
+class ViewExecutableTest extends ViewTestBase {
+
+  /**
+   * Properties that should be stored in the configuration.
+   *
+   * @var array
+   */
+  protected $configProperties = array(
+    'disabled',
+    'api_version',
+    'name',
+    'description',
+    'tag',
+    'base_table',
+    'human_name',
+    'core',
+    'display',
+  );
+
+  /**
+   * Properties that should be stored in the executable.
+   *
+   * @var array
+   */
+  protected $executableProperties = array(
+    'build_info'
+  );
+
+  public static function getInfo() {
+    return array(
+      'name' => 'View executable tests',
+      'description' => 'Tests the ViewExecutable class.',
+      'group' => 'Views'
+    );
+  }
+
+  /**
+   * Tests the generation of the executable object.
+   */
+  public function testConstructing() {
+    $view = $this->getView();
+  }
+
+  /**
+   * Tests the accessing of values on the object.
+   */
+  public function testProperties() {
+    $view = $this->getView();
+    $storage = $view->storage;
+    foreach ($this->configProperties as $property) {
+      $this->assertTrue(isset($view->{$property}));
+      $this->assertIdentical($view->{$property}, $storage->{$storage});
+    }
+    foreach ($this->executableProperties as $property) {
+      $this->assertTrue(isset($view->{$property}));
+    }
+
+    // Set one storage property manually on the storage and verify that it is
+    // access on the executable.
+    $storage->human_name = $this->randomName();
+    $this->assertIdentical($view->human_name, $storage->human_name);
+  }
+}
diff --git a/lib/Drupal/views/Tests/ViewStorageTest.php b/lib/Drupal/views/Tests/ViewStorageTest.php
index ffe354d1f9ca..5daa30f71245 100644
--- a/lib/Drupal/views/Tests/ViewStorageTest.php
+++ b/lib/Drupal/views/Tests/ViewStorageTest.php
@@ -9,7 +9,7 @@
 
 use Drupal\simpletest\WebTestBase;
 use Drupal\views\ViewStorageController;
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 use Drupal\views\ViewDisplay;
 use Drupal\views\Plugin\views\display\Page;
 
@@ -91,12 +91,13 @@ function testConfigurationEntityCRUD() {
    * Tests loading configuration entities.
    */
   protected function loadTests() {
-    $view = $this->loadView('archive');
+    $storage = $this->loadView('archive');
+    $view = new ViewExecutable();
     $data = config('views.view.archive')->get();
 
     // Confirm that an actual view object is loaded and that it returns all of
     // expected properties.
-    $this->assertTrue($view instanceof View, 'Single View instance loaded.');
+    $this->assertTrue($view instanceof ViewStorage, 'Single View instance loaded.');
     foreach ($this->config_properties as $property) {
       $this->assertTrue(isset($view->{$property}), format_string('Property: @property loaded onto View.', array('@property' => $property)));
     }
@@ -293,7 +294,7 @@ protected function statusTests() {
    * @param string $view_name
    *   The machine name of the view.
    *
-   * @return object Drupal\views\View.
+   * @return object Drupal\views\ViewExecutable.
    *   The loaded view object.
    */
   protected function loadView($view_name) {
diff --git a/lib/Drupal/views/Tests/ViewTest.php b/lib/Drupal/views/Tests/ViewTest.php
index 3197734136cf..20c8da8a6484 100644
--- a/lib/Drupal/views/Tests/ViewTest.php
+++ b/lib/Drupal/views/Tests/ViewTest.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Tests;
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 /**
  * Views class tests.
@@ -71,10 +71,10 @@ function assertViewDestroy($view) {
   }
 
   /**
-   * Tests view::viewsHandlerTypes().
+   * Tests ViewExecutable::viewsHandlerTypes().
    */
   public function testViewshandlerTypes() {
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     foreach (array('field', 'filter', 'argument', 'sort', 'header', 'footer', 'empty') as $type) {
       $this->assertTrue(isset($types[$type]));
       // @todo The key on the display should be footers, headers and empties
diff --git a/lib/Drupal/views/Tests/ViewTestBase.php b/lib/Drupal/views/Tests/ViewTestBase.php
index fd4e80460add..670ae09fd503 100644
--- a/lib/Drupal/views/Tests/ViewTestBase.php
+++ b/lib/Drupal/views/Tests/ViewTestBase.php
@@ -22,7 +22,7 @@ abstract class ViewTestBase extends WebTestBase {
   /**
    * The view to use for the test.
    *
-   * @var Drupal\views\View
+   * @var Drupal\views\ViewExecutable
    */
   protected $view;
 
@@ -390,7 +390,7 @@ protected function dataSet() {
   /**
    * Build and return a basic view of the views_test_data table.
    *
-   * @return Drupal\views\View
+   * @return Drupal\views\ViewExecutable
    */
   protected function getBasicView() {
     return $this->createViewFromConfig('test_view');
@@ -402,7 +402,7 @@ protected function getBasicView() {
    * @param string $view_name
    *   The name of the test view to create.
    *
-   * @return Drupal\views\View
+   * @return Drupal\views\ViewExecutable
    *   A View instance.
    */
   protected function createViewFromConfig($view_name) {
@@ -421,11 +421,11 @@ protected function createViewFromConfig($view_name) {
   /**
    * Clones the view used in this test and sets the default display.
    *
-   * @param Drupal\views\View $original_view
+   * @param Drupal\views\ViewStorage $original_view
    *   (optional) The view to clone. If not specified, the default view for the
    *   test will be used.
    *
-   * @return Drupal\views\View
+   * @return Drupal\views\ViewStorage
    *   A clone of the view.
    */
   protected function getView($original_view = NULL) {
diff --git a/lib/Drupal/views/View.php b/lib/Drupal/views/ViewExecutable.php
similarity index 94%
rename from lib/Drupal/views/View.php
rename to lib/Drupal/views/ViewExecutable.php
index d867d56d20c0..0b13387f501c 100644
--- a/lib/Drupal/views/View.php
+++ b/lib/Drupal/views/ViewExecutable.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\views\View.
+ * Definition of Drupal\views\ViewExecutable.
  */
 
 namespace Drupal\views;
@@ -20,78 +20,13 @@
  * 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 View extends ViewStorage {
-
-  /**
-   * The name of the base table this view will use.
-   *
-   * @var string
-   */
-  public $base_table = 'node';
-
-  /**
-   * The name of the base field to use.
-   *
-   * @var string
-   */
-  public $base_field = 'nid';
-
-  /**
-   * The name of the view.
-   *
-   * @var string
-   */
-  public $name = '';
-
-  /**
-   * The description of the view, which is used only in the interface.
-   *
-   * @var string
-   */
-  public $description = '';
-
-  /**
-   * The "tags" of a view.
-   *
-   * The tags are stored as a single string, though it is used as multiple tags
-   * for example in the views overview.
-   *
-   * @var string
-   */
-  public $tag = '';
-
-  /**
-   * The human readable name of the view.
-   *
-   * @var string
-   */
-  public $human_name = '';
-
-  /**
-   * The core version the view was created for.
-   *
-   * @var int
-   */
-  public $core = DRUPAL_CORE_COMPATIBILITY;
-
-  /**
-   * The views API version this view was created by.
-   *
-   * @var string
-   */
-  public $api_version = VIEWS_API_VERSION;
-
+class ViewExecutable {
   /**
-   * Returns whether the view's status is disabled or not.
+   * The config entity in which the view is stored.
    *
-   * This value is used for exported view, to provide some default views which
-   * aren't enabled.
-   *
-   * @var bool
+   * @var Drupal\views\ViewStorage
    */
-  public $disabled = FALSE;
-
-  // State variables
+  protected $storage;
 
   /**
    * Whether or not the view has been built.
@@ -266,16 +201,6 @@ class View extends ViewStorage {
    */
   public $display_handler;
 
-  /**
-   * Stores all display handlers of this view.
-   *
-   * An array containing Drupal\views\Plugin\views\display\DisplayPluginBase
-   * objects.
-   *
-   * @var array
-   */
-  public $display;
-
   /**
    * The current used style plugin.
    *
@@ -404,6 +329,45 @@ class View extends ViewStorage {
    */
   protected $response = NULL;
 
+  /**
+   * Constructs a new ViewExecutable object.
+   *
+   * @param Drupal\views\ViewStorage $storage
+   *   The view config entity the actual information is stored on.
+   */
+  function __construct(ViewStorage $storage) {
+    // Reference the storage and the executable to each other.
+    $this->storage = $storage;
+    $this->storage->setExecutable($this);
+  }
+
+  /**
+   * @todo
+   */
+  function __get($name) {
+    if (property_exists($this->storage, $name)) {
+      return $this->storage->{$name};
+    }
+  }
+
+  /**
+   * @todo
+   */
+  function __set($name, $value) {
+    if (property_exists($this->storage, $name)) {
+      $this->storage->{$name} = $value;
+    }
+  }
+
+  /**
+   * @todo
+   */
+  function __call($name, $arguments) {
+    if (method_exists($this->storage, $name)) {
+      call_user_func_array(array($this->storage, $name), $arguments);
+    }
+  }
+
   /**
    * Perform automatic updates when loading or importing a view.
    *
@@ -712,7 +676,7 @@ public function initStyle() {
    */
   public function initHandlers() {
     if (empty($this->inited)) {
-      foreach (View::viewsHandlerTypes() as $key => $info) {
+      foreach (ViewExecutable::viewsHandlerTypes() as $key => $info) {
         $this->_initHandler($key, $info);
       }
       $this->inited = TRUE;
@@ -776,7 +740,7 @@ public function getBaseTables() {
    * Run the preQuery() on all active handlers.
    */
   protected function _preQuery() {
-    foreach (View::viewsHandlerTypes() as $key => $info) {
+    foreach (ViewExecutable::viewsHandlerTypes() as $key => $info) {
       $handlers = &$this->$key;
       $position = 0;
       foreach ($handlers as $id => $handler) {
@@ -791,7 +755,7 @@ protected function _preQuery() {
    * Run the postExecute() on all active handlers.
    */
   protected function _postExecute() {
-    foreach (View::viewsHandlerTypes() as $key => $info) {
+    foreach (ViewExecutable::viewsHandlerTypes() as $key => $info) {
       $handlers = &$this->$key;
       foreach ($handlers as $id => $handler) {
         $handlers[$id]->postExecute($this->result);
@@ -1616,21 +1580,6 @@ public function setTitle($title) {
     return TRUE;
   }
 
-  /**
-   * Return the human readable name for a view.
-   *
-   * When a certain view doesn't have a human readable name return the machine readable name.
-   */
-  public function getHumanName() {
-    if (!empty($this->human_name)) {
-      $human_name = $this->human_name;
-    }
-    else {
-      $human_name = $this->name;
-    }
-    return $human_name;
-  }
-
   /**
    * Force the view to build a title.
    */
@@ -1844,7 +1793,7 @@ public function createDuplicate() {
    *
    * This will completely wipe a view clean so it can be considered fresh.
    *
-   * @return Drupal\views\View
+   * @return Drupal\views\ViewExecutable
    *    The cloned view.
    */
   public function cloneView() {
@@ -1888,7 +1837,7 @@ public function destroy() {
       }
     }
 
-    foreach (View::viewsHandlerTypes() as $type => $info) {
+    foreach (ViewExecutable::viewsHandlerTypes() as $type => $info) {
       if (isset($this->$type)) {
         $handlers = &$this->$type;
         foreach ($handlers as $id => $item) {
@@ -1979,36 +1928,6 @@ public function isTranslatable() {
     return (!isset($this->type) || in_array($this->type, array(t('Normal'), t('Overridden')))) ? TRUE : FALSE;
   }
 
-  /**
-   * Returns the valid types of plugins that can be used.
-   *
-   * @return array
-   *   An array of plugin type strings.
-   */
-  public static function getPluginTypes() {
-    return array(
-      'access',
-      'area',
-      'argument',
-      'argument_default',
-      'argument_validator',
-      'cache',
-      'display_extender',
-      'display',
-      'exposed_form',
-      'field',
-      'filter',
-      'join',
-      'pager',
-      'query',
-      'relationship',
-      'row',
-      'sort',
-      'style',
-      'wizard',
-    );
-  }
-
   /**
    * Provide a list of views handler types used in a view, with some information
    * about them.
@@ -2095,52 +2014,33 @@ public static function viewsHandlerTypes() {
   }
 
   /**
-   * Gets a list of paths assigned to the view.
-   *
-   * @return array
-   *   An array of paths for this view.
-   */
-  public function getPaths() {
-    $all_paths = array();
-    if (empty($this->display)) {
-      $all_paths[] = t('Edit this view to add a display.');
-    }
-    else {
-      $this->initDisplay();   // Make sure all the handlers are set up
-      foreach ($this->display as $display) {
-        if (!empty($display->handler) && $display->handler->hasPath()) {
-          $path = $display->handler->getOption('path');
-          if ($this->isEnabled() && strpos($path, '%') === FALSE) {
-            $all_paths[] = l('/' . $path, $path);
-          }
-          else {
-            $all_paths[] = check_plain('/' . $path);
-          }
-        }
-      }
-    }
-
-    return array_unique($all_paths);
-  }
-
-  /**
-   * Gets a list of displays included in the view.
+   * Returns the valid types of plugins that can be used.
    *
    * @return array
-   *   An array of display types that this view includes.
+   *   An array of plugin type strings.
    */
-  function getDisplaysList() {
-    $this->initDisplay();
-
-    $displays = array();
-    foreach ($this->display as $display) {
-      if (!empty($display->handler->definition['admin'])) {
-        $displays[$display->handler->definition['admin']] = TRUE;
-      }
-    }
-
-    ksort($displays);
-    return array_keys($displays);
+  public static function getPluginTypes() {
+    return array(
+      'access',
+      'area',
+      'argument',
+      'argument_default',
+      'argument_validator',
+      'cache',
+      'display_extender',
+      'display',
+      'exposed_form',
+      'field',
+      'filter',
+      'join',
+      'pager',
+      'query',
+      'relationship',
+      'row',
+      'sort',
+      'style',
+      'wizard',
+    );
   }
 
 }
diff --git a/lib/Drupal/views/ViewStorage.php b/lib/Drupal/views/ViewStorage.php
index f2367dfcee52..ca6c7033d21d 100644
--- a/lib/Drupal/views/ViewStorage.php
+++ b/lib/Drupal/views/ViewStorage.php
@@ -13,6 +13,100 @@
  * Defines a ViewStorage configuration entity class.
  */
 class ViewStorage extends ConfigEntityBase implements ViewStorageInterface {
+  /**
+   * The name of the base table this view will use.
+   *
+   * @var string
+   */
+  public $base_table = 'node';
+
+
+  /**
+   * The name of the view.
+   *
+   * @var string
+   */
+  public $name = '';
+
+  /**
+   * The description of the view, which is used only in the interface.
+   *
+   * @var string
+   */
+  public $description = '';
+
+  /**
+   * The "tags" of a view.
+   *
+   * The tags are stored as a single string, though it is used as multiple tags
+   * for example in the views overview.
+   *
+   * @var string
+   */
+  public $tag = '';
+
+  /**
+   * The human readable name of the view.
+   *
+   * @var string
+   */
+  public $human_name = '';
+
+  /**
+   * The core version the view was created for.
+   *
+   * @var int
+   */
+  public $core = DRUPAL_CORE_COMPATIBILITY;
+
+  /**
+   * The views API version this view was created by.
+   *
+   * @var string
+   */
+  public $api_version = VIEWS_API_VERSION;
+
+  /**
+   * Stores all display handlers of this view.
+   *
+   * An array containing Drupal\views\Plugin\views\display\DisplayPluginBase
+   * objects.
+   *
+   * @var array
+   */
+  public $display;
+
+  /**
+   * The name of the base field to use.
+   *
+   * @var string
+   */
+  public $base_field = 'nid';
+
+  /**
+   * Returns whether the view's status is disabled or not.
+   *
+   * This value is used for exported view, to provide some default views which
+   * aren't enabled.
+   *
+   * @var bool
+   */
+  public $disabled = FALSE;
+
+  /**
+   * @todo
+   */
+  public $executable;
+
+  public function setExecutable($executable) {
+    $this->executable = $executable;
+  }
+
+  function __call($name, $arguments) {
+    if (isset($executable) && method_exists($this->executable, $name)) {
+      return call_user_func_array(array($this->executable, $name), $arguments);
+    }
+  }
 
   /**
    * Overrides Drupal\Core\Entity\EntityInterface::id().
@@ -44,6 +138,21 @@ public function isEnabled() {
     return !$this->disabled;
   }
 
+  /**
+   * Return the human readable name for a view.
+   *
+   * When a certain view doesn't have a human readable name return the machine readable name.
+   */
+  public function getHumanName() {
+    if (!empty($this->human_name)) {
+      $human_name = $this->human_name;
+    }
+    else {
+      $human_name = $this->name;
+    }
+    return $human_name;
+  }
+
   /**
    * Adds a new display handler to the view, automatically creating an ID.
    *
@@ -196,6 +305,57 @@ public function &newDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
     return $this->display[$id]->handler;
   }
 
+  /**
+   * Gets a list of displays included in the view.
+   *
+   * @return array
+   *   An array of display types that this view includes.
+   */
+  function getDisplaysList() {
+    $this->initDisplay();
+
+    $displays = array();
+    foreach ($this->display as $display) {
+      if (!empty($display->handler->definition['admin'])) {
+        $displays[$display->handler->definition['admin']] = TRUE;
+      }
+    }
+
+    ksort($displays);
+    return array_keys($displays);
+  }
+
+
+
+  /**
+   * Gets a list of paths assigned to the view.
+   *
+   * @return array
+   *   An array of paths for this view.
+   */
+  public function getPaths() {
+    $all_paths = array();
+    if (empty($this->display)) {
+      $all_paths[] = t('Edit this view to add a display.');
+    }
+    else {
+      $this->initDisplay();   // Make sure all the handlers are set up
+      foreach ($this->display as $display) {
+        if (!empty($display->handler) && $display->handler->hasPath()) {
+          $path = $display->handler->getOption('path');
+          if ($this->isEnabled() && strpos($path, '%') === FALSE) {
+            $all_paths[] = l('/' . $path, $path);
+          }
+          else {
+            $all_paths[] = check_plain('/' . $path);
+          }
+        }
+      }
+    }
+
+    return array_unique($all_paths);
+  }
+
   /**
    * Adds an instance of a handler to the view.
    *
@@ -219,7 +379,7 @@ public function &newDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
    *   The unique ID for this handler instance.
    */
   public function addItem($display_id, $type, $table, $field, $options = array(), $id = NULL) {
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     $this->setDisplay($display_id);
 
     $fields = $this->display[$display_id]->handler->getOption($types[$type]['plural']);
@@ -265,7 +425,7 @@ public function getItems($type, $display_id = NULL) {
     }
 
     // Get info about the types so we can get the right data.
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     return $this->display[$display_id]->handler->getOption($types[$type]['plural']);
   }
 
@@ -285,7 +445,7 @@ public function getItems($type, $display_id = NULL) {
    */
   public function getItem($display_id, $type, $id) {
     // Get info about the types so we can get the right data.
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     // Initialize the display
     $this->setDisplay($display_id);
 
@@ -311,7 +471,7 @@ public function getItem($display_id, $type, $id) {
    */
   public function setItem($display_id, $type, $id, $item) {
     // Get info about the types so we can get the right data.
-    $types = View::viewsHandlerTypes();
+    $types = ViewExecutable::viewsHandlerTypes();
     // Initialize the display.
     $this->setDisplay($display_id);
 
diff --git a/lib/Drupal/views/ViewsBundle.php b/lib/Drupal/views/ViewsBundle.php
index 58ccc83b9a4d..a432e3563a34 100644
--- a/lib/Drupal/views/ViewsBundle.php
+++ b/lib/Drupal/views/ViewsBundle.php
@@ -9,7 +9,7 @@
 
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\HttpKernel\Bundle\Bundle;
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 /**
  * Views dependency injection container.
@@ -20,7 +20,7 @@ class ViewsBundle extends Bundle {
    * Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
    */
   public function build(ContainerBuilder $container) {
-    foreach (View::getPluginTypes() as $type) {
+    foreach (ViewExecutable::getPluginTypes() as $type) {
       $container->register("plugin.manager.views.$type", 'Drupal\views\Plugin\Type\ViewsPluginManager')
         ->addArgument($type);
     }
diff --git a/modules/node.views_template.inc b/modules/node.views_template.inc
index fbf6d7ba6c53..fe1b2b925664 100644
--- a/modules/node.views_template.inc
+++ b/modules/node.views_template.inc
@@ -10,7 +10,7 @@ function node_views_templates() {
   if (variable_get('install_profile', 'standard') != 'standard') {
     return array();
   }
-  $view = new Drupal\views\View(array(), 'view');
+  $view = new Drupal\views\ViewExecutable(array(), 'view');
   $view->name = 'image_gallery';
   $view->description = 'Shows all images which was uploaded on the "field_image" field';
   $view->tag = '';
diff --git a/tests/views_test_data/views_test_data.module b/tests/views_test_data/views_test_data.module
index 3daccc9ee718..0e4fdeca4e68 100644
--- a/tests/views_test_data/views_test_data.module
+++ b/tests/views_test_data/views_test_data.module
@@ -5,7 +5,7 @@
  * Helper module for Views tests.
  */
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 /**
  * Implements hook_permission().
diff --git a/views.api.php b/views.api.php
index 7c537a3c08f6..a980bc1f3a19 100644
--- a/views.api.php
+++ b/views.api.php
@@ -666,7 +666,7 @@ function hook_views_api() {
  */
 function hook_views_default_views() {
   // Begin copy and paste of output from the Export tab of a view.
-  $view = new Drupal\views\View();
+  $view = new Drupal\views\ViewExecutable();
   $view->name = 'frontpage';
   $view->description = 'Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page.';
   $view->tag = 'default';
diff --git a/views.module b/views.module
index ae295a038298..bafbc71a6a41 100644
--- a/views.module
+++ b/views.module
@@ -10,8 +10,9 @@
  */
 
 use Drupal\Core\Database\Query\AlterableInterface;
+use Drupal\views\ViewExecutable;
 use Drupal\views\TempStore\UserTempStore;
-use Drupal\views\View;
+use Drupal\views\ViewStorage;
 use Drupal\Component\Plugin\Exception\PluginException;
 
 /**
@@ -86,7 +87,7 @@ function views_entity_info() {
   $return = array(
     'view' => array(
       'label' => t('View'),
-      'entity class' => 'Drupal\views\View',
+      'entity class' => 'Drupal\views\ViewStorage',
       'controller class' => 'Drupal\views\ViewStorageController',
       'list controller class' => 'Drupal\views\ViewListController',
       'list path' => 'admin/structure/views',
@@ -1125,7 +1126,7 @@ function &views_set_page_view($view = NULL) {
  * this returns a reference, so be careful! You can unintentionally modify the
  * $view object.
  *
- * @return Drupal\views\View
+ * @return Drupal\views\ViewExecutable
  *   A fully formed, empty $view object.
  */
 function &views_get_page_view() {
@@ -1136,7 +1137,7 @@ function &views_get_page_view() {
  * Set the current 'current view' that is being built/rendered so that it is
  * easy for other modules or items in drupal_eval to identify
  *
- * @return Drupal\views\View
+ * @return Drupal\views\ViewExecutable
  */
 function &views_set_current_view($view = NULL) {
   static $cache = NULL;
@@ -1152,7 +1153,7 @@ function &views_set_current_view($view = NULL) {
  * this returns a reference, so be careful! You can unintentionally modify the
  * $view object.
  *
- * @return Drupal\views\View
+ * @return Drupal\views\ViewExecutable
  */
 function &views_get_current_view() {
   return views_set_current_view();
@@ -1450,7 +1451,7 @@ function views_get_plugin($type, $plugin_id) {
  */
 function views_get_plugin_definitions($type = FALSE) {
   $plugins = array();
-  $plugin_types = $type ? array($type) : View::getPluginTypes();
+  $plugin_types = $type ? array($type) : ViewExecutable::getPluginTypes();
   $container = drupal_container();
   foreach ($plugin_types as $plugin_type) {
     $plugins[$plugin_type] = $container->get("plugin.manager.views.$plugin_type")->getDefinitions();
@@ -1518,7 +1519,7 @@ function views_get_all_templates() {
 /**
  * Create an empty view to work with.
  *
- * @return Drupal\views\View
+ * @return Drupal\views\ViewExecutable
  *   A fully formed, empty $view object. This object must be populated before
  *   it can be successfully saved.
  */
@@ -1683,7 +1684,7 @@ function views_get_views_as_options($views_only = FALSE, $filter = 'all', $exclu
 /**
  * Returns whether the view is enabled.
  *
- * @param Drupal\views\View $view
+ * @param Drupal\views\ViewExecutable $view
  *   The view object to check.
  *
  * @return bool
@@ -1696,7 +1697,7 @@ function views_view_is_enabled($view) {
 /**
  * Returns whether the view is disabled.
  *
- * @param Drupal\views\View $view
+ * @param Drupal\views\ViewExecutable $view
  *   The view object to check.
  *
  * @return bool
@@ -1712,14 +1713,16 @@ function views_view_is_disabled($view) {
  * @param string $name
  *   The name of the view.
  *
- * @return Drupal\views\View
+ * @return Drupal\views\ViewExecutable
  *   A reference to the $view object.
  */
 function views_get_view($name) {
   $view = entity_load('view', $name);
   if ($view) {
-    $view->update();
-    return $view->cloneView();
+    $executable = new ViewExecutable($view);
+    $executable->update();
+    // @figure out whether it makes sense to clone this here.
+    return $executable->cloneView();
   }
 }
 
diff --git a/views_ui.module b/views_ui.module
index dc8246c67f60..dd936d80f2b5 100644
--- a/views_ui.module
+++ b/views_ui.module
@@ -5,7 +5,7 @@
  * Provide structure for the administrative interface to Views.
  */
 
-use Drupal\views\View;
+use Drupal\views\ViewExecutable;
 
 /**
  * Implements hook_menu().
@@ -465,7 +465,7 @@ function views_ui_view_preview_section_handler_links($view, $type, $title = FALS
   $handlers = $view->display_handler->getHandlers($type);
   $links = array();
 
-  $types = View::viewsHandlerTypes();
+  $types = ViewExecutable::viewsHandlerTypes();
   if ($title) {
     $links[$type . '-title'] = array(
       'title' => $types[$type]['title'],
-- 
GitLab