I have a project that started with drupal 8.3 and I have upgraded each time a new minor release was out. So I got through 8.4, 8.5 and 8.6 and at some point I have installed the menu item extras module. I have used it a bit and uninstalled it and now as 8.7 is out I have tried to upgrade.

Trying to do a drush updatedb it get's stuck with an class not found exception, respectively Drupal\menu_item_extras\Entity\MenuItemExtrasMenuLinkContent so one of the menu item extras module that was uninstalled almost one year ago.

Searching the database I have found in the key_value table that for the row

         collection                                        name
entity.definitions.installed            menu_link_content.entity_type

the value blob looks like this (pretty printed for easy reading)

O: 36: "Drupal\Core\Entity\ContentEntityType": 42: {
	s: 25: " * revision_metadata_keys";
	a: 1: {
		s: 16: "revision_default";
		s: 16: "revision_default";
	}
	s: 31: " * requiredRevisionMetadataKeys";
	a: 1: {
		s: 16: "revision_default";
		s: 16: "revision_default";
	}
	s: 15: " * static_cache";
	b: 1;
	s: 15: " * render_cache";
	b: 1;
	s: 19: " * persistent_cache";
	b: 1;
	s: 14: " * entity_keys";
	a: 9: {
		s: 2: "id";
		s: 2: "id";
		s: 5: "label";
		s: 5: "title";
		s: 8: "langcode";
		s: 8: "langcode";
		s: 4: "uuid";
		s: 4: "uuid";
		s: 6: "bundle";
		s: 6: "bundle";
		s: 9: "published";
		s: 7: "enabled";
		s: 8: "revision";
		s: 0: "";
		s: 16: "default_langcode";
		s: 16: "default_langcode";
		s: 29: "revision_translation_affected";
		s: 29: "revision_translation_affected";
	}
	s: 5: " * id";
	s: 17: "menu_link_content";
	s: 16: " * originalClass";
	s: 47: "Drupal\menu_link_content\Entity\MenuLinkContent";
	s: 11: " * handlers";
	a: 7: {
		s: 7: "storage";
		s: 46: "Drupal\Core\Entity\Sql\SqlContentEntityStorage";
		s: 14: "storage_schema";
		s: 53: "Drupal\menu_link_content\MenuLinkContentStorageSchema";
		s: 6: "access";
		s: 60: "Drupal\menu_link_content\MenuLinkContentAccessControlHandler";
		s: 4: "form";
		a: 2: {
			s: 7: "default";
			s: 49: "Drupal\menu_link_content\Form\MenuLinkContentForm";
			s: 6: "delete";
			s: 55: "Drupal\menu_link_content\Form\MenuLinkContentDeleteForm";
		}
		s: 12: "view_builder";
		s: 36: "Drupal\Core\Entity\EntityViewBuilder";
		s: 11: "inline_form";
		s: 48: "\Drupal\inline_entity_form\Form\EntityInlineForm";
		s: 10: "views_data";
		s: 48: "Drupal\menu_item_extras\MenuLinkContentViewsData";
	}
	s: 19: " * admin_permission";
	s: 15: "administer menu";
	s: 25: " * permission_granularity";
	s: 11: "entity_type";
	s: 8: " * links";
	a: 9: {
		s: 9: "canonical";
		s: 51: "/admin/structure/menu/item/{menu_link_content}/edit";
		s: 9: "edit-form";
		s: 51: "/admin/structure/menu/item/{menu_link_content}/edit";
		s: 11: "delete-form";
		s: 53: "/admin/structure/menu/item/{menu_link_content}/delete";
		s: 10: "devel-load";
		s: 44: "/devel/menu_link_content/{menu_link_content}";
		s: 12: "devel-render";
		s: 51: "/devel/menu_link_content/{menu_link_content}/render";
		s: 16: "devel-definition";
		s: 55: "/devel/menu_link_content/{menu_link_content}/definition";
		s: 7: "display";
		s: 66: "/admin/structure/menu/item/{menu_link_content}/edit/manage-display";
		s: 12: "devel-markup";
		s: 64: "/admin/structure/menu/item/{menu_link_content}/edit/devel/markup";
		s: 11: "token-devel";
		s: 63: "/admin/structure/menu/item/{menu_link_content}/edit/devel/token";
	}
	s: 17: " * label_callback";
	N;
	s: 21: " * bundle_entity_type";
	s: 4: "menu";
	s: 12: " * bundle_of";
	N;
	s: 15: " * bundle_label";
	N;
	s: 13: " * base_table";
	s: 17: "menu_link_content";
	s: 22: " * revision_data_table";
	N;
	s: 17: " * revision_table";
	N;
	s: 13: " * data_table";
	s: 22: "menu_link_content_data";
	s: 11: " * internal";
	b: 0;
	s: 15: " * translatable";
	b: 1;
	s: 19: " * show_revision_ui";
	b: 0;
	s: 8: " * label";
	O: 48: "Drupal\Core\StringTranslation\TranslatableMarkup": 3: {
		s: 9: " * string";
		s: 16: "Custom menu link";
		s: 12: " * arguments";
		a: 0: {}
		s: 10: " * options";
		a: 0: {}
	}
	s: 19: " * label_collection";
	O: 48: "Drupal\Core\StringTranslation\TranslatableMarkup": 3: {
		s: 9: " * string";
		s: 17: "Custom menu links";
		s: 12: " * arguments";
		a: 0: {}
		s: 10: " * options";
		a: 0: {}
	}
	s: 17: " * label_singular";
	O: 48: "Drupal\Core\StringTranslation\TranslatableMarkup": 3: {
		s: 9: " * string";
		s: 16: "custom menu link";
		s: 12: " * arguments";
		a: 0: {}
		s: 10: " * options";
		a: 0: {}
	}
	s: 15: " * label_plural";
	O: 48: "Drupal\Core\StringTranslation\TranslatableMarkup": 3: {
		s: 9: " * string";
		s: 17: "custom menu links";
		s: 12: " * arguments";
		a: 0: {}
		s: 10: " * options";
		a: 0: {}
	}
	s: 14: " * label_count";
	a: 3: {
		s: 8: "singular";
		s: 23: "@count custom menu link";
		s: 6: "plural";
		s: 24: "@count custom menu links";
		s: 7: "context";
		N;
	}
	s: 15: " * uri_callback";
	N;
	s: 8: " * group";
	s: 7: "content";
	s: 14: " * group_label";
	O: 48: "Drupal\Core\StringTranslation\TranslatableMarkup": 3: {
		s: 9: " * string";
		s: 7: "Content";
		s: 12: " * arguments";
		a: 0: {}
		s: 10: " * options";
		a: 1: {
			s: 7: "context";
			s: 17: "Entity type group";
		}
	}
	s: 22: " * field_ui_base_route";
	s: 21: "entity.menu.edit_form";
	s: 26: " * common_reference_target";
	b: 0;
	s: 22: " * list_cache_contexts";
	a: 0: {}
	s: 18: " * list_cache_tags";
	a: 1: {
		i: 0;
		s: 22: "menu_link_content_list";
	}
	s: 14: " * constraints";
	a: 2: {
		s: 13: "EntityChanged";
		N;
		s: 26: "EntityUntranslatableFields";
		N;
	}
	s: 13: " * additional";
	a: 1: {
		s: 10: "token_type";
		s: 17: "menu_link_content";
	}
	s: 8: " * class";
	s: 60: "Drupal\menu_item_extras\Entity\MenuItemExtrasMenuLinkContent";
	s: 11: " * provider";
	s: 17: "menu_link_content";
	s: 14: " * _serviceIds";
	a: 0: {}
	s: 18: " * _entityStorages";
	a: 0: {}
	s: 20: " * stringTranslation";
	N;
}

