Issue #3065212 by amateescu, pmelab, leolando.tan: Workspaces views query alter multiplies result set by number of languages

merge-requests/1119/head
catch 2019-07-11 18:49:22 +01:00
parent 3c7bc9f908
commit 88fede1bcf
2 changed files with 39 additions and 7 deletions

View File

@ -6,6 +6,7 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\Plugin\views\query\Sql;
use Drupal\views\Plugin\ViewsHandlerManager;
@ -55,6 +56,13 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
*/
protected $viewsJoinPluginManager;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* Constructs a new ViewsQueryAlter instance.
*
@ -68,13 +76,16 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
* The views data.
* @param \Drupal\views\Plugin\ViewsHandlerManager $views_join_plugin_manager
* The views join plugin manager.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, WorkspaceManagerInterface $workspace_manager, ViewsData $views_data, ViewsHandlerManager $views_join_plugin_manager) {
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, WorkspaceManagerInterface $workspace_manager, ViewsData $views_data, ViewsHandlerManager $views_join_plugin_manager, LanguageManagerInterface $language_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
$this->workspaceManager = $workspace_manager;
$this->viewsData = $views_data;
$this->viewsJoinPluginManager = $views_join_plugin_manager;
$this->languageManager = $language_manager;
}
/**
@ -86,7 +97,8 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
$container->get('entity_field.manager'),
$container->get('workspaces.manager'),
$container->get('views.views_data'),
$container->get('plugin.manager.views.join')
$container->get('plugin.manager.views.join'),
$container->get('language_manager')
);
}
@ -335,7 +347,7 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
// to modify the join and make sure that 'workspace_association' comes
// first.
if (empty($table_queue[$alias]['join']->workspace_adjusted)) {
$table_queue[$alias]['join'] = $this->getRevisionTableJoin($relationship, $base_revision_table, $revision_field, $workspace_association_table);
$table_queue[$alias]['join'] = $this->getRevisionTableJoin($relationship, $base_revision_table, $revision_field, $workspace_association_table, $entity_type);
// We also have to ensure that our 'workspace_association' comes before
// this.
$this->moveEntityTable($query, $workspace_association_table, $alias);
@ -346,7 +358,7 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
}
// Construct a new join.
$join = $this->getRevisionTableJoin($relationship, $base_revision_table, $revision_field, $workspace_association_table);
$join = $this->getRevisionTableJoin($relationship, $base_revision_table, $revision_field, $workspace_association_table, $entity_type);
return $query->queueTable($base_revision_table, $relationship, $join);
}
@ -362,19 +374,27 @@ class ViewsQueryAlter implements ContainerInjectionInterface {
* @param string $workspace_association_table
* The alias of the 'workspace_association' table joined to the main entity
* table.
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type that is being queried.
*
* @return \Drupal\views\Plugin\views\join\JoinPluginInterface
* An adjusted views join object to add to the query.
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
protected function getRevisionTableJoin($relationship, $table, $field, $workspace_association_table) {
protected function getRevisionTableJoin($relationship, $table, $field, $workspace_association_table, EntityTypeInterface $entity_type) {
$definition = [
'table' => $table,
'field' => $field,
// Making this explicitly null allows the left table to be a formula.
// Making this explicitly NULL allows the left table to be a formula.
'left_table' => NULL,
'left_field' => "COALESCE($workspace_association_table.target_entity_revision_id, $relationship.$field)",
];
if ($entity_type->isTranslatable() && $this->languageManager->isMultilingual()) {
$langcode_field = $entity_type->getKey('langcode');
$definition['extra'] = "$table.$langcode_field = $relationship.$langcode_field";
}
/** @var \Drupal\views\Plugin\views\join\JoinPluginInterface $join */
$join = $this->viewsJoinPluginManager->createInstance('standard', $definition);
$join->adjusted = TRUE;

View File

@ -6,6 +6,7 @@ use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Form\FormState;
use Drupal\entity_test\Entity\EntityTestMulRevPub;
use Drupal\KernelTests\KernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\system\Form\SiteInformationForm;
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
@ -62,6 +63,8 @@ class WorkspaceIntegrationTest extends KernelTestBase {
'user',
'system',
'views',
'language',
'content_translation',
];
/**
@ -78,20 +81,29 @@ class WorkspaceIntegrationTest extends KernelTestBase {
$this->installEntitySchema('node');
$this->installEntitySchema('user');
$this->installConfig(['filter', 'node', 'system']);
$this->installConfig(['filter', 'node', 'system', 'language', 'content_translation']);
$this->installSchema('system', ['key_value_expire', 'sequences']);
$this->installSchema('node', ['node_access']);
$language = ConfigurableLanguage::createFromLangcode('de');
$language->save();
$this->createContentType(['type' => 'page']);
$this->setCurrentUser($this->createUser(['administer nodes']));
$this->container->get('content_translation.manager')->setEnabled('node', 'page', TRUE);
// Create two nodes, a published and an unpublished one, so we can test the
// behavior of the module with default/existing content.
$this->createdTimestamp = \Drupal::time()->getRequestTime();
$this->nodes[] = $this->createNode(['title' => 'live - 1 - r1 - published', 'created' => $this->createdTimestamp++, 'status' => TRUE]);
$this->nodes[] = $this->createNode(['title' => 'live - 2 - r2 - unpublished', 'created' => $this->createdTimestamp++, 'status' => FALSE]);
$translation = $this->nodes[0]->addTranslation('de');
$translation->setTitle('live - 1 - r1 - published - de');
$translation->save();
}
/**