You are here

delete_menu_options.module in Delete menu options 7

Same filename and directory in other branches
  1. 6 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 check_markup(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_query("SELECT mlid, link_path FROM {menu_links} WHERE mlid = :mlid", array(
      ":mlid" => $item['mlid'],
    ))
      ->fetch();
    _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++;
  if ($recursion_counter > 10) {
    return array();
  }
  $childs = array();
  $childs_result = db_query("SELECT mlid, link_path FROM {menu_links} WHERE plid = :mlid", array(
    ":mlid" => $mlid,
  ))
    ->fetchAll();
  foreach ($childs_result as $child) {
    $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_result = db_query("SELECT * \n                          FROM {menu_links} \n                          WHERE (link_path = :alias AND mlid != :mlid)", array(
    ":alias" => $system_url,
    ":mlid" => $child->mlid,
  ))
    ->fetchAll();
  $other_url_links_count = count($other_url_links_result);

  // 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 = ':alias' AND mlid <> :mlid)", array(
      ":alias" => $alias,
      ":mlid" => $child->mlid,
    ))
      ->fetchAll();
    $other_alias_links_count = count($other_alias_links_result);
  }
  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.