You are here

public function StrawSelection::createNewEntity in Super Term Reference Autocomplete Widget 8

Creates a new entity object that can be used as a valid reference.

Parameters

string $entity_type_id: The entity type ID.

string $bundle: The bundle name.

string $label: The entity label.

int $uid: The entity owner ID, if the entity type supports it.

Return value

\Drupal\Core\Entity\EntityInterface An unsaved entity object.

Overrides TermSelection::createNewEntity

File

src/Plugin/EntityReferenceSelection/StrawSelection.php, line 116

Class

StrawSelection
Provides specific access control for the taxonomy_term entity type.

Namespace

Drupal\straw\Plugin\EntityReferenceSelection

Code

public function createNewEntity($entity_type_id, $bundle, $label, $uid) {

  // Straw only works with terms; $entity_type_id should always be
  // "taxonomy_term". Since we need term-specific handling here, we ignore
  // that setting (as well as $uid, since terms don't implement
  // EntityOwnerInterface).
  $term_names = explode('>>', $label);

  /** @var \Drupal\straw\NewTermStorage $new_term_storage */
  $new_term_storage = \Drupal::service('straw.new_term_storage');

  // Tracks the deepest term we've already processed.
  $last_term = NULL;

  // Loop to find the term deepest in the existing hierarchy which matches
  // the desired tree path.
  $tree_path = '';
  while ($term_name = array_shift($term_names)) {
    $tree_path .= ($tree_path ? ' >> ' : '') . trim($term_name);
    $matching_terms_by_vocabulary = $this
      ->getReferenceableEntities($tree_path, '=', 1);
    if (empty($matching_terms_by_vocabulary[$bundle])) {

      // We'll process the unmatched term again, below, to create it.
      array_unshift($term_names, $term_name);
      break;
    }
    $last_term = key($matching_terms_by_vocabulary[$bundle]);
  }

  // Create terms of the tree path which have not been found (meaning that
  // they don't exist). There *should* always be at least one of these if
  // this function is getting called, though it should still function if there
  // isn't. The NewTermStorage service is used to track which terms have
  // already been created but which have not yet necessarily been saved, to
  // prevent creating duplicate terms if the same new term is named by
  // multiple term hierarchies being created during the same request.
  while ($term_name = array_shift($term_names)) {
    $tree_path .= ($tree_path ? ' >> ' : '') . trim($term_name);
    if ($found_term = $new_term_storage
      ->get($bundle, $tree_path)) {
      $last_term = $found_term;
    }
    else {
      $last_term = Term::create([
        'vid' => $bundle,
        'name' => trim($term_name),
        'parent' => $last_term,
      ]);
      $new_term_storage
        ->set($bundle, $tree_path, $last_term);
    }
  }
  return $last_term;
}