As you can see there are two references to the uninstalled menu_item_extras:

s: 10: "views_data";
s: 48: "Drupal\menu_item_extras\MenuLinkContentViewsData";

and
s: 8: " * class";
s: 60: "Drupal\menu_item_extras\Entity\MenuItemExtrasMenuLinkContent";

Also a lot of the entity_keys are doubled (not sure if the menu_item_extras is the culprit here).

Is it safe to just delete the two references to the menu_item_extras module?

Comments

devarch created an issue. See original summary.

vladimiraus’s picture

vladimiraus’s picture

devarch’s picture

@VladimirAus I don't think they are related, please look at #11 on that bug. I was getting the same error message:

>  [notice] Update started: menu_link_content_post_update_make_menu_link_content_revisionable
>  [error]  Error: Class 'Drupal\menu_item_extras\Entity\MenuItemExtrasMenuLinkContent' not found in Drupal\Core\Entity\Sql\SqlContentEntityStorage->mapFromStorageRecords() (line 530 of /var/www/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php) #0 /var/www/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(449): Drupal\Core\Entity\Sql\SqlContentEntityStorage->mapFromStorageRecords(Array)

Very important to note that menu_item_extras was for a long time uninstalled and not present in the drupal module folder. So why the update process would search for a class in a non existing module?

