You are here

delete_menu_options.module in Delete menu options 6

Same filename and directory in other branches
  1. 7 delete_menu_options.module

Provides extra options when deleting a menu item.

File

delete_menu_options.module
View source
<?php

/**
 * @file
 * Provides extra options when deleting a menu item.
 */

/**
 * Implements hook_help(). 
 */
function delete_menu_options_help($path, $arg) {
  switch ($path) {
    case 'admin/help#delete_menu_options':

      // Return a line-break version of README.txt.
      return filter_filter('process', 1, NULL, file_get_contents(dirname(__FILE__) . "/README.txt"));
  }
}

/**
 * Implements hook_form_alter().
 *
 * This hook adds 2 checkboxes which the user may select to delete child menu
 * items and/or the referenced node(s)."
 */
function delete_menu_options_form_alter(&$form, &$form_state, $form_id) {
  if ($form['#id'] === 'menu-item-delete-form') {
    if (user_access('administer nodes')) {
      $form['delete_menu_children']['#type'] = 'checkbox';
      $form['delete_menu_children']['#title'] = t('Delete all children of this menu.');
      $form['delete_menu_node']['#type'] = 'checkbox';
      $form['delete_menu_node']['#title'] = t('Delete nodes referenced by the menu items that will be deleted (orphaned nodes only).');
      $form['#submit'] = array(
        'delete_menu_options_item_form_submit',
      );
    }
  }
}

/**
 * Process menu delete form submissions.
 */
function delete_menu_options_item_form_submit($form, &$form_state) {
  $item = $form['#item'];

  // Check if we need to delete childs.
  if ($form_state['values']['delete_menu_children'] === 1) {
    $parent_mlid = $item['mlid'];
    $children = _delete_menu_options_get_menu_children($parent_mlid);
    foreach ($children as $child) {
      menu_link_delete($child['mlid']);
      if ($form_state['values']['delete_menu_node'] === 1) {
        _delete_menu_options_delete_node($child);
      }
    }
  }

  // Only delete the node of the parent menu item.
  if ($form_state['values']['delete_menu_children'] === 0 && $form_state['values']['delete_menu_node'] === 1) {
    $menu_item = db_fetch_array(db_query("SELECT mlid, link_path FROM {menu_links} WHERE mlid = %d", $item['mlid']));
    _delete_menu_options_delete_node($menu_item);
  }

  // Remove parent menu item.
  menu_link_delete($item['mlid']);
  $t_args = array(
    '%title' => $item['link_title'],
  );
  if ($form_state['values']['delete_menu_children'] === 1 && $form_state['values']['delete_menu_node'] === 1) {
    drupal_set_message(t('The menu item %title, its children and nodes have been deleted.', $t_args));
  }
  elseif ($form_state['values']['delete_menu_children'] === 1) {
    drupal_set_message(t('The menu item %title and its children have been deleted.', $t_args));
  }
  elseif ($form_state['values']['delete_menu_node'] === 1) {
    drupal_set_message(t('The menu item %title and its linked node have been deleted.', $t_args));
  }
  else {
    drupal_set_message(t('The menu item %title has been deleted.', $t_args));
  }
  watchdog('delete_menu', 'Deleted menu item %title.', $t_args, WATCHDOG_NOTICE);
  $form_state['redirect'] = 'admin/build/menu-customize/' . $item['menu_name'];
}

/**
 * Recursive function which returns all children menu items in an array.
 */
function _delete_menu_options_get_menu_children($mlid) {
  static $recursion_counter = 0;
  $recursion_counter++;

  // When the recursion counter is higher than 20 it is likely that we
  // have an endless loop in the menuitems
  if ($recursion_counter > 20) {
    return array();
  }
  $childs = array();
  $childs_result = db_query("SELECT mlid, link_path FROM {menu_links} WHERE plid = %d", $mlid);
  while ($child = db_fetch_array($childs_result)) {
    $childs[] = $child;
    $sub_childs = _delete_menu_options_get_menu_children($child['mlid']);
    $childs = array_merge($childs, $sub_childs);
  }
  return $childs;
}

/**
 * Function deletes the given node if no other menu_links references to it.
 * 
 * @param array $child 
 *   Menu item array.
 */
function _delete_menu_options_delete_node($child) {

  // Check if node is an orphan. We check system_url and alias.
  if ($child['link_path'] && strpos($child['link_path'], "node/") === 0) {

    // The link_path is a system url.
    $system_url = $child['link_path'];
    $alias = drupal_lookup_path("source", $child['link_path']);
    $nid = substr($child['link_path'], 5);
  }
  else {

    // link_path is an alias, get the system url.
    $alias = $child['link_path'];
    $system_url = drupal_lookup_path("source", $child['link_path']);
    if ($system_url && strpos($system_url, "node/") === 0) {
      $nid = substr($system_url, 5);
    }
  }

  // Check if this user is allowed to delete this node
  if (is_numeric($nid)) {
    $node = node_load($nid);
    if (!node_access('delete', $node)) {
      return;
    }
  }

  // Check for menu links to system url.
  $other_url_links_count = 0;
  $other_url_links_result = db_query("SELECT * \n                          FROM {menu_links} \n                          WHERE (link_path = '%s' AND mlid != %d)", $system_url, $child['mlid']);
  while (db_fetch_array($other_url_links_result)) {
    $other_url_links_count++;
  }

  // Check for menu links to alias.
  $other_alias_links_count = 0;
  if ($alias) {
    $other_alias_links_result = db_query("SELECT * \n                                  FROM {menu_links} \n                                  WHERE (link_path = '%s' AND mlid <> %d)", $alias, $child['mlid']);
    while (db_fetch_array($other_alias_links_result)) {
      $other_alias_links_count++;
    }
  }
  if ($other_url_links_count === 0 && $other_alias_links_count === 0) {
    if (is_numeric($nid)) {
      node_delete($nid);
    }
  }
}

Functions

Namesort descending Description
delete_menu_options_form_alter Implements hook_form_alter().
delete_menu_options_help Implements hook_help().
delete_menu_options_item_form_submit Process menu delete form submissions.
_delete_menu_options_delete_node Function deletes the given node if no other menu_links references to it.
_delete_menu_options_get_menu_children Recursive function which returns all children menu items in an array.