Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 296506

trap for null titles in hook_menu to optimize DB

$
0
0

The database doesn't allow menu_router to have null titles for certain routes. The documentation for hook_menu has all kind of goody examples that are without titles. This creates a DB integrity constraint that isn't fatal but will slow things down if you have too many error messages piling up in the transaction.

This is so prevalent in contrib that I think it warrents a trap in _menu_router_save to ensure that the title is empty as opposed to null. This was causing many of my sites to throw 43 errors per route of the menu system (so save a node, hit, delete a entity hit, anything that writes / deletes an entity or field basically). This was silently killing performance of just about everything I do and as soon as I applied it instantly my universe of Drupal sites speed up dramatically.

https://api.drupal.org/api/drupal/modules%21system%21system.api.php/func... for docs reference. Patch coming

/**
 * Saves data from menu_router_build() to the router table.
 */
function _menu_router_save($menu, $masks) {
  // Delete the existing router since we have some data to replace it.
  db_truncate('menu_router')->execute();

  // Prepare insert object.
  $insert = db_insert('menu_router')
    ->fields(array(
      'path',
      'load_functions',
      'to_arg_functions',
      'access_callback',
      'access_arguments',
      'page_callback',
      'page_arguments',
      'delivery_callback',
      'fit',
      'number_parts',
      'context',
      'tab_parent',
      'tab_root',
      'title',
      'title_callback',
      'title_arguments',
      'theme_callback',
      'theme_arguments',
      'type',
      'description',
      'position',
      'weight',
      'include_file',
    ));

  $num_records = 0;

  foreach ($menu as $path => $item) {
    // avoid database integrity constraint fault
    if ($item['title'] == null) {
      $item['title'] = '';
    }
    // Fill in insert object values.
    $insert->values(array(
      'path' => $item['path'],
      'load_functions' => $item['load_functions'],
      'to_arg_functions' => $item['to_arg_functions'],
      'access_callback' => $item['access callback'],
      'access_arguments' => serialize($item['access arguments']),
      'page_callback' => $item['page callback'],
      'page_arguments' => serialize($item['page arguments']),
      'delivery_callback' => $item['delivery callback'],
      'fit' => $item['_fit'],
      'number_parts' => $item['_number_parts'],
      'context' => $item['context'],
      'tab_parent' => $item['tab_parent'],
      'tab_root' => $item['tab_root'],
      'title' => $item['title'],
      'title_callback' => $item['title callback'],
      'title_arguments' => ($item['title arguments'] ? serialize($item['title arguments']) : ''),
      'theme_callback' => $item['theme callback'],
      'theme_arguments' => serialize($item['theme arguments']),
      'type' => $item['type'],
      'description' => $item['description'],
      'position' => $item['position'],
      'weight' => $item['weight'],
      'include_file' => $item['include file'],
    ));

    // Execute in batches to avoid the memory overhead of all of those records
    // in the query object.
    if (++$num_records == 20) {
      $insert->execute();
      $num_records = 0;
    }
  }
  // Insert any remaining records.
  $insert->execute();
  // Store the masks.
  variable_set('menu_masks', $masks);

  return $menu;
}

Viewing all articles
Browse latest Browse all 296506

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>