Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4016956
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T09:48:10+00:00 2026-05-20T09:48:10+00:00

/** * Implementation of hook_menu_alter(). */ function joke_menu_alter(&$callbacks) { // If the user does

  • 0
/**
 * Implementation of hook_menu_alter().
 */
function joke_menu_alter(&$callbacks) {
  // If the user does not have 'administer nodes' permission,
  // disable the joke menu item by setting its access callback to FALSE.
  if (!user_access('administer nodes')) {
    $callbacks['node/add/joke']['access callback'] = FALSE;
    // Must unset access arguments or Drupal will use user_access()
    // as a default access callback.
    unset($callbacks['node/add/joke']['access arguments']);
  }
}

The above function is from the pro development drupal. I can’t understand it well. Why must I unset the access arguments (unset($callbacks['node/add/joke']['access arguments']);)?

Thank you.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T09:48:10+00:00Added an answer on May 20, 2026 at 9:48 am

    That entire example seems broken and bad. In short, a joke. First, let me answer your question, then I’ll go on to explain why you shouldn’t follow that example in practice.

    From includes/menu.inc:

    if (!isset($item['access callback']) && isset($item['access arguments'])) {
      // Default callback.
      $item['access callback'] = 'user_access';
    }
    

    Unsetting the access callbacks when you no longer need them (relying on a boolean now, after all) prevents the over-clever logic in Drupal’s routing system from slapping in user_access() just so it has something to do.

    Now, on to why that’s bad code.

    hook_menu() and hook_menu_alter() are both run on cache clear (more specifically when the menu routing system is rebuilt). This means that the permissions of whichever user hits the site to rebuild the menus will be hard-coded into menu routing behaviors. This is a very bad and inconsistent arrangement.

    If you want to block access to a path based on a permission, you need to change the callback to something that will test for that permission. Then when the menu is rebuilt, it will check the new callback function per page load to see if the current user should be granted permission.

    A simple example of this might look like:

    /**
     * Implementation of hook_menu_alter().
     */
    function joke_menu_alter(&$items) {
      $items['node/add/joke']['access callback'] = 'user_access';
      $items['node/add/joke']['access arguments'] = array('administer nodes');
    }
    

    Now we have a function which takes the node/add/joke path and declares that the only thing that matters is whether or not the user has administer nodes permission. Of course, that’s a little more limited than the apparent intentions of the example, which were to preserve the existing access controls, but also require the user to have administer nodes permission.

    That is also fixable, but is more complicated. To borrow some concepts from the Spaces project:

    /**
     * Implementation of hook_menu_alter().
     */
    function joke_menu_alter(&$items) {
      $path = 'node/add/joke';
      $items[$path]['access arguments'][] = $items[$path]['access callback'];
      $items[$path]['access callback'] = 'joke_menu_access';
    }
    
    function joke_menu_access() {
      $args = func_get_args();
      $access_callback = array_pop($args);
      $original_access = call_user_func_array($access_callback, $args);
      return $original_access && user_access('administer nodes');
    }
    

    We have successfully wrapped the original access callback in a new access callback, to which we can add whatever additional logic we need.

    Note that in the last two function examples, I used the $path variable to keep the code simple. I also separated $original_access to it’s own line and had it checked first, in practice I would check user_access() first as it would almost certainly be more performant than whatever happens in the original access callback.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

What is a good implementation of a IsLeapYear function in VBA? Edit: I ran
I have a page that is definitely not a form but I need to
I have a problem with the following implementation of hook_cron in Drupal 6.1.3. The
I have constructed a set of nodes. After running them through node_save() , I
I've created an implementation of the QAbstractListModel class in Qt Jambi 4.4 and am
.Net's implementation of HTTP is ... problematic. Beyond some issues in compliance with HTTP/1.0,
Do you know any implementation / technique which would provide similar behavior as Viewstate
Here is my short implementation of Russian Peasant Multiplication . How can it be
I'm writing an implementation of the XXTEA encryption algorithm that works on streams, ie,
I'm writing an implementation of a virtual machine in C#, and I need to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.