diff --git a/includes/admin.inc b/includes/admin.inc index bd0b169b9a4f36c6e0b810fffc9ba44878859da4..21c531d628349d02baf5723eed6c9cbb35fcb7ad 100644 --- a/includes/admin.inc +++ b/includes/admin.inc @@ -1722,9 +1722,6 @@ function views_ui_edit_form_get_build_from_option($id, $option, $view, $display) } } $option_build['#attributes']['class'][] = drupal_clean_css_identifier($display_id . '-' . $id); - if (!empty($view->changed_sections[$display_id . '-' . $id])) { - $option_build['#changed'] = TRUE; - } return $option_build; } @@ -2259,10 +2256,6 @@ function views_ui_edit_form_get_bucket($type, $view, $display) { } $build['fields'][$id]['#link'] = l($link_text, "admin/structure/views/nojs/config-item/$view->name/$display->id/$type/$id", array('attributes' => $link_attributes, 'html' => TRUE)); $build['fields'][$id]['#class'][] = drupal_clean_css_identifier($display->id . '-' . $type . '-' . $id); - if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $id])) { - // @TODO: #changed is no longer being used? - $build['fields'][$id]['#changed'] = TRUE; - } if ($display->handler->useGroupBy() && $handler->usesGroupBy()) { $build['fields'][$id]['#settings_links'][] = l('<span class="label">' . t('Aggregation settings') . '</span>', "admin/structure/views/nojs/config-item-group/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Aggregation settings')), 'html' => TRUE)); @@ -2458,12 +2451,6 @@ function views_ui_standard_submit($form, &$form_state) { list($was_defaulted, $is_defaulted, $revert) = views_ui_standard_override_values($form, $form_state); - // Mark the changed section of the view as changed. - // TODO: Document why we are doing this, and see if we still need it. - if (!empty($form['#section'])) { - $form_state['view']->changed_sections[$form['#section']] = TRUE; - } - // Based on the user's choice in the display dropdown, determine which display // these changes apply to. if ($revert) { diff --git a/lib/Drupal/views/Analyzer.php b/lib/Drupal/views/Analyzer.php index 2c6263977a6655982b5c07ac0118128c5e00f4b4..8021e0d7243aa42a8178b984860db93e98bbc980 100644 --- a/lib/Drupal/views/Analyzer.php +++ b/lib/Drupal/views/Analyzer.php @@ -32,7 +32,7 @@ class Analyzer { * @param Drupal\views\ViewExecutable $view * (optional) The view to analyze. */ - function __construct(View $view = NULL) { + function __construct(ViewExecutable $view = NULL) { if (isset($view)) { $this->view = $view; } @@ -44,7 +44,7 @@ function __construct(View $view = NULL) { * @param Drupal\views\ViewExecutable * The view to analyze. */ - public function setView(View $view = NULL) { + public function setView(ViewExecutable $view = NULL) { $this->view = $view; } diff --git a/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php b/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php index d4964f75951e12140d062b3e1448eae838189c47..96b1d1ff5e9436316439b07ec3e2e979d0e0aead 100644 --- a/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php +++ b/lib/Drupal/views/Plugin/views/argument/ArgumentPluginBase.php @@ -786,7 +786,7 @@ function default_summary() { // Summaries have their own sorting and fields, so tell the View not // to build these. - $this->view->build_sort = $this->view->build_fields = FALSE; + $this->view->build_sort = FALSE; return TRUE; } diff --git a/lib/Drupal/views/Plugin/views/display/Attachment.php b/lib/Drupal/views/Plugin/views/display/Attachment.php index 7a1fc1af59c29ce38f9bafa6db5fd4f17587de5d..d52d743359eb3fdecea0edd217ee66380a621489 100644 --- a/lib/Drupal/views/Plugin/views/display/Attachment.php +++ b/lib/Drupal/views/Plugin/views/display/Attachment.php @@ -244,7 +244,6 @@ public function attachTo($display_id) { // Get a fresh view because our current one has a lot of stuff on it because it's // already been executed. $view = $this->view->cloneView(); - $view->original_args = $view->args; $args = $this->getOption('inherit_arguments') ? $this->view->args : array(); $view->setArguments($args); diff --git a/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php index 1af446bb199e1c419ad981d23634009dfbbe1731..3037525b459bf0e8b638ff8f9cbccecf270d6f2f 100644 --- a/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php +++ b/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php @@ -1061,7 +1061,7 @@ protected function retrieve_validated_view(array $form, array &$form_state, $uns * @param Drupal\views\ViewExecutable $view * The validated view object. */ - protected function set_validated_view(array $form, array &$form_state, View $view) { + protected function set_validated_view(array $form, array &$form_state, ViewExecutable $view) { $key = hash('sha256', serialize($form_state['values'])); $this->validated_views[$key] = $view; } diff --git a/lib/Drupal/views/Tests/AnalyzeTest.php b/lib/Drupal/views/Tests/AnalyzeTest.php index 41c8844bf3ee56bb502c899a0ddbc6b57207c6bc..a368d395388102b54cea042e534d725e79821e47 100644 --- a/lib/Drupal/views/Tests/AnalyzeTest.php +++ b/lib/Drupal/views/Tests/AnalyzeTest.php @@ -41,7 +41,7 @@ function testAnalyzeBasic() { $this->drupalLogin($this->admin); // Enable the frontpage view and click the analyse button. $view = views_get_view('frontpage'); - $view->save(); + $view = $view->createDuplicate(); $this->drupalGet('admin/structure/views/view/frontpage/edit'); $this->assertLink(t('analyze view')); diff --git a/lib/Drupal/views/Tests/Handler/FieldTest.php b/lib/Drupal/views/Tests/Handler/FieldTest.php index 38d6adc8922c9f885cd0fa57ba48ef94004c1af8..80f31b3b11ff05c52eeb8f8557e9ff3614b0f48f 100644 --- a/lib/Drupal/views/Tests/Handler/FieldTest.php +++ b/lib/Drupal/views/Tests/Handler/FieldTest.php @@ -92,6 +92,7 @@ public function testQuery() { */ public function testClickSorting() { $this->drupalGet('test_click_sort'); + $this->assertResponse(200); // Only the id and name should be click sortable, but not the name. $this->assertLinkByHref(url('test_click_sort', array('query' => array('order' => 'id', 'sort' => 'asc')))); $this->assertLinkByHref(url('test_click_sort', array('query' => array('order' => 'name', 'sort' => 'desc')))); diff --git a/lib/Drupal/views/Tests/Plugin/CacheTest.php b/lib/Drupal/views/Tests/Plugin/CacheTest.php index cf2e61966d1222463845d44449a1f9869856b534..2c75f441b75668aec510c3784df5d2118e0a5edf 100644 --- a/lib/Drupal/views/Tests/Plugin/CacheTest.php +++ b/lib/Drupal/views/Tests/Plugin/CacheTest.php @@ -37,8 +37,7 @@ protected function setUp() { */ protected function getBasicView() { // Create the basic view. - $view = new View(array(), 'view'); - $view->name = 'test_view'; + $view = $this->createViewFromConfig('test_view'); $view->addDisplay('default'); $view->base_table = 'views_test_data'; @@ -169,12 +168,11 @@ function testHeaderStorage() { )); $view->preview(); - $view->destroy(); unset($view->pre_render_called); drupal_static_reset('drupal_add_css'); drupal_static_reset('drupal_add_js'); - $view->initDisplay(); + $view = $this->getView($view); $view->preview(); $css = drupal_add_css(); $css_path = drupal_get_path('module', 'views_test_data') . '/views_cache.test.css'; @@ -183,8 +181,7 @@ function testHeaderStorage() { $this->assertTrue(isset($css[$css_path]), 'Make sure the css is added for cached views.'); $this->assertTrue(isset($js[$js_path]), 'Make sure the js is added for cached views.'); - $this->assertFalse(!empty($view->pre_render_called), 'Make sure hook_views_pre_render is not called for the cached view.'); - $view->destroy(); + $this->assertFalse(!empty($view->build_info['pre_render_called']), 'Make sure hook_views_pre_render is not called for the cached view.'); // Now add some css/jss before running the view. // Make sure that this css is not added when running the cached view. @@ -195,13 +192,12 @@ function testHeaderStorage() { $system_js_path = drupal_get_path('module', 'system') . '/system.cron.js'; drupal_add_js($system_js_path); - $view->initDisplay(); + $view = $this->getView($view); $view->preview(); - $view->destroy(); drupal_static_reset('drupal_add_css'); drupal_static_reset('drupal_add_js'); - $view->initDisplay(); + $view = $this->getView($view); $view->preview(); $css = drupal_add_css(); @@ -209,7 +205,6 @@ function testHeaderStorage() { $this->assertFalse(isset($css[$system_css_path]), 'Make sure that unrelated css is not added.'); $this->assertFalse(isset($js[$system_js_path]), 'Make sure that unrelated js is not added.'); - } } diff --git a/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php b/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php index e8878940b3f9fdb27a98236a03ace064ff2d75ea..f415a251ef35247cf22ef2f61423cfe4ff4d9a69 100644 --- a/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php +++ b/lib/Drupal/views/Tests/Plugin/ExposedFormTest.php @@ -62,6 +62,7 @@ public function testRenameResetButton() { // Look whether ther reset button label changed. $this->drupalGet('test_rename_reset_button'); + $this->assertResponse(200); $this->helperButtonHasLabel('edit-reset', $expected_label); } diff --git a/lib/Drupal/views/Tests/UI/DefaultViewsTest.php b/lib/Drupal/views/Tests/UI/DefaultViewsTest.php index b891e967971f4b7954f6c449e61d84493def6045..86eadad4756af6fad2e54f599d20543957b65a95 100644 --- a/lib/Drupal/views/Tests/UI/DefaultViewsTest.php +++ b/lib/Drupal/views/Tests/UI/DefaultViewsTest.php @@ -52,6 +52,7 @@ function testDefaultViews() { $this->drupalPost('admin/structure/views/nojs/display/frontpage/page/title', $edit, t('Apply')); $this->drupalPost('admin/structure/views/view/frontpage/edit/page', array(), t('Save')); $this->drupalGet('frontpage'); + $this->assertResponse(200); $this->assertText($new_title); // It should now be possible to revert the view. Do that, and make sure the diff --git a/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php b/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php index aac77ae33aa59b81240e731e3f0791285dcb86da..3c7e6cc14f6096a07a63e93231312c80ade29f89 100644 --- a/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php +++ b/lib/Drupal/views/Tests/UI/OverrideDisplaysTest.php @@ -62,6 +62,7 @@ function testOverrideDisplays() { // Make sure the title appears in both the page and the block. $this->drupalGet($view_path); + $this->assertResponse(200); $this->assertText($original_title); $this->drupalGet(''); $this->assertText($original_title); @@ -74,6 +75,7 @@ function testOverrideDisplays() { $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page/title", $edit, t('Apply')); $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/page", array(), t('Save')); $this->drupalGet($view_path); + $this->assertResponse(200); $this->assertText($new_title); $this->assertNoText($original_title); $this->drupalGet(''); @@ -119,9 +121,11 @@ function testWizardMixedDefaultOverriddenDisplays() { // Make sure that the feed, page and block all start off with the correct // titles. $this->drupalGet($view['page[path]']); + $this->assertResponse(200); $this->assertText($view['page[title]']); $this->assertNoText($view['block[title]']); $this->drupalGet($view['page[feed_properties][path]']); + $this->assertResponse(200); $this->assertText($view['page[title]']); $this->assertNoText($view['block[title]']); $this->drupalGet(''); @@ -135,10 +139,12 @@ function testWizardMixedDefaultOverriddenDisplays() { $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page/title", $edit, t('Apply')); $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/page", array(), t('Save')); $this->drupalGet($view['page[path]']); + $this->assertResponse(200); $this->assertText($new_default_title); $this->assertNoText($view['page[title]']); $this->assertNoText($view['block[title]']); $this->drupalGet($view['page[feed_properties][path]']); + $this->assertResponse(200); $this->assertText($new_default_title); $this->assertNoText($view['page[title]']); $this->assertNoText($view['block[title]']); @@ -154,9 +160,11 @@ function testWizardMixedDefaultOverriddenDisplays() { $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/block/title", $edit, t('Apply')); $this->drupalPost("admin/structure/views/view/{$view['name']}/edit/block", array(), t('Save')); $this->drupalGet($view['page[path]']); + $this->assertResponse(200); $this->assertText($new_default_title); $this->assertNoText($new_block_title); $this->drupalGet($view['page[feed_properties][path]']); + $this->assertResponse(200); $this->assertText($new_default_title); $this->assertNoText($new_block_title); $this->drupalGet(''); diff --git a/lib/Drupal/views/Tests/ViewExecutableTest.php b/lib/Drupal/views/Tests/ViewExecutableTest.php index cb6c03743a24e01e057780e608616f76b7b2e079..c518f56e0e10fc92b1672d4a873b5b19591568c2 100644 --- a/lib/Drupal/views/Tests/ViewExecutableTest.php +++ b/lib/Drupal/views/Tests/ViewExecutableTest.php @@ -61,8 +61,7 @@ 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}); + $this->assertIdentical($view->{$property}, $storage->{$property}, format_string("Property '%property' is set on the stored view.", array('%property' => $property))); } foreach ($this->executableProperties as $property) { $this->assertTrue(isset($view->{$property})); diff --git a/lib/Drupal/views/Tests/ViewStorageTest.php b/lib/Drupal/views/Tests/ViewStorageTest.php index 5daa30f712457344782357cbdd55f72d94119c4a..74832a15ceb6df16500fd6c967dd43022c98dd09 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\ViewExecutable; +use Drupal\views\ViewStorage; use Drupal\views\ViewDisplay; use Drupal\views\Plugin\views\display\Page; @@ -91,8 +91,7 @@ function testConfigurationEntityCRUD() { * Tests loading configuration entities. */ protected function loadTests() { - $storage = $this->loadView('archive'); - $view = new ViewExecutable(); + $view = $this->loadView('archive'); $data = config('views.view.archive')->get(); // Confirm that an actual view object is loaded and that it returns all of @@ -150,7 +149,7 @@ protected function createTests() { // Create a new View instance with empty values. $created = $this->controller->create(array()); - $this->assertTrue($created instanceof View, 'Created object is a View.'); + $this->assertTrue($created instanceof ViewStorage, 'Created object is a View.'); // Check that the View contains all of the properties. foreach ($this->config_properties as $property) { $this->assertTrue(property_exists($created, $property), format_string('Property: @property created on View.', array('@property' => $property))); @@ -160,7 +159,7 @@ protected function createTests() { $values = config('views.view.glossary')->get(); $created = $this->controller->create($values); - $this->assertTrue($created instanceof View, 'Created object is a View.'); + $this->assertTrue($created instanceof ViewStorage, 'Created object is a View.'); // Check that the View contains all of the properties. $properties = $this->config_properties; // Remove display from list. @@ -251,7 +250,6 @@ protected function displayTests() { // Ensure the right display_plugin is created/instantiated. $this->assertEqual($new_display->display_plugin, 'page', 'New page display "test" uses the right display plugin.'); - $view->initDisplay(); $this->assertTrue($new_display->handler instanceof Page, 'New page display "test" uses the right display plugin.'); diff --git a/lib/Drupal/views/Tests/ViewTest.php b/lib/Drupal/views/Tests/ViewTest.php index 20c8da8a64847d07933e525ad3cf311e2a282b0a..50801040674ba6e8fcd8d85b24755ae37e589d7f 100644 --- a/lib/Drupal/views/Tests/ViewTest.php +++ b/lib/Drupal/views/Tests/ViewTest.php @@ -8,6 +8,7 @@ namespace Drupal\views\Tests; use Drupal\views\ViewExecutable; +use Drupal\views\ViewStorage; /** * Views class tests. @@ -112,7 +113,7 @@ public function testCreateDuplicate() { $view = views_get_view('archive'); $copy = $view->createDuplicate(); - $this->assertTrue($copy instanceof View, 'The copied object is a View.'); + $this->assertTrue($copy instanceof ViewStorage, 'The copied object is a View.'); // Check that the original view and the copy have different uuids. $this->assertNotIdentical($view->uuid(), $copy->uuid(), 'The copied view has a new uuid.'); diff --git a/lib/Drupal/views/Tests/ViewTestBase.php b/lib/Drupal/views/Tests/ViewTestBase.php index 670ae09fd503eefabbae27b46cec794e45b76496..7c00eb3fd657085b3c1ce39d046f5aa4f7e6fc64 100644 --- a/lib/Drupal/views/Tests/ViewTestBase.php +++ b/lib/Drupal/views/Tests/ViewTestBase.php @@ -5,6 +5,8 @@ */ namespace Drupal\views\Tests; + +use Drupal\views\ViewExecutable; use Drupal\simpletest\WebTestBase; /** @@ -413,6 +415,7 @@ protected function createViewFromConfig($view_name) { $data = config("views.view.$view_name")->get(); $view = entity_create('view', $data); + $view = new ViewExecutable($view); $view->setDisplay(); return $view; @@ -425,7 +428,7 @@ protected function createViewFromConfig($view_name) { * (optional) The view to clone. If not specified, the default view for the * test will be used. * - * @return Drupal\views\ViewStorage + * @return Drupal\views\ViewExecutable * A clone of the view. */ protected function getView($original_view = NULL) { diff --git a/lib/Drupal/views/ViewExecutable.php b/lib/Drupal/views/ViewExecutable.php index 0b13387f501c5e5594067825cb8c6fe6d9eb91f0..ef599dcd797baffc7744d2c5beaded53bb1f5d13 100644 --- a/lib/Drupal/views/ViewExecutable.php +++ b/lib/Drupal/views/ViewExecutable.php @@ -21,16 +21,19 @@ * functions to build the view query, execute the query and render the output. */ class ViewExecutable { + /** * The config entity in which the view is stored. * * @var Drupal\views\ViewStorage */ - protected $storage; + public $storage; /** * Whether or not the view has been built. * + * @todo Group with other static properties. + * * @var bool */ public $built = FALSE; @@ -38,6 +41,8 @@ class ViewExecutable { /** * Whether the view has been executed/query has been run. * + * @todo Group with other static properties. + * * @var bool */ public $executed = FALSE; @@ -45,6 +50,8 @@ class ViewExecutable { /** * Indicates if a view is currently being edited. * + * @todo Group with other UI-only properties. + * * @var bool */ public $editing = FALSE; @@ -208,14 +215,6 @@ class ViewExecutable { */ public $style_plugin; - /** - * Stored the changed options of the style plugin. - * - * @deprecated Better use $view->style_plugin->options - * @var array - */ - public $style_options; - /** * Stores the current active row while rendering. * @@ -329,42 +328,217 @@ class ViewExecutable { */ protected $response = NULL; + /** + * Stores an array of errors for any displays. + * + * @todo Group with other UI-only properties. + * + * @var array + */ + public $display_errors; + + /** + * Stores an array of displays that have been changed. + * + * @todo Group with other UI-only properties. + * + * @var array + */ + public $changed_display; + + /** + * Does this view already have loaded it's handlers. + * + * @todo Group with other static properties. + * + * @var bool + */ + public $inited; + + /** + * The name of the active style plugin of the view. + * + * @todo remove this and just use $this->style_plugin + * + * @var string + */ + public $plugin_name; + + /** + * The options used by the style plugin of this running view. + * + * @todo To be able to remove it, Drupal\views\Plugin\views\argument\ArgumentPluginBase::default_summary() + * should instantiate the style plugin. + * @var array + */ + public $style_options; + + /** + * The rendered output of the exposed form. + * + * @var string + */ + public $exposed_widgets; + + /** + * If this view has been previewed. + * + * @var bool + */ + public $preview; + + /** + * Force the query to calculate the total number of results. + * + * @todo Move to the query. + * + * @var bool + */ + public $get_total_rows; + + /** + * Indicates if the sorts have been built. + * + * @todo Group with other static properties. + * + * @var bool + */ + public $build_sort; + + /** + * How long the view takes to build. + * + * @todo Group with other UI-only properties. + * + * @var int + */ + public $build_time; + + /** + * How long the view takes to render. + * + * @todo Group with other UI-only properties. + * + * @var int + */ + public $render_time; + + /** + * How long the view takes to execute. + * + * @todo Group with other UI-only properties. + * + * @var int + */ + public $execute_time; + + /** + * If this view is locked for editing. + * + * @todo Group with other UI-only properties. + * + * @var bool + */ + public $locked; + + /** + * If this view has been changed. + * + * @todo Group with other UI-only properties. + * + * @var bool + */ + public $changed; + + /** + * Stores options temporarily while editing. + * + * @todo Group with other UI-only properties. + * + * @var array + */ + public $temporary_options; + + /** + * Stores a stack of UI forms to display. + * + * @todo Group with other UI-only properties. + * + * @var array + */ + public $stack; + + /** + * Stores the many-to-one tables for performance. + * + * @var array + */ + public $many_to_one_tables; + + /** + * Is the view runned in a context of the preview in the admin interface. + * + * @todo Group with other UI-only properties. + * + * @var bool + */ + public $live_preview; + + /** + * A unique identifier which allows to update multiple views output via js. + * + * @var string + */ + public $dom_id; + /** * Constructs a new ViewExecutable object. * * @param Drupal\views\ViewStorage $storage * The view config entity the actual information is stored on. */ - function __construct(ViewStorage $storage) { + public function __construct(ViewStorage $storage) { // Reference the storage and the executable to each other. $this->storage = $storage; $this->storage->setExecutable($this); } /** - * @todo + * Implements the magic __get() method. + * + * @todo Remove this once all calls are changed to use storage directly. */ - function __get($name) { + public function &__get($name) { if (property_exists($this->storage, $name)) { return $this->storage->{$name}; } + elseif (property_exists($this, $name)) { + return $this->{$name}; + } } /** - * @todo + * Implements the magic __set() method. + * + * @todo Remove this once all calls are changed to use storage directly. */ - function __set($name, $value) { - if (property_exists($this->storage, $name)) { + public function __set($name, $value) { + if (property_exists($this, $name)) { + $this->{$name} = $value; + } + elseif (property_exists($this->storage, $name)) { $this->storage->{$name} = $value; } } /** - * @todo + * Implements the magic __call() method. + * + * @todo Remove this once all calls are changed to use storage directly. */ - function __call($name, $arguments) { + public function __call($name, $arguments) { if (method_exists($this->storage, $name)) { - call_user_func_array(array($this->storage, $name), $arguments); + return call_user_func_array(array($this->storage, $name), $arguments); } } @@ -378,10 +552,9 @@ function __call($name, $arguments) { public function update() { // When views are converted automatically the base_table should be renamed // to have a working query. - $this->base_table = views_move_table($this->base_table); + $this->storage->base_table = views_move_table($this->storage->base_table); } - /** * Returns a list of the sub-object types used by this view. These types are * stored on the display, and are used in the build process. @@ -525,8 +698,8 @@ public function getExposedInput() { // remember settings. $display_id = ($this->display_handler->isDefaulted('filters')) ? 'default' : $this->current_display; - if (empty($this->exposed_input) && !empty($_SESSION['views'][$this->name][$display_id])) { - $this->exposed_input = $_SESSION['views'][$this->name][$display_id]; + if (empty($this->exposed_input) && !empty($_SESSION['views'][$this->storage->name][$display_id])) { + $this->exposed_input = $_SESSION['views'][$this->storage->name][$display_id]; } } @@ -569,7 +742,7 @@ public function initDisplay($reset = FALSE) { } $this->current_display = 'default'; - $this->display_handler = &$this->display['default']->handler; + $this->display_handler = $this->storage->display['default']->handler; return TRUE; } @@ -639,7 +812,7 @@ public function setDisplay($display_id = NULL) { } // Set a shortcut - $this->display_handler = &$this->display[$display_id]->handler; + $this->display_handler = $this->storage->display[$display_id]->handler; return TRUE; } @@ -700,7 +873,7 @@ public function initPager() { // These overrides may have been set earlier via $view->set_* // functions. if (isset($this->items_per_page)) { - $this->pager->setItemsPerPage($this->items_per_page); + $this->pager->set_items_per_page($this->items_per_page); } if (isset($this->offset)) { @@ -726,7 +899,7 @@ public function renderPager($exposed_input) { */ public function getBaseTables() { $base_tables = array( - $this->base_table => TRUE, + $this->storage->base_table => TRUE, '#global' => TRUE, ); @@ -910,7 +1083,7 @@ public function initQuery() { } // Create and initialize the query object. - $views_data = views_fetch_data($this->base_table); + $views_data = views_fetch_data($this->storage->base_table); $this->base_field = !empty($views_data['table']['base']['field']) ? $views_data['table']['base']['field'] : ''; if (!empty($views_data['table']['base']['database'])) { $this->base_database = $views_data['table']['base']['database']; @@ -927,7 +1100,7 @@ public function initQuery() { return FALSE; } - $this->query->init($this->base_table, $this->base_field, $query_options['options']); + $this->query->init($this->storage->base_table, $this->base_field, $query_options['options']); return TRUE; } @@ -1205,7 +1378,7 @@ public function render($display_id = NULL) { if (!empty($this->build_info['fail'])) { return; } - if (!empty($this->view->build_info['denied'])) { + if (!empty($this->build_info['denied'])) { return; } @@ -1495,7 +1668,7 @@ public function executeHookBlockList($display_id = NULL) { */ public function access($displays = NULL, $account = NULL) { // Noone should have access to disabled views. - if (!empty($this->disabled)) { + if (!empty($this->storage->disabled)) { return FALSE; } @@ -1797,14 +1970,13 @@ public function createDuplicate() { * The cloned view. */ public function cloneView() { - $clone = clone $this; + $clone = clone $this->storage; $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'exposed_widgets', 'many_to_one_tables', 'feed_icon'); foreach ($keys as $key) { - if (isset($clone->$key)) { - unset($clone->$key); - } + unset($clone->$key); } + $clone = new ViewExecutable($clone); $clone->built = $clone->executed = FALSE; $clone->build_info = array(); $clone->attachment_before = ''; @@ -1849,27 +2021,11 @@ public function destroy() { if (isset($this->style_plugin)) { $this->style_plugin->destroy(); - unset($this->style_plugin); - } - - // Clear these to make sure the view can be processed/used again. - if (isset($this->display_handler)) { - unset($this->display_handler); - } - - if (isset($this->current_display)) { - unset($this->current_display); } - if (isset($this->query)) { - unset($this->query); - } - - $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'result', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables'); + $keys = array('current_display', 'display_handler', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'result', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables'); foreach ($keys as $key) { - if (isset($this->$key)) { - unset($this->$key); - } + unset($this->$key); } // These keys are checked by the next init, so instead of unsetting them, @@ -1919,15 +2075,6 @@ public function validate() { return $errors ? $errors : TRUE; } - /** - * Determine whether a view supports admin string translation. - */ - public function isTranslatable() { - // If the view is normal or overridden, use admin string translation. - // A newly created view won't have a type. Accept this. - return (!isset($this->type) || in_array($this->type, array(t('Normal'), t('Overridden')))) ? TRUE : FALSE; - } - /** * Provide a list of views handler types used in a view, with some information * about them. diff --git a/lib/Drupal/views/ViewStorage.php b/lib/Drupal/views/ViewStorage.php index ca6c7033d21d52096c820402e67a31f194bf8fe9..9700f007e6167ac793f07b41102c65e345a7a0d4 100644 --- a/lib/Drupal/views/ViewStorage.php +++ b/lib/Drupal/views/ViewStorage.php @@ -13,6 +13,16 @@ * Defines a ViewStorage configuration entity class. */ class ViewStorage extends ConfigEntityBase implements ViewStorageInterface { + + /** + * Provide direct access to the UUID. + * + * @todo Change usage of this to the uuid() method. + * + * @var string + */ + public $uuid; + /** * The name of the base table this view will use. * @@ -20,7 +30,6 @@ class ViewStorage extends ConfigEntityBase implements ViewStorageInterface { */ public $base_table = 'node'; - /** * The name of the view. * @@ -94,20 +103,87 @@ class ViewStorage extends ConfigEntityBase implements ViewStorageInterface { public $disabled = FALSE; /** - * @todo + * Stores a reference to the executable version of this view. + * + * @var Drupal\views\ViewExecutable */ public $executable; - public function setExecutable($executable) { + /** + * A copy of the original entity. + * + * @todo This should be moved to Drupal\Core\Entity\Entity. + * + * @var Drupal\Core\Entity\EntityInterface + */ + public $original; + + /** + * Stores the executable version of this view. + * + * @param Drupal\views\ViewExecutable $executable + * The executable version of this view. + */ + public function setExecutable(ViewExecutable $executable) { $this->executable = $executable; } - function __call($name, $arguments) { - if (isset($executable) && method_exists($this->executable, $name)) { + /** + * Initializes the display. + * + * @todo Inspect calls to this and attempt to clean up. + * + * @param bool $reset + * If the display should be reset. Defaults to FALSE. + * + * @see Drupal\views\ViewExecutable::initDisplay() + */ + public function initDisplay($reset = FALSE) { + if (!isset($this->executable)) { + $this->setExecutable(new ViewExecutable($this)); + } + $this->executable->initDisplay($reset); + } + + /** + * Implements the magic __call() method. + * + * @todo Remove this once all calls are changed to use executable directly. + */ + public function __call($name, $arguments) { + if (method_exists($this->executable, $name)) { return call_user_func_array(array($this->executable, $name), $arguments); } } + /** + * Implements the magic __get() method. + * + * @todo Remove this once all calls are changed to use executable directly. + */ + public function &__get($name) { + if (property_exists($this->executable, $name)) { + return $this->executable->{$name}; + } + if (property_exists($this, $name)) { + return $this->{$name}; + } + } + + /** + * Implements the magic __set() method. + * + * @todo Remove this once all calls are changed to use executable directly. + */ + public function __set($name, $value) { + if (property_exists($this, $name)) { + $this->{$name} = $value; + } + elseif (property_exists($this->executable, $name)) { + $this->executable->{$name} = $value; + } + } + /** * Overrides Drupal\Core\Entity\EntityInterface::id(). */ @@ -325,8 +401,6 @@ function getDisplaysList() { return array_keys($displays); } - - /** * Gets a list of paths assigned to the view. * diff --git a/tests/views_test_data/views_test_data.module b/tests/views_test_data/views_test_data.module index 0e4fdeca4e688e50b7e39056dcb2a16c86ed5890..62a67df1d33d46994c8678f6a81562c27ceb870b 100644 --- a/tests/views_test_data/views_test_data.module +++ b/tests/views_test_data/views_test_data.module @@ -51,14 +51,14 @@ function views_test_data_views_pre_render(&$view) { if ($view->name == 'test_cache_header_storage') { drupal_add_js(drupal_get_path('module', 'views_test_data') . '/views_cache.test.js'); drupal_add_css(drupal_get_path('module', 'views_test_data') . '/views_cache.test.css'); - $view->pre_render_called = TRUE; + $view->build_info['pre_render_called'] = TRUE; } } /** * Implements hook_views_post_build(). */ -function views_test_data_views_post_build(View &$view) { +function views_test_data_views_post_build(ViewExecutable &$view) { if ($view->name == 'test_page_display') { if ($view->current_display == 'page_1') { $view->build_info['denied'] = TRUE; diff --git a/views.module b/views.module index bafbc71a6a41453ca9965ddfcf8797e01cb327f3..17549b665a4aac0d555685f5cd88f4387b22ff68 100644 --- a/views.module +++ b/views.module @@ -739,10 +739,6 @@ function views_block_info() { if ($hashes != $old_hashes) { variable_set('views_block_hashes', $hashes); } - // Save memory: Destroy those views. - foreach ($views as $view) { - $view->destroy(); - } views_cache_set('views_block_items', $items, TRUE); @@ -1546,12 +1542,13 @@ function views_get_applicable_views($type) { $views = views_get_all_views(); foreach ($views as $view) { + $view = new ViewExecutable($view); // Skip disabled views. - if (!empty($view->disabled)) { + if (!empty($view->storage->disabled)) { continue; } - if (empty($view->display)) { + if (empty($view->storage->display)) { // Skip this view as it is broken. continue; } @@ -1580,8 +1577,11 @@ function views_get_applicable_views($type) { /** * Return an array of all views as fully loaded $view objects. * + * @todo Figure out whether you expect to return config entities or + * view executables. * @param $reset * If TRUE, reset the static cache forcing views to be reloaded. + * */ function views_get_all_views($reset = FALSE) { return entity_get_controller('view')->load(); diff --git a/views_ui_listing/views_ui_listing.module b/views_ui_listing/views_ui_listing.module index b5b7bedc9af36a970ba28c40210b434da125dbbd..34a926f189eac7c3d9bda8d9655dc392cb094d9a 100644 --- a/views_ui_listing/views_ui_listing.module +++ b/views_ui_listing/views_ui_listing.module @@ -2,6 +2,7 @@ use Drupal\views_ui_listing\EntityListControllerInterface; use Drupal\config\ConfigEntityInterface; +use Drupal\views\ViewExecutable; /** * Implements hook_menu(). @@ -51,7 +52,7 @@ function views_ui_listing_entity_listing_page($entity_id) { * * @param Drupal\views_ui_listing\EntityListControllerInterface $controller * The list controller for this entity. - * @param Drupal\config\ConfigEntityInterface $entity + * @param Drupal\views\ViewExecutable $entity * The config entity being acted upon. * @param string $op * The action to perform, e.g., 'enable' or 'disable'. @@ -60,7 +61,7 @@ function views_ui_listing_entity_listing_page($entity_id) { * Either returns the listing page as JSON, or calls drupal_goto() to * redirect back to the listing page. */ -function views_ui_listing_ajax_callback(EntityListControllerInterface $controller, ConfigEntityInterface $entity, $op) { +function views_ui_listing_ajax_callback(EntityListControllerInterface $controller, ViewExecutable $entity, $op) { // Perform the operation. $entity->$op();