A possible answer could be the #1 on this issue, when uninstalling the menu_item_extras it does not cleanly erase everything, which is true, as I have already shown in the key_value table.

vladimiraus’s picture

@devarch - that's exactly the case with other two reporters (including me): module is not installed or was removed but MenuItemExtrasMenuLinkContent definition is still present in value column of key_value table for the following record:

  • collection: entity.definitions.installed
  • name: menu_link_content.entity_type
sklompar’s picture

I am having the same issue. Menu Item Extras was installed to evaluate, then removed; database update fails after upgrading to Drupal 8.7.0.

sklompar’s picture

I was able to work around this by doing the following:

  1. Downloading the latest dev release of Menu Item Extras
  2. Installing and enabling the devel module
  3. Reinstalling Menu Item Extras; drush dre menu_item_extras
  4. Rebuild cache; drush cr
  5. Update database; drush updb
  6. Rebuild cache again; drush cr
  7. Uninstall Menu Item Extras; drush pm-uninstall menu_item_extras

I hope this can help anyone else dealing with this issue.

devarch’s picture

@sklompar Thanks for the info. I was also able to come around this by installing menu_item_extras on the drupal 8.6.14 before upgrading to 8.7.0 but that is a workaround not a fix. The main question still remains: why there are still references in the database to uninstalled modules.

vladimiraus’s picture

Reinstalling on 8.7.0 gives me the following error

In SqlContentEntityStorage.php line 847:
                                                                               
  SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'bundle' canno  
  t be null: UPDATE {menu_link_content} SET bundle=:db_update_placeholder_0,   
  uuid=:db_update_placeholder_1, langcode=:db_update_placeholder_2             
  WHERE id = :db_condition_placeholder_0; Array                                
  (                                                                            
      [:db_update_placeholder_0] =>                                            
      [:db_update_placeholder_1] => e2f10602-6806-4943-9f22-aa2f059b2aed       
      [:db_update_placeholder_2] => en                                         
      [:db_condition_placeholder_0] => 1                                       
  )                                                                            
                                                                               

In Connection.php line 689:
                                                                               
  SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'bundle' canno  
  t be null: UPDATE {menu_link_content} SET bundle=:db_update_placeholder_0,   
  uuid=:db_update_placeholder_1, langcode=:db_update_placeholder_2             
  WHERE id = :db_condition_placeholder_0; Array                                
  (                                                                            
      [:db_update_placeholder_0] =>                                            
      [:db_update_placeholder_1] => e2f10602-6806-4943-9f22-aa2f059b2aed       
      [:db_update_placeholder_2] => en                                         
      [:db_condition_placeholder_0] => 1                                       
  )                                                                            
                                                                               

In Statement.php line 59:
                                                                               
  SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'bundle' cannot be null 
nsciacca’s picture

Re-installing the module suppresses the error about the missing Class but doesn't fix the problems with upgrading.

Based on the original post information I was able to manual edit the row in key_value [collection=entity.definitions.installed
and name=menu_link_content.entity_type] as follows:

s:8:" * class";s:60:"Drupal\menu_item_extras\Entity\MenuItemExtrasMenuLinkContent";
s:8:" * class";s:47:"Drupal\menu_link_content\Entity\MenuLinkContent";

Then I was able to run the database updates without error. Not sure how this needs to be fixed in future versions so the module uninstalls clean, but hopefully this will help some folks stuck in a similar spot.

Update, I wrote an update hook for use in a custom module to do the basic replace:

/**
 * Fix for uninstalled Menu Item Extras Class that was left behind.
 */
