From 2a5524d95d5d8c3fced9f1cf227146dbbe7d2b95 Mon Sep 17 00:00:00 2001
From: Sascha Grossenbacher <saschagros@gmail.com>
Date: Thu, 5 May 2011 12:17:46 +0200
Subject: [PATCH] Issue #1089290 by Berdir: Added default and variable_get() fallback and migration for old pm disable settings.

---
 privatemsg.install |   16 ++++++++++++++++
 privatemsg.module  |   29 ++++++++++++++++++++++++++---
 privatemsg.test    |   20 +++++++++++++++++++-
 3 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/privatemsg.install b/privatemsg.install
index 6fed143..afbf809 100644
--- a/privatemsg.install
+++ b/privatemsg.install
@@ -731,6 +731,22 @@ function privatemsg_update_6205() {
 }
 
 /**
+ * Migrate settings from {pm_disable} and delete table.
+ */
+function privatemsg_update_6206() {
+  $ret = array();
+
+  $result = db_query('SELECT * FROM {pm_disable}');
+  while ($row = db_fetch_object($result)) {
+    privatemsg_set_setting('user', $row->uid, 'disabled', 1);
+  }
+
+  db_drop_table($ret, 'pm_disable');
+  return $ret;
+}
+
+
+/**
  * Checks if an index exists in the given table.
  *
  * @param $table
diff --git a/privatemsg.module b/privatemsg.module
index 440ba10..469cac5 100644
--- a/privatemsg.module
+++ b/privatemsg.module
@@ -1366,9 +1366,20 @@ function privatemsg_user($op, &$edit, &$account, $category = NULL) {
  * Hides the settings fieldset if there are no options to be displayed.
  */
 function privatemsg_account_fieldset_remove_if_empty($element) {
+  // If there are no children elements, deny access.
   if (count(element_children($element)) == 0) {
     $element['#access'] = FALSE;
   }
+  else {
+    // If there are elements, check if at least one of them is visible. Deny
+    // access.
+    foreach (element_children($element) as $key) {
+      if ($element[$key]['#type'] != 'value' && (!isset($element[$key]['#access']) || $element[$key]['#access'])) {
+        return $element;
+      }
+    }
+    $element['#access'] = FALSE;
+  }
   return $element;
 }
 
@@ -2875,6 +2886,10 @@ function privatemsg_privatemsg_header_info() {
 
 /**
  * Retrieve a user setting.
+ *
+ * First, the entries in {pm_setting} are loaded. If there is no value for the
+ * global, a variable with the name privatemsg_setting_$setting is also checked.
+ *
  * @param $setting
  *   Name of the setting.
  * @param $ids
@@ -2882,13 +2897,15 @@ function privatemsg_privatemsg_header_info() {
  *   ids for that type. The first key is the most specific (typically user),
  *   followed by optional others, ordered by importance. For example roles and
  *   then global.
+ * @param $default
+ *   The default value if none was found. Defaults to NULL.
  *
  * @return
  *   The most specific value found.
  *
  * @see privatemsg_get_default_settings_ids().
  */
-function privatemsg_get_setting($setting, $ids = NULL) {
+function privatemsg_get_setting($setting, $ids = NULL, $default = NULL) {
   $cache = &_privatemsg_setting_static_cache();
 
   if (empty($ids)) {
@@ -2927,6 +2944,12 @@ function privatemsg_get_setting($setting, $ids = NULL) {
     while ($row = db_fetch_object($result)) {
       $cache[$setting][$row->type][$row->id] = $row->value;
     }
+
+    // If there is no global default in the database, try to get one with
+    // variable_get().
+    if ($cache[$setting]['global'][0] === FALSE) {
+      $cache[$setting]['global'][0] = variable_get('privatemsg_setting_' . $setting, FALSE);
+    }
   }
 
   // Now, go over all cached settings and return the first match.
@@ -2938,8 +2961,8 @@ function privatemsg_get_setting($setting, $ids = NULL) {
     }
   }
 
-  // Nothing matched, return default.
-  return 0;
+  // Nothing matched, return the provided default.
+  return $default;
 }
 
 function privatemsg_set_setting($type, $id, $setting, $value) {
diff --git a/privatemsg.test b/privatemsg.test
index dadfc01..195ad1c 100644
--- a/privatemsg.test
+++ b/privatemsg.test
@@ -1265,7 +1265,6 @@ class PrivatemsgAPITestCase extends DrupalWebTestCase {
     $user = $this->drupalCreateUser(array('write privatemsg'));
     $user2 = $this->drupalCreateUser(array('write privatemsg'));
 
-
     // Create some global and role default settings.
     privatemsg_set_setting('global', 0, 'test', 1);
     privatemsg_set_setting('role', array_pop(array_keys($user->roles)), 'test', 2);
@@ -1306,5 +1305,24 @@ class PrivatemsgAPITestCase extends DrupalWebTestCase {
 
     $this->assertEqual(privatemsg_get_setting('test', $admin_ids), 1, t('The user level setting was deleted, the default is now used.'));
     $this->assertEqual(privatemsg_get_setting('test', $user_ids), 1, t('The role level setting was deleted, the default is now used.'));
+
+    // Test variable_get() fallback.
+    variable_set('privatemsg_setting_test3', 10);
+    privatemsg_set_setting('user', $admin->uid, 'test3', 11);
+    $this->assertEqual(privatemsg_get_setting('test3', $user_ids), 10, t('The variable_get() fallback is used when no other value exists.'));
+    $this->assertEqual(privatemsg_get_setting('test3', $admin_ids),11, t('The updated user level setting is used.'));
+
+    // Explicitly set a global default now.
+    privatemsg_set_setting('global', 0, 'test3', 12);
+    $this->assertEqual(privatemsg_get_setting('test3', $user_ids), 12, t('The variable_get() fallback is not used when other values exists.'));
+
+    // Test argument fallback.
+    privatemsg_set_setting('user', $admin->uid, 'test4', 14);
+    $this->assertEqual(privatemsg_get_setting('test4', $user_ids, 13), 13, t('The argument fallback is used when no other value exists.'));
+    $this->assertEqual(privatemsg_get_setting('test4', $admin_ids),14, t('The user level setting is used.'));
+
+    // Explicitly set a global default now.
+    privatemsg_set_setting('global', 0, 'test4', 15);
+    $this->assertEqual(privatemsg_get_setting('test4', $user_ids, 13), 15, t('The variable_get() fallback is not used when other values exists.'));
   }
 }
-- 
1.7.4.1

