Source for file db_prefs.php

Documentation is available at db_prefs.php

  1. <?php
  2.  
  3. /**
  4.  * db_prefs.php
  5.  *
  6.  * This contains functions for manipulating user preferences
  7.  * stored in a database, accessed though the Pear DB layer.
  8.  *
  9.  * Database:
  10.  *
  11.  * The preferences table should have three columns:
  12.  *    user       char  \  primary
  13.  *    prefkey    char  /  key
  14.  *    prefval    blob
  15.  *
  16.  *   CREATE TABLE userprefs (user CHAR(128) NOT NULL DEFAULT '',
  17.  *                           prefkey CHAR(64) NOT NULL DEFAULT '',
  18.  *                           prefval BLOB NOT NULL DEFAULT '',
  19.  *                           primary key (user,prefkey));
  20.  *
  21.  * Configuration of databasename, username and password is done
  22.  * by using conf.pl or the administrator plugin
  23.  *
  24.  * @copyright 1999-2015 The SquirrelMail Project Team
  25.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  26.  * @version $Id: db_prefs.php 14510 2015-06-21 10:05:27Z pdontthink $
  27.  * @package squirrelmail
  28.  * @subpackage prefs
  29.  * @since 1.1.3
  30.  */
  31.  
  32. /** @ignore */
  33. if (!defined('SM_PATH')) define('SM_PATH','../');
  34.  
  35. /** Unknown database */
  36. define('SMDB_UNKNOWN'0);
  37. /** MySQL */
  38. define('SMDB_MYSQL'1);
  39. /** PostgreSQL */
  40. define('SMDB_PGSQL'2);
  41.  
  42. /**
  43.  * don't display errors (no code execution in functions/*.php).
  44.  * will handle error in dbPrefs class.
  45.  */
  46. @include_once('DB.php');
  47.  
  48. global $prefs_are_cached$prefs_cache;
  49.  
  50. /**
  51.  * @ignore
  52.  */
  53. function cachePrefValues($username{
  54.     global $prefs_are_cached$prefs_cache;
  55.  
  56.     sqgetGlobalVar('prefs_are_cached'$prefs_are_cachedSQ_SESSION );
  57.     if ($prefs_are_cached{
  58.         sqgetGlobalVar('prefs_cache'$prefs_cacheSQ_SESSION );
  59.         return;
  60.     }
  61.  
  62.     sqsession_unregister('prefs_cache');
  63.     sqsession_unregister('prefs_are_cached');
  64.  
  65.     $db new dbPrefs;
  66.     if(isset($db->error)) {
  67.         printf_("Preference database error (%s). Exiting abnormally"),
  68.               $db->error);
  69.         exit;
  70.     }
  71.  
  72.     $db->fillPrefsCache($username);
  73.     if (isset($db->error)) {
  74.         printf_("Preference database error (%s). Exiting abnormally"),
  75.               $db->error);
  76.         exit;
  77.     }
  78.  
  79.     $prefs_are_cached true;
  80.  
  81.     sqsession_register($prefs_cache'prefs_cache');
  82.     sqsession_register($prefs_are_cached'prefs_are_cached');
  83. }
  84.  
  85. /**
  86.  * Class used to handle connections to prefs database and operations with preferences
  87.  *
  88.  * @package squirrelmail
  89.  * @subpackage prefs
  90.  * @since 1.1.3
  91.  *
  92.  */
  93. class dbPrefs {
  94.     /**
  95.      * Table used to store preferences
  96.      * @var string 
  97.      */
  98.     var $table = 'userprefs';
  99.  
  100.     /**
  101.      * Field used to store owner of preference
  102.      * @var string 
  103.      */
  104.     var $user_field = 'user';
  105.  
  106.     /**
  107.      * Field used to store preference name
  108.      * @var string 
  109.      */
  110.     var $key_field = 'prefkey';
  111.  
  112.     /**
  113.      * Field used to store preference value
  114.      * @var string 
  115.      */
  116.     var $val_field = 'prefval';
  117.  
  118.     /**
  119.      * Database connection object
  120.      * @var object 
  121.      */
  122.     var $dbh   = NULL;
  123.  
  124.     /**
  125.      * Error messages
  126.      * @var string 
  127.      */
  128.     var $error = NULL;
  129.  
  130.     /**
  131.      * Database type (SMDB_* constants)
  132.      * Is used in setKey().
  133.      * @var integer 
  134.      */
  135.     var $db_type = SMDB_UNKNOWN;
  136.  
  137.     /**
  138.      * Default preferences
  139.      * @var array 
  140.      */
  141.     var $default = Array('theme_default' => 0,
  142.                          'include_self_reply_all' => '0',
  143.                          'do_not_reply_to_self' => '1',
  144.                          'show_html_default' => '0');
  145.  
  146.     /**
  147.      * Preference owner field size
  148.      * @var integer 
  149.      * @since 1.5.1
  150.      */
  151.     var $user_size = 128;
  152.  
  153.     /**
  154.      * Preference key field size
  155.      * @var integer 
  156.      * @since 1.5.1
  157.      */
  158.     var $key_size = 64;
  159.  
  160.     /**
  161.      * Preference value field size
  162.      * @var integer 
  163.      * @since 1.5.1
  164.      */
  165.     var $val_size = 65536;
  166.  
  167.  
  168.  
  169.     /**
  170.      * initialize the default preferences array.
  171.      *
  172.      */
  173.     function dbPrefs({
  174.         // Try and read the default preferences file.
  175.         $default_pref SM_PATH 'config/default_pref';
  176.         if (@file_exists($default_pref)) {
  177.             if ($file @fopen($default_pref'r')) {
  178.                 while (!feof($file)) {
  179.                     $pref fgets($file1024);
  180.                     $i strpos($pref'=');
  181.                     if ($i 0{
  182.                         $this->default[trim(substr($pref0$i))trim(substr($pref$i 1));
  183.                     }
  184.                 }
  185.                 fclose($file);
  186.             }
  187.         }
  188.     }
  189.  
  190.     /**
  191.      * initialize DB connection object
  192.      *
  193.      * @return boolean true, if object is initialized
  194.      *
  195.      */
  196.     function open({
  197.         global $prefs_dsn$prefs_table;
  198.         global $prefs_user_size$prefs_key_size$prefs_val_size;
  199.  
  200.         /* test if Pear DB class is available and freak out if it is not */
  201.         if (class_exists('DB')) {
  202.             // same error also in abook_database.php
  203.             $this->error  = _("Could not include PEAR database functions required for the database backend.""\n";
  204.             $this->error .= sprintf(_("Is PEAR installed, and is the include path set correctly to find %s?"),
  205.                               'DB.php'"\n";
  206.             $this->error .= _("Please contact your system administrator and report this error.");
  207.             return false;
  208.         }
  209.  
  210.         if(isset($this->dbh)) {
  211.             return true;
  212.         }
  213.  
  214.         if (preg_match('/^mysql/'$prefs_dsn)) {
  215.             $this->db_type = SMDB_MYSQL;
  216.         elseif (preg_match('/^pgsql/'$prefs_dsn)) {
  217.             $this->db_type = SMDB_PGSQL;
  218.         }
  219.  
  220.         if (!empty($prefs_table)) {
  221.             $this->table = $prefs_table;
  222.         }
  223.         if (!empty($prefs_user_field)) {
  224.             $this->user_field = $prefs_user_field;
  225.         }
  226.  
  227.         // the default user field is "user", which in PostgreSQL
  228.         // is an identifier and causes errors if not escaped
  229.         //
  230.         if ($this->db_type == SMDB_PGSQL{
  231.            $this->user_field = '"' $this->user_field . '"';
  232.         }
  233.  
  234.         if (!empty($prefs_key_field)) {
  235.             $this->key_field = $prefs_key_field;
  236.         }
  237.         if (!empty($prefs_val_field)) {
  238.             $this->val_field = $prefs_val_field;
  239.         }
  240.         if (!empty($prefs_user_size)) {
  241.             $this->user_size = (int) $prefs_user_size;
  242.         }
  243.         if (!empty($prefs_key_size)) {
  244.             $this->key_size = (int) $prefs_key_size;
  245.         }
  246.         if (!empty($prefs_val_size)) {
  247.             $this->val_size = (int) $prefs_val_size;
  248.         }
  249.         $dbh DB::connect($prefs_dsntrue);
  250.  
  251.         if(DB::isError($dbh)) {
  252.             $this->error = DB::errorMessage($dbh);
  253.             return false;
  254.         }
  255.  
  256.         $this->dbh = $dbh;
  257.         return true;
  258.     }
  259.  
  260.     /**
  261.      * Function used to handle database connection errors
  262.      *
  263.      * @param object PEAR Error object
  264.      *
  265.      */
  266.     function failQuery($res NULL{
  267.         if($res == NULL{
  268.             printf(_("Preference database error (%s). Exiting abnormally"),
  269.                   $this->error);
  270.         else {
  271.             printf(_("Preference database error (%s). Exiting abnormally"),
  272.                   DB::errorMessage($res));
  273.         }
  274.         exit;
  275.     }
  276.  
  277.     /**
  278.      * Get user's prefs setting
  279.      *
  280.      * @param string $user user name
  281.      * @param string $key preference name
  282.      * @param mixed $default (since 1.2.5) default value
  283.      *
  284.      * @return mixed preference value
  285.      *
  286.      */
  287.     function getKey($user$key$default ''{
  288.         global $prefs_cache;
  289.  
  290.         $temp array(&$user&$key);
  291.         $result do_hook('get_pref_override'$temp);
  292.         if (is_null($result)) {
  293.             cachePrefValues($user);
  294.  
  295.             if (isset($prefs_cache[$key])) {
  296.                 $result $prefs_cache[$key];
  297.             else {
  298. //FIXME: is there a justification for having two prefs hooks so close?  who uses them?
  299.                 $temp array(&$user&$key);
  300.                 $result do_hook('get_pref'$temp);
  301.                 if (is_null($result)) {
  302.                     if (isset($this->default[$key])) {
  303.                         $result $this->default[$key];
  304.                     else {
  305.                         $result $default;
  306.                     }
  307.                 }
  308.             }
  309.         }
  310.         return $result;
  311.     }
  312.  
  313.     /**
  314.      * Delete user's prefs setting
  315.      *
  316.      * @param string $user user name
  317.      * @param string $key  preference name
  318.      *
  319.      * @return boolean 
  320.      *
  321.      */
  322.     function deleteKey($user$key{
  323.         global $prefs_cache;
  324.  
  325.         if (!$this->open()) {
  326.             return false;
  327.         }
  328.         $query sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
  329.                          $this->table,
  330.                          $this->user_field,
  331.                          $this->dbh->quoteString($user),
  332.                          $this->key_field,
  333.                          $this->dbh->quoteString($key));
  334.  
  335.         $res $this->dbh->simpleQuery($query);
  336.         if(DB::isError($res)) {
  337.             $this->failQuery($res);
  338.         }
  339.  
  340.         unset($prefs_cache[$key]);
  341.  
  342.         return true;
  343.     }
  344.  
  345.     /**
  346.      * Set user's preference
  347.      *
  348.      * @param string $user  user name
  349.      * @param string $key   preference name
  350.      * @param mixed  $value preference value
  351.      *
  352.      * @return boolean 
  353.      *
  354.      */
  355.     function setKey($user$key$value{
  356.         if (!$this->open()) {
  357.             return false;
  358.         }
  359.  
  360.         /**
  361.          * Check if username fits into db field
  362.          */
  363.         if (strlen($user$this->user_size{
  364.             $this->error = "Oversized username value."
  365.                 ." Your preferences can't be saved."
  366.                 ." See the administrator's manual or contact your system administrator.";
  367.  
  368.             /**
  369.              * Debugging function. Can be used to log all issues that trigger
  370.              * oversized field errors. Function should be enabled in all three
  371.              * strlen checks. See http://www.php.net/error-log
  372.              */
  373.             // error_log($user.'|'.$key.'|'.$value."\n",3,'/tmp/oversized_log');
  374.  
  375.             // error is fatal
  376.             $this->failQuery(null);
  377.         }
  378.         /**
  379.          * Check if preference key fits into db field
  380.          */
  381.         if (strlen($key$this->key_size{
  382.             $err_msg "Oversized user's preference key."
  383.                 ." Some preferences were not saved."
  384.                 ." See the administrator's manual or contact your system administrator.";
  385.             // error is not fatal. Only some preference is not saved.
  386.             trigger_error($err_msg,E_USER_WARNING);
  387.             return false;
  388.         }
  389.         /**
  390.          * Check if preference value fits into db field
  391.          */
  392.         if (strlen($value$this->val_size{
  393.             $err_msg "Oversized user's preference value."
  394.                 ." Some preferences were not saved."
  395.                 ." See the administrator's manual or contact your system administrator.";
  396.             // error is not fatal. Only some preference is not saved.
  397.             trigger_error($err_msg,E_USER_WARNING);
  398.             return false;
  399.         }
  400.  
  401.  
  402.         if ($this->db_type == SMDB_MYSQL{
  403.             $query sprintf("REPLACE INTO %s (%s, %s, %s) ".
  404.                              "VALUES('%s','%s','%s')",
  405.                              $this->table,
  406.                              $this->user_field,
  407.                              $this->key_field,
  408.                              $this->val_field,
  409.                              $this->dbh->quoteString($user),
  410.                              $this->dbh->quoteString($key),
  411.                              $this->dbh->quoteString($value));
  412.  
  413.             $res $this->dbh->simpleQuery($query);
  414.             if(DB::isError($res)) {
  415.                 $this->failQuery($res);
  416.             }
  417.         elseif ($this->db_type == SMDB_PGSQL{
  418.             $this->dbh->simpleQuery("BEGIN TRANSACTION");
  419.             $query sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
  420.                              $this->table,
  421.                              $this->user_field,
  422.                              $this->dbh->quoteString($user),
  423.                              $this->key_field,
  424.                              $this->dbh->quoteString($key));
  425.             $res $this->dbh->simpleQuery($query);
  426.             if (DB::isError($res)) {
  427.                 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
  428.                 $this->failQuery($res);
  429.             }
  430.             $query sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
  431.                              $this->table,
  432.                              $this->user_field,
  433.                              $this->key_field,
  434.                              $this->val_field,
  435.                              $this->dbh->quoteString($user),
  436.                              $this->dbh->quoteString($key),
  437.                              $this->dbh->quoteString($value));
  438.             $res $this->dbh->simpleQuery($query);
  439.             if (DB::isError($res)) {
  440.                 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
  441.                 $this->failQuery($res);
  442.             }
  443.             $this->dbh->simpleQuery("COMMIT TRANSACTION");
  444.         else {
  445.             $query sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
  446.                              $this->table,
  447.                              $this->user_field,
  448.                              $this->dbh->quoteString($user),
  449.                              $this->key_field,
  450.                              $this->dbh->quoteString($key));
  451.             $res $this->dbh->simpleQuery($query);
  452.             if (DB::isError($res)) {
  453.                 $this->failQuery($res);
  454.             }
  455.             $query sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
  456.                              $this->table,
  457.                              $this->user_field,
  458.                              $this->key_field,
  459.                              $this->val_field,
  460.                              $this->dbh->quoteString($user),
  461.                              $this->dbh->quoteString($key),
  462.                              $this->dbh->quoteString($value));
  463.             $res $this->dbh->simpleQuery($query);
  464.             if (DB::isError($res)) {
  465.                 $this->failQuery($res);
  466.             }
  467.         }
  468.  
  469.         return true;
  470.     }
  471.  
  472.     /**
  473.      * Fill preference cache array
  474.      *
  475.      * @param string $user user name
  476.      *
  477.      * @since 1.2.3
  478.      *
  479.      */
  480.     function fillPrefsCache($user{
  481.         global $prefs_cache;
  482.  
  483.         if (!$this->open()) {
  484.             return;
  485.         }
  486.  
  487.         $prefs_cache array();
  488.         $query sprintf("SELECT %s as prefkey, %s as prefval FROM %s ".
  489.                          "WHERE %s = '%s'",
  490.                          $this->key_field,
  491.                          $this->val_field,
  492.                          $this->table,
  493.                          $this->user_field,
  494.                          $this->dbh->quoteString($user));
  495.         $res $this->dbh->query($query);
  496.         if (DB::isError($res)) {
  497.             $this->failQuery($res);
  498.         }
  499.  
  500.         while ($row $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  501.             $prefs_cache[$row['prefkey']] $row['prefval'];
  502.         }
  503.     }
  504.  
  505. /* end class dbPrefs */
  506.  
  507.  
  508. /**
  509.  * Returns the value for the requested preference
  510.  * @ignore
  511.  */
  512. function getPref($data_dir$username$pref_name$default ''{
  513.     $db new dbPrefs;
  514.     if(isset($db->error)) {
  515.         printf_("Preference database error (%s). Exiting abnormally"),
  516.               $db->error);
  517.         exit;
  518.     }
  519.  
  520.     return $db->getKey($username$pref_name$default);
  521. }
  522.  
  523. /**
  524.  * Remove the desired preference setting ($pref_name)
  525.  * @ignore
  526.  */
  527. function removePref($data_dir$username$pref_name{
  528.     global $prefs_cache;
  529.     $db new dbPrefs;
  530.     if(isset($db->error)) {
  531.         $db->failQuery();
  532.     }
  533.  
  534.     $db->deleteKey($username$pref_name);
  535.  
  536.     if (isset($prefs_cache[$pref_name])) {
  537.         unset($prefs_cache[$pref_name]);
  538.     }
  539.  
  540.     sqsession_register($prefs_cache 'prefs_cache');
  541.     return;
  542. }
  543.  
  544. /**
  545.  * Sets the desired preference setting ($pref_name) to whatever is in $value
  546.  * @ignore
  547.  */
  548. function setPref($data_dir$username$pref_name$value{
  549.     global $prefs_cache;
  550.  
  551.     if (isset($prefs_cache[$pref_name]&& ($prefs_cache[$pref_name== $value)) {
  552.         return;
  553.     }
  554.  
  555.     if ($value === ''{
  556.         removePref($data_dir$username$pref_name);
  557.         return;
  558.     }
  559.  
  560.     $db new dbPrefs;
  561.     if(isset($db->error)) {
  562.         $db->failQuery();
  563.     }
  564.  
  565.     $db->setKey($username$pref_name$value);
  566.     $prefs_cache[$pref_name$value;
  567.     assert_options(ASSERT_ACTIVE1);
  568.     assert_options(ASSERT_BAIL1);
  569.     assert ('$value == $prefs_cache[$pref_name]');
  570.     sqsession_register($prefs_cache 'prefs_cache');
  571.     return;
  572. }
  573.  
  574. /**
  575.  * This checks if the prefs are available
  576.  * @ignore
  577.  */
  578. function checkForPrefs($data_dir$username{
  579.     $db new dbPrefs;
  580.     if(isset($db->error)) {
  581.         $db->failQuery();
  582.     }
  583. }
  584.  
  585. /**
  586.  * Writes the Signature
  587.  * @ignore
  588.  */
  589. function setSig($data_dir$username$number$value{
  590.     if ($number == "g"{
  591.         $key '___signature___';
  592.     else {
  593.         $key sprintf('___sig%s___'$number);
  594.     }
  595.     setPref($data_dir$username$key$value);
  596.     return;
  597. }
  598.  
  599. /**
  600.  * Gets the signature
  601.  * @ignore
  602.  */
  603. function getSig($data_dir$username$number{
  604.     if ($number == "g"{
  605.         $key '___signature___';
  606.     else {
  607.         $key sprintf('___sig%d___'$number);
  608.     }
  609.     return getPref($data_dir$username$key);
  610. }

Documentation generated on Tue, 01 Sep 2015 04:17:29 +0200 by phpDocumentor 1.4.3