Loading core/modules/taxonomy/src/TermForm.php +6 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,12 @@ public function form(array $form, FormStateInterface $form_state) { $parent = [0]; } if ($this->getRequest()->query->has('parent')) { $parent = array_values(array_intersect( array_keys($options), (array) $this->getRequest()->query->all()['parent'], )); } $form['relations']['parent'] = [ '#type' => 'select', '#title' => $this->t('Parent terms'), Loading core/modules/taxonomy/taxonomy.module +20 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,26 @@ function template_preprocess_taxonomy_term(&$variables) { } } /** * Implements hook_entity_operation(). */ function taxonomy_entity_operation(EntityInterface $term) { $operations = []; if ($term instanceof Term && $term->access('create')) { $operations['add-child'] = [ 'title' => t('Add child'), 'weight' => 10, 'url' => Url::fromRoute( 'entity.taxonomy_term.add_form', ['taxonomy_vocabulary' => $term->bundle()], ['query' => ['parent' => $term->id()]], ), ]; } return $operations; } /** * Returns whether the current page is the page of the passed-in term. * Loading core/modules/taxonomy/tests/src/Functional/TermParentsTest.php +48 −0 Original line number Diff line number Diff line Loading @@ -248,6 +248,54 @@ protected function doTestEditingSingleParent() { return $terms; } /** * Test the term add/edit form with parent query parameter. */ public function testParentFromQuery() { // Create three terms without any parents. $term_1 = $this->createTerm('Test term 1'); $term_2 = $this->createTerm('Test term 2'); $term_3 = $this->createTerm('Test term 3'); // Add term form with one parent. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent' => $term_1->id()]]); $this->assertParentOption('Test term 1', TRUE); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Add term form with two parents. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent[0]' => $term_1->id(), 'parent[1]' => $term_2->id()]]); $this->assertParentOption('Test term 1', TRUE); $this->assertParentOption('Test term 2', TRUE); $this->assertParentOption('Test term 3', FALSE); // Add term form with no parents. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent' => '']]); $this->assertParentOption('Test term 1', FALSE); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Add term form with invalid parent. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent' => -1]]); $this->assertParentOption('Test term 1', FALSE); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Edit term form with one parent. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent' => $term_2->id()]]); $this->assertParentOption('Test term 2', TRUE); $this->assertParentOption('Test term 3', FALSE); // Edit term form with two parents. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent[0]' => $term_2->id(), 'parent[1]' => $term_3->id()]]); $this->assertParentOption('Test term 2', TRUE); $this->assertParentOption('Test term 3', TRUE); // Edit term form with no parents. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent' => '']]); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Edit term form with invalid parent. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent' => -1]]); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); } /** * Creates a term, saves it and returns it. * Loading core/modules/taxonomy/tests/src/Functional/TermTest.php +16 −2 Original line number Diff line number Diff line Loading @@ -321,12 +321,26 @@ public function testTermInterface() { $this->assertSession()->pageTextContains($edit['name[0][value]']); $this->assertSession()->pageTextContains($edit['description[0][value]']); // Test the "Add child" link on the overview page. $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); $this->assertSession()->linkExistsExact('Add child'); $this->clickLink('Add child'); $edit = [ 'name[0][value]' => $this->randomMachineName(14), 'description[0][value]' => $this->randomMachineName(102), 'name[0][value]' => 'Child term', ]; $this->submitForm($edit, 'Save'); $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([ 'name' => 'Child term', ]); $child = reset($terms); $this->assertNotNull($child, 'Child term found in database.'); $this->assertEquals($term->id(), $child->get('parent')->getValue()[0]['target_id']); // Edit the term. $edit = [ 'name[0][value]' => $this->randomMachineName(14), 'description[0][value]' => $this->randomMachineName(102), ]; $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); $this->submitForm($edit, 'Save'); Loading Loading
core/modules/taxonomy/src/TermForm.php +6 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,12 @@ public function form(array $form, FormStateInterface $form_state) { $parent = [0]; } if ($this->getRequest()->query->has('parent')) { $parent = array_values(array_intersect( array_keys($options), (array) $this->getRequest()->query->all()['parent'], )); } $form['relations']['parent'] = [ '#type' => 'select', '#title' => $this->t('Parent terms'), Loading
core/modules/taxonomy/taxonomy.module +20 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,26 @@ function template_preprocess_taxonomy_term(&$variables) { } } /** * Implements hook_entity_operation(). */ function taxonomy_entity_operation(EntityInterface $term) { $operations = []; if ($term instanceof Term && $term->access('create')) { $operations['add-child'] = [ 'title' => t('Add child'), 'weight' => 10, 'url' => Url::fromRoute( 'entity.taxonomy_term.add_form', ['taxonomy_vocabulary' => $term->bundle()], ['query' => ['parent' => $term->id()]], ), ]; } return $operations; } /** * Returns whether the current page is the page of the passed-in term. * Loading
core/modules/taxonomy/tests/src/Functional/TermParentsTest.php +48 −0 Original line number Diff line number Diff line Loading @@ -248,6 +248,54 @@ protected function doTestEditingSingleParent() { return $terms; } /** * Test the term add/edit form with parent query parameter. */ public function testParentFromQuery() { // Create three terms without any parents. $term_1 = $this->createTerm('Test term 1'); $term_2 = $this->createTerm('Test term 2'); $term_3 = $this->createTerm('Test term 3'); // Add term form with one parent. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent' => $term_1->id()]]); $this->assertParentOption('Test term 1', TRUE); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Add term form with two parents. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent[0]' => $term_1->id(), 'parent[1]' => $term_2->id()]]); $this->assertParentOption('Test term 1', TRUE); $this->assertParentOption('Test term 2', TRUE); $this->assertParentOption('Test term 3', FALSE); // Add term form with no parents. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent' => '']]); $this->assertParentOption('Test term 1', FALSE); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Add term form with invalid parent. $this->drupalGet("/admin/structure/taxonomy/manage/{$this->vocabularyId}/add", ['query' => ['parent' => -1]]); $this->assertParentOption('Test term 1', FALSE); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Edit term form with one parent. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent' => $term_2->id()]]); $this->assertParentOption('Test term 2', TRUE); $this->assertParentOption('Test term 3', FALSE); // Edit term form with two parents. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent[0]' => $term_2->id(), 'parent[1]' => $term_3->id()]]); $this->assertParentOption('Test term 2', TRUE); $this->assertParentOption('Test term 3', TRUE); // Edit term form with no parents. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent' => '']]); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); // Edit term form with invalid parent. $this->drupalGet($term_1->toUrl('edit-form'), ['query' => ['parent' => -1]]); $this->assertParentOption('Test term 2', FALSE); $this->assertParentOption('Test term 3', FALSE); } /** * Creates a term, saves it and returns it. * Loading
core/modules/taxonomy/tests/src/Functional/TermTest.php +16 −2 Original line number Diff line number Diff line Loading @@ -321,12 +321,26 @@ public function testTermInterface() { $this->assertSession()->pageTextContains($edit['name[0][value]']); $this->assertSession()->pageTextContains($edit['description[0][value]']); // Test the "Add child" link on the overview page. $this->drupalGet('admin/structure/taxonomy/manage/' . $this->vocabulary->id() . '/overview'); $this->assertSession()->linkExistsExact('Add child'); $this->clickLink('Add child'); $edit = [ 'name[0][value]' => $this->randomMachineName(14), 'description[0][value]' => $this->randomMachineName(102), 'name[0][value]' => 'Child term', ]; $this->submitForm($edit, 'Save'); $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties([ 'name' => 'Child term', ]); $child = reset($terms); $this->assertNotNull($child, 'Child term found in database.'); $this->assertEquals($term->id(), $child->get('parent')->getValue()[0]['target_id']); // Edit the term. $edit = [ 'name[0][value]' => $this->randomMachineName(14), 'description[0][value]' => $this->randomMachineName(102), ]; $this->drupalGet('taxonomy/term/' . $term->id() . '/edit'); $this->submitForm($edit, 'Save'); Loading