Problem/Motivation

When a menu is deleted, which was previously referenced in a node types' available menu settings, an error is thrown and "parent item" select field contains invalid options.

Issue is still present in 8.2, 8.3., 8.5.4

To reproduce

Required modules: menu_ui, node

  1. Create a menu.
  2. Create, then edit a node type. In Menu Settings -> Available menus. Select the previously created menu. (Figure)
  3. Save the node type.
  4. Delete the previously created menu. (Figure)
  5. Create or edit a node entity, with the previous node type.
  6. The following issues arise:

An error is thrown on a node entity edit form:

Notice: Undefined index: MENUNAME in menu_ui_form_node_form_alter() (line 279 of core/modules/menu_ui/menu_ui.module).

And invalid parent item select options:

Invalid  select field

Proposed resolution

Add soft dependency from menu configs to node type.

Remaining tasks

Patch, tests.

User interface changes

API changes

Data model changes

Comments

jan.rysavy created an issue. See original summary.

jan.rysavy’s picture

Title: Error displayed in edit page: Undefined index: test2 in menu_ui_form_node_form_alter() (line 267 of core/modules/menu_ui/menu_ui.module). » Error displayed on edit page: Undefined index: test2 in menu_ui_form_node_form_alter() (line 266 of core/modules/menu_ui/menu_ui.module).
Issue summary: View changes

Note: correct menu_ui.module error line is 266. Originally reported line 267 was caused by my debug print.

cilefen’s picture

Issue tags: +Needs title update

Thank you for reporting this. I followed the steps to reproduce (thank you for including some!) on 8.0.x HEAD but the error did not occur. Is it possible a step towards the error was omitted?

I have tagged this "Needs title update" because the title as written does not describe the problem. Something more like "Deleted menus are still referenced as available menus on content types and cause an error when content is edited" may be better.

jan.rysavy’s picture

Title: Error displayed on edit page: Undefined index: test2 in menu_ui_form_node_form_alter() (line 266 of core/modules/menu_ui/menu_ui.module). » Deleted menus are still referenced as available menus on content types and cause an error when content is edited
jan.rysavy’s picture

StatusFileSize
new16.56 KB
new18.97 KB
new53.28 KB
new41.69 KB
new41.21 KB
new74 KB

Maybe problem is already fixed in 8.0.x HEAD? I'm on 8.0.0 RC1.
Just to be sure I just repeated described sequence and there is no other step involved. Please see attached screenshots.

jan.rysavy’s picture

Issue tags: -Needs title update
cilefen’s picture

Was the "home" node added to the test2 menu at any stage?

jan.rysavy’s picture

I'm not 100% sure, so I created a new page, a new menu and reproduced problem again just with described steps.

Btw, to "fix" this problem you must open Structure > Content Types > Page again and just edit and save it. Error message will be gone.

cilefen’s picture

Actually the error did occur but it is in my watchdog log because I don't display them. So, the steps are reproducible. I am sorry to have had you do it twice.

jan.rysavy’s picture

Great, thanks for quick confirmation.

dawehner’s picture

Version: 8.0.0-rc1 » 8.0.x-dev

That is totally in scope of 8.0.x, so its just a simple bug.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dpi’s picture

Component: menu system » menu_ui.module
Assigned: Unassigned » dpi
Issue summary: View changes
StatusFileSize
new174.34 KB

Simplified issue summary, using issue template, moving to correct component, taking over.

dpi’s picture

Version: 8.2.x-dev » 8.3.x-dev
Status: Active » Needs review
StatusFileSize
new6.5 KB

Contains both fixes and tests. See what testbot thinks.

dpi’s picture

StatusFileSize
new4.3 KB

Great! Attaching test only patch.

Status: Needs review » Needs work

The last submitted patch, 16: available-menus-2592829-testonly.patch, failed testing.

dpi’s picture

Status: Needs work » Needs review