function mymodule_update_8100() {

  // Load the menu_link_content.entity_type value and modify class.
  $connection = \Drupal::database();
  $query = $connection->select('key_value', 'k');
  $query->condition('k.collection', 'entity.definitions.installed');
  $query->condition('k.name', 'menu_link_content.entity_type');
  $query->fields('k', ['value']);
  $result = $query->execute();

  foreach ($result as $record) {
    $value = unserialize($record->value);
    $value->setClass('Drupal\menu_link_content\Entity\MenuLinkContent');
    $query = \Drupal::database()->update('key_value');
    $query->fields(['value' => serialize($value)]);
    $query->condition('collection', 'entity.definitions.installed');
    $query->condition('name', 'menu_link_content.entity_type');
    $query->execute();
    break;
  }

}
vladimiraus’s picture

I ended up removing all DB entries for menus and then manually entering them after updating to 8.7
Here's SQL


DELETE FROM menu_tree
 WHERE id LIKE 'menu_link_content:%';

TRUNCATE TABLE menu_link_content;
TRUNCATE TABLE menu_link_content_data;

demonde’s picture

@nsciacca: Thanks. The update in #11 works but does not remove

s: 10: "views_data";
s: 48: "Drupal\menu_item_extras\MenuLinkContentViewsData";

which is stated in the issue summary.

nsciacca’s picture

@demonde You're right. I wasn't getting any specific errors with that handler in place so I didn't investigate further. When the system calls getClassHandler('views_data') on the menu_link_content entity type actually returns 'null' because the class doesn't exist when the menu_item_extras module is uninstalled. We can't remove this handler because there's no remove method, but we can set it to null to remove all traces of the menu_items_extra. Here's an updated function to do so, if you've already run the one above, you can increase the update number and re-run, no harm will be done.

/**
 * Fix for uninstalled Menu Item Extras Class that was left behind.
 */
function mymodule_update_8100() {

  // Load the menu_link_content.entity_type value and modify class.
  $connection = \Drupal::database();
  $query = $connection->select('key_value', 'k');
  $query->condition('k.collection', 'entity.definitions.installed');
  $query->condition('k.name', 'menu_link_content.entity_type');
  $query->fields('k', ['value']);
  $result = $query->execute();

  foreach ($result as $record) {
    $value = unserialize($record->value);

    // Update class if still using menu_item_extras.
    if ($value->getClass() == 'Drupal\menu_item_extras\Entity\MenuItemExtrasMenuLinkContent') {
      $value->setClass('Drupal\menu_link_content\Entity\MenuLinkContent');
      $update = TRUE;
    }

    // Set views_data handler to null if using menu_item_extras.
    $handler_classes = $value->getHandlerClasses();
    if (!empty($handler_classes['views_data']) && $handler_classes['views_data'] == 'Drupal\menu_item_extras\MenuLinkContentViewsData') {
      $value->setHandlerClass('views_data', NULL);
      $update = TRUE;
    }

    // Make SQL call to re-save entity type.
    if (isset($update)) {
      $query = \Drupal::database()->update('key_value');
      $query->fields(['value' => serialize($value)]);
      $query->condition('collection', 'entity.definitions.installed');
      $query->condition('name', 'menu_link_content.entity_type');
      $query->execute();
    }

    break;
  }

}
demonde’s picture

Thanks, works nice.

back from 7’s picture

This module completely broke all of my menu editing capabilities. There should be a warning about installing this module. I feel I have just lost an entire days work because this module is causing havoc on the menu system and there seems to be no clear way to fix this (easily)

DO NOT INSTALL THIS MODULE - should be a warning on the project page....

devarch’s picture

StatusFileSize
new1.4 KB

