You are here

Drupal 6 to 7 upgrade: "PHP Fatal error: Unsupported operand types in /usr/share/drupal7/includes/common.inc"

The scenario is a Drupal 6 website running on Debian GNU/Linux current stable is upgraded to Drupal 7 from backports in order to test its behaviour once the new Debian stable is released and Drupal 6 becomes unavailable.

On the Drupal 6 website there is a menu link created as a short-cut to log a user in and take them to the home page. This hides away the huge login block.

Path: user/login?destination=node
Menu link title: Login

Now the upgrade is performed. Once complete the menu link has to be re-enabled. Once this is done, and the user logs out, the web site is no longer available. A review of the /var/log/apache2/error.log Apache 2 error log shows the following.

[Sun Feb 24 23:56:10 2013] [error] [client 2a01:x:x:x:x:x:x:x] PHP Fatal error: Unsupported operand types in /usr/share/drupal7/includes/common.inc on line 2209

A search online could not find a solution to this problem but did reveal a couple of methods to diagnose this further. Editing /usr/share/drupal7/includes/common.inc, on line 2209, there is an assignment that expects an array. If we don't have an array, dump out what we do have instead. My changes are emphasised

    if ($options['query']) {
      // We do not use array_merge() here to prevent overriding $path via query
      // parameters.
      print_r($options);
      print_r($query);
      print_r($options['query']);
      print "\n--------------\n";
      if (!is_array($options['query'])) {
        $backtrace = debug_backtrace();
        var_export($backtrace);
        die();
      }
      $query += $options['query'];
    }

Now we can apply a workaround to access the web site again.

    if ($options['query']) {
      // We do not use array_merge() here to prevent overriding $path via query
      // parameters.
      if (!is_array($options['query'])) {
        $query = array('q' => 'node');
        $options['query'] = array('destination' => 'node');
      }
      $query += $options['query'];
    }

My ultimate fix was to patch the database directly, i.e.

update menu_links set options='a:2:{s:10:"attributes";a:1:{s:5:"title";s:5:"Login";}s:5:"query";a:1:{s:11:"destination";s:4:"node";}}' where link_title='Login';

Classifications: