Commit 2d503f7c authored by plach's avatar plach

Issue #2942986 by alexpott, Lendude, chr.fritsch, larowlan, dawehner, catch:...

Issue #2942986 by alexpott, Lendude, chr.fritsch, larowlan, dawehner, catch: Views should be dependent on providers of table data via hook_views_data
parent 258f5444
......@@ -39,7 +39,7 @@ public function testAccessRole() {
$this->container->get('router.builder')->rebuildIfNeeded();
$expected = [
'config' => ['user.role.' . $this->normalRole],
'module' => ['user'],
'module' => ['user', 'views_test_data'],
];
$this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
......@@ -79,7 +79,7 @@ public function testAccessRole() {
sort($roles);
$expected = [
'config' => $roles,
'module' => ['user'],
'module' => ['user', 'views_test_data'],
];
$this->assertIdentical($expected, $view->calculateDependencies()->getDependencies());
$this->drupalLogin($this->webUser);
......
......@@ -845,4 +845,19 @@ public function submitFormCalculateOptions(array $options, array $form_state_opt
return $form_state_options + $options;
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$dependencies = parent::calculateDependencies();
if ($this->table) {
// Ensure that the view depends on the module that provides the table.
$data = $this->getViewsData()->get($this->table);
if (isset($data['table']['provider'])) {
$dependencies['module'][] = $data['table']['provider'];
}
}
return $dependencies;
}
}
......@@ -169,11 +169,11 @@ public function query() {
* {@inheritdoc}
*/
public function calculateDependencies() {
$dependencies = parent::calculateDependencies();
// Add the provider of the relationship's base table to the dependencies.
$table_data = $this->getViewsData()->get($this->definition['base']);
return [
'module' => [$table_data['table']['provider']],
];
$dependencies['module'][] = $table_data['table']['provider'];
return $dependencies;
}
}
......
<?php
/**
* @file
* Contains database additions to drupal-8.bare.standard.php.gz for testing
* views_post_update_views_data_table_dependencies().
*/
use Drupal\Core\Database\Database;
use Drupal\Core\Serialization\Yaml;
use Drupal\views\Tests\ViewTestData;
$connection = Database::getConnection();
// Install the views_test_data module.
$extensions = $connection->select('config')
->fields('config', ['data'])
->condition('collection', '')
->condition('name', 'core.extension')
->execute()
->fetchField();
$extensions = unserialize($extensions);
$extensions['module']['views_test_data'] = 8000;
$connection->update('config')
->fields([
'data' => serialize($extensions),
])
->condition('collection', '')
->condition('name', 'core.extension')
->execute();
$views_configs = [];
// A view that should depend on views_data_test.
$views_configs[] = Yaml::decode(file_get_contents(__DIR__ . '/views.view.test_table_dependency_update.yml'));
foreach ($views_configs as $views_config) {
$connection->insert('config')
->fields([
'collection',
'name',
'data',
])
->values([
'collection' => '',
'name' => 'views.view.' . $views_config['id'],
'data' => serialize($views_config),
])
->execute();
}
// We need the views_test_data table to exist and state entries for
// views_test_data_schema() and views_test_data_views_data().
$schema = ViewTestData::schemaDefinition();
$connection->schema()->createTable('views_test_data', $schema['views_test_data']);
$connection->insert('key_value')
->fields([
'collection',
'name',
'value',
])
->values([
'collection' => 'state',
'name' => 'views_test_data_schema',
'value' => serialize($schema),
])
->values([
'collection' => 'state',
'name' => 'views_test_data_views_data',
'value' => serialize(ViewTestData::viewsData()),
])
->execute();
langcode: en
status: true
dependencies: { }
id: test_table_dependency_update
label: ''
module: views
description: ''
tag: ''
base_table: views_test_data
base_field: nid
core: '8'
display:
default:
display_options:
defaults:
fields: false
pager: false
sorts: false
fields:
id:
field: id
id: id
relationship: none
table: views_test_data
plugin_id: numeric
pager:
options:
offset: 0
type: none
sorts:
id:
field: id
id: id
order: ASC
relationship: none
table: views_test_data
plugin_id: numeric
empty:
title:
field: title
id: title
table: views
plugin_id: title
title: test_title_empty
header:
result:
id: result
table: views
field: result
relationship: none
group_type: group
admin_label: ''
empty: true
content: "start: @start | end: @end | total: @total | label: @label | per page: @per_page | current page: @current_page | current record count: @current_record_count | page count: @page_count"
plugin_id: result
display_plugin: default
display_title: Master
id: default
position: 0
page_1:
display_options:
path: test-area-result
defaults:
header: false
header:
result:
id: result
table: views
field: result
relationship: none
group_type: group
admin_label: ''
empty: false
content: "start: @start | end: @end | total: @total | label: @label | per page: @per_page | current page: @current_page | current record count: @current_record_count | page count: @page_count"
plugin_id: result
display_plugin: page
display_title: 'Page 1'
id: page_1
position: 1
<?php
namespace Drupal\Tests\views\Functional\Update;
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
use Drupal\views\Views;
/**
* Tests the upgrade path for views data table provider dependencies.
*
* @see views_post_update_views_data_table_dependencies()
*
* @group Update
*/
class ViewsDataTableDependencyUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz',
// This creates a view called test_table_dependency_update which has no
// dependencies.
__DIR__ . '/../../../fixtures/update/views-data-table-dependency.php',
];
}
/**
* Tests that dependencies are correct after update.
*/
public function testPostUpdate() {
$this->runUpdates();
// Load and initialize our test view.
$view = Views::getView('test_table_dependency_update');
$this->assertEquals(['module' => ['views_test_data']], $view->getDependencies());
}
}
......@@ -162,6 +162,7 @@ public function testGetDependencies() {
],
'module' => [
'core',
'node',
'text',
'views'
],
......
......@@ -194,6 +194,7 @@ public function doTestCalculateDependencies() {
$this->assertEqual([
'config' => ['block.block.test_block'],
'content' => ['entity_test:entity_test:aa0c61cb-b7bb-4795-972a-493dabcf529c'],
'module' => ['views_test_data'],
], $dependencies);
}
......
......@@ -36,7 +36,7 @@ public function testViewArea() {
$view = Views::getView('test_area_view');
// Tests \Drupal\views\Plugin\views\area\View::calculateDependencies().
$this->assertIdentical(['config' => ['views.view.test_simple_argument']], $view->getDependencies());
$this->assertIdentical(['config' => ['views.view.test_simple_argument'], 'module' => ['views_test_data']], $view->getDependencies());
$this->executeView($view);
$output = $view->render();
......
......@@ -131,7 +131,7 @@ public function testMenuLinks() {
*/
public function testDependencies() {
$view = Views::getView('test_page_display');
$this->assertIdentical([], $view->getDependencies());
$this->assertIdentical(['module' => ['views_test_data']], $view->getDependencies());
$view = Views::getView('test_page_display_route');
$expected = [
......@@ -146,6 +146,9 @@ public function testDependencies() {
'system.menu.admin',
'system.menu.tools',
],
'module' => [
'views_test_data',
],
];
$this->assertIdentical($expected, $view->getDependencies());
}
......
......@@ -322,6 +322,32 @@ function views_post_update_filter_placeholder_text() {
}
}
/**
* Include views data table provider in views dependencies.
*/
function views_post_update_views_data_table_dependencies(&$sandbox = NULL) {
$storage = \Drupal::entityTypeManager()->getStorage('view');
if (!isset($sandbox['views'])) {
$sandbox['views'] = $storage->getQuery()->accessCheck(FALSE)->execute();
$sandbox['count'] = count($sandbox['views']);
}
// Process 10 views at a time.
$views = $storage->loadMultiple(array_splice($sandbox['views'], 0, 10));
foreach ($views as $view) {
$original_dependencies = $view->getDependencies();
// Only re-save if dependencies have changed.
if ($view->calculateDependencies()->getDependencies() !== $original_dependencies) {
// We can trust the data because we've already recalculated the
// dependencies.
$view->trustData();
$view->save();
}
}
$sandbox['#finished'] = empty($sandbox['views']) ? 1 : ($sandbox['count'] - count($sandbox['views'])) / $sandbox['count'];
}
/**
* Fix cache max age for table displays.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment