I have managed to reproduce this bug with a stock install of Drupal 7.14 and the 2.x-dev (2012-Apr-26) version of privatemsg.

  1. Give users permission to disable private messages.
  2. Go to an edit user account page.
  3. Uncheck the box to enable private messages.
  4. Save.
  5. Go back to the same edit user account page.
  6. Check the box to enable private messages.
  7. Save.

At this point, an error like the following will be thrown:

PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'value' at row 1: UPDATE {pm_setting} SET value=:db_update_placeholder_0 WHERE ( (type = :db_condition_placeholder_0) AND (id = :db_condition_placeholder_1) AND (setting = :db_condition_placeholder_2) ); Array ( [:db_update_placeholder_0] => [:db_condition_placeholder_0] => user [:db_condition_placeholder_1] => 8 [:db_condition_placeholder_2] => disabled ) in privatemsg_set_setting() (line 3395 of /Volumes/Bullfrog/patrick/Sites/acquia-drupal/sites/all/modules/privatemsg/privatemsg.module).
The website encountered an unexpected error. Please try again later. 

I have reproduced this on a local MAMP development environment and on Pantheon's servers.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

seddonym’s picture

Status: Active » Needs review
FileSize
577 bytes

The problem here seems to be that sometimes privatemsg_set_setting() receives a boolean value for the setting, but the database schema specifies an integer value.

Specifically here's the call to privatemsg_set_setting() from within privatemsg_user_update(), which is what's called when the user updates whether or not they want to disable private messages.

    $current = privatemsg_is_disabled($account);
    $disabled = (!$edit['pm_enable']);
    $edit['pm_enable'] = NULL;

    // only perform the save if the value has changed
    if ($current != $disabled) {
      privatemsg_set_setting('user', $account->uid, 'disabled', $disabled);
    }

You'll see that the value of $disabled is boolean.

The attached patch includes a test in privatemsg_set_setting() to typecast any boolean values into integer values before inserting them into the database:

function privatemsg_set_setting($type, $id, $setting, $value) {

  // Sometimes the $value is provided as a boolean, but this causes a PDOException
  // if we try to insert it into the database.  Change it here to an integer.
  if (is_bool($value)) $value = (int)$value;
  ...

Status: Needs review » Needs work

The last submitted patch, privatemsg-no_reenable-1605190-1.patch, failed testing.

seddonym’s picture

Hmm that last patch failed testing, relating to privatemsg_filter module. Is it possible that these errors are present in the latest dev version anyway? Having had a brief look at the tests that failed I'd be surprised if the change I made would have caused these problems, though I could be wrong.

Still it's not a priority for me at the moment to get this fix working with privatemsg_filter module (which I don't use) so if anyone does use that module feel free to take a look!

Maks’s picture

In my case patch posted by seddonym works perfectly.
I have installed 7.x-2.x-dev

bogeyman’s picture

When disabling the users' private message, a new row is inserted to pm_setting table to mark that the user's private message is disabled. But where we try to re-enable it again, the row should be deleted which this module didn't do.
Here is the patch to fix the bug. I also add a new checking, if the edited user has no permission re-enable his/her private message, the administrator can't disable his/her private message.

bogeyman’s picture

Status: Needs work » Needs review
FileSize
3.3 KB

Re-submit the patch for automated testing.

ptmkenny’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, this fixed the issue for me.

Rosamunda’s picture

I can confirm that too. It works for me too.

Berdir’s picture

Status: Reviewed & tested by the community » Fixed

Sorry for the long wait, committed and pushed. Marking as fixed, please change to 6.x-2.x and re-open if the same error exists there as well.

Status: Fixed » Closed (fixed)

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