class TaxonomyManagerTree in Taxonomy Manager 2.0.x
Same name and namespace in other branches
- 8 src/Element/TaxonomyManagerTree.php \Drupal\taxonomy_manager\Element\TaxonomyManagerTree
Taxonomy Manager Tree Form Element.
Plugin annotation
@FormElement("taxonomy_manager_tree");Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait- class \Drupal\Core\Render\Element\RenderElement implements ElementInterface- class \Drupal\Core\Render\Element\FormElement implements FormElementInterface- class \Drupal\taxonomy_manager\Element\TaxonomyManagerTree
 
 
- class \Drupal\Core\Render\Element\FormElement implements FormElementInterface
 
- class \Drupal\Core\Render\Element\RenderElement implements ElementInterface
 
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of TaxonomyManagerTree
1 file declares its use of TaxonomyManagerTree
- SubTreeController.php in src/Controller/ SubTreeController.php 
1 #type use of TaxonomyManagerTree
- TaxonomyManagerForm::buildForm in src/Form/ TaxonomyManagerForm.php 
- Form constructor.
File
- src/Element/ TaxonomyManagerTree.php, line 16 
Namespace
Drupal\taxonomy_manager\ElementView source
class TaxonomyManagerTree extends FormElement {
  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#process' => [
        [
          $class,
          'processTree',
        ],
      ],
    ];
  }
  /**
   * {@inheritdoc}
   */
  public static function processTree(&$element, FormStateInterface $form_state, &$complete_form) {
    $element['#tree'] = TRUE;
    if (!empty($element['#vocabulary'])) {
      $taxonomy_vocabulary = \Drupal::entityTypeManager()
        ->getStorage('taxonomy_vocabulary')
        ->load($element['#vocabulary']);
      $pager_size = isset($element['#pager_size']) ? $element['#pager_size'] : -1;
      $terms = TaxonomyManagerTree::loadTerms($taxonomy_vocabulary, 0, $pager_size);
      $list = TaxonomyManagerTree::getNestedListJsonArray($terms);
      // Expand tree to given terms.
      if (isset($element['#terms_to_expand'])) {
        $terms_to_expand = is_array($element['#terms_to_expand']) ? $element['#terms_to_expand'] : [
          $element['#terms_to_expand'],
        ];
        foreach ($terms_to_expand as $term_to_expand) {
          TaxonomyManagerTree:
          self::getFirstPath($term_to_expand, $list);
        }
      }
      $element['#attached']['library'][] = 'taxonomy_manager/tree';
      $element['#attached']['drupalSettings']['taxonomy_manager']['tree'][] = [
        'id' => $element['#id'],
        'name' => $element['#name'],
        'source' => $list,
      ];
      $element['tree'] = [];
      $element['tree']['#prefix'] = '<div id="' . $element['#id'] . '">';
      $element['tree']['#suffix'] = '</div>';
    }
    return $element;
  }
  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
    // Validate that all submitted terms belong to the original vocabulary and
    // are not faked via manual $_POST changes.
    $selected_terms = [];
    if (is_array($input) && !empty($input)) {
      foreach ($input as $tid) {
        $term = \Drupal::entityTypeManager()
          ->getStorage('taxonomy_term')
          ->load($tid);
        if ($term && $term
          ->bundle() == $element['#vocabulary']) {
          $selected_terms[] = $tid;
        }
      }
    }
    return $selected_terms;
  }
  /**
   * Load one single level of terms, sorted by weight and alphabet.
   */
  public static function loadTerms($vocabulary, $parent = 0, $pager_size = -1) {
    try {
      $query = \Drupal::entityQuery('taxonomy_term')
        ->condition('vid', $vocabulary
        ->id())
        ->condition('parent', $parent)
        ->sort('weight')
        ->sort('name');
      if ($pager_size > 0) {
        $query
          ->pager($pager_size);
      }
      $tids = $query
        ->execute();
      return \Drupal::entityTypeManager()
        ->getStorage('taxonomy_term')
        ->loadMultiple($tids);
    } catch (QueryException $e) {
      // This site is still using the pre-Drupal 8.5 database schema, where
      // https://www.drupal.org/project/drupal/issues/2543726 was not yet
      // committed to Drupal core.
      // @todo Remove both the try/catch wrapper and the code below the catch-
      // statement once the taxonomy_manager module only supports Drupal 8.5 or
      // newer.
    }
    $database = \Drupal::database();
    if ($pager_size > 0) {
      $query = $database
        ->select('taxonomy_term_data', 'td')
        ->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender');
    }
    else {
      $query = $database
        ->select('taxonomy_term_data', 'td');
    }
    $query
      ->fields('td', [
      'tid',
    ]);
    $query
      ->condition('td.vid', $vocabulary
      ->id());
    $query
      ->join('taxonomy_term__parent', 'th', 'td.tid = th.entity_id AND th.parent_target_id = :parent', [
      ':parent' => $parent,
    ]);
    $query
      ->join('taxonomy_term_field_data', 'tfd', 'td.tid = tfd.tid');
    $query
      ->orderBy('tfd.weight');
    $query
      ->orderBy('tfd.name');
    if ($pager_size > 0) {
      $query
        ->limit($pager_size);
    }
    $result = $query
      ->execute();
    $tids = [];
    foreach ($result as $record) {
      $tids[] = $record->tid;
    }
    return \Drupal::entityTypeManager()
      ->getStorage('taxonomy_term')
      ->loadMultiple($tids);
  }
  /**
   * Helper function that transforms a flat taxonomy tree in a nested array.
   */
  public static function getNestedList($tree = [], $max_depth = NULL, $parent = 0, $parents_index = [], $depth = 0) {
    foreach ($tree as $term) {
      foreach ($term->parents as $term_parent) {
        if ($term_parent == $parent) {
          $return[$term
            ->id()] = $term;
        }
        else {
          $parents_index[$term_parent][$term
            ->id()] = $term;
        }
      }
    }
    foreach ($return as &$term) {
      if (isset($parents_index[$term
        ->id()]) && (is_null($max_depth) || $depth < $max_depth)) {
        $term->children = TaxonomyManagerTree::getNestedList($parents_index[$term
          ->id()], $max_depth, $term
          ->id(), $parents_index, $depth + 1);
      }
    }
    return $return;
  }
  /**
   * Function that generates the nested list for the JSON array structure.
   */
  public static function getNestedListJsonArray($terms) {
    $items = [];
    if (!empty($terms)) {
      foreach ($terms as $term) {
        $item = [
          'title' => Html::escape($term
            ->getName()),
          'key' => $term
            ->id(),
        ];
        if (isset($term->children) || TaxonomyManagerTree::getChildCount($term
          ->id()) >= 1) {
          // If the given terms array is nested, directly process the terms.
          if (isset($term->children)) {
            $item['children'] = TaxonomyManagerTree::getNestedListJsonArray($term->children);
          }
          else {
            $item['lazy'] = TRUE;
          }
        }
        $items[] = $item;
      }
    }
    return $items;
  }
  /**
   * Helper function to calculate path.
   *
   * Helper function that calculates the path to a child term and injects it
   * into the json list structure.
   */
  public static function getFirstPath($tid, &$list) {
    $path = [];
    $next_tid = $tid;
    $i = 0;
    // Prevent infinite loop if inconsistent hierarchy.
    while ($i < 100) {
      $parents = \Drupal::entityTypeManager()
        ->getStorage('taxonomy_term')
        ->loadParents($next_tid);
      if (count($parents)) {
        // Takes first parent.
        $parent = array_shift($parents);
        $path[] = $parent;
        $next_tid = $parent
          ->id();
        if (TaxonomyManagerTree::isRoot($parent
          ->id())) {
          break;
        }
      }
      else {
        break;
      }
      $i++;
    }
    if (count($path)) {
      $path = array_reverse($path);
      $root_term = $path[0];
      foreach ($list as $current_index => $list_item) {
        if ($list_item['key'] == $root_term
          ->id()) {
          $index = $current_index;
          break;
        }
      }
      if (isset($index)) {
        $path[] = \Drupal::entityTypeManager()
          ->getStorage('taxonomy_term')
          ->load($tid);
        $list[$index]['children'] = TaxonomyManagerTree::getPartialTree($path);
        $list[$index]['lazy'] = FALSE;
        $list[$index]['expanded'] = TRUE;
      }
    }
  }
  /**
   * Returns partial tree for a given path.
   */
  public function getPartialTree($path, $depth = 0) {
    $tree = [];
    $parent = $path[$depth];
    $children = \Drupal::entityTypeManager()
      ->getStorage('taxonomy_term')
      ->loadChildren($parent
      ->id());
    if (isset($path[++$depth])) {
      $next_term = $path[$depth];
    }
    $index = 0;
    foreach ($children as $child) {
      $child->depth = $depth;
      $child->parents = [
        0 => $parent->tid,
      ];
      $tree[] = [
        'title' => $child
          ->getName(),
        'key' => $child
          ->id(),
        'expanded' => TRUE,
        'selected' => TRUE,
      ];
      if (isset($next_term) && $child
        ->id() == $next_term
        ->id()) {
        $tree[$index]['children'] = TaxonomyManagerTree::getPartialTree($path, $depth);
      }
      $index++;
    }
    return $tree;
  }
  /**
   * Helper function to check whether a given term is a root term.
   */
  public static function isRoot($tid) {
    return empty(static::getTermStorage()
      ->loadParents($tid));
  }
  /**
   * Helper function that returns the number of child terms.
   */
  public static function getChildCount($tid) {
    static $tids = [];
    if (!isset($tids[$tid])) {
      /** @var \Drupal\taxonomy\TermInterface $term */
      $term = Term::load($tid);
      $tids[$tid] = count(static::getTermStorage()
        ->loadTree($term
        ->bundle(), $tid, 1));
    }
    return $tids[$tid];
  }
  /**
   * Function to get term storage.
   *
   * @return \Drupal\taxonomy\TermStorageInterface
   *   The term storage.
   */
  protected static function getTermStorage() {
    return \Drupal::entityTypeManager()
      ->getStorage('taxonomy_term');
  }
}Members
| Name   | Modifiers | Type | Description | Overrides | 
|---|---|---|---|---|
| DependencySerializationTrait:: | protected | property | ||
| DependencySerializationTrait:: | protected | property | ||
| DependencySerializationTrait:: | public | function | 2 | |
| DependencySerializationTrait:: | public | function | 2 | |
| FormElement:: | public static | function | Adds autocomplete functionality to elements. | |
| FormElement:: | public static | function | #process callback for #pattern form element property. | |
| FormElement:: | public static | function | #element_validate callback for #pattern form element property. | |
| MessengerTrait:: | protected | property | The messenger. | 27 | 
| MessengerTrait:: | public | function | Gets the messenger. | 27 | 
| MessengerTrait:: | public | function | Sets the messenger. | |
| PluginBase:: | protected | property | Configuration information passed into the plugin. | 1 | 
| PluginBase:: | protected | property | The plugin implementation definition. | 1 | 
| PluginBase:: | protected | property | The plugin_id. | |
| PluginBase:: | constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
| PluginBase:: | public | function | Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: | |
| PluginBase:: | public | function | Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: | |
| PluginBase:: | public | function | Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: | 2 | 
| PluginBase:: | public | function | Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: | |
| PluginBase:: | public | function | Determines if the plugin is configurable. | |
| PluginBase:: | public | function | Constructs a \Drupal\Component\Plugin\PluginBase object. | 98 | 
| RenderElement:: | public static | function | Adds Ajax information about an element to communicate with JavaScript. | |
| RenderElement:: | public static | function | Adds members of this group as actual elements for rendering. | |
| RenderElement:: | public static | function | Form element processing handler for the #ajax form property. | 1 | 
| RenderElement:: | public static | function | Arranges elements into groups. | |
| RenderElement:: | public static | function | Sets a form element's class attribute. Overrides ElementInterface:: | |
| StringTranslationTrait:: | protected | property | The string translation service. | 4 | 
| StringTranslationTrait:: | protected | function | Formats a string containing a count of items. | |
| StringTranslationTrait:: | protected | function | Returns the number of plurals supported by a given language. | |
| StringTranslationTrait:: | protected | function | Gets the string translation service. | |
| StringTranslationTrait:: | public | function | Sets the string translation service to use. | 2 | 
| StringTranslationTrait:: | protected | function | Translates a string to the current language or to a given language. | |
| TaxonomyManagerTree:: | public static | function | Helper function that returns the number of child terms. | |
| TaxonomyManagerTree:: | public static | function | Helper function to calculate path. | |
| TaxonomyManagerTree:: | public | function | Returns the element properties for this element. Overrides ElementInterface:: | |
| TaxonomyManagerTree:: | public static | function | Helper function that transforms a flat taxonomy tree in a nested array. | |
| TaxonomyManagerTree:: | public static | function | Function that generates the nested list for the JSON array structure. | |
| TaxonomyManagerTree:: | public | function | Returns partial tree for a given path. | |
| TaxonomyManagerTree:: | protected static | function | Function to get term storage. | |
| TaxonomyManagerTree:: | public static | function | Helper function to check whether a given term is a root term. | |
| TaxonomyManagerTree:: | public static | function | Load one single level of terms, sorted by weight and alphabet. | |
| TaxonomyManagerTree:: | public static | function | ||
| TaxonomyManagerTree:: | public static | function | Determines how user input is mapped to an element's #value property. Overrides FormElement:: | 
