home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / PrefManager.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  15.3 KB  |  415 lines

  1. <?php
  2. require_once("DB.php");
  3.  
  4. /**
  5.  * A simple preference manager, takes userid, preference name pairs and returns the value
  6.  * of that preference.
  7.  *  
  8.  * CREATE TABLE `preferences` (
  9.  * `user_id` varchar( 255 ) NOT NULL default '',
  10.  * `pref_id` varchar( 32 ) NOT NULL default '',
  11.  * `pref_value` longtext NOT NULL ,
  12.  *     PRIMARY KEY ( `user_id` , `pref_id` )
  13.  * )
  14.  * 
  15.  * @author Jon Wood <jon@jellybob.co.uk>
  16.  * @pacakge Auth.PrefManager
  17.  */ 
  18. class Auth_PrefManager
  19. {
  20.     /**
  21.      * The database object.
  22.      * @var object
  23.      * @access private
  24.      */
  25.     var $_db;
  26.  
  27.     /**
  28.      * The user name to get preferences from if the user specified doesn't
  29.      * have that preference set.
  30.      * @var string
  31.      * @access private
  32.      */
  33.     var $_defaultUser = "__default__";
  34.  
  35.     /**
  36.      * Should we search for default values, or just fail when we find out that
  37.      * the specified user didn't have it set.
  38.      * 
  39.      * @var bool
  40.      * @access private
  41.      */
  42.     var $_returnDefaults = true;
  43.  
  44.     /**
  45.      * The table containing the preferences.
  46.      * @var string
  47.      * @access private
  48.      */
  49.     var $_table = "preferences";
  50.  
  51.     /**
  52.      * The column containing user ids.
  53.      * @var string
  54.      * @access private
  55.      */
  56.     var $_userColumn = "user_id";
  57.  
  58.     /**
  59.      * The column containing preference names.
  60.      * @var string
  61.      * @access private
  62.      */
  63.     var $_nameColumn = "pref_id";
  64.  
  65.     /**
  66.      * The column containing preference values.
  67.      * @var string
  68.      * @access private
  69.      */
  70.     var $_valueColumn = "pref_value";
  71.  
  72.     /**
  73.      * The session variable that the cache array is stored in.
  74.      * @var string
  75.      * @access private
  76.      */
  77.      var $_cacheName = "prefCache";
  78.  
  79.     /**
  80.      * The last error given.
  81.      * @var string
  82.      * @access private
  83.      */
  84.     var $_lastError;
  85.  
  86.     /**
  87.      * Defines whether the cache should be used or not.
  88.      * @var bool
  89.      * @access private
  90.      */
  91.     var $_useCache = true;
  92.     
  93.     /**
  94.      * Defines whether values should be serialized before saving.
  95.      * @var bool
  96.      * @access private
  97.      */
  98.     var $_serialize = false;
  99.     
  100.     /**
  101.      * Constructor
  102.      * 
  103.      * Options:
  104.      *  table: The table to get prefs from. [preferences]
  105.      *  userColumn: The field name to search for userid's [user_id]
  106.      *  nameColumn: The field name to search for preference names [pref_name]
  107.      *  valueColumn: The field name to search for preference values [pref_value]
  108.      *  defaultUser: The userid assigned to default values [__default__]
  109.      *  cacheName: The name of cache in the session variable ($_SESSION[cacheName]) [prefsCache]
  110.      *  useCache: Whether or not values should be cached.
  111.      *  serialize: Should preference values be serialzed before saving?
  112.      *
  113.      * @param string $dsn The DSN of the database connection to make, or a DB object.
  114.      * @param array $properties An array of properties to set.
  115.      * @param string $defaultUser The default user to manage for.
  116.      * @return bool Success or failure.
  117.      * @access public
  118.      */
  119.     function Auth_PrefManager($dsn, $properties = NULL)
  120.     {
  121.         // Connect to the database.
  122.         if (isset($dsn)) {
  123.             if (is_subclass_of($dsn, 'db_common')) {
  124.                 $this->_db = &$dsn;
  125.             } else {
  126.                 $this->_db = DB::Connect($dsn);
  127.                 if (DB::isError($this->_db)) {
  128.                     $this->_lastError = "DB Error: ".$this->_db->getMessage();
  129.                 }
  130.             }
  131.         } else {
  132.             $this->_lastError = "No DSN specified.";
  133.             return false;
  134.         }
  135.  
  136.         if (is_array($properties)) {
  137.             if (isset($properties["table"]))        { $this->_table = $properties["table"]; }
  138.             if (isset($properties["userColumn"]))   { $this->_userColumn = $properties["userColumn"]; }
  139.             if (isset($properties["nameColumn"]))   { $this->_nameColumn = $properties["nameColumn"]; }
  140.             if (isset($properties["valueColumn"]))  { $this->_valueColumn = $properties["valueColumn"]; }
  141.             if (isset($properties["defaultUser"]))  { $this->_defaultUser = $properties["defaultUser"]; }
  142.             if (isset($properties["cacheName"]))    { $this->_cacheName = $properties["cacheName"]; }
  143.         if (isset($properties["useCache"]))     { $this->_useCache = $properties["useCache"]; }
  144.             if (isset($properties["serialize"]))    { $this->_serialize = $properties["serialize"]; }
  145.         }
  146.  
  147.         return true;
  148.     }
  149.  
  150.     function setReturnDefaults($returnDefaults = true)
  151.     {
  152.         if (is_bool($returnDefaults)) {
  153.             $this->_returnDefaults = $returnDefaults;
  154.         }
  155.     }
  156.  
  157.     /**
  158.      * Sets whether the cache should be used.
  159.      * 
  160.      * @param bool $use Should the cache be used.
  161.      * @access public
  162.      */
  163.     function useCache($use = true)
  164.     {
  165.         $this->_useCache = $use;
  166.     }
  167.     
  168.     /**
  169.      * Cleans out the cache.
  170.      * 
  171.      * @access public
  172.      */
  173.     function clearCache()
  174.     {
  175.         unset($_SESSION[$this->_cacheName]);
  176.     }
  177.  
  178.     /**
  179.      * Get a preference for the specified user, or, if returning default values
  180.      * is enabled, the default.
  181.      * 
  182.      * @param string $user_id The user to get the preference for.
  183.      * @param string $pref_id The preference to get.
  184.      * @param bool $showDefaults Should default values be searched (overrides the global setting).
  185.      * @return mixed The value if it's found, or NULL if it isn't.
  186.      * @access public
  187.      */
  188.     function getPref($user_id, $pref_id, $showDefaults = true)
  189.     {
  190.         if (isset($_SESSION[$this->_cacheName][$user_id][$pref_id]) && $this->_useCache) {
  191.             // Value is cached for the specified user, so give them the cached copy.
  192.             return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  193.         } else {
  194.             // Not cached, search the database for this user's preference.
  195.             $query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  196.                                                                        $this->_userColumn,
  197.                                                                        $this->_db->quote($user_id),
  198.                                                                        $this->_nameColumn,
  199.                                                                        $this->_db->quote($pref_id));
  200.             $result = $this->_db->query($query);
  201.             if (DB::isError($result)) {
  202.                 // Ouch! The query failed!
  203.                 $this->_lastError = "DB Error: ".$result->getMessage();
  204.                 return NULL;
  205.             } else if ($result->numRows()) {
  206.                 // The query found a value, so we can cache that, and then return it.
  207.                 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
  208.                 $_SESSION[$this->_cacheName][$user_id][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
  209.                 return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  210.             } else if ($this->_returnDefaults && $showDefaults) {
  211.                 // I was doing this with a call to getPref again, but it threw things into an
  212.                 // infinite loop if the default value didn't exist. If you can fix that, it would
  213.                 // be great ;)
  214.                 if (isset($_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id]) && $this->_useCache) {
  215.                     $_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  216.                     return $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  217.                 } else {
  218.                     $query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  219.                                                                                $this->_userColumn,
  220.                                                                                $this->_db->quote($this->_defaultUser),
  221.                                                                                $this->_nameColumn,
  222.                                                                                $this->_db->quote($pref_id));
  223.                     $result = $this->_db->query($query);
  224.                     if (DB::isError($result)) {
  225.                         $this->_lastError = "DB Error: ".$result->getMessage();
  226.                         return NULL;
  227.                     } else {
  228.                         if ($result->numRows()) {
  229.                             $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
  230.                             $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
  231.                             $_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  232.                             return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  233.                         } else {
  234.                             return NULL;
  235.                         }
  236.                     }
  237.                 }
  238.             } else {
  239.                 // We've used up all the resources we're allowed to search, so return a NULL.
  240.                 return NULL;
  241.             }
  242.         }
  243.     }
  244.  
  245.     /**
  246.     * A shortcut function for getPref($this->_defaultUser, $pref_id, $value),
  247.     * useful if you have a logged in user, but want to get defaults anyway.
  248.     *
  249.     * @param string $pref_id The name of the preference to get.
  250.     * @return mixed The value if it's found, or NULL if it isn't.
  251.     * @access public
  252.     */
  253.     function getDefaultPref($pref_id)
  254.     {
  255.         return $this->getPref($this->_defaultUser, $pref_id);
  256.     }
  257.  
  258.     /**
  259.      * Set a preference for the specified user.
  260.      * 
  261.      * @param string $user_id The user to set for.
  262.      * @param string $pref_id The preference to set.
  263.      * @param mixed $value The value it should be set to.
  264.      * @return bool Sucess or failure.
  265.      * @access public
  266.      */
  267.     function setPref($user_id, $pref_id, $value)
  268.     {
  269.         // Start off by checking if the preference is already set (if it is we need to do
  270.         // an UPDATE, if not, it's an INSERT.
  271.         if ($this->_exists($user_id, $pref_id, false)) {
  272.             $query = sprintf("UPDATE %s SET %s=%s WHERE %s=%s AND %s=%s", $this->_table,
  273.                                                                           $this->_valueColumn,
  274.                                                                           $this->_db->quote($this->_pack($value)),
  275.                                                                           $this->_userColumn,
  276.                                                                           $this->_db->quote($user_id),
  277.                                                                           $this->_nameColumn,
  278.                                                                           $this->_db->quote($pref_id));
  279.         } else {
  280.             $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES(%s, %s, %s)", $this->_table,
  281.                                                                                $this->_userColumn,
  282.                                                                                $this->_nameColumn,
  283.                                                                                $this->_valueColumn,
  284.                                                                                $this->_db->quote($user_id),
  285.                                                                                $this->_db->quote($pref_id),
  286.                                                                                $this->_db->quote($this->_pack($value)));
  287.         }
  288.         $result = $this->_db->query($query);
  289.         if (DB::isError($result)) {
  290.             $this->_lastError = "DB Error: ".$result->getMessage();
  291.             return false;
  292.         } else {
  293.             if ($this->_useCache) {
  294.                 $_SESSION[$this->_cacheName][$user_id][$pref_id] = $value;
  295.             }
  296.             return true;
  297.         }
  298.     }
  299.  
  300.     /**
  301.     * A shortcut function for setPref($this->_defaultUser, $pref_id, $value)
  302.     *
  303.     * @param string $pref_id The name of the preference to set.
  304.     * @param mixed $value The value to set it to.
  305.     * @return bool Sucess or failure.
  306.     * @access public
  307.     */
  308.     function setDefaultPref($pref_id, $value)
  309.     {
  310.         return $this->setPref($this->_defaultUser, $pref_id, $value);
  311.     }
  312.  
  313.     /**
  314.     * Deletes a preference for the specified user.
  315.     * 
  316.     * @param string $user_id The userid of the user to delete from.
  317.     * @param string $pref_id The preference to delete.
  318.     * @return bool Success/Failure
  319.     * @access public
  320.     */
  321.     function deletePref($user_id, $pref_id)
  322.     {
  323.         if ($this->getPref($user_id, $pref_id) == NULL) {
  324.             // The user doesn't have this variable anyway ;)
  325.             return true;
  326.         } else {
  327.             $query = sprintf("DELETE FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  328.                                                                      $this->_userColumn,
  329.                                                                      $this->_db->quote($user_id),
  330.                                                                      $this->_nameColumn,
  331.                                                                      $this->_db->quote($pref_id));
  332.             $result = $this->_db->query($query);
  333.             if (DB::isError($result)) {
  334.                 $this->_lastError = "DB Error: ".$result->getMessage();
  335.                 return false;
  336.             } else {
  337.                 if ($this->_useCache) {
  338.                     unset($_SESSION[$this->_cacheName][$user_id][$pref_id]);
  339.                 }
  340.                 return true;
  341.             }
  342.         }
  343.     }
  344.  
  345.     /**
  346.     * Deletes a preference for the default user.
  347.     * 
  348.     * @param string $pref_id The preference to delete.
  349.     * @return bool Success/Failure
  350.     * @access public
  351.     */
  352.     function deleteDefaultPref($pref_id)
  353.     {
  354.         $this->deletePref($this->_defaultUser, $pref_id);
  355.     }
  356.     
  357.     /**
  358.      * Checks if a preference exists in the database.  
  359.      *
  360.      * @param string $user_id The userid of the preference owner.
  361.      * @param string $pref_id The preference to check for.
  362.      * @return bool True if the preference exists.
  363.      * @access private
  364.      */
  365.     function _exists($user_id, $pref_id)
  366.     {
  367.         $query = sprintf("SELECT COUNT(%s) FROM %s WHERE %s=%s AND %s=%s", $this->_nameColumn,
  368.                                                                            $this->_table,
  369.                                                                            $this->_userColumn,
  370.                                                                               $this->_db->quote($user_id),
  371.                                                                            $this->_nameColumn,
  372.                                                                            $this->_db->quote($pref_id));
  373.         $result = $this->_db->getOne($query);
  374.         if (DB::isError($result)) {
  375.             $this->_lastError = "DB Error: ".$result->getMessage();
  376.             return false;
  377.         } else {
  378.             return (bool)$result;
  379.         }
  380.     }
  381.  
  382.     /**
  383.      * Does anything needed to prepare a value for saving in the database.
  384.      *
  385.      * @param mixed $value The value to be saved.
  386.      * @return string The value in a format valid for saving to the database.
  387.      * @access private
  388.      */
  389.     function _pack($value)
  390.     {
  391.         if ($this->_serialize) {
  392.             return serialize($value);
  393.         } else {
  394.             return $value;
  395.         }
  396.     }
  397.     
  398.     /**
  399.      * Does anything needed to create a value of the preference, such as unserializing.
  400.      *
  401.      * @param string $value The value of the preference.
  402.      * @return mixed The unpacked version of the preference.
  403.      * @access private
  404.      */
  405.     function _unpack($value)
  406.     {
  407.         if ($this->_serialize) {
  408.             return unserialize($value);
  409.         } else {
  410.             return $value;
  411.         }
  412.     }
  413. }
  414. ?>
  415.