Summary of above patch (#15):

It contains tests and fixes:

Ensures the Parent item <select> element found on node forms do not contain an empty <option> where a deleted menu would normally occupy (see screenshot in issue summary). This simultaneously fixes the PHP notice that appeared.

When a menu configuration is deleted, an entity hook will iterate over all node types and remove any menus referenced in the third party configuration storage. Tests ensure the entity delete hook purges invalid data on menu deletion. A new test file was created since there were no pre-existing kernel tests for menu_ui. The test creates a menu configuration, adds the menu to a node type's available menu settings, then deletes the menu configuration entity.

Patch is ready for review since #15 passed, and test only patch failed on the introduced assertions.

benjy’s picture

  1. +++ b/core/modules/menu_ui/menu_ui.module
    @@ -17,7 +17,9 @@
    @@ -112,6 +114,21 @@ function menu_ui_menu_delete(Menu $menu) {
    
    @@ -112,6 +114,21 @@ function menu_ui_menu_delete(Menu $menu) {
    +  if (\Drupal::moduleHandler()->moduleExists('node')) {
    

    Couldn't the node module implement node_menu_delete() ?

  2. +++ b/core/modules/menu_ui/menu_ui.module
    @@ -272,12 +289,12 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) {
    -  $menu_names = menu_ui_get_menus();
    ...
    +  }, Menu::loadMultiple($type_menus));
    

    Replacing this we're losing the sort behaviour from menu_ui_get_menus()?

dpi’s picture

Status: Needs review » Needs work

Couldn't the node module implement node_menu_delete() ?

The node module does not know about the menu items, or available menus. I put that functionality in menu_ui_menu_delete since menu_ui module is responsible for it all.

Replacing this we're losing the sort behaviour from menu_ui_get_menus()?

No problem, didnt realise this was a thing from reading the function doc block.

dpi’s picture

Status: Needs work » Needs review
StatusFileSize
new1.17 KB
new4.31 KB
new6.52 KB

Patch changes reverts to using menu_ui_get_menus. Invalid menu ID's filtered with array_intersect_key.

The last submitted patch, 21: available-menus-2592829-21-testonly.patch, failed testing.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

misc’s picture

Assigned: dpi » misc
StatusFileSize
new6.11 KB

Updated patch for 8.4.x-dev

misc’s picture

Assigned: misc » Unassigned

See now that the tests will fail with patch. But unassigning for now.

Status: Needs review » Needs work

The last submitted patch, 24: available-menus-2592829-23.patch, failed testing.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Yaazkal’s picture

Hi, this happens not only when a menu has been created and then deleted, but also when a migration takes place.

To reproduce

  1. Install a standard Drupal 7 site (7.56 in my case)
  2. Create a content type and select Main menu as an available menu for that content type
  3. Install a standard Drupal 8 site (8.4.0 in my case)
  4. Migrate content from Drupal 7 to Drupal 8
  5. In D8 try to edit a node from the content type you migrated from D7

I guess that this happens because in D7 the menu is 'main-menu' but in D8 the menu is 'main', so from the D8 perspective, 'main-menu' doesn't exist. So I guess that this can be handled too in the migration process as seems that that information of the available menu for a given content type is not migrated/updated.

Not sure if a new issue must be created but as this is related I report it here. Let me know if I had to create a new issue.

arosboro’s picture

This resolved the issue for me after migrating from Drupal 7 to Drupal 8.

mirom’s picture

dillix’s picture

We also have this issue on migrated site. Is there a way to fix this on already migrated site?

dillix’s picture

I resaved my content types and all errors gone away:)

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Adon Irani’s picture

Confirming resaving my content types worked for me as well.

imanoop’s picture

Thank you for sharing this. Perfect solution.

Thanks,
Anoop Singh

dadderley’s picture

Thanks dillix

crash_springfield’s picture

For those tracking site configuration with Git, you could re-save the content type and then export configuration or you could edit the YAML directly. For example, this is happening with my "article" content type, so I can update "node.type.article.yml"

from:

third_party_settings:
  menu_ui:
    available_menus: {  }
    parent: 'main-menu'

to:

third_party_settings:
  menu_ui:
    available_menus: {  }
    parent: ''
kellyimagined’s picture

Issue summary: View changes

Still an issue in 8.5.4 as well. I have updated the parent.

edwardchiapet’s picture

StatusFileSize
new61.22 KB

I made an update to the patch for 8.5.5.

edwardchiapet’s picture

StatusFileSize
new2.77 KB

Previous patch was wrong - here is the the updated patch for 8.5.x.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Christopher Riley’s picture

I had to manually run the patch it didn't play nice with composer. Anyone have any ideas?

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ckaotik’s picture

I just wish there was better integration for third_party_settings. For example, a way to say "By the way, that thing is now a dependency!". Or handling for default settings, so the provider is not added as a dependency when it's added config is empty.

Then we could do something like this:

function menu_ui_form_node_type_form_builder($entity_type, NodeTypeInterface $type, &$form, FormStateInterface $form_state) {
  $available_menus = array_values(array_filter($form_state->getValue('menu_options')));
  if (!empty($available_menus)) {
    $menus = \Drupal::entityTypeManager()->getStorage('menu')->loadMultiple($available_menus);
    foreach ($menus as $menu) {
      // Does not work: Protected function and dependencies is cleared in ConfigEntityBase::calculateDependencies().
      $type->addDependency($menu->getConfigDependencyKey(), $menu->getConfigDependencyName());
    }
  }
  $type->setThirdPartySetting('menu_ui', 'available_menus', $available_menus);
  $type->setThirdPartySetting('menu_ui', 'parent', $form_state->getValue('menu_parent'));
}

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

johnwebdev’s picture

StatusFileSize
new1.89 KB

I followed the steps to reproduce on 8.9.x, and the error seems not to be occurring anymore.

Here is the test I wrote, (following the steps listed in the issue)

  /**
   * Tests that a deleted menu is no longer referenced as an available menu.
   */
  public function testDeletedMenuIsNoLongerReferencedAsAnAvailableMenu() {
    // Create a new menu.
    $menu = Menu::create([
      'id' => 'llama',
      'label' => 'Llama',
    ]);
    $menu->save();

    // Enable the llama menu.
    $edit = [
      'menu_options[llama]' => TRUE,
    ];
    $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));

    // Ensure the llama menu is available.
    $this->drupalGet('/node/add/page');
    $this->assertOption('edit-menu-menu-parent', 'llama:');
    $this->assertOptionByText('edit-menu-menu-parent', '<Llama>');

    // Delete the llama menu.
    $menu->delete();

    // Ensure the llama menu is not available.
    $this->drupalGet('/node/add/page');
    $this->assertNoOption('edit-menu-menu-parent', 'llama:');
  }

