Просмотр исходного кода

Add ability to explicitly set prefs DB connection charset, though usually if database defaults are sensible this is not something to be concerned with in configuring SquirrelMail

pdontthink 3 лет назад
Родитель
Сommit
eb1008dffb
2 измененных файлов с 41 добавлено и 1 удалено
  1. 8 0
      config/config_local.example.php
  2. 33 1
      functions/db_prefs.php

+ 8 - 0
config/config_local.example.php

@@ -125,6 +125,14 @@
  * being used (backtick for MySQL (and thus MariaDB),
  * double quotes for all others).
  *
+ * $prefs_db_charset (string) allows you to explicitly
+ * set the user preferences (SQL) database connection
+ * character set.  In most cases, system defaults should
+ * be sufficient, even for UTF-8 preference values and
+ * so forth, but this allows you to specifically make
+ * the selection as needed, for example:
+ * $prefs_db_charset = 'utf8mb4';
+ *
  * $use_expiring_security_tokens (boolean) allows you to
  * make SquirrelMail use short-lived anti-CSRF security
  * tokens that expire as desired (not recommended, can

+ 33 - 1
functions/db_prefs.php

@@ -47,6 +47,11 @@
  *                                     NOT to quote identifiers by setting
  *                                     this to "none"
  *
+ * If needed, you can also set $prefs_db_charset as a string
+ * (such as "utf8mb4") in config/config_local.php if your system
+ * does not default the SQL connection character set as expected
+ * (most sensible systems will do the right thing transparently).
+ *
  * @copyright 1999-2022 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
@@ -245,7 +250,7 @@ class dbPrefs {
      *
      */
     function open() {
-        global $prefs_dsn, $prefs_table, $use_pdo, $db_identifier_quote_char;
+        global $prefs_dsn, $prefs_db_charset, $prefs_table, $use_pdo, $db_identifier_quote_char;
         global $prefs_user_field, $prefs_key_field, $prefs_val_field;
         global $prefs_user_size, $prefs_key_size, $prefs_val_size;
 
@@ -347,6 +352,8 @@ class dbPrefs {
                 $pdo_prefs_dsn = $matches[1] . ':unix_socket=' . $matches[9] . ';dbname=' . $matches[5];
             else
                 $pdo_prefs_dsn = $matches[1] . ':host=' . $matches[4] . (!empty($matches[6]) ? ';port=' . $matches[6] : '') . ';dbname=' . $matches[5];
+            if (!empty($prefs_db_charset))
+                $pdo_prefs_dsn .= ';charset=' . $prefs_db_charset;
             try {
                 $dbh = new PDO($pdo_prefs_dsn, $matches[2], $matches[3]);
             } catch (Exception $e) {
@@ -363,6 +370,31 @@ class dbPrefs {
         }
 
         $this->dbh = $dbh;
+
+        // Older versions of PHP are buggy with setting charset on the dsn so we also issue a SET NAMES
+        if (!empty($prefs_db_charset)) {
+            if ($use_pdo) {
+                $res = $dbh->exec('SET NAMES \'' . $prefs_db_charset . '\'');
+                /* Purposefully not checking for errors; some setups reportedly botch this on queries like this
+                if ($res === FALSE) {
+                    if ($pdo_show_sql_errors)
+                        $this->error = implode(' - ', $sth->errorInfo());
+                    else
+                        $this->error = _("Could not execute query");
+                }
+                $this->failQuery();
+                */
+            }
+            else {
+                $res = $this->dbh->simpleQuery('SET NAMES \'' . $prefs_db_charset . '\'');
+                /* Purposefully not checking for errors; some setups reportedly botch this on queries like this
+                if(DB::isError($res)) {
+                    $this->failQuery($res);
+                }
+                */
+            }
+        }
+
         return true;
     }