bulk_edit_terms-8.x-1.1/tests/src/Functional/BulkEditTermsTest.php

tests/src/Functional/BulkEditTermsTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\bulk_edit_terms\Functional;

use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\taxonomy\TermInterface;
use Drupal\Tests\BrowserTestBase;

/**
 * Tests the edit term assignment action plugin via views bulk operations.
 */
class BulkEditTermsTest extends BrowserTestBase {

  /**
   * {@inheritDoc}
   */
  protected static $modules = ['node', 'taxonomy', 'views', 'bulk_edit_terms'];

  /**
   * {@inheritDoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritDoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $vocab = Vocabulary::create([
      'vid' => 'tag',
      'name' => 'Tag',
    ]);
    $vocab->save();
    $vocab = Vocabulary::create([
      'vid' => 'category',
      'name' => 'Category',
    ]);
    $vocab->save();

    // Create an Article content type that has both a
    // multi-value tag term ref field to Tag and a single-value
    // term ref field to Category.
    $this->drupalCreateContentType([
      'type' => 'article',
      'name' => 'Article',
    ]);
    $field_storage = FieldStorageConfig::create([
      'field_name' => 'field_tags',
      'entity_type' => 'node',
      'translatable' => FALSE,
      'entity_types' => [],
      'settings' => [
        'target_type' => 'taxonomy_term',
      ],
      'type' => 'entity_reference',
      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
    ]);
    $field_storage->save();
    $field = FieldConfig::create([
      'field_name' => 'field_tags',
      'entity_type' => 'node',
      'bundle' => 'article',
      'label' => 'Tags',
      'settings' => [
        'handler' => 'default',
        'handler_settings' => [
          'target_bundles' => [
            'tag',
          ],
        ],
      ],
    ]);
    $field->save();
    $field_storage = FieldStorageConfig::create([
      'field_name' => 'field_category',
      'entity_type' => 'node',
      'translatable' => FALSE,
      'entity_types' => [],
      'settings' => [
        'target_type' => 'taxonomy_term',
      ],
      'type' => 'entity_reference',
      'cardinality' => 1,
    ]);
    $field_storage->save();
    $field = FieldConfig::create([
      'field_name' => 'field_category',
      'entity_type' => 'node',
      'bundle' => 'article',
      'label' => 'Category',
      'settings' => [
        'handler' => 'default',
        'handler_settings' => [
          'target_bundles' => [
            'category',
          ],
        ],
      ],
    ]);
    $field->save();

    $entity_display = \Drupal::service('entity_display.repository');
    $entity_display->getViewDisplay('node', 'article', 'default')
      ->setComponent('field_tags')
      ->save();
    $entity_display->getViewDisplay('node', 'article', 'default')
      ->setComponent('field_category')
      ->save();

    // Create a Page content type that has a multi-value tags field only.
    $this->drupalCreateContentType([
      'type' => 'page',
      'name' => 'Page',
    ]);
    $field = FieldConfig::create([
      'field_name' => 'field_tags',
      'entity_type' => 'node',
      'bundle' => 'page',
      'label' => 'Tags',
      'settings' => [
        'handler' => 'default',
        'handler_settings' => [
          'target_bundles' => [
            'tag',
          ],
        ],
      ],
      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
    ]);
    $field->save();
    $entity_display->getViewDisplay('node', 'page', 'default')
      ->setComponent('field_tags')
      ->save();

    // Create some terms in each vocabulary.
    $tag1 = Term::create([
      'name' => 'tag1',
      'vid' => 'tag',
    ]);
    $tag1->save();
    $tag2 = Term::create([
      'name' => 'tag2',
      'vid' => 'tag',
    ]);
    $tag2->save();
    $tag3 = Term::create([
      'name' => 'tag3',
      'vid' => 'tag',
    ]);
    $tag3->save();

    $cat1 = Term::create([
      'name' => 'cat1',
      'vid' => 'category',
    ]);
    $cat1->save();
    $cat2 = Term::create([
      'name' => 'cat2',
      'vid' => 'category',
    ]);
    $cat2->save();

    // Create some nodes. Set specific created & changed timestamps to ensure
    // the order they display in the content view. This allows us to easily
    // know which nodes we're selecting with the bulk checkboxes on the form.
    // First, an article with no existing term references.
    $article1 = Node::create([
      'type' => 'article',
      'title' => 'Test Article 1',
      'created' => \Drupal::time()->getRequestTime() - 30,
      'changed' => \Drupal::time()->getRequestTime() - 30,
    ]);
    $article1->save();
    // An article with existing references.
    $article2 = Node::create([
      'type' => 'article',
      'title' => 'Test Article 2',
      'field_tags' => [$tag1, $tag3],
      'field_category' => $cat1,
      'created' => \Drupal::time()->getRequestTime() - 20,
      'changed' => \Drupal::time()->getRequestTime() - 20,
    ]);
    $article2->save();
    // A page with no existing references.
    $page1 = Node::create([
      'type' => 'page',
      'title' => 'Test Page 1',
      'created' => \Drupal::time()->getRequestTime() - 10,
      'changed' => \Drupal::time()->getRequestTime() - 10,
    ]);
    $page1->save();

    // Baseline assertions to ensure our term references were set.
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_category', (int) $cat1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_category', (int) $cat2->id()));

    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag2->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_category', (int) $cat1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_category', (int) $cat2->id()));

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag2->id()));

    $admin_user = $this->drupalCreateUser([
      'access content overview',
      'administer bulk edit terms',
      'administer content types',
      'administer nodes',
      'bypass node access',
    ]);

    $this->drupalLogin($admin_user);
  }

  /**
   * Tests the Clear action.
   */
  public function testClearAction(): void {
    // Login as administrator and go to admin/content.
    $this->drupalGet('admin/content');
    $this->assertSession()->pageTextContains('Test Article 1');
    $this->assertSession()->pageTextContains('Test Article 2');
    $this->assertSession()->pageTextContains('Test Page 1');

    // Let's edit all three of them.
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    $this->submitForm([
      // This is an autocomplete tags field, so we need to write out the name
      // and TID as it would be filled out via autocomplete.
      'field_tags_action' => 'clear',
      'field_category_action' => 'clear',
    ], 'Update terms');

    // Only the one node that had any term assignments should have been
    // updated.
    $this->assertSession()->pageTextContains('1 node was updated.');

    // Confirm the tag updates stuck. Reload entities from storage so they
    // get the updates.
    $article1 = $this->getNodeByTitle('Test Article 1', TRUE);
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $page1 = $this->getNodeByTitle('Test Page 1', TRUE);

    // The reference fields should be empty now on all nodes.
    $this->assertTrue($article1->get('field_tags')->isEmpty());
    $this->assertTrue($article2->get('field_tags')->isEmpty());
    $this->assertTrue($page1->get('field_tags')->isEmpty());
    $this->assertTrue($article1->get('field_category')->isEmpty());
    $this->assertTrue($article2->get('field_category')->isEmpty());
  }