@joedevdrupal You are right! With the latest version (2.5) all hell breaks loose. What worked before to get around this issue (see #9) doesn't work anymore, trying to install menu_item_extras on drupal 8.6.15 (that had the problem in the database from the initial report) to be able to upgrade to drupal 8.7.2, spews all sorts of errors that I don't have the time, nor the drive to investigate further.

Is menu_item_extras 2.5 not compatible with Drupal 8.6 line? Should the maintainers at least say something about this in the release notes if not putting the dependency in the composer file?

Anyway, to fix the initial problem, if you have a Drupal that had at some point menu_item_extras installed and now you want to upgrade to Drupal 8.7 and can't, you can use the code from #14. I have place it in a standalone script since you don't need it to run it more than once and I have attached it for easy access.

Download it, rename it from txt to php, put it in your drupal root folder, then execute it with drush scr command.

I have done this and then the upgrade from Drupal 8.6.15 to 8.7.2 went smoothly, without any errors. Thank you @nsciacca for taking the time to provide this script.

RmrJmrGrl’s picture

Thanks, devarch. #17 fixed it for me. Glad to have a solution!

alexpertsi’s picture

Hello, I have installed Menu Item Extra module, on drupal 8.7.1 installation, but finally I did my work in a different way so I had to uninstall it.
After unstalling it, I saw an error report on /admin/reports/status

"ENTITY/FIELD DEFINITIONS
Mismatched entity and/or field definitions
The following changes were detected in the entity type and field definitions.
Custom menu link
The View mode field needs to be uninstalled."

I tried many ways to get rid of it, also #17, but nothing...

Any help would be appreciated...

devarch’s picture

@alexpertsi You might encounter another problem than the one described in this issue. Please have in mind that Drupal 8.7.0 had some serious bugs that were NOT fixed in 8.7.1. The 8.7.1 was a security release only.

If I were you I would try upgrading to 8.7.2 and see if the error gets fixed, or, even better, start again on 8.7.2.

alexpertsi’s picture

Hello @devarch and thank you,
I've already upgraded to 8.7.2 but the error is still not fixed...
and its very complicated (enormous content and menu items) to start it again...

gcaudle’s picture

Really annoyed at this one. I simply tested this module, decided against it, then after uninstalling I have multiple WSOD messages on any menu editing or adding process. In the midst of moving a huge high traffic site from 7 to 8, having a menu items add-on break core menu functionality is the last thing I need or would have expected. This is ridiculous.

Update: Upgraded to 8.7.3, followed #11 in the database, then ran uninstall twice. It failed on first one, succeeded on the second try. I seem to have all menu functionality back now. However, this process did delete a lot of my menu items on the main menu. Easier to rebuild those than fight with it though, at least.

alexpertsi’s picture

StatusFileSize
new1.39 KB

Ok, Menu item extras uninstalled cleanly (I hope), on drupal 8.7.3
with the use of #14 (Thank you nsciacca!) code.
I simply installed the remove_menu_extras.zip custom module based on #14
and the error is gone!

semkulych’s picture

StatusFileSize
new1.07 KB

Hi, everyone!
I had added the test coverage for this case. After uninstalling of the module test check entity type definition and expects that classes provided by the module not set.
After running this test locally looks like entity updates on uninstall phase going correct as this issue can't be reproduce now.
As a recommendation how to fix the errors in such case, try to install and uninstall this module again.

semkulych’s picture

Status: Active » Needs review

  • ozin committed 5142e95 on 8.x-2.x authored by -t0r-
    Issue #3052746 by -t0r-, devarch, alexpertsi: Menu item extras doesn't...
ozin’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

runzipel’s picture

i had to

drush config-delete core.entity_form_display.menu_link_content.mie-demo-base-menu.default
drush config-delete core.entity_form_display.taxonomy_term.mie_demo_content.default
drush config-delete core.entity_view_display.menu_link_content.mie-demo-base-menu.banner
drush config-delete core.entity_view_display.menu_link_content.mie-demo-base-menu.default
drush config-delete core.entity_view_display.menu_link_content.mie-demo-base-menu.terms
drush config-delete core.entity_view_display.taxonomy_term.mie_demo_content.default
drush config-delete core.entity_view_mode.menu_link_content.banner
drush config-delete core.entity_view_mode.menu_link_content.terms
drush config-delete field.field.taxonomy_term.mie_demo_content.field_mie_image
drush config-delete field.storage.taxonomy_term.field_mie_image
drush config-delete image.style.mie_demo_teaser
drush config-delete taxonomy.vocabulary.mie_demo_content

the submitted fix did not resolve my problem.
Menu Item Extras Demo Base did not install/uninstall correct. So only resulution for me was to delete active config.
After this update from drupal 8.6.13 to 8.8.0 did work.
switched to en as default on multisite setup.