Hello,

I am trying to convert a module from 5.x to 6.x. I changed the hook_menu function and thats when I get the Invalid argument supplied foreach() in menu.inc Line 259. Below is the module code that is being ported to 6.x:


// $Id: warcraft_itemstats.module,v 1.35 2007/05/24 20:55:34 thoughtlover Exp $
drupal_add_js( variable_get('warcraft_itemstats_js_uri', 'itemstats/overlib/overlib.js'));
drupal_add_css( variable_get('warcraft_itemstats_css_uri', 'modules/warcraft_itemstats/drupal_itemstats.css'),'module','all',false);


function warcraft_itemstats_help($section) {
  switch ($section) {
    case 'admin/help#warcraft_itemstats':
      $output = '<p>'. t('The warcraft_itemstats module automatically converts [item], [itemico], and [itememb], [itembi] bbcode tags into item views for warcraft.') .'</p>';
      return $output;
    case 'admin/modules#description':
      return t('The warcraft_itemstats module automatically converts [item], [itemico], [itememb], and [itembi] bbcode tags into item views for warcraft.');
  }
}

function warcraft_itemstats_filter_tips($delta, $format, $long = false) {
  return t('[item], [itemico], [itememb], and [itembi] tags are automatically turned into warcraft items.');
}

function warcraft_itemstats_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'no cache':
          return TRUE;
    case 'list':
      return array(0 => t('Itemstat filter'));

    case 'description':
      return t('[item], [itemico], [itememb], and [itembi] tags are automatically turned into warcraft items.');

    case 'process':
      $filename = variable_get('warcraft_itemstats_dir', $_SERVER['DOCUMENT_ROOT'] . variable_get('warcraft_itemstats_uri', 'itemstats/')) . variable_get('warcraft_itemstats_php', 'drupal_itemstats.php');
      if (file_exists($filename)){
        define(path_itemstats, preg_replace("/\/$/","",variable_get('warcraft_itemstats_uri', 'itemstats/')));
        include_once($filename);
        return itemstats_parse($text);
      }
      else
        return $text;
    default:
      return $text;
  }
}

/**
 * Implementation of hook_menu
 */
function warcraft_itemstats_menu() {
  $items = array();
  
  $items['admin/settings/warcraft_itemstats'] = array(
  	'title' => t('Warcraft Itemstats settings'),
	'description' => t('Configure settings for embedding Warcraft Itemstats into Drupal.'),
	'page callback' => 'drupal_get_form',
	'page arguments' => array('warcraft_itemstats_admin_settings'),
	'access arguments' => array('administer site configuration'),
	'type' => MENU_NORMAL_ITEM,
  );
  
  $items['admin/content/warcraft_itemstats_sync'] = array(
  	'title' => t('View Warcraft Itemstat database'),
	'description' => t('Allows Items to be resynched between Warcraft Itemsync and Item sites.'),
	'page callback' => 'warcraft_itemstats_sync',
	'access arguments' => array('administer content'),
  );
  
  $items['warcraft-itemstats/update'] = array(
  	'title' => 'Test',
	'description' => 'Test',
	'page callback' => 'warcraft_itemstats_update',
	'access arguments' => TRUE,
	'type' => MENU_CALLBACK,
  );
  
  return $items;
  /*
  $items = array();
  $items[] = array(
    'path' => 'admin/settings/warcraft_itemstats',
    'title' => t('Warcraft Itemstats settings'),
    'description' => t('Configure settings for embedding Warcraft Itemstats into Drupal.'),
    'callback' => 'drupal_get_form',
    'callback arguments' => 'warcraft_itemstats_admin_settings',
    'access' => user_access('administer site configuration'),
    'type' => MENU_NORMAL_ITEM,
    );
  $items[] = array(
    'path' => 'admin/content/warcraft_itemstats_sync', 
    'title' => t('View Warcraft Itemstat database'),
    'description' => t('Allows Items to be resynched between Warcraft Itemsync and Item sites.'),
    'callback' => 'warcraft_itemstats_sync',
    'access' => user_access('administer content'),
    );
  $items[] = array(
    'path' => 'warcraft-itemstats/update', 
    'title' => t('Test'),
    'description' => t('Test.'),
    'callback' => 'warcraft_itemstats_update',
    'access' => TRUE,
    'type' => MENU_CALLBACK,
    );
  return $items;
  */
} 

