3 namespace Drupal\taxonomy;
5 use Drupal\Core\Entity\ContentEntityForm;
6 use Drupal\Core\Form\FormStateInterface;
9 * Base for handler for taxonomy term edit forms.
11 class TermForm extends ContentEntityForm {
16 public function form(array $form, FormStateInterface $form_state) {
17 $term = $this->entity;
18 $vocab_storage = $this->entityManager->getStorage('taxonomy_vocabulary');
19 $taxonomy_storage = $this->entityManager->getStorage('taxonomy_term');
20 $vocabulary = $vocab_storage->load($term->bundle());
22 $parent = array_keys($taxonomy_storage->loadParents($term->id()));
23 $form_state->set(['taxonomy', 'parent'], $parent);
24 $form_state->set(['taxonomy', 'vocabulary'], $vocabulary);
26 $form['relations'] = [
28 '#title' => $this->t('Relations'),
29 '#open' => $vocabulary->getHierarchy() == VocabularyInterface::HIERARCHY_MULTIPLE,
33 // \Drupal\taxonomy\TermStorageInterface::loadTree() and
34 // \Drupal\taxonomy\TermStorageInterface::loadParents() may contain large
35 // numbers of items so we check for taxonomy.settings:override_selector
36 // before loading the full vocabulary. Contrib modules can then intercept
37 // before hook_form_alter to provide scalable alternatives.
38 if (!$this->config('taxonomy.settings')->get('override_selector')) {
39 $parent = array_keys($taxonomy_storage->loadParents($term->id()));
40 $children = $taxonomy_storage->loadTree($vocabulary->id(), $term->id());
42 // A term can't be the child of itself, nor of its children.
43 foreach ($children as $child) {
44 $exclude[] = $child->tid;
46 $exclude[] = $term->id();
48 $tree = $taxonomy_storage->loadTree($vocabulary->id());
49 $options = ['<' . $this->t('root') . '>'];
54 foreach ($tree as $item) {
55 if (!in_array($item->tid, $exclude)) {
56 $options[$item->tid] = str_repeat('-', $item->depth) . $item->name;
60 $form['relations']['parent'] = [
62 '#title' => $this->t('Parent terms'),
63 '#options' => $options,
64 '#default_value' => $parent,
69 $form['relations']['weight'] = [
70 '#type' => 'textfield',
71 '#title' => $this->t('Weight'),
73 '#default_value' => $term->getWeight(),
74 '#description' => $this->t('Terms are displayed in ascending order by weight.'),
80 '#value' => $vocabulary->id(),
85 '#value' => $term->id(),
88 return parent::form($form, $form_state, $term);
94 public function validateForm(array &$form, FormStateInterface $form_state) {
95 parent::validateForm($form, $form_state);
97 // Ensure numeric values.
98 if ($form_state->hasValue('weight') && !is_numeric($form_state->getValue('weight'))) {
99 $form_state->setErrorByName('weight', $this->t('Weight value must be numeric.'));
106 public function buildEntity(array $form, FormStateInterface $form_state) {
107 $term = parent::buildEntity($form, $form_state);
109 // Prevent leading and trailing spaces in term names.
110 $term->setName(trim($term->getName()));
112 // Assign parents with proper delta values starting from 0.
113 $term->parent = array_keys($form_state->getValue('parent'));
121 public function save(array $form, FormStateInterface $form_state) {
122 $term = $this->entity;
124 $result = $term->save();
126 $edit_link = $term->link($this->t('Edit'), 'edit-form');
127 $view_link = $term->link($term->getName());
130 drupal_set_message($this->t('Created new term %term.', ['%term' => $view_link]));
131 $this->logger('taxonomy')->notice('Created new term %term.', ['%term' => $term->getName(), 'link' => $edit_link]);
134 drupal_set_message($this->t('Updated term %term.', ['%term' => $view_link]));
135 $this->logger('taxonomy')->notice('Updated term %term.', ['%term' => $term->getName(), 'link' => $edit_link]);
139 $current_parent_count = count($form_state->getValue('parent'));
140 $previous_parent_count = count($form_state->get(['taxonomy', 'parent']));
141 // Root doesn't count if it's the only parent.
142 if ($current_parent_count == 1 && $form_state->hasValue(['parent', 0])) {
143 $current_parent_count = 0;
144 $form_state->setValue('parent', []);
147 // If the number of parents has been reduced to one or none, do a check on the
148 // parents of every term in the vocabulary value.
149 $vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
150 if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) {
151 taxonomy_check_vocabulary_hierarchy($vocabulary, $form_state->getValues());
153 // If we've increased the number of parents and this is a single or flat
154 // hierarchy, update the vocabulary immediately.
155 elseif ($current_parent_count > $previous_parent_count && $vocabulary->getHierarchy() != VocabularyInterface::HIERARCHY_MULTIPLE) {
156 $vocabulary->setHierarchy($current_parent_count == 1 ? VocabularyInterface::HIERARCHY_SINGLE : VocabularyInterface::HIERARCHY_MULTIPLE);
160 $form_state->setValue('tid', $term->id());
161 $form_state->set('tid', $term->id());