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 &copy; 1999-2006 The SquirrelMail Project Team
  25.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  26.  * @version $Id: db_prefs.php,v 1.49 2006/07/15 12:00:44 tokul Exp $
  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.  * @package squirrelmail
  88.  * @subpackage prefs
  89.  * @since 1.1.3
  90.  */
  91. class dbPrefs {
  92.     /**
  93.      * Table used to store preferences
  94.      * @var string 
  95.      */
  96.     var $table = 'userprefs';
  97.     /**
  98.      * Field used to store owner of preference
  99.      * @var string 
  100.      */
  101.     var $user_field = 'user';
  102.     /**
  103.      * Field used to store preference name
  104.      * @var string 
  105.      */
  106.     var $key_field = 'prefkey';
  107.     /**
  108.      * Field used to store preference value
  109.      * @var string 
  110.      */
  111.     var $val_field = 'prefval';
  112.  
  113.     /**
  114.      * Database connection object
  115.      * @var object 
  116.      */
  117.     var $dbh   = NULL;
  118.     /**
  119.      * Error messages
  120.      * @var string 
  121.      */
  122.     var $error = NULL;
  123.     /**
  124.      * Database type (SMDB_* constants)
  125.      * Is used in setKey().
  126.      * @var integer 
  127.      */
  128.     var $db_type = SMDB_UNKNOWN;
  129.  
  130.     /**
  131.      * Default preferences
  132.      * @var array 
  133.      */
  134.     var $default = Array('theme_default' => 0,
  135.                          'show_html_default' => '0');
  136.  
  137.     /**
  138.      * Preference owner field size
  139.      * @var integer 
  140.      * @since 1.5.1
  141.      */
  142.     var $user_size = 128;
  143.     /**
  144.      * Preference key field size
  145.      * @var integer 
  146.      * @since 1.5.1
  147.      */
  148.     var $key_size = 64;
  149.     /**
  150.      * Preference value field size
  151.      * @var integer 
  152.      * @since 1.5.1
  153.      */
  154.     var $val_size = 65536;
  155.  
  156.     /**
  157.      * initialize DB connection object
  158.      * @return boolean true, if object is initialized
  159.      */
  160.     function open({
  161.         global $prefs_dsn$prefs_table;
  162.         global $prefs_user_size$prefs_key_size$prefs_val_size;
  163.  
  164.         /* test if Pear DB class is available and freak out if it is not */
  165.         if (class_exists('DB')) {
  166.             // same error also in abook_database.php
  167.             $this->error  = _("Could not include PEAR database functions required for the database backend.""<br />\n";
  168.             $this->error .= sprintf(_("Is PEAR installed, and is the include path set correctly to find %s?"),
  169.                               '<tt>DB.php</tt>'"<br />\n";
  170.             $this->error .= _("Please contact your system administrator and report this error.");
  171.             return false;
  172.         }
  173.  
  174.         if(isset($this->dbh)) {
  175.             return true;
  176.         }
  177.  
  178.         if (preg_match('/^mysql/'$prefs_dsn)) {
  179.             $this->db_type = SMDB_MYSQL;
  180.         elseif (preg_match('/^pgsql/'$prefs_dsn)) {
  181.             $this->db_type = SMDB_PGSQL;
  182.         }
  183.  
  184.         if (!empty($prefs_table)) {
  185.             $this->table = $prefs_table;
  186.         }
  187.         if (!empty($prefs_user_field)) {
  188.             $this->user_field = $prefs_user_field;
  189.         }
  190.         if (!empty($prefs_key_field)) {
  191.             $this->key_field = $prefs_key_field;
  192.         }
  193.         if (!empty($prefs_val_field)) {
  194.             $this->val_field = $prefs_val_field;
  195.         }
  196.         if (!empty($prefs_user_size)) {
  197.             $this->user_size = (int) $prefs_user_size;
  198.         }
  199.         if (!empty($prefs_key_size)) {
  200.             $this->key_size = (int) $prefs_key_size;
  201.         }
  202.         if (!empty($prefs_val_size)) {
  203.             $this->val_size = (int) $prefs_val_size;
  204.         }
  205.         $dbh DB::connect($prefs_dsntrue);
  206.  
  207.         if(DB::isError($dbh)) {
  208.             $this->error = DB::errorMessage($dbh);
  209.             return false;
  210.         }
  211.  
  212.         $this->dbh = $dbh;
  213.         return true;
  214.     }
  215.  
  216.     /**
  217.      * Function used to handle database connection errors
  218.      * @param object PEAR Error object
  219.      */
  220.     function failQuery($res NULL{
  221.         if($res == NULL{
  222.             printf(_("Preference database error (%s). Exiting abnormally"),
  223.                   $this->error);
  224.         else {
  225.             printf(_("Preference database error (%s). Exiting abnormally"),
  226.                   DB::errorMessage($res));
  227.         }
  228.         exit;
  229.     }
  230.  
  231.     /**
  232.      * Get user's prefs setting
  233.      * @param string $user user name
  234.      * @param string $key preference name
  235.      * @param mixed $default (since 1.2.5) default value
  236.      * @return mixed preference value
  237.      */
  238.     function getKey($user$key$default ''{
  239.         global $prefs_cache;
  240.  
  241.         cachePrefValues($user);
  242.  
  243.         if (isset($prefs_cache[$key])) {
  244.             return $prefs_cache[$key];
  245.         else {
  246.             if (isset($this->default[$key])) {
  247.                 return $this->default[$key];
  248.             else {
  249.                 return $default;
  250.             }
  251.         }
  252.     }
  253.  
  254.     /**
  255.      * Delete user's prefs setting
  256.      * @param string $user user name
  257.      * @param string $key preference name
  258.      * @return boolean 
  259.      */
  260.     function deleteKey($user$key{
  261.         global $prefs_cache;
  262.  
  263.         if (!$this->open()) {
  264.             return false;
  265.         }
  266.         $query sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
  267.                          $this->table,
  268.                          $this->user_field,
  269.                          $this->dbh->quoteString($user),
  270.                          $this->key_field,
  271.                          $this->dbh->quoteString($key));
  272.  
  273.         $res $this->dbh->simpleQuery($query);
  274.         if(DB::isError($res)) {
  275.             $this->failQuery($res);
  276.         }
  277.  
  278.         unset($prefs_cache[$key]);
  279.  
  280.         return true;
  281.     }
  282.  
  283.     /**
  284.      * Set user's preference
  285.      * @param string $user user name
  286.      * @param string $key preference name
  287.      * @param mixed $value preference value
  288.      * @return boolean 
  289.      */
  290.     function setKey($user$key$value{
  291.         if (!$this->open()) {
  292.             return false;
  293.         }
  294.  
  295.         /**
  296.          * Check if username fits into db field
  297.          */
  298.         if (strlen($user$this->user_size{
  299.             $this->error = "Oversized username value."
  300.                 ." Your preferences can't be saved."
  301.                 ." See doc/db-backend.txt or contact your system administrator.";
  302.  
  303.             /**
  304.              * Debugging function. Can be used to log all issues that trigger
  305.              * oversized field errors. Function should be enabled in all three
  306.              * strlen checks. See http://www.php.net/error-log
  307.              */
  308.             // error_log($user.'|'.$key.'|'.$value."\n",3,'/tmp/oversized_log');
  309.  
  310.             // error is fatal
  311.             $this->failQuery(null);
  312.         }
  313.         /**
  314.          * Check if preference key fits into db field
  315.          */
  316.         if (strlen($key$this->key_size{
  317.             $err_msg "Oversized user's preference key."
  318.                 ." Some preferences were not saved."
  319.                 ." See doc/db-backend.txt or contact your system administrator.";
  320.             // error is not fatal. Only some preference is not saved.
  321.             trigger_error($err_msg,E_USER_WARNING);
  322.             return false;
  323.         }
  324.         /**
  325.          * Check if preference value fits into db field
  326.          */
  327.         if (strlen($value$this->val_size{
  328.             $err_msg "Oversized user's preference value."
  329.                 ." Some preferences were not saved."
  330.                 ." See doc/db-backend.txt or contact your system administrator.";
  331.             // error is not fatal. Only some preference is not saved.
  332.             trigger_error($err_msg,E_USER_WARNING);
  333.             return false;
  334.         }
  335.  
  336.  
  337.         if ($this->db_type == SMDB_MYSQL{
  338.             $query sprintf("REPLACE INTO %s (%s, %s, %s) ".
  339.                              "VALUES('%s','%s','%s')",
  340.                              $this->table,
  341.                              $this->user_field,
  342.                              $this->key_field,
  343.                              $this->val_field,
  344.                              $this->dbh->quoteString($user),
  345.                              $this->dbh->quoteString($key),
  346.                              $this->dbh->quoteString($value));
  347.  
  348.             $res $this->dbh->simpleQuery($query);
  349.             if(DB::isError($res)) {
  350.                 $this->failQuery($res);
  351.             }
  352.         elseif ($this->db_type == SMDB_PGSQL{
  353.             $this->dbh->simpleQuery("BEGIN TRANSACTION");
  354.             $query sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
  355.                              $this->table,
  356.                              $this->user_field,
  357.                              $this->dbh->quoteString($user),
  358.                              $this->key_field,
  359.                              $this->dbh->quoteString($key));
  360.             $res $this->dbh->simpleQuery($query);
  361.             if (DB::isError($res)) {
  362.                 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
  363.                 $this->failQuery($res);
  364.             }
  365.             $query sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
  366.                              $this->table,
  367.                              $this->user_field,
  368.                              $this->key_field,
  369.                              $this->val_field,
  370.                              $this->dbh->quoteString($user),
  371.                              $this->dbh->quoteString($key),
  372.                              $this->dbh->quoteString($value));
  373.             $res $this->dbh->simpleQuery($query);
  374.             if (DB::isError($res)) {
  375.                 $this->dbh->simpleQuery("ROLLBACK TRANSACTION");
  376.                 $this->failQuery($res);
  377.             }
  378.             $this->dbh->simpleQuery("COMMIT TRANSACTION");
  379.         else {
  380.             $query sprintf("DELETE FROM %s WHERE %s='%s' AND %s='%s'",
  381.                              $this->table,
  382.                              $this->user_field,
  383.                              $this->dbh->quoteString($user),
  384.                              $this->key_field,
  385.                              $this->dbh->quoteString($key));
  386.             $res $this->dbh->simpleQuery($query);
  387.             if (DB::isError($res)) {
  388.                 $this->failQuery($res);
  389.             }
  390.             $query sprintf("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
  391.                              $this->table,
  392.                              $this->user_field,
  393.                              $this->key_field,
  394.                              $this->val_field,
  395.                              $this->dbh->quoteString($user),
  396.                              $this->dbh->quoteString($key),
  397.                              $this->dbh->quoteString($value));
  398.             $res $this->dbh->simpleQuery($query);
  399.             if (DB::isError($res)) {
  400.                 $this->failQuery($res);
  401.             }
  402.         }
  403.  
  404.         return true;
  405.     }
  406.  
  407.     /**
  408.      * Fill preference cache array
  409.      * @param string $user user name
  410.      * @since 1.2.3
  411.      */
  412.     function fillPrefsCache($user{
  413.         global $prefs_cache;
  414.  
  415.         if (!$this->open()) {
  416.             return;
  417.         }
  418.  
  419.         $prefs_cache array();
  420.         $query sprintf("SELECT %s as prefkey, %s as prefval FROM %s ".
  421.                          "WHERE %s = '%s'",
  422.                          $this->key_field,
  423.                          $this->val_field,
  424.                          $this->table,
  425.                          $this->user_field,
  426.                          $this->dbh->quoteString($user));
  427.         $res $this->dbh->query($query);
  428.         if (DB::isError($res)) {
  429.             $this->failQuery($res);
  430.         }
  431.  
  432.         while ($row $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  433.             $prefs_cache[$row['prefkey']] $row['prefval'];
  434.         }
  435.     }
  436.  
  437. /* end class dbPrefs */
  438.  
  439.  
  440. /**
  441.  * returns the value for the pref $string
  442.  * @ignore
  443.  */
  444. function getPref($data_dir$username$string$default ''{
  445.     $db new dbPrefs;
  446.     if(isset($db->error)) {
  447.         printf_("Preference database error (%s). Exiting abnormally"),
  448.               $db->error);
  449.         exit;
  450.     }
  451.  
  452.     return $db->getKey($username$string$default);
  453. }
  454.  
  455. /**
  456.  * Remove the pref $string
  457.  * @ignore
  458.  */
  459. function removePref($data_dir$username$string{
  460.     global $prefs_cache;
  461.     $db new dbPrefs;
  462.     if(isset($db->error)) {
  463.         $db->failQuery();
  464.     }
  465.  
  466.     $db->deleteKey($username$string);
  467.  
  468.     if (isset($prefs_cache[$string])) {
  469.         unset($prefs_cache[$string]);
  470.     }
  471.  
  472.     sqsession_register($prefs_cache 'prefs_cache');
  473.     return;
  474. }
  475.  
  476. /**
  477.  * sets the pref, $string, to $set_to
  478.  * @ignore
  479.  */
  480. function setPref($data_dir$username$string$set_to{
  481.     global $prefs_cache;
  482.  
  483.     if (isset($prefs_cache[$string]&& ($prefs_cache[$string== $set_to)) {
  484.         return;
  485.     }
  486.  
  487.     if ($set_to === ''{
  488.         removePref($data_dir$username$string);
  489.         return;
  490.     }
  491.  
  492.     $db new dbPrefs;
  493.     if(isset($db->error)) {
  494.         $db->failQuery();
  495.     }
  496.  
  497.     $db->setKey($username$string$set_to);
  498.     $prefs_cache[$string$set_to;
  499.     assert_options(ASSERT_ACTIVE1);
  500.     assert_options(ASSERT_BAIL1);
  501.     assert ('$set_to == $prefs_cache[$string]');
  502.     sqsession_register($prefs_cache 'prefs_cache');
  503.     return;
  504. }
  505.  
  506. /**
  507.  * This checks if the prefs are available
  508.  * @ignore
  509.  */
  510. function checkForPrefs($data_dir$username{
  511.     $db new dbPrefs;
  512.     if(isset($db->error)) {
  513.         $db->failQuery();
  514.     }
  515. }
  516.  
  517. /**
  518.  * Writes the Signature
  519.  * @ignore
  520.  */
  521. function setSig($data_dir$username$number$string{
  522.     if ($number == "g"{
  523.         $key '___signature___';
  524.     else {
  525.         $key sprintf('___sig%s___'$number);
  526.     }
  527.     setPref($data_dir$username$key$string);
  528.     return;
  529. }
  530.  
  531. /**
  532.  * Gets the signature
  533.  * @ignore
  534.  */
  535. function getSig($data_dir$username$number{
  536.     if ($number == "g"{
  537.         $key '___signature___';
  538.     else {
  539.         $key sprintf('___sig%d___'$number);
  540.     }
  541.     return getPref($data_dir$username$key);
  542. }
  543.  
  544. // vim: et ts=4

Documentation generated on Sat, 07 Oct 2006 16:10:24 +0300 by phpDocumentor 1.3.0RC6