function warcraft_itemstats_update() {
    if (isset($_GET['destination']))
      $destination = $_GET['destination'];
    else
      $destination = '';
    if (isset($_GET['item']))
      $item = $_GET['item'];
    else
      drupal_goto($destination);

    require_once( variable_get('warcraft_itemstats_dir', 'itemstats/') . 'config.php');
    require_once( variable_get('warcraft_itemstats_dir', 'itemstats/') . 'itemstats.php');

    $item_stats = new ItemStats(false, 1);
    if ($item_stats->connected == true)
    {
        $item_stats->updateItem(urldecode(urldecode($item)));
    }

    drupal_goto($destination);
}

function warcraft_itemstats_sync() {
  $myhtml = '';
  require_once( variable_get('warcraft_itemstats_dir', 'itemstats/') . 'config.php');
  require_once( variable_get('warcraft_itemstats_dir', 'itemstats/') . 'itemstats.php');
  require_once( variable_get('warcraft_itemstats_dir', 'itemstats/') . 'drupal_itemstats.php');
  require_once( variable_get('warcraft_itemstats_dir', 'itemstats/') . 'includes/sqlhelper.php');

  $myhtml = ""; //"<table>";
  $text = "";

  $sql = new SqlHelper(dbhost, dbname, dbuser, dbpass);
  if ($sql->connected == false)
      return t('Database connect error');

  $result = $sql->query("SELECT item_id, item_name FROM " . item_cache_table . " ORDER BY item_name ASC");

  $text .= '<table border="1">';

  while ($item = $sql->fetch_record($result))
  {
    $item_name = $item['item_name'];
    $item_id = $item['item_id'];
    if ($item_id == 0)
      $item_link = l('Update', 'warcraft-itemstats/update', array(), 'item=' . urlencode($item_name) . '&destination=' .  urlencode('admin/content/warcraft_itemstats_sync') );
    else
      $item_link = l('Update', 'warcraft-itemstats/update', array(), 'item=' . urlencode($item_id) . '&destination=' .  urlencode('admin/content/warcraft_itemstats_sync') );

    if (function_exists('itemstats_parse_one_item'))
    {
      $html = itemstats_parse_one_item($item_name, preg_replace("/\/$/","",variable_get('warcraft_itemstats_uri', 'itemstats/')));
    }
    else
      $html = $item_name;

    $text .= '<tr>';
    $text .= '  <td>';
    $text .=     $html;
    $text .= '  </td>';
    $text .= '  <td>';
    $text .= "    &nbsp;&nbsp;" . $item_link . "&nbsp;&nbsp;";
    $text .= '  </td>';
    $text .= '<tr>';
  }
  $myhtml = $text;
  $sql->close();

  $myhtml .= "</table>";

  drupal_set_title(t('Warcraft Itemstat Database'));
  $myhtml .= "<br/>&nbsp;&nbsp;=> <a href='" . variable_get('warcraft_itemstats_uri', 'itemstats/') . "clear_cache.php'>Clear unfound objects</a>";

  return t($myhtml);
}

/**
 * Implementation of hook_settings
 */
