Commit f42515e2 authored by webchick's avatar webchick

Issue #1798574 by tim.plunkett: Refactor Views UI to be a form controller.

parent a213f310
......@@ -250,7 +250,7 @@ protected function build_filters(&$form, &$form_state) {
parent::build_filters($form, $form_state);
$entity_info = $this->entity_info;
$selected_bundle = views_ui_get_selected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
$selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
// Add the "tagged with" filter to the view.
......
......@@ -23,6 +23,11 @@
* module = "views",
* controller_class = "Drupal\views\ViewStorageController",
* list_controller_class = "Drupal\views_ui\ViewListController",
* form_controller_class = {
* "edit" = "Drupal\views_ui\ViewEditFormController",
* "add" = "Drupal\views_ui\ViewAddFormController",
* "preview" = "Drupal\views_ui\ViewPreviewFormController"
* },
* config_prefix = "views.view",
* fieldable = FALSE,
* entity_keys = {
......@@ -39,7 +44,7 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var string
*/
public $base_table = 'node';
protected $base_table = 'node';
/**
* The name of the view.
......@@ -53,7 +58,7 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var string
*/
public $description = '';
protected $description = '';
/**
* The "tags" of a view.
......@@ -63,7 +68,7 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var string
*/
public $tag = '';
protected $tag = '';
/**
* The human readable name of the view.
......@@ -77,14 +82,14 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var int
*/
public $core = DRUPAL_CORE_COMPATIBILITY;
protected $core = DRUPAL_CORE_COMPATIBILITY;
/**
* The views API version this view was created by.
*
* @var string
*/
public $api_version = VIEWS_API_VERSION;
protected $api_version = VIEWS_API_VERSION;
/**
* Stores all display handlers of this view.
......@@ -94,14 +99,14 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var array
*/
public $display;
protected $display;
/**
* The name of the base field to use.
*
* @var string
*/
public $base_field = 'nid';
protected $base_field = 'nid';
/**
* Returns whether the view's status is disabled or not.
......@@ -111,7 +116,7 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var bool
*/
public $disabled = FALSE;
protected $disabled = FALSE;
/**
* The UUID for this entity.
......@@ -132,58 +137,18 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
*
* @var string
*/
public $module = 'views';
protected $module = 'views';
/**
* 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;
}
/**
* Retrieves the executable version of this view.
*
* @param bool $reset
* Get a new Drupal\views\ViewExecutable instance.
* @param bool $ui
* If this should return Drupal\views_ui\ViewUI instead.
*
* @return Drupal\views\ViewExecutable
* The executable version of this view.
* Overrides Drupal\Core\Entity\EntityInterface::get().
*/
public function getExecutable($reset = FALSE, $ui = FALSE) {
if (!isset($this->executable) || $reset) {
// @todo Remove this approach and use proper dependency injection.
if ($ui) {
$executable = new ViewUI($this);
}
else {
$executable = new ViewExecutable($this);
}
$this->setExecutable($executable);
public function get($property_name, $langcode = NULL) {
// Ensure that an executable View is available.
if ($property_name == 'executable' && !isset($this->{$property_name})) {
$this->set('executable', new ViewExecutable($this));
}
return $this->executable;
}
/**
* Initializes the display.
*
* @todo Inspect calls to this and attempt to clean up.
* @see Drupal\views\ViewExecutable::initDisplay()
*/
public function initDisplay() {
$this->getExecutable()->initDisplay();
}
/**
* Returns the name of the module implementing this view.
*/
public function getModule() {
return $this->module;
return parent::get($property_name, $langcode);
}
/**
......@@ -199,7 +164,7 @@ public function uri() {
* Overrides Drupal\Core\Entity\EntityInterface::id().
*/
public function id() {
return $this->name;
return $this->get('name');
}
/**
......@@ -231,11 +196,8 @@ public function isEnabled() {
* 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;
if (!$human_name = $this->get('human_name')) {
$human_name = $this->get('name');
}
return $human_name;
}
......@@ -344,7 +306,7 @@ protected function generateDisplayId($plugin_id) {
*/
public function &newDisplay($plugin_id = 'page', $title = NULL, $id = NULL) {
$id = $this->addDisplay($plugin_id, $title, $id);
return $this->getExecutable()->newDisplay($id);
return $this->get('executable')->newDisplay($id);
}
/**
......
......@@ -2156,7 +2156,7 @@ public function submitOptionsForm(&$form, &$form_state) {
$access = array('type' => $form_state['values']['access']['type']);
$this->setOption('access', $access);
if ($plugin->usesOptions()) {
$this->view->addFormToStack('display', $this->display['id'], array('access_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('access_options'));
}
}
}
......@@ -2179,7 +2179,7 @@ public function submitOptionsForm(&$form, &$form_state) {
$cache = array('type' => $form_state['values']['cache']['type']);
$this->setOption('cache', $cache);
if ($plugin->usesOptions()) {
$this->view->addFormToStack('display', $this->display['id'], array('cache_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('cache_options'));
}
}
}
......@@ -2240,7 +2240,7 @@ public function submitOptionsForm(&$form, &$form_state) {
// send ajax form to options page if we use it.
if ($plugin->usesOptions()) {
$this->view->addFormToStack('display', $this->display['id'], array('row_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('row_options'));
}
}
}
......@@ -2256,7 +2256,7 @@ public function submitOptionsForm(&$form, &$form_state) {
$this->setOption($section, $row);
// send ajax form to options page if we use it.
if ($plugin->usesOptions()) {
$this->view->addFormToStack('display', $this->display['id'], array('style_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('style_options'));
}
}
}
......@@ -2290,7 +2290,7 @@ public function submitOptionsForm(&$form, &$form_state) {
$exposed_form = array('type' => $form_state['values']['exposed_form']['type'], 'options' => array());
$this->setOption('exposed_form', $exposed_form);
if ($plugin->usesOptions()) {
$this->view->addFormToStack('display', $this->display['id'], array('exposed_form_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('exposed_form_options'));
}
}
}
......@@ -2317,7 +2317,7 @@ public function submitOptionsForm(&$form, &$form_state) {
$pager = array('type' => $form_state['values']['pager']['type'], 'options' => $plugin->options);
$this->setOption('pager', $pager);
if ($plugin->usesOptions()) {
$this->view->addFormToStack('display', $this->display['id'], array('pager_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('pager_options'));
}
}
}
......
......@@ -400,7 +400,7 @@ public function submitOptionsForm(&$form, &$form_state) {
$this->setOption('menu', $form_state['values']['menu']);
// send ajax form to options page if we use it.
if ($form_state['values']['menu']['type'] == 'default tab') {
$this->view->addFormToStack('display', $this->display['id'], array('tab_options'));
$form_state['view']->addFormToStack('display', $this->display['id'], array('tab_options'));
}
break;
case 'tab_options':
......
......@@ -164,7 +164,7 @@ public function buildOptionsForm(&$form, &$form_state) {
function get_temporary_view() {
$view = entity_create('view', array('base_table' => $this->definition['base']));
$view->addDisplay('default');
return $view->getExecutable();
return $view->get('executable');
}
/**
......
......@@ -74,11 +74,11 @@ protected function defineOptions() {
public function buildOptionsForm(&$form, &$form_state) {
parent::buildOptionsForm($form, $form_state);
if (isset($this->base_table)) {
$view = &$form_state['view'];
$executable = $form_state['view']->get('executable');
// A whole bunch of code to figure out what relationships are valid for
// this item.
$relationships = $view->display_handler->getOption('relationships');
$relationships = $executable->display_handler->getOption('relationships');
$relationship_options = array();
foreach ($relationships as $relationship) {
......@@ -88,7 +88,7 @@ public function buildOptionsForm(&$form, &$form_state) {
$data = views_fetch_data($relationship['table']);
$base = $data[$relationship['field']]['relationship']['base'];
if ($base == $this->base_table) {
$relationship_handler->init($view, $relationship);
$relationship_handler->init($executable, $relationship);
$relationship_options[$relationship['id']] = $relationship_handler->label();
}
}
......
......@@ -257,7 +257,7 @@ function build_form(array $form, array &$form_state) {
'#options' => $style_options,
);
$style_form = &$form['displays']['page']['options']['style'];
$style_form['style_plugin']['#default_value'] = views_ui_get_selected($form_state, array('page', 'style', 'style_plugin'), 'default', $style_form['style_plugin']);
$style_form['style_plugin']['#default_value'] = static::getSelected($form_state, array('page', 'style', 'style_plugin'), 'default', $style_form['style_plugin']);
// Changing this dropdown updates $form['displays']['page']['options'] via
// AJAX.
views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'page', 'options'));
......@@ -394,7 +394,7 @@ function build_form(array $form, array &$form_state) {
'#options' => $style_options,
);
$style_form = &$form['displays']['block']['options']['style'];
$style_form['style_plugin']['#default_value'] = views_ui_get_selected($form_state, array('block', 'style', 'style_plugin'), 'default', $style_form['style_plugin']);
$style_form['style_plugin']['#default_value'] = static::getSelected($form_state, array('block', 'style', 'style_plugin'), 'default', $style_form['style_plugin']);
// Changing this dropdown updates $form['displays']['block']['options'] via
// AJAX.
views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'block', 'options'));
......@@ -415,6 +415,85 @@ function build_form(array $form, array &$form_state) {
return $form;
}
/**
* Gets the current value of a #select element, from within a form constructor function.
*
* This function is intended for use in highly dynamic forms (in particular the
* add view wizard) which are rebuilt in different ways depending on which
* triggering element (AJAX or otherwise) was most recently fired. For example,
* sometimes it is necessary to decide how to build one dynamic form element
* based on the value of a different dynamic form element that may not have
* even been present on the form the last time it was submitted. This function
* takes care of resolving those conflicts and gives you the proper current
* value of the requested #select element.
*
* By necessity, this function sometimes uses non-validated user input from
* $form_state['input'] in making its determination. Although it performs some
* minor validation of its own, it is not complete. The intention is that the
* return value of this function should only be used to help decide how to
* build the current form the next time it is reloaded, not to be saved as if
* it had gone through the normal, final form validation process. Do NOT use
* the results of this function for any other purpose besides deciding how to
* build the next version of the form.
*
* @param $form_state
* The standard associative array containing the current state of the form.
* @param $parents
* An array of parent keys that point to the part of the submitted form
* values that are expected to contain the element's value (in the case where
* this form element was actually submitted). In a simple case (assuming
* #tree is TRUE throughout the form), if the select element is located in
* $form['wrapper']['select'], so that the submitted form values would
* normally be found in $form_state['values']['wrapper']['select'], you would
* pass array('wrapper', 'select') for this parameter.
* @param $default_value
* The default value to return if the #select element does not currently have
* a proper value set based on the submitted input.
* @param $element
* An array representing the current version of the #select element within
* the form.
*
* @return
* The current value of the #select element. A common use for this is to feed
* it back into $element['#default_value'] so that the form will be rendered
* with the correct value selected.
*/
public static function getSelected($form_state, $parents, $default_value, $element) {
// For now, don't trust this to work on anything but a #select element.
if (!isset($element['#type']) || $element['#type'] != 'select' || !isset($element['#options'])) {
return $default_value;
}
// If there is a user-submitted value for this element that matches one of
// the currently available options attached to it, use that. We need to check
// $form_state['input'] rather than $form_state['values'] here because the
// triggering element often has the #limit_validation_errors property set to
// prevent unwanted errors elsewhere on the form. This means that the
// $form_state['values'] array won't be complete. We could make it complete
// by adding each required part of the form to the #limit_validation_errors
// property individually as the form is being built, but this is difficult to
// do for a highly dynamic and extensible form. This method is much simpler.
if (!empty($form_state['input'])) {
$key_exists = NULL;
$submitted = drupal_array_get_nested_value($form_state['input'], $parents, $key_exists);
// Check that the user-submitted value is one of the allowed options before
// returning it. This is not a substitute for actual form validation;
// rather it is necessary because, for example, the same select element
// might have #options A, B, and C under one set of conditions but #options
// D, E, F under a different set of conditions. So the form submission
// might have occurred with option A selected, but when the form is rebuilt
// option A is no longer one of the choices. In that case, we don't want to
// use the value that was submitted anymore but rather fall back to the
// default value.
if ($key_exists && in_array($submitted, array_keys($element['#options']))) {
return $submitted;
}
}
// Fall back on returning the default value if nothing was returned above.
return $default_value;
}
/**
* Adds the style options to the wizard form.
*
......@@ -443,7 +522,7 @@ protected function build_form_style(array &$form, array &$form_state, $type) {
// if it's available (since that's the most common use case).
$block_with_linked_titles_available = ($type == 'block' && isset($options['titles_linked']));
$default_value = $block_with_linked_titles_available ? 'titles_linked' : key($options);
$style_form['row_plugin']['#default_value'] = views_ui_get_selected($form_state, array($type, 'style', 'row_plugin'), $default_value, $style_form['row_plugin']);
$style_form['row_plugin']['#default_value'] = static::getSelected($form_state, array($type, 'style', 'row_plugin'), $default_value, $style_form['row_plugin']);
// Changing this dropdown updates the individual row options via AJAX.
views_ui_add_ajax_trigger($style_form, 'row_plugin', array('displays', $type, 'options', 'style', 'row_options'));
......@@ -493,7 +572,7 @@ protected function build_filters(&$form, &$form_state) {
'#title' => t('of type'),
'#options' => $options,
);
$selected_bundle = views_ui_get_selected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
$selected_bundle = static::getSelected($form_state, array('show', 'type'), 'all', $form['displays']['show']['type']);
$form['displays']['show']['type']['#default_value'] = $selected_bundle;
// Changing this dropdown updates the entire content of $form['displays']
// via AJAX, since each bundle might have entirely different fields
......@@ -1066,7 +1145,7 @@ protected function set_validated_view(array $form, array &$form_state, ViewUI $v
*/
public function validateView(array $form, array &$form_state) {
$view = $this->instantiate_view($form, $form_state);
$errors = $view->validate();
$errors = $view->get('executable')->validate();
if (!is_array($errors) || empty($errors)) {
$this->set_validated_view($form, $form_state, $view);
return array();
......
......@@ -59,7 +59,7 @@ public function testHandlers() {
}
$view = views_new_view();
$view->base_table = $base_table;
$view->set('base_table', $base_table);
$view = new ViewExecutable($view);
// @todo The groupwise relationship is currently broken.
......
......@@ -163,12 +163,12 @@ public function testLoadFunctions() {
// Test $exclude_view parameter.
$this->assertFalse(array_key_exists('archive', views_get_views_as_options(TRUE, 'all', 'archive')), 'View excluded from options based on name');
$this->assertFalse(array_key_exists('archive:default', views_get_views_as_options(FALSE, 'all', 'archive:default')), 'View display excluded from options based on name');
$this->assertFalse(array_key_exists('archive', views_get_views_as_options(TRUE, 'all', $archive->getExecutable())), 'View excluded from options based on object');
$this->assertFalse(array_key_exists('archive', views_get_views_as_options(TRUE, 'all', $archive->get('executable'))), 'View excluded from options based on object');
// Test the $opt_group parameter.
$expected_opt_groups = array();
foreach ($all_views as $id => $view) {
foreach ($view->display as $display_id => $display) {
foreach ($view->get('display') as $display_id => $display) {
$expected_opt_groups[$view->id()][$view->id() . ':' . $display['id']] = t('@view : @display', array('@view' => $view->id(), '@display' => $display['id']));
}
}
......@@ -205,7 +205,7 @@ function testStatusFunctions() {
protected function formatViewOptions(array $views = array()) {
$expected_options = array();
foreach ($views as $id => $view) {
foreach ($view->display as $display_id => $display) {
foreach ($view->get('display') as $display_id => $display) {
$expected_options[$view->id() . ':' . $display['id']] = t('View: @view - Display: @display',
array('@view' => $view->name, '@display' => $display['id']));
}
......
......@@ -55,7 +55,7 @@ public function testRemoveDisplay() {
// Delete the page, so we can test the undo process.
$this->drupalPost($path_prefix . '/page_1', array(), 'delete Page');
$this->assertFieldById('edit-displays-settings-settings-content-tab-content-details-top-actions-undo-delete', 'undo delete of Page', 'Make sure there a undo button on the page display after deleting.');
$this->assertTrue($this->xpath('//div[contains(@class, views-display-deleted-link)]'). 'Make sure the display link is marked as to be deleted.');
$this->assertTrue($this->xpath('//a[contains(@class, :class)]', array(':class' => 'views-display-deleted-link')), 'Make sure the display link is marked as to be deleted.');
// Undo the deleting of the display.
$this->drupalPost($path_prefix . '/page_1', array(), 'undo delete of Page');
......@@ -66,7 +66,7 @@ public function testRemoveDisplay() {
$this->drupalPost($path_prefix . '/page_1', array(), 'delete Page');
$this->drupalPost(NULL, array(), t('Save'));
$this->assertNoLinkByHref($path_prefix . '/page', 'Make sure there is no display tab for the deleted display.');
$this->assertNoLinkByHref($path_prefix . '/page_1', 'Make sure there is no display tab for the deleted display.');
}
/**
......
......@@ -40,7 +40,7 @@ public function testDetails() {
$view = views_get_view($view->storage->get('name'));
foreach (array('human_name', 'tag', 'description') as $property) {
$this->assertEqual($view->storage->{$property}, $edit[$property], format_string('Make sure the property @property got probably saved.', array('@property' => $property)));
$this->assertEqual($view->storage->get($property), $edit[$property], format_string('Make sure the property @property got probably saved.', array('@property' => $property)));
}
}
......
......@@ -16,7 +16,7 @@
/**
* Tests the functionality of View and ViewStorageController.
*
* @see Drupal\views\ViewStorage
* @see Drupal\views\Plugin\Core\Entity\View
* @see Drupal\views\ViewStorageController
*/
class ViewStorageTest extends ViewTestBase {
......@@ -103,16 +103,16 @@ protected function loadTests() {
// expected properties.
$this->assertTrue($view instanceof View, '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)));
$this->assertTrue($view->get($property), format_string('Property: @property loaded onto View.', array('@property' => $property)));
}
// Check the displays have been loaded correctly from config display data.
$expected_displays = array('default', 'page_1', 'block_1');
$this->assertEqual(array_keys($view->display), $expected_displays, 'The correct display names are present.');
$this->assertEqual(array_keys($view->get('display')), $expected_displays, 'The correct display names are present.');
// Check each ViewDisplay object and confirm that it has the correct key and
// property values.
foreach ($view->display as $key => $display) {
foreach ($view->get('display') as $key => $display) {
$this->assertEqual($key, $display['id'], 'The display has the correct ID assigned.');
// Get original display data and confirm that the display options array
......@@ -171,8 +171,8 @@ protected function createTests() {
// Test all properties except displays.
foreach ($properties as $property) {
$this->assertTrue(isset($created->{$property}), format_string('Property: @property created on View.', array('@property' => $property)));
$this->assertIdentical($values[$property], $created->{$property}, format_string('Property value: @property matches configuration value.', array('@property' => $property)));
$this->assertTrue($created->get($property), format_string('Property: @property created on View.', array('@property' => $property)));
$this->assertIdentical($values[$property], $created->get($property), format_string('Property value: @property matches configuration value.', array('@property' => $property)));
}
// Check the UUID of the loaded View.
......@@ -191,11 +191,11 @@ protected function displayTests() {
$view->newDisplay('page', 'Test', 'test');
$new_display = $view->display['test'];
$new_display = $view->get('display');
// Ensure the right display_plugin is created/instantiated.
$this->assertEqual($new_display['display_plugin'], 'page', 'New page display "test" uses the right display plugin.');
$this->assertTrue($view->getExecutable()->displayHandlers[$new_display['id']] instanceof Page, 'New page display "test" uses the right display plugin.');
$this->assertEqual($new_display['test']['display_plugin'], 'page', 'New page display "test" uses the right display plugin.');
$this->assertTrue($view->get('executable')->displayHandlers[$new_display['test']['id']] instanceof Page, 'New page display "test" uses the right display plugin.');
$view->set('name', 'frontpage_new');
......@@ -290,15 +290,18 @@ protected function displayMethodTests() {
$id = $view->addDisplay('page', $random_title);
$this->assertEqual($id, 'page_1', format_string('Make sure the first display (%id_new) has the expected ID (%id)', array('%id_new' => $id, '%id' => 'page_1')));
$this->assertEqual($view->display[$id]['display_title'], $random_title);
$display = $view->get('display');
$this->assertEqual($display[$id]['display_title'], $random_title);
$random_title = $this->randomName();
$id = $view->addDisplay('page', $random_title);
$display = $view->get('display');
$this->assertEqual($id, 'page_2', format_string('Make sure the second display (%id_new) has the expected ID (%id)', array('%id_new' => $id, '%id' => 'page_2')));
$this->assertEqual($view->display[$id]['display_title'], $random_title);
$this->assertEqual($display[$id]['display_title'], $random_title);
$id = $view->addDisplay('page');
$this->assertEqual($view->display[$id]['display_title'], 'Page 3');
$display = $view->get('display');
$this->assertEqual($display[$id]['display_title'], 'Page 3');
// Tests Drupal\views\Plugin\Core\Entity\View::generateDisplayId().
// @todo Sadly this method is not public so it cannot be tested.
......@@ -314,23 +317,23 @@ protected function displayMethodTests() {
$display = $view->newDisplay('page');
$this->assertTrue($display instanceof Page);
$this->assertTrue($view->getExecutable()->displayHandlers['page_1'] instanceof Page);
$this->assertTrue($view->getExecutable()->displayHandlers['page_1']->default_display instanceof DefaultDisplay);
$this->assertTrue($view->get('executable')->displayHandlers['page_1'] instanceof Page);
$this->assertTrue($view->get('executable')->displayHandlers['page_1']->default_display instanceof DefaultDisplay);
$display = $view->newDisplay('page');
$this->assertTrue($display instanceof Page);
$this->assertTrue($view->getExecutable()->displayHandlers['page_2'] instanceof Page);
$this->assertTrue($view->getExecutable()->displayHandlers['page_2']->default_display instanceof DefaultDisplay);
$this->assertTrue($view->get('executable')->displayHandlers['page_2'] instanceof Page);
$this->assertTrue($view->get('executable')->displayHandlers['page_2']->default_display instanceof DefaultDisplay);
$display = $view->newDisplay('feed');
$this->assertTrue($display instanceof Feed);
$this->assertTrue($view->getExecutable()->displayHandlers['feed_1'] instanceof Feed);
$this->assertTrue($view->getExecutable()->displayHandlers['feed_1']->default_display instanceof DefaultDisplay);
$this->assertTrue($view->get('executable')->displayHandlers['feed_1'] instanceof Feed);
$this->assertTrue($view->get('executable')->displayHandlers['feed_1']->default_display instanceof DefaultDisplay);
// Tests item related methods().
$view = $this->controller->create(array('base_table' => 'views_test_data'));
$view->addDisplay('default');
$view = $view->getExecutable();
$view = $view->get('executable');
$display_id = 'default';
$expected_items = array();
......@@ -405,13 +408,14 @@ public function testCreateDuplicate() {
);
foreach ($config_properties as $property) {
$this->assertIdentical($view->storage->{$property}, $copy->{$property}, format_string('@property property is identical.', array('@property' => $property)));
$this->assertIdentical($view->storage->get($property), $copy->get($property), format_string('@property property is identical.', array('@property' => $property)));
}
// Check the displays are the same.
$copy_display = $copy->get('display');
foreach ($view->storage->get('display') as $id => $display) {
// assertIdentical will not work here.
$this->assertEqual($display, $copy->display[$id], format_string('The @display display has been copied correctly.', array('@display' => $id)));
$this->assertEqual($display, $copy_display[$id], format_string('The @display display has been copied correctly.', array('@display' => $id)));
}
}
......
......@@ -409,7 +409,7 @@ protected function createViewFromConfig($view_name) {
$data = config("views.view.$view_name")->get();
$view = entity_create('view', $data);
$view = $view->getExecutable();
$view = $view->get('executable');
$view->setDisplay();
return $view;
......
......@@ -406,7 +406,7 @@ class ViewExecutable {
public function __construct(View $storage) {
// Reference the storage and the executable to each other.
$this->storage = $storage;
$this->storage->setExecutable($this);
$this->storage->set('executable', $this);
}
/**
......@@ -1821,7 +1821,9 @@ public function createDuplicate() {
*/
public function cloneView() {
$storage = clone $this->storage;
return $storage->getExecutable(TRUE);
$executable = new ViewExecutable($storage);
$storage->set('executable', $executable);
return $executable;
}
/**
......
......@@ -31,7 +31,7 @@ public function load(array $ids = NULL) {
// Only return views for enabled modules.
return array_filter($entities, function ($entity) {
if (module_exists($entity->getModule())) {
if (module_exists($entity->get('module'))) {
return TRUE;
}
return FALSE;
......@@ -78,6 +78,8 @@ public function create(array $values) {
'display_plugin' => 'default',
'id' => 'default',
'display_title' => 'Master',
'position' => 0,
'display_options' => array(),
),
)
);
......@@ -113,4 +115,29 @@ protected function attachDisplays(EntityInterface $entity) {
}
}
/**
* Overrides Drupal\config\ConfigStorageController::getProperties();
*/
protected function getProperties(EntityInterface $entity) {
$names = array(
'api_version',
'base_field',
'base_table',
'core',
'description',
'disabled',
'display',
'human_name',
'module',
'name',
'tag',
'uuid',
);
$properties = array();
foreach ($names as $name) {
$properties[$name] = $entity->get($name);
}
return $properties;
}