2

I am working on creating a form with Autocomplete feature for the text field. This is the code I have so far..

    /**
     * Implementation of hook_menu()
     */
    function suggest_feature_menu() {  
      $item['suggest_feature/autocomplete'] = array(   
        'page callback' => '_suggest_feature_autocomplete',   
        'access arguments' => user_access('access example autocomplete'),
        'type' => MENU_CALLBACK
        ); 

        return $item;
      }

    /**
     * Implementation of autocomplete
     */

 function suggest_feature_autocomplete($string){

    $query = db_select('node', 'n')
    ->fields('n', array('nid', 'title'))
    ->condition('status', 1) //Published.
    ->condition('type', array('e_hood', 'oranization'))
    ->condition('n.title','%'.db_like($string) . '%', 'LIKE')
    ->orderBy('created', 'DESC') //Most recent first.
    ->range(0,10)
    ->execute();

    $items = array();

    foreach ($query as $node){
       $items[$node->nid] = check_plain($node->title);
    }

    return drupal_json_output($items);

  }

    /**
     * Implementation of hook_form()
     */


    function suggest_feature_form($form_state) {
     $form = array();

       $form['test_item'] = array(   
        '#type' => 'textfield',   
        '#autocomplete_path' => 'suggest_feature/autocomplete'  
        ); 

      return $form;
    }

all my functionality works but i get a warning which says

Warning: Invalid argument supplied for foreach() in menu_unserialize() (line 393 of C:\xampp\htdocs\drupal7\includes\menu.inc).

Please let me know how to solve this. Is this an issue with my code ? Also I use superfish menu's in my drupal. Is this related ?

1

This is a bit of a shot in the dark, but the 'title' property is required for items defined in hook_menu(), and it's missing in your code.

I can think of a couple of scenarios where a lack of the 'title' property might cause this error in menu_unserialize() so it's worth adding it to see if that helps. Remember to flush the caches once you make the code change.

| improve this answer | |
  • Thanks for your reply but it didn't work.. – Jayaram May 1 '12 at 17:34
  • Also do you know how to filter autocomplete results based on type ? – Jayaram May 1 '12 at 18:46
2

There are three functions calling menu_unserialize(), the function for which the error is reported:

  • menu_get_item() uses it in the following code

      if ($router_item['access']) {
        $router_item['map'] = $map;
        $router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $map), array_slice($map, $router_item['number_parts']));
        $router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map), array_slice($map, $router_item['number_parts']));
      }
    
  • _menu_check_access() uses it in the following code

    $arguments = menu_unserialize($item['access_arguments'], $map);
    
  • _menu_item_localize() uses it in the following code

    $item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map));
    

The Invalid argument supplied for foreach() error simply means that foreach() is getting a value that is not an array. With the code you are showing, that is happening only for $arguments = menu_unserialize($item['access_arguments'], $map); since you are setting $item['suggest_feature/autocomplete']['access arguments'] to TRUE when it should be an array.

In your case, the code should be the following one.

/**
 * Implementation of hook_menu()
 */
function suggest_feature_menu() {  
  $item['suggest_feature/autocomplete'] = array(   
    'page callback' => '_suggest_feature_autocomplete',   
    'access arguments' => array('access example autocomplete'),
    'type' => MENU_CALLBACK
  ); 

  return $item;
}

For Drupal that code would be equivalent to the following one.

/**
 * Implementation of hook_menu()
 */
function suggest_feature_menu() {  
  $item['suggest_feature/autocomplete'] = array(   
    'page callback' => '_suggest_feature_autocomplete',
    'access callback' => 'user_access',
    'access arguments' => array('access example autocomplete'),
    'type' => MENU_CALLBACK
  ); 

  return $item;
}

You can understand now why your code is wrong.

It's not the access arguments that you can set to a boolean value, but the access callback. See what the documentation for hook_menu() says. (Emphasis is mine.)

  • "access callback": A function returning TRUE if the user has access rights to this menu item, and FALSE if not. It can also be a boolean constant instead of a function, and you can also use numeric values (will be cast to boolean). Defaults to user_access() unless a value is inherited from the parent menu item; only MENU_DEFAULT_LOCAL_TASK items can inherit access callbacks. To use the user_access() default callback, you must specify the permission to check as 'access arguments' (see below).

And for the access arguments, it says:

  • "access arguments": An array of arguments to pass to the access callback function, with path component substitution as described above. If the access callback is inherited (see above), the access arguments will be inherited with it, unless overridden in the child menu item.
| improve this answer | |
0

Your "access argument" in hook_menu must be an array e.g "access argument" => array() in your custom module.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.