Hi

The API for hook_user says that elements can be inserted into $user and should be done so on 'load'. The following simple module demonstrates that information inserted into $user on 'load' doesn't survive by printing the information that should have been inserted into $user in a block. The 'specialstring' which is inserted into $user cannot be printed when the block is rendered.

<?php
function block_example_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      // This description is shown in the listing at admin/modules.
      return t('An example module showing how to define a block.');
  }
}

function block_example_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks[0]['info'] = t('Example: configurable text string');
      return $blocks;
    case 'configure':
      $form = array();
      if ($delta == 0) {
        $form['block_example_string'] = array(
          '#type' => 'textfield',
          '#title' => t('Block contents'),
          '#size' => 60,
          '#description' => t('This string will appear in the example block.'),
          '#default_value' =>
            variable_get('block_example_string',  t('Some example content.')),
        );
      }
      return $form;
    case 'save':
      if ($delta == 0) {
        variable_set('block_example_string', $edit['block_example_string']);
      }
      return;
    case 'view': default:
      switch ($delta) {
        case 0:
          $block['subject'] = t('Title of block #1');
          $block['content'] = block_example_contents(1);
          break;
      }
      return $block;
  }
}
function block_example_contents($which_block) {
global $user;
  if ($which_block == 1) {
    $output = variable_get('block_example_string',  t('A default value.'));
    $output .="<br />user name is : $user->name";
    $output .="<br />user special string is : $user->specialstring";
    return $output;
  }
}

function block_example_user($op, &$edit, &$user, $category = NULL) {
  switch ($op) {
    case 'load':
        $user->{specialstring} = "Hello World";
    break;
  }
}
?>

I also tried all of the following in vain:

        $user->specialstring = "Hello World";
        $user->{'specialstring'} = "Hello World";
        $user['specialstring'] = "Hello World";

I also loaded a clean system for drupal-cvs as of 10:30am PDT (GMT-8:00) on Jan 26 and the problem persists.

Mark

Comments

marknewlyn’s picture

I also tried 4.7-beta4 and it is still not working.

Mark

marknewlyn’s picture

Version: 4.7.0-beta3 » 4.7.0-beta4

Hi

I managed to get a confirmation of the behaviour from another user - see node/49385. It seems
that the information exists immediately after the module_invoke_all('load'... in user.module but later disappears.

The block module I uploaded still demonstrates the problem. It isn't possible to make the string added to the user object dispaly in the
block.

Help?!?

Mark

marcp’s picture

This is an email that I sent to the development mailing list, followed by Moshe's response:

> Should sess_read() call hook_user (via user_load)?
>
> This question came up due to a module developer's trouble maintaining
> user state across pages:
>
> http://drupal.org/node/49385
>
> I traced through what was happening and came across sess_read() in
> session.inc which loads up the global $user with the most recent user
> for the session with some code that looks a lot like what's in
> user_load(), but it doesn't ever call hook_user -- is this by design?
>
> Thanks,
>
> Marc
>
>

This is from Moshe:

the modules are not loaded during that time in the bootstrap. It is probably correct that the user object should get fully loaded by core later in the bootstrap.

sammys’s picture

Version: 4.7.0-beta4 » 4.7.0
Status: Active » Closed (fixed)

Core doesn't automatically load up module specific user data because it isn't required by most of the modules. This is by design and will remain that way.

A quote from killes, "You almost never need the extra data and it can be a lot of queries."

Issue closed.