I have a couple custom modules which use data generated from the profile module to change each user's experience on my site. So, when I upgraded our installation to 5.1, I very quickly noticed that the profile module now stores profile data in the "data" comumn of the user table instead of in the "profile_values" table. Although I was a bit frustrated that this change hadn't been documented, I quickly got over it, changed my code to use the global "$user" variable and "user_load()" and "user_save()", and went on about my day. However, I began to notice some weird things happening, and after some research, have come to the conclusion that the following is happening:

1. When a user registers, all the "profile" information filled out in the registration form is saved to the "data" column of the "user" table.
2. When a user edits his/her profile, all the data from whichever "category" page they submit is removed from this field and inserted (for the first time) into the "profile_values" table.
3. If and when an administrator edit's a user's profile, the same thing happens as in #2
4. If an administrator creates a user while he/she [the admin] is logged in, all the profile data from the administrative registration form is inserted into the "profile_values" table, and none of it is saved to the "data" column of the "user" table

I'm sure you can imagine how difficult it is to work with not knowing where certain data is at any given time, and where it should be updated to or deleted from, etc... I am quite willing to give you any information that you need in order to help get this solved expediently.

System information:
Windows XP Pro SP2
Apache 2.2.2
PHP 4.4.2

Thank you!

Comments

denver.root’s picture

Priority: Normal » Critical

Sorry for a second post, but I realized that while this bug is still operating, my website is in maintenance mode, and no one can access it, so I changed the priority to "critical". Please understand that I have customers all over the United States who are paying to be able to use my website, and are quite unhappy with it being down...

janosch’s picture

I'm listening in on this one as well. I have issues concerning this as well.

I tried to edit my version so i could get some of the profile fields added to my "og" subscription email that is sent out. I tried to collect the information in any possible way i could imagine, but it seems the data is stored somehow in variable that i can't find. (not "global $user"). The information is not available in the data field or the profile_value fields at the time the mail is sent.

denver.root’s picture

Here's some more information (warning, it's quite detailed):

When a user is authenticated upon login, the "$user" object is built by the "user_load()" function, and it actually gets all the information from the profile module, as well as a few other places. However, this is the only time that all the user's data is available. For every other page load and pass through the Drupal code (in this session, however long the cookie lasts), the "$user" object is built in "session.inc", [apparently] _before_ the "user" module is loaded. Because of this, "session.inc" does not have access to the "user_load()" function and simply queries two tables in order to build the "$user" object (it queries the "user" and "sessions" tables), which populates the same global variable, "$user", with insufficient data, thus creating the noted inconsistency, and lots of potential problems.

I have been using the Komodo IDE application to do some in-depth debugging of this issue, and the following is a summary of my results:

  • When a user logs in, "$user" is created correctly and contains all predicted user data, this is done through the "user_load()" function
    • This happens on the first "pass" through the Drupal code, unless another module intercepts the page load before the login form is processed and halts or redirects the load process
    • Callstack:
      user.module, line 966, in user_authenticate
      "          , line 929, in user_login_validate
      form.inc, line 0, in call_user_func_array
      "       , line 575, in _form_validate
      "       , line 400, in drupal_validate_form
      "       , line 253, in drupal_process_form
      
      [Common Callstack 1]
      
      "       , line 80, in drupal_get_form
      user.module, line 551, in user_block
      module.inc, line 0, in call_user_func_array
      "         , line 386, in module_invoke
      block.module, line 689, in block_list
      theme.inc, line 1013, in theme_blocks
      "        , line 0, in call_user_func_array
      "        , line 170, in theme
      phptemplate.engine, line 171, in phptemplate_page
      theme.inc, line 0, in call_user_func_array
      "        , line 170, in theme
      index.php, line 33, in {main}
      
      [/Common Callstack 1]
  • Then "hook_user($type='login')" is invoked
    • This happens on the same "pass" through the code
    • Callstack:
      [Common Callstack 2]
      
      user.module, line 955, in user_login_submit
      form.inc, line 0, in call_user_func_array
      "       , line 428, in drupal_submit_form
      "       , line 258, in drupal_process_form
      (Insert Common Callstack 1 from above)
      
      [/Common Callstack 2]
  • Then my login code is called/"invoked" by the hook described above
    • Same "pass" still
    • Callstack:
      myModule.module, line 12, in myModule_user
      user.module, line 22, in user_module_invoke
      (Insert Common Callstack 2 from above)
  • My code (myModule.module, ~line 12) calls "drupal_goto(myModule_myCustomFunction)"
  • Begin Second "Pass" through Drupal's code for this logical request (e.g., the page is still loading from the end user's perspective, but Drupal is running through all of its code from the top all over again)
  • The variable "$user" is created, but this time not through the "user_load()" function. As described above (before this debugging report), _this_ time, the "$user" object is created in the "session.inc" file, apparently before the "user" module has been loaded; thus, since "user_load()" is not available to call, "session.inc" simply runs a SQL query on the db to get the basic user info, but Drupal doesn't attempt to get the rest of the user data later in the load process. This is the root of the bug this report is making note of.
    • This happens on the second "pass" through the Drupal code during the initial login request, but for _all_ subsequent requests in this session, this happens _first_, and the "$user" variable is never given all the correct data
    • Callstack:
      session.inc, line 32, in sess_read
      session.inc, line 0, in session_start
      bootstrap.inc, line 811, in _drupal_bootstrap
      "            , line 771, in drupal_bootstrap
      index.php, line 13, in {main}