which passes.

However, it looks like the "llama" menu, is still present on the node type configuration after deleting the menu.

So the following patch updates the test above, to ensure the third party settings is no longer present, which currently fails.

I am not entirely sure when and how this was fixed, and perhaps we could refactor the test to a kernel, because the fix we need here currently would only need to update the third party settings, however, I guess unless not covered somewhere else, it would be nice to prove that we don't actually have this problem anymore. I'll let someone else decide that :)

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

larowlan’s picture

Triaged as part of bug smash initiative - this needs a reroll, looks like the last passing patch was from @dpi in #21

yogeshmpawar’s picture

Assigned: Unassigned » yogeshmpawar

.

yogeshmpawar’s picture

Assigned: yogeshmpawar » Unassigned

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

tvb’s picture

Issue summary: View changes

As mentioned in #46: displaying the error in the UI cannot be reproduced, but the deleted menu is still available in the node type configuration in third party settings.

Run this snippet after deleting a menu in step 4 above:

use Drupal\node\Entity\NodeType;
use Drupal\system\Entity\Menu;
$node_type = NodeType::load('page');  // Replace 'page' if necessary.
$menu_ids = $node_type->getThirdPartySetting('menu_ui', 'available_menus');
var_dump($menu_ids);
$menus = Menu::loadMultiple();
var_dump(array_keys($menus));
tvb’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new5.7 KB
new11.33 KB

Rebasing: two merge conflicts in MenuUiNodeTest.php and menu_ui.module. New patch based on #21 en #46:

menu_ui.module:

  1. Moved patch code in menu_ui_menu_delete() to MenuDeleteForm.php

    Replace $menu->id() with $this->entity->id().

    This hunk fixes the third party settings after deleting a menu via the UI.

  2. Skipped re-applying patch code in menu_ui_form_node_form_alter(). This seems no longer necessary.

menu_ui/tests/src/Kernel/MenuNodeTest.php:

  1. This kernel test, which does not require a UI, always fails. It was replaced with the testDeletedMenuIsNoLongerReferencedAsAnAvailableMenu() (see below)

menu_ui/tests/src/Functional/MenuUiNodeTest.php:

  1. Add testNodeFormInvalidMenu()
     

    Retrieved from menu_ui/src/Tests/MenuNodeTest.php (cfr. point 2)

    Add property and modify setup() accordingly.

    Replace assertEqual() with assertEquals().
    Replace assertOption() with assertSession()->optionExists().
    Replace assertNoOption() with aassertSession()->optionNotExists.

  2. Add testDeletedMenuIsNoLongerReferencedAsAnAvailableMenu() from 2592829-46--TEST-ONLY.patch in comment #46.

    Replace $menu->delete(); with:

      $this->drupalGet('admin/structure/menu/manage/llama/delete');
      $this->getSession()->getPage()->pressButton('Delete');
      $this->assertSession()->statusCodeEquals(200);
    

    Replace drupalPostForm() with drupalGet() and submitForm().
    Replace assertOptionByText() with assertSession()->optionExists().
    Replace assertOption() with assertSession()->optionExists().
    Replace assertNoOption() with aassertSession()->optionNotExists.

  3. A few minor changes to pass Drupal code quality checks.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

pameeela’s picture

Status: Needs review » Postponed (maintainer needs more info)
StatusFileSize
new39.96 KB
new47.86 KB

Hmm, I can't reproduce this anymore. Following the steps in the IS, it works as expected.

Before deleting:

After deleting:

And no warnings in the logs.

pameeela’s picture

Status: Postponed (maintainer needs more info) » Closed (outdated)

I'm going to close this since the original issue is no longer valid. I will create a follow up for the lingering config.

pameeela’s picture