function warcraft_itemstats_admin_settings() {
  $output = '';
  $extra = l(t('More information about directory settings (including examples).'), 
    'admin/help/warcraft_itemstats');             
  $form['directory'] = array(
    '#type' => 'fieldset',
    '#title' => t('Directory settings'),
    '#description' => $extra,
    '#collapsible' => TRUE, 
    '#collapsed' => variable_get('warcraft_itemstats_valid', 0),
  );  
      
  $form['directory']['warcraft_itemstats_uri'] = array(
    '#type' => 'textfield',
    '#title' => t('URI of Itemstats'),
    '#default_value' =>  variable_get('warcraft_itemstats_uri', 'itemstats/'),
    '#size' => 64,
    '#maxlength' => 128,
    '#description' => t('URI of the Warcraft Itemstats directory from docroot.'),
  ); 

  $form['directory']['warcraft_itemstats_dir'] = array(
    '#type' => 'textfield',
    '#title' => t('Location of Itemstats'),
    '#default_value' => variable_get('warcraft_itemstats_dir', $_SERVER['DOCUMENT_ROOT'] . '/' . variable_get('warcraft_itemstats_uri', 'itemstats/')),
    '#size' => 64,
    '#maxlength' => 128,
    '#description' => t('Location of your Itemstats directory (absolute path or relative to the root 
                         directory of your Drupal installation).'),
  );  

  $form['directory']['warcraft_itemstats_php'] = array(
    '#type' => 'textfield',
    '#title' => t('Name of Itemstats Hook Script'),
    '#default_value' =>  variable_get('warcraft_itemstats_php', 'drupal_itemstats.php'),
    '#size' => 64,
    '#maxlength' => 128,
    '#description' => t('Name of the Warcraft Itemstats hook php script (inside Itemstats directory).'),
  ); 
  $form['directory']['warcraft_itemstats_js_uri'] = array(
    '#type' => 'textfield',
    '#title' => t('URI and Name of the Overlib JS'),
    '#default_value' =>  variable_get('warcraft_itemstats_js_uri', 'itemstats/overlib/overlib.js'),
    '#size' => 64,
    '#maxlength' => 128,
    '#description' => t('Location of the overlib tooltip script from docroot.'),
  ); 
  $form['directory']['warcraft_itemstats_css_uri'] = array(
    '#type' => 'textfield',
    '#title' => t('URI  and Name of the Itemstats CSS'),
    '#default_value' =>  variable_get('warcraft_itemstats_css_uri', 'modules/warcraft_itemstats/drupal_itemstats.css'),
    '#size' => 64,
    '#maxlength' => 128,
    '#description' => t('Location of the Warcraft Itemstats CSS template from docroot.<br/>(There is a custom one for Drupal named drupal_itemstats.css in the module directory)'),
  ); 
return system_settings_form($form);
}

Here is menu.inc lines 237-269:


/**
 * The menu system uses serialized arrays stored in the database for
 * arguments. However, often these need to change according to the
 * current path. This function unserializes such an array and does the
 * necessary change.
 *
 * Integer values are mapped according to the $map parameter. For
 * example, if unserialize($data) is array('view', 1) and $map is
 * array('node', '12345') then 'view' will not be changed because
 * it is not an integer, but 1 will as it is an integer. As $map[1]
 * is '12345', 1 will be replaced with '12345'. So the result will
 * be array('node_load', '12345').
 *
 * @param @data
 *   A serialized array.
 * @param @map
 *   An array of potential replacements.
 * @return
 *   The $data array unserialized and mapped.
 */
function menu_unserialize($data, $map) {
  if ($data = unserialize($data)) {
    foreach ($data as $k => $v) {
      if (is_int($v)) {
        $data[$k] = isset($map[$v]) ? $map[$v] : '';
      }
    }
    return $data;
  }
  else {
    return array();
  }
}

Comments

Greenparot’s picture

Just to add, I've done some debugging on the hook_menu and here is the $items array:


Array 
( 	
	[admin/settings/warcraft_itemstats] => 
		Array 
		( 
			[title] => Warcraft Itemstats settings 
			[description] => Configure settings for embedding Warcraft Itemstats into Drupal. 
			[page callback] => drupal_get_form 
			[page arguments] => 
				Array 
				( 
					[0] => warcraft_itemstats_admin_settings 
				) 
			[access arguments] => 1 
			[type] => 6 
		) 
	[admin/content/warcraft_itemstats_sync] => 
		Array 
		( 
			[title] => View Warcraft Itemstat database 
			[description] => Allows Items to be resynched between Warcraft Itemsync and Item sites. 
			[page callback] => warcraft_itemstats_sync 
			[access arguments] => 
				Array 
				( 
					[0] => administer content 
				) 
		) 
	[warcraft-itemstats/update] => 
		Array 
		( 
			[title] => Test 
			[description] => Test 
			[page callback] => warcraft_itemstats_update 
			[access arguments] => 1 
			[type] => 4 
		) 
)


tanoshimi’s picture

If i'm not mistaken...

  $items['warcraft-itemstats/update'] = array(
      'title' => 'Test',
    'description' => 'Test',
    'page callback' => 'warcraft_itemstats_update',
    'access arguments' => TRUE,
    'type' => MENU_CALLBACK,
  );
  

Should be:

  $items['warcraft-itemstats/update'] = array(
      'title' => 'Test',
    'description' => 'Test',
    'page callback' => 'warcraft_itemstats_update',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  
Greenparot’s picture

Ok thanks, that fixed the php warnings.

Can't seem to get the links working but thats another issue.

Greenparot’s picture

Status: Active » Fixed
Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.