Please note that I haven't found a way to copy/paste data out of the Komodo debugger, so all of the above is hand-typed; please excuse any typos.

Anyways, this gives us a much better look at what is going on, and where the problem is (line 32 of session.inc). Possible solutions include, but are obviously not limited to having the Drupal core rebuild the "$user" object later in the load process, or rewriting some of the process to give "session.inc" access to "user_load()". It is obvious that the inconsistency in the value and contents of the "$user" variable, which a significant number of modules (core and contrib) rely on for information, must be corrected. I have changed part of my custom module to run its own "user_load()" in order to work around the bug for now, but this is aweful coding, since "$user" is supposed to already be built for the current user...

Please let me know how I can provide more information or help in getting this bug patched, as it appears to be a part of the general distribution of Drupal 5.1, and thus may result in untold numbers of bugs, and it will likely not always be evident that this is the cause.
Thank you.
Denver Root

denver.root’s picture

Umm, I'm sorry; is someone going to review this? I was under the impression that this is where I should report bugs, and that action would be taken to remedy the issue...

Please correct me if I am handling this the wrong way.

webchick’s picture

I actually believe the behaviour you describe in #3 (thanks for the very detailed bug report) is "by design"...

We don't do a full user_load in session.inc because it's very expensive. Rather, it only loads the bear user properties in order to maintain the session, and modules are expected to call user_load explicitly when they need the full range of data.

I know this has come up before as a point of confusion. We probably need some better docs for the user_load function or something...

profile module saving data to the user.data field though sounds completely wrong. Are you able to replicate this behaviour on a clean install of just core and no contributed/custom modules?

denver.root’s picture

Yes.
Following your prompt, I setup a new site with a new database, logged in (after creating the first user), enabled the profile module, and added a single text-field with the [paraphrased] checkboxes "required" and "on registration form". There are no contrib or custom modules enabled for this site.
I then did some testing, and the exact four things I noted in the creation of the issue (numbered 1-4 above) still behave the exact way in this [clean] installation of Drupal 5.1.

Thoughts? Do you need more info? I could send you a dump of my db (small, since it's empty) and a copy of my drupal installation (minus private code in the sites dirs, since none of this will apply except for one settings.php file). If you'd like a callstack for the code that saves the profile data into the "user" table instead of profile_fields, just let me know.

Thank you!

stevenpatz’s picture

Priority: Critical » Normal
Patrick Nelson’s picture

Listening in on this too as it is a problem for several sites that I'm upgrading to 5.x. The whole issue behind profiles not appearing until they have been edited is quite a problem.

denney’s picture

I'm having the exact same problem here. I posted another issue about it before seeing this one.

Subscribing.

denney’s picture

I'm having the exact same problem here. I posted another issue about it before seeing this one.

Subscribing.

pancho’s picture

Status: Active » Closed (duplicate)