/**
  * Form constructor.
  *
  * Display a tree of all the terms in a vocabulary, with options to edit
  * each one. The form implements the Taxonomy Manager intefrace.
  *
  * @param array $form
  *   An associative array containing the structure of the form.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  * @param VocabularyInterface $taxonomy_vocabulary
  *   The vocabulary being with worked with
  *
  * @return array
  *   The form structure.
  */
 public function buildForm(array $form, FormStateInterface $form_state, VocabularyInterface $taxonomy_vocabulary = NULL)
 {
     $form['voc'] = array('#type' => 'value', "#value" => $taxonomy_vocabulary);
     $form['#attached']['library'][] = 'taxonomy_manager/form';
     if (TaxonomyManagerHelper::_taxonomy_manager_voc_is_empty($taxonomy_vocabulary->id())) {
         $form['text'] = array('#markup' => $this->t('No terms available'));
         $form[] = \Drupal::formBuilder()->getForm('Drupal\\taxonomy_manager\\Form\\AddTermsToVocabularyForm', $taxonomy_vocabulary);
         return $form;
     }
     $form['toolbar'] = array('#type' => 'fieldset', '#title' => $this->t('Toolbar'));
     $form['toolbar']['add'] = array('#type' => 'submit', '#name' => 'add', '#value' => $this->t('Add'), '#ajax' => array('callback' => '::addFormCallback'));
     $form['toolbar']['delete'] = array('#type' => 'submit', '#name' => 'delete', '#value' => $this->t('Delete'), '#ajax' => array('callback' => '::deleteFormCallback'));
     $form['toolbar']['move'] = array('#type' => 'submit', '#name' => 'move', '#value' => $this->t('Move'), '#ajax' => array('callback' => '::moveFormCallback'));
     $form['toolbar']['export'] = array('#type' => 'submit', '#name' => 'export', '#value' => $this->t('Export'), '#ajax' => array('callback' => '::exportFormCallback'));
     /* Taxonomy manager. */
     $form['taxonomy']['#tree'] = TRUE;
     $form['taxonomy']['manager'] = array('#type' => 'fieldset', '#title' => HTML::escape($taxonomy_vocabulary->label()), '#tree' => TRUE);
     $form['taxonomy']['manager']['top'] = array('#markup' => '', '#prefix' => '<div class="taxonomy-manager-tree-top">', '#suffix' => '</div>');
     /*$grippie_image = array(
           '#theme' => 'image',
           '#uri' => drupal_get_path('module', 'taxonomy_manager') . "/images/grippie.png",
           '#alt' => $this->t("Resize tree"),
           '#title' => $this->t("Resize tree"),
           '#attributes' => array('class' => array('div-grippie')),
         );
     
         $form['taxonomy']['manager']['top']['size'] = array(
           '#markup' =>
             '<div class="taxonomy-manager-tree-size">'
             . \Drupal::service('renderer')->render($grippie_image, true)
             . '</div>'
         );*/
     $form['taxonomy']['manager']['tree'] = array('#type' => 'taxonomy_manager_tree', '#vocabulary' => $taxonomy_vocabulary->id(), '#pager_size' => \Drupal::config('taxonomy_manager.settings')->get('taxonomy_manager_pager_tree_page_size'));
     $form['taxonomy']['manager']['pager'] = array('#type' => 'pager');
     // Add placeholder for term data form, the load-term-data field has AJAX
     // events attached and will trigger the load of the term data form. The
     // field is hidden via CSS and the value gets set in termData.js.
     $form['term-data']['#prefix'] = '<div id="taxonomy-term-data-form">';
     $form['term-data']['#suffix'] = '</div>';
     $form['load-term-data'] = array('#type' => 'textfield', '#ajax' => array('callback' => '::termDataCallback', 'event' => 'change'));
     return $form;
 }
 /**
  * Helper function that generates the nested list for the JSON array structure.
  */
 public static function getNestedListJSONArray($terms)
 {
     $items = array();
     if (!empty($terms)) {
         foreach ($terms as $term) {
             $item = array('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;
 }