Issue #3101738 by Lendude, jannakha, alexpott, daffie, catch, bkosborne, Berdir: Exposed term filters should not show term options that the user does not have access to

(cherry picked from commit 6c878ed56a)
merge-requests/64/head
catch 2020-09-01 09:30:32 +01:00
parent e934b62e5c
commit fc6ae2af06
2 changed files with 61 additions and 2 deletions

View File

@ -4,6 +4,7 @@ namespace Drupal\taxonomy\Plugin\views\filter;
use Drupal\Core\Entity\Element\EntityAutocomplete;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\TermStorageInterface;
use Drupal\taxonomy\VocabularyStorageInterface;
@ -38,6 +39,13 @@ class TaxonomyIndexTid extends ManyToOne {
*/
protected $termStorage;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* Constructs a TaxonomyIndexTid object.
*
@ -51,11 +59,18 @@ class TaxonomyIndexTid extends ManyToOne {
* The vocabulary storage.
* @param \Drupal\taxonomy\TermStorageInterface $term_storage
* The term storage.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, VocabularyStorageInterface $vocabulary_storage, TermStorageInterface $term_storage) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, VocabularyStorageInterface $vocabulary_storage, TermStorageInterface $term_storage, AccountInterface $current_user = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->vocabularyStorage = $vocabulary_storage;
$this->termStorage = $term_storage;
if (!$current_user) {
@trigger_error('The current_user service must be passed to ' . __NAMESPACE__ . '\TaxonomyIndexTid::__construct(). It was added in drupal:8.9.0 and will be required before drupal:10.0.0.', E_USER_DEPRECATED);
$current_user = \Drupal::service('current_user');
}
$this->currentUser = $current_user;
}
/**
@ -67,7 +82,8 @@ class TaxonomyIndexTid extends ManyToOne {
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager')->getStorage('taxonomy_vocabulary'),
$container->get('entity_type.manager')->getStorage('taxonomy_term')
$container->get('entity_type.manager')->getStorage('taxonomy_term'),
$container->get('current_user')
);
}
@ -181,6 +197,9 @@ class TaxonomyIndexTid extends ManyToOne {
if ($tree) {
foreach ($tree as $term) {
if (!$term->isPublished() && !$this->currentUser->hasPermission('administer taxonomy')) {
continue;
}
$choice = new \stdClass();
$choice->option = [$term->id() => str_repeat('-', $term->depth) . \Drupal::service('entity.repository')->getTranslationFromContext($term)->label()];
$options[] = $choice;
@ -195,6 +214,9 @@ class TaxonomyIndexTid extends ManyToOne {
->sort('weight')
->sort('name')
->addTag('taxonomy_term_access');
if (!$this->currentUser->hasPermission('administer taxonomy')) {
$query->condition('status', 1);
}
if ($this->options['limit']) {
$query->condition('vid', $vocabulary->id());
}

View File

@ -231,4 +231,41 @@ class TaxonomyIndexTidUiTest extends UITestBase {
$this->assertTrue(empty($preview), 'No results.');
}
/**
* Tests that an exposed taxonomy filter doesn't show unpublished terms.
*/
public function testExposedUnpublishedFilterOptions() {
$this->terms[1][0]->setUnpublished()->save();
// Expose the filter.
$this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid', [], 'Expose filter');
$edit = ['options[expose_button][checkbox][checkbox]' => TRUE];
$this->drupalPostForm(NULL, $edit, 'Apply');
$this->drupalPostForm(NULL, [], 'Save');
// Make sure the unpublished term is shown to the admin user.
$this->drupalGet('test-filter-taxonomy-index-tid');
$this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
$this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
$this->drupalLogout();
$this->drupalGet('test-filter-taxonomy-index-tid');
// Make sure the unpublished term isn't shown to the anonymous user.
$this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
$this->assertEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
// Tests that the term also isn't shown when not showing hierarchy.
$this->drupalLogin($this->adminUser);
$edit = [
'options[hierarchy]' => FALSE,
];
$this->drupalPostForm('admin/structure/views/nojs/handler-extra/test_filter_taxonomy_index_tid/default/filter/tid', $edit, 'Apply');
$this->drupalPostForm(NULL, [], 'Save');
$this->drupalGet('test-filter-taxonomy-index-tid');
$this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
$this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
$this->drupalLogout();
$this->drupalGet('test-filter-taxonomy-index-tid');
// Make sure the unpublished term isn't shown to the anonymous user.
$this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
$this->assertEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
}
}