  /**
   * Tests the Replace action.
   */
  public function testReplaceAction(): void {
    $tag1 = $this->getTermByName('tag1');
    $tag2 = $this->getTermByName('tag2');
    $tag3 = $this->getTermByName('tag3');
    $cat1 = $this->getTermByName('cat1');
    $cat2 = $this->getTermByName('cat2');

    // Login as administrator and go to admin/content.
    $this->drupalGet('admin/content');
    $this->assertSession()->pageTextContains('Test Article 1');
    $this->assertSession()->pageTextContains('Test Article 2');
    $this->assertSession()->pageTextContains('Test Page 1');

    // Let's edit all three of them.
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    $this->assertSession()->fieldExists('field_tags');
    $this->assertSession()->fieldExists('field_category');

    $this->submitForm([
      // This is an autocomplete tags field, so we need to write out the name
      // and TID as it would be filled out via autocomplete.
      'field_tags' => "{$tag2->label()} ({$tag2->id()})",
      'field_tags_action' => 'replace',
      'field_category' => $cat2->id(),
      'field_category_action' => 'replace',
    ], 'Update terms');

    $this->assertSession()->pageTextContains('3 nodes were updated.');

    // Confirm the tag updates stuck. Reload entities from storage so they
    // get the updates.
    $article1 = $this->getNodeByTitle('Test Article 1', TRUE);
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $page1 = $this->getNodeByTitle('Test Page 1', TRUE);

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag3->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_category', (int) $cat1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article1, 'field_category', (int) $cat2->id()));

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag3->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_category', (int) $cat1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_category', (int) $cat2->id()));

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag3->id()));
  }

  /**
   * Tests add action.
   */
  public function testAddAction(): void {
    $tag1 = $this->getTermByName('tag1');
    $tag2 = $this->getTermByName('tag2');
    $tag3 = $this->getTermByName('tag3');

    // Login as administrator and go to admin/content.
    $this->drupalGet('admin/content');
    $this->assertSession()->pageTextContains('Test Article 1');
    $this->assertSession()->pageTextContains('Test Article 2');
    $this->assertSession()->pageTextContains('Test Page 1');

    // Let's edit all three of them.
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    $this->assertSession()->fieldExists('field_tags');
    $this->assertSession()->fieldExists('field_category');

    // Don't submit anything for the single-value category field, but confirm
    // that "add" is not an option for it.
    $this->submitForm([
      'field_tags' => "{$tag2->label()} ({$tag2->id()})",
      'field_tags_action' => 'append',
      'field_category_action' => 'none',
    ], 'Update terms');

    $this->assertSession()->pageTextContains('3 nodes were updated.');

    // Confirm the tag updates stuck. Reload entities from storage so they
    // get the updates.
    $article1 = $this->getNodeByTitle('Test Article 1', TRUE);
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $page1 = $this->getNodeByTitle('Test Page 1', TRUE);

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag3->id()));

    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag2->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag3->id()));

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag1->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag3->id()));
  }

  /**
   * Tests remove action.
   */
  public function testRemoveAction(): void {
    $tag1 = $this->getTermByName('tag1');
    $tag2 = $this->getTermByName('tag2');
    $tag3 = $this->getTermByName('tag3');

    // Login as administrator and go to admin/content.
    $this->drupalGet('admin/content');
    $this->assertSession()->pageTextContains('Test Article 1');
    $this->assertSession()->pageTextContains('Test Article 2');
    $this->assertSession()->pageTextContains('Test Page 1');

    // Let's edit all three of them.
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    $this->assertSession()->fieldExists('field_tags');
    $this->assertSession()->fieldExists('field_category');

    // Don't submit anything for the single-value category field, but confirm
    // that "add" is not an option for it.
    $this->submitForm([
      'field_tags' => "{$tag1->label()} ({$tag1->id()})",
      'field_tags_action' => 'remove',
      'field_category_action' => 'none',
    ], 'Update terms');

    $this->assertSession()->pageTextContains('1 node was updated.');

    // Confirm the tag updates stuck. Reload entities from storage so they
    // get the updates.
    $article1 = $this->getNodeByTitle('Test Article 1', TRUE);
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $page1 = $this->getNodeByTitle('Test Page 1', TRUE);

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article1, 'field_tags', (int) $tag3->id()));

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag2->id()));
    $this->assertTrue($this->hasTaxonomyTermInReferenceField($article2, 'field_tags', (int) $tag3->id()));

    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag1->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag2->id()));
    $this->assertFalse($this->hasTaxonomyTermInReferenceField($page1, 'field_tags', (int) $tag3->id()));
  }

  /**
   * Test making a change without creating a new revision.
   */
  public function testChangeWithNoRevision(): void {
    // Edit all three pages.
    $this->drupalGet('admin/content');
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    // Submit a change but indicate no revision should be made.
    $this->submitForm([
      'field_tags_action' => 'clear',
      'field_category_action' => 'clear',
      'create_revision' => FALSE,
    ], 'Update terms');

    // Only Test Article 2 should have been updated, it's the only one that
    // had something to clear.
    $this->assertSession()->pageTextContains('1 node was updated.');

    // Verify there's only one revision still for the node.
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $this->drupalGet('/node/' . $article2->id() . '/revisions');
    $this->assertSession()->pageTextContains('Revisions for Test Article 2');
    $this->assertSession()->elementsCount('css', '.node-revision-table tbody tr', 1);
  }

  /**
   * Test making a change and providing a revision log message.
   */
  public function testChangeWithRevision(): void {
    // Edit all three pages.
    $this->drupalGet('admin/content');
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    // Submit a change but indicate a revision should be made.
    $this->submitForm([
      'field_tags_action' => 'clear',
      'field_category_action' => 'clear',
      'create_revision' => TRUE,
      'revision_log_message' => 'Test revision log',
    ], 'Update terms');

    // Only Test Article 2 should have been updated, it's the only one that
    // had something to clear.
    $this->assertSession()->pageTextContains('1 node was updated.');

    // Verify that there's a new revision for the updated article.
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $this->drupalGet('/node/' . $article2->id() . '/revisions');
    $this->assertSession()->pageTextContains('Revisions for Test Article 2');
    $this->assertSession()->elementsCount('css', '.node-revision-table tbody tr', 2);
    $this->assertSession()->elementContains('css', '.node-revision-table tbody tr:nth-child(1)', 'Test revision log');
  }

  /**
   * Tests using config form to change multi value form widget.
   */
  public function testChangingMultivalueFormWidget(): void {
    // First check using autocomplete widget (this is the default anyway).
    $this->drupalGet('admin/config/content/bulk_edit_terms');
    $this->submitForm([
      'multi_value_widget_type' => 'entity_autocomplete',
    ], 'Save configuration');
    $this->assertSession()->pageTextContains('The configuration options have been saved.');

    // Edit all three pages.
    $this->drupalGet('admin/content');
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    // Verify that the autocomplete widget is rendered for the multi-value tags
    // field.
    $this->assertSession()->elementExists('css', 'input#edit-field-tags.form-autocomplete');
    $this->assertSession()->elementNotExists('css', 'select#edit-field-tags');

    // Change widget to select and try again.
    $this->drupalGet('admin/config/content/bulk_edit_terms');
    $this->submitForm([
      'multi_value_widget_type' => 'select',
    ], 'Save configuration');
    $this->assertSession()->pageTextContains('The configuration options have been saved.');

    $this->drupalGet('admin/content');
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'node_bulk_form[1]' => TRUE,
      'node_bulk_form[2]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');

    $this->assertSession()->elementNotExists('css', 'input#edit-field-tags.form-autocomplete');
    $this->assertSession()->elementExists('css', 'select#edit-field-tags');

    // Submit a change using the multi-value select and verify it works as
    // expected.
    $tag1 = $this->getTermByName('tag1');
    $this->submitForm([
      'field_tags[]' => [$tag1->id()],
      'field_tags_action' => 'remove',
      'field_category_action' => 'none',
    ], 'Update terms');
    // Article 2 was the only one with tag1 on it, so it should be the only
    // one updated.
    $this->assertSession()->pageTextContains('1 node was updated.');
    // Visit article 2 and confirm tag1 is no longer there.
    $article2 = $this->getNodeByTitle('Test Article 2', TRUE);
    $this->drupalGet('/node/' . $article2->id());
    $this->assertSession()->pageTextNotContains('tag1');
    // tag3 should still be here, we didn't mess with it.
    $this->assertSession()->pageTextContains('tag3');
  }

  /**
   * Tests users can't edit nodes or fields they don't have access to.
   */
  public function testAccessRestrictions(): void {
    // Create a user that only has permission to edit articles but not pages.
    $limited_user = $this->drupalCreateUser([
      'access content overview',
      'administer nodes',
      'edit any article content',
    ]);
    $this->drupalLogin($limited_user);
    $this->drupalGet('admin/content');

    // Confirm when selecting a Page node, we get an error indicating we cannot
    // edit it since we don't have access.
    $this->submitForm([
      'node_bulk_form[0]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');
    $this->assertSession()->pageTextContains('No access to execute Update taxonomy terms on the Content Test Page 1.');

    // But we are able to bulk edit an Article, which we do have perms for.
    $this->submitForm([
      'node_bulk_form[1]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');
    $this->assertSession()->pageTextNotContains('No access to execute Update taxonomy terms on the Content Test Article 2.');
    $this->assertSession()->pageTextNotContains('No access');

    // Now let check field access perms are working.
    // Start by confirming user can edit Tags field on an Article.
    $this->drupalGet('admin/content');
    $this->submitForm([
      'node_bulk_form[1]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');
    $this->assertSession()->elementExists('css', 'input#edit-field-tags');

    // And now confirm they don't once we restrict access with a hook from
    // a test module.
    \Drupal::service('module_installer')->install(['bulk_edit_terms_field_permissions_test']);
    $this->drupalGet('admin/content');
    $this->submitForm([
      'node_bulk_form[1]' => TRUE,
      'action' => 'node_edit_terms_action',
    ], 'Apply to selected items');
    $this->assertSession()->elementNotExists('css', 'input#edit-field-tags');
  }

  /**
   * Check if an entity reference field contains a reference to a term.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node.
   * @param string $fieldName
   *   The term reference field name.
   * @param int $tid
   *   The term ID.
   *
   * @return bool
   *   TRUE if the term is in the reference field.
   */
  private function hasTaxonomyTermInReferenceField(NodeInterface $node, string $fieldName, int $tid): bool {
    $fieldItemList = $node->get($fieldName);
    assert($fieldItemList instanceof EntityReferenceFieldItemListInterface);
    foreach ($fieldItemList->referencedEntities() as $term) {
      assert($term instanceof TermInterface);
      if ((int) $term->id() === $tid) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * Get taxonomy term by name.
   *
   * @param string $name
   *   The term name.
   *
   * @return \Drupal\taxonomy\TermInterface
   *   The term.
   */
  private function getTermByName(string $name): TermInterface {
    $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([
      'name' => $name,
    ]);
    return array_shift($terms);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc