Clean up IMP_Quota
authorMichael M Slusarz <slusarz@curecanti.org>
Fri, 14 May 2010 20:48:06 +0000 (14:48 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 18 May 2010 17:17:01 +0000 (11:17 -0600)
imp/lib/Injector/Binder/Quota.php
imp/lib/Quota.php
imp/lib/Quota/Command.php
imp/lib/Quota/Driver.php [new file with mode: 0644]
imp/lib/Quota/Hook.php
imp/lib/Quota/Imap.php
imp/lib/Quota/Maildir.php
imp/lib/Quota/Mdaemon.php
imp/lib/Quota/Mercury32.php
imp/lib/Quota/Null.php [new file with mode: 0644]
imp/lib/Quota/Sql.php

index 27a9140..ca52cae 100644 (file)
@@ -16,7 +16,19 @@ class IMP_Injector_Binder_Quota implements Horde_Injector_Binder
      */
     public function create(Horde_Injector $injector)
     {
-        return IMP_Quota::factory($_SESSION['imp']['imap']['quota']['driver'], isset($_SESSION['imp']['imap']['quota']['params']) ? $_SESSION['imp']['imap']['quota']['params'] : array());
+        $driver = $_SESSION['imp']['imap']['quota']['driver'];
+        $params = isset($_SESSION['imp']['imap']['quota']['params'])
+            ? $_SESSION['imp']['imap']['quota']['params']
+            : array();
+
+        /* If 'password' exists in params, it has been encrypted in the
+         * session so we need to decrypt. */
+        if (isset($params['password'])) {
+            $secret = $injector->getInstance('Horde_Secret');
+            $params['password'] = $secret->read($secret->getKey('imp'), $params['password']);
+        }
+
+        return IMP_Quota::factory($driver, $params);
     }
 
     /**
index 9eaae8e..8dcdc11 100644 (file)
 class IMP_Quota
 {
     /**
-     * Hash containing connection parameters.
-     *
-     * @var array
-     */
-    protected $_params = array();
-
-    /**
      * Attempts to return a concrete instance based on $driver.
      *
      * @param string $driver  The type of concrete subclass to return.
-     * @param array $params   A hash containing any additional configuration or
-     *                        connection parameters a subclass might need.
+     * @param array $params   A hash containing any additional configuration
+     *                        parameters a subclass might need.
      *
-     * @return IMP_Quota  The concrete instance.
+     * @return IMP_Quota_Driver  The concrete instance.
      * @throws IMP_Exception
      */
     static public function factory($driver, $params = array())
@@ -42,85 +35,4 @@ class IMP_Quota
         throw new IMP_Exception('Could not create ' . __CLASS__ .  ' instance: ' . $driver);
     }
 
-    /**
-     * Constructor.
-     *
-     * @param array $params  Hash containing connection parameters.
-     */
-    protected function __construct($params = array())
-    {
-        $this->_params = $params;
-
-        /* If 'password' exists in params, it has been encrypted in the
-         * session so we need to decrypt. */
-        if (isset($this->_params['password'])) {
-            $secret = $GLOBALS['injector']->getInstance('Horde_Secret');
-            $this->_params['password'] = $secret->read($secret->getKey('imp'), $this->_params['password']);
-        }
-    }
-
-    /**
-     * Get quota information (used/allocated), in bytes.
-     *
-     * @return array  An array with the following keys:
-     *                'limit' = Maximum quota allowed
-     *                'usage' = Currently used portion of quota (in bytes)
-     * @throws Horde_Exception
-     */
-    public function getQuota()
-    {
-        return array('usage' => 0, 'limit' => 0);
-    }
-
-    /**
-     * Returns the quota messages variants, including sprintf placeholders.
-     *
-     * @return array  An array with quota message templates.
-     */
-    public function getMessages()
-    {
-        return array(
-            'long' => isset($this->_params['format']['long'])
-                ? $this->_params['format']['long']
-                : _("Quota status: %.2f %s / %.2f %s  (%.2f%%)"),
-            'short' => isset($this->_params['format']['short'])
-                ? $this->_params['format']['short']
-                : _("%.0f%% of %.0f %s"),
-            'nolimit_long' => isset($this->_params['format']['nolimit_long'])
-                ? $this->_params['format']['nolimit_long']
-                : _("Quota status: %.2f %s / NO LIMIT"),
-            'nolimit_short' => isset($this->_params['format']['nolimit_short'])
-                ? $this->_params['format']['nolimit_short']
-                : _("%.0f %s")
-        );
-    }
-
-    /**
-     * Determine the units of storage to display in the quota message.
-     *
-     * @return array  An array of size and unit type.
-     */
-    public function getUnit()
-    {
-        $unit = isset($this->_params['unit']) ? $this->_params['unit'] : 'MB';
-
-        switch ($unit) {
-        case 'GB':
-            $calc = 1024 * 1024 * 1024.0;
-            break;
-
-        case 'KB':
-            $calc = 1024.0;
-            break;
-
-        case 'MB':
-        default:
-            $calc = 1024 * 1024.0;
-            $unit = 'MB';
-            break;
-        }
-
-        return array($calc, $unit);
-    }
-
 }
index 599086c..51ee566 100644 (file)
@@ -7,16 +7,6 @@
  * authentication and file servers (e.g. via NIS/NFS).  And last, it (as
  * written) requires the POSIX PHP extensions.
  *
- * You must configure this driver in imp/config/servers.php.  The driver
- * supports the following parameters:
- * <pre>
- * 'grep_path' - (string) [REQUIRD] Path to the grep binary.
- * 'partition' - (string) If all user mailboxes are on a single partition, the
- *               partition label.  By default, quota will determine quota
- *               information using the user's home directory value.
- * 'quota_path' - (string) [REQUIRED] Path to the quota binary.
- * </pre>
- *
  * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (GPL). If you
  * @author  Eric Rostetter <eric.rostetter@physics.utexas.edu>
  * @package IMP
  */
-class IMP_Quota_Command extends IMP_Quota
+class IMP_Quota_Command extends IMP_Quota_Driver
 {
     /**
      * Constructor.
      *
-     * @param array $params  Hash containing connection parameters.
+     * @param array $params  Parameters:
+     * <pre>
+     * 'grep_path' - (string) [REQUIRED] Path to the grep binary.
+     * 'partition' - (string) If all user mailboxes are on a single partition,
+     *               the partition label.  By default, quota will determine
+     *               quota information using the user's home directory value.
+     * 'quota_path' - (string) [REQUIRED] Path to the quota binary.
+     * </pre>
      */
-    protected function __construct($params = array())
+    public function __construct(array $params = array())
     {
         $params = array_merge(array(
             'quota_path' => 'quota',
@@ -79,13 +76,15 @@ class IMP_Quota_Command extends IMP_Quota
         } else {
             $search_string = $this->_params['partition'];
         }
-        $cmdline = $this->_params['quota_path'] . ' -u ' . $_SESSION['imp']['user'] . ' | ' . $this->_params['grep_path'] . ' ' . $search_string;
+        $cmdline = $this->_params['quota_path'] . ' -u ' . escapeshellarg($_SESSION['imp']['user']) . ' | ' . escapeshellcmd($this->_params['grep_path']) . ' ' . escapeshellarg($search_string);
         exec($cmdline, $quota_data, $return_code);
         if (($return_code == 0) && (count($quota_data) == 1)) {
             $quota = split("[[:blank:]]+", trim($quota_data[0]));
             $blocksize = $this->_blockSize();
-            return array('usage' => $quota[1] * $blocksize,
-                        'limit' => $quota[2] * $blocksize);
+            return array(
+                'limit' => $quota[2] * $blocksize,
+                'usage' => $quota[1] * $blocksize
+            );
         }
 
         throw new IMP_Exception(_("Unable to retrieve quota"));
diff --git a/imp/lib/Quota/Driver.php b/imp/lib/Quota/Driver.php
new file mode 100644 (file)
index 0000000..9d320fb
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+/**
+ * The IMP_Quota_Driver:: class is the abstract class that all driver
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Michael Slusarz <slusarz@horde.org>
+ * @package IMP
+ */
+abstract class IMP_Quota_Driver
+{
+    /**
+     * Driver parameters.
+     *
+     * @var array
+     */
+    protected $_params = array(
+        'unit' => 'MB'
+    );
+
+    /**
+     * Constructor.
+     *
+     * @param array $params  Parameters:
+     * <pre>
+     * 'format' - (string) The formats of the quota messages in the user
+     *            interface. Must be a hash with the four possible elements
+     *            'long', 'short', 'nolimit_long', and 'nolimit_short'. The
+     *            strings will be passed through sprintf().
+     * 'unit' - (string) What storage unit the quota messages should be
+     *          displayed in. Either 'GB', 'MB', or 'KB'.
+     * </pre>
+     */
+    public function __construct(array $params = array())
+    {
+        $this->_params = array_merge($this->_params, $params);
+
+        $this->_params['format'] = array(
+            'long' => isset($this->_params['format']['long'])
+                ? $this->_params['format']['long']
+                : _("Quota status: %.2f %s / %.2f %s  (%.2f%%)"),
+            'short' => isset($this->_params['format']['short'])
+                ? $this->_params['format']['short']
+                : _("%.0f%% of %.0f %s"),
+            'nolimit_long' => isset($this->_params['format']['nolimit_long'])
+                ? $this->_params['format']['nolimit_long']
+                : _("Quota status: %.2f %s / NO LIMIT"),
+            'nolimit_short' => isset($this->_params['format']['nolimit_short'])
+                ? $this->_params['format']['nolimit_short']
+                : _("%.0f %s")
+        );
+    }
+
+    /**
+     * Get quota information (used/allocated), in bytes.
+     *
+     * @return array  An array with the following keys:
+     *                'limit' = Maximum quota allowed
+     *                'usage' = Currently used portion of quota (in bytes)
+     * @throws IMP_Exception
+     */
+    abstract public function getQuota();
+
+    /**
+     * Returns the quota messages variants, including sprintf placeholders.
+     *
+     * @return array  An array with quota message templates.
+     */
+    public function getMessages()
+    {
+        return $this->_params['format'];
+    }
+
+    /**
+     * Determine the units of storage to display in the quota message.
+     *
+     * @return array  An array of size and unit type.
+     */
+    public function getUnit()
+    {
+        $unit = $this->_params['unit'];
+
+        switch ($unit) {
+        case 'GB':
+            $calc = 1024 * 1024 * 1024.0;
+            break;
+
+        case 'KB':
+            $calc = 1024.0;
+            break;
+
+        case 'MB':
+        default:
+            $calc = 1024 * 1024.0;
+            $unit = 'MB';
+            break;
+        }
+
+        return array($calc, $unit);
+    }
+
+}
index 15b902a..f714bd4 100644 (file)
@@ -17,7 +17,7 @@
  * @author  Michael Redinger <Michael.Redinger@uibk.ac.at>
  * @package IMP
  */
-class IMP_Quota_Hook extends IMP_Quota
+class IMP_Quota_Hook extends IMP_Quota_Driver
 {
     /**
      * Get quota information (used/allocated), in bytes.
@@ -40,7 +40,10 @@ class IMP_Quota_Hook extends IMP_Quota
             throw new IMP_Exception(_("Unable to retrieve quota"));
         }
 
-        return array('usage' => $quota[0], 'limit' => $quota[1]);
+        return array(
+            'limit' => $quota[1],
+            'usage' => $quota[0]
+        );
     }
 
 }
index 8dd63c3..c3cb9a3 100644 (file)
@@ -2,9 +2,6 @@
 /**
  * Implementation of the IMP_Quota API for IMAP servers.
  *
- * You must configure this driver in imp/config/servers.php.  The driver does
- * not require any parameters.
- *
  * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (GPL). If you
@@ -13,7 +10,7 @@
  * @author  Mike Cochrane <mike@graftonhall.co.nz>
  * @package IMP
  */
-class IMP_Quota_Imap extends IMP_Quota
+class IMP_Quota_Imap extends IMP_Quota_Driver
 {
     /**
      * Get quota information (used/allocated), in bytes.
@@ -37,8 +34,8 @@ class IMP_Quota_Imap extends IMP_Quota
 
         $quota_val = reset($quota);
         return array(
-            'usage' => $quota_val['storage']['usage'] * 1024,
-            'limit' => $quota_val['storage']['limit'] * 1024
+            'limit' => $quota_val['storage']['limit'] * 1024,
+            'usage' => $quota_val['storage']['usage'] * 1024
         );
     }
 
index 28046e7..7ec58e1 100644 (file)
@@ -5,15 +5,6 @@
  * expanded to be configurable to support storage or message limits in the
  * configuration array.
  *
- * You must configure this driver in imp/config/servers.php.  The driver
- * supports the following parameters:
- * <pre>
- * path - (string) The path to the user's Maildir directory. You may use the
- *        two-character sequence "~U" to represent the user's account name,
- *        and the actual username will be substituted in that location.
- *        E.g., '/home/~U/Maildir/' or '/var/mail/~U/Maildir/'
- * </pre>
- *
  * TODO: Add config param for storage vs message quota
  *
  * Copyright 2007-2010 The Horde Project (http://www.horde.org/)
  * @author  Eric Rostetter <eric.rostetter@physics.utexas.edu>
  * @package IMP
  */
-class IMP_Quota_Maildir extends IMP_Quota
+class IMP_Quota_Maildir extends IMP_Quota_Driver
 {
     /**
      * Constructor.
      *
-     * @param array $params  Hash containing connection parameters.
+     * @param array $params  Parameters:
+     * <pre>
+     * 'path' - (string) The path to the user's Maildir directory. You may use
+     *          the two-character sequence "~U" to represent the user's
+     *          account name, and the actual username will be substituted in
+     *          that location.
+     *          E.g., '/home/~U/Maildir/' or '/var/mail/~U/Maildir/'
+     * </pre>
      */
-    protected function __construct($params = array())
+    public function __construct($params = array())
     {
-        parent::__construct(array_merge(array('path' => ''), $params));
+        parent::__construct(array_merge(array(
+            'path' => ''
+        ), $params));
     }
 
     /**
@@ -100,7 +100,10 @@ class IMP_Quota_Maildir extends IMP_Quota
             }
         }
 
-        return array('usage' => $storage_used, 'limit' => $storage_limit);
+        return array(
+            'limit' => $storage_limit,
+            'usage' => $storage_used
+        );
     }
 
 }
index 110972c..99bd004 100644 (file)
@@ -2,12 +2,6 @@
 /**
  * Implementation of the Quota API for MDaemon servers.
  *
- * You must configure this driver in imp/config/servers.php.  The driver
- * supports the following parameters:
- * <pre>
- * 'app_location' - (string) Location of the application.
- * </pre>
- *
  * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (GPL). If you
  * @author  Mike Cochrane <mike@graftonhall.co.nz>
  * @package IMP
  */
-class IMP_Quota_Mdaemon extends IMP_Quota
+class IMP_Quota_Mdaemon extends IMP_Quota_Driver
 {
     /**
+     * Constructor.
+     *
+     * @param array $params  Parameters:
+     * <pre>
+     * 'app_location' - (string) [REQUIRED] Location of the application.
+     * </pre>
+     *
+     * @throws IMP_Exception
+     */
+    public function __construct(array $params = array())
+    {
+        if (!isset($params['app_location'])) {
+            throw new IMP_Exception('Missing app_location parameter in quota config.');
+        }
+
+        parent::__construct($params);
+    }
+
+    /**
      * Get quota information (used/allocated), in bytes.
      *
      * @return array  An array with the following keys:
@@ -70,15 +83,13 @@ class IMP_Quota_Mdaemon extends IMP_Quota
         }
 
         /* Recursivly check subfolders. */
-        $d = dir($path);
-        while (($entry = $d->read()) !== false) {
-            if (($entry != '.') &&
-                ($entry != '..') &&
-                (substr($entry, -5, 5) == '.IMAP')) {
-                $size += $this->_mailboxSize($path . $entry . '\\');
+        $di = new DirectoryIterator($path);
+        foreach ($di as $filename => $entry) {
+            if (!$di->isDot() &&
+                (substr($filename, -5) == '.IMAP')) {
+                $size += $this->_mailboxSize($entry->getPathname() . '\\');
             }
         }
-        $d->close();
 
         return $size;
     }
index 03de211..267d88d 100644 (file)
@@ -3,14 +3,8 @@
  * Implementation of the Quota API for Mercury/32 IMAP servers.
  * For reading Quota, read size folder user.
  *
- * You must configure this driver in imp/config/servers.php.  The driver
- * supports the following parameters:
- * <pre>
- * 'mail_user_folder' - (string) The path to folder mail mercury.
- * </pre>
- *
  *****************************************************************************
- * PROBLEM TO ACCESS NETWORK DIRECOTRY
+ * PROBLEM TO ACCESS NETWORK DIRECTORY
  *****************************************************************************
  * Matt Grimm
  * 06-Jun-2003 10:25
  * @author  Frank Lupo <frank_lupo@email.it>
  * @package IMP
  */
-class IMP_Quota_Mercury32 extends IMP_Quota
+class IMP_Quota_Mercury32 extends IMP_Quota_Driver
 {
     /**
+     * Constructor.
+     *
+     * @param array $params  Parameters:
+     * <pre>
+     * 'mail_user_folder' - (string) [REQUIRED] The path to folder mail
+                             mercury.
+     * </pre>
+     *
+     * @throws IMP_Exception
+     */
+    public function __construct(array $params = array())
+    {
+        if (!isset($params['mail_user_folder'])) {
+            throw new IMP_Exception('Missing mail_user_folder parameter in quota config.');
+        }
+
+        parent::__construct($params);
+    }
+
+    /**
      * Get quota information (used/allocated), in bytes.
      *
      * @return array  An array with the following keys:
@@ -46,21 +60,22 @@ class IMP_Quota_Mercury32 extends IMP_Quota
      */
     public function getQuota()
     {
-        $quota = null;
+        $quota = 0;
 
-        $dir_path = $this->_params['mail_user_folder'] . '/' . $_SESSION['imp']['user'] . '/';
-        if ($dir = @opendir($dir_path)) {
-            while (($file = readdir($dir)) !== false) {
-                $quota += filesize($dir_path . $file);
-            }
-            closedir($dir);
+        try {
+            $di = new DirectoryIterator($this->_params['mail_user_folder'] . '/' . $_SESSION['imp']['user'] . '/');
+        } catch (UnexpectedValueException $e) {
+            throw new IMP_Exception(_("Unable to retrieve quota"));
+        }
 
-            if (!is_null($quota)) {
-                return array('usage' => $quota, 'limit' => 0);
-            }
+        foreach ($di as $val) {
+            $quota += $val->getSize();
         }
 
-        throw new IMP_Exception(_("Unable to retrieve quota"));
+        return array(
+            'limit' => 0,
+            'usage' => $quota
+        );
     }
 
 }
diff --git a/imp/lib/Quota/Null.php b/imp/lib/Quota/Null.php
new file mode 100644 (file)
index 0000000..c5ab1d1
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * The IMP_Quota_Null:: is a null implementation of the quota driver.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author  Michael Slusarz <slusarz@horde.org>
+ * @package IMP
+ */
+class IMP_Quota_Null extends IMP_Quota_Driver
+{
+    /**
+     * Get quota information (used/allocated), in bytes.
+     *
+     * @return array  An array with the following keys:
+     *                'limit' = Maximum quota allowed
+     *                'usage' = Currently used portion of quota (in bytes)
+     * @throws IMP_Exception
+     */
+    public function getQuota()
+    {
+        return array(
+            'limit' => 0,
+            'usage' => 0
+        );
+    }
+
+}
index 4fe36de..e8c68dc 100644 (file)
@@ -3,22 +3,6 @@
  * Implementation of the Quota API for servers keeping quota information in a
  * custom SQL database.
  *
- * You must configure this driver in imp/config/servers.php.  The driver
- * supports the following parameters:
- * <pre>
- * query_quota - (string) SQL query which returns single row/column with user
- *               quota (in bytes). %u is replaced with current user name, %U
- *               with the user name without the domain part, %d with the
- *               domain.
- * query_used - (string) SQL query which returns single row/column with user
- *              used space (in bytes). Placeholders are the same like in
- *              query_quota.
- * </pre>
- *
- * Additionally, the driver takes SQL connection parameters 'phptype',
- * 'hostspec',' 'username', 'password', and 'database'. See
- * horde/config/conf.php for further information on these parameters
- *
  * Copyright 2006-2007 Tomas Simonaitis <haden@homelan.lt>
  * Copyright 2006-2010 The Horde Project (http://www.horde.org/)
  *
@@ -29,7 +13,7 @@
  * @author  Jan Schneider <jan@horde.org>
  * @package IMP
  */
-class IMP_Quota_Sql extends IMP_Quota
+class IMP_Quota_Sql extends IMP_Quota_Driver
 {
     /**
      * SQL connection object.
@@ -39,21 +23,43 @@ class IMP_Quota_Sql extends IMP_Quota
     protected $_db;
 
     /**
+     * Constructor.
+     *
+     * @param array $params  Parameters:
+     * <pre>
+     * 'query_quota' - (string) SQL query which returns single row/column with
+     *                 user quota (in bytes). %u is replaced with current user
+     *                 name, %U with the user name without the domain part, %d
+     *                 with the domain.
+     * 'query_used' - (string) SQL query which returns single row/column with
+     *                user used space (in bytes). Placeholders are the same
+     *                as in 'query_quota'.
+     * </pre>
+     */
+    public function __construct(array $params = array())
+    {
+        parent::__construct(array_merge(array(
+            'query_quota' => null,
+            'query_used' => null
+        ), $params);
+    }
+
+    /**
      * Connects to the database.
      *
      * @throws IMP_Exception
      */
     protected function _connect()
     {
-        if ($this->_db) {
-            return;
-        }
+        if (!$this->_db) {
+            $this->_db = DB::connect($this->_params, array(
+                'persistent' => !empty($this->_params['persistent']),
+                'ssl' => !empty($this->_params['ssl'])
+            ));
 
-        $this->_db = DB::connect($this->_params,
-                                 array('persistent' => !empty($this->_params['persistent']),
-                                       'ssl' => !empty($this->_params['ssl'])));
-        if ($this->_db instanceof PEAR_Error) {
-            throw new IMP_Exception(_("Unable to connect to SQL server."));
+            if ($this->_db instanceof PEAR_Error) {
+                throw new IMP_Exception(_("Unable to connect to SQL server."));
+            }
         }
     }
 
@@ -70,7 +76,10 @@ class IMP_Quota_Sql extends IMP_Quota
         $this->_connect();
 
         $user = $_SESSION['imp']['user'];
-        $quota = array('limit' => 0, 'usage' => 0);
+        $quota = array(
+            'limit' => 0,
+            'usage' => 0
+        );
 
         if (!empty($this->_params['query_quota'])) {
             @list($bare_user, $domain) = explode('@', $user, 2);