static public function singleton($driver, $params = array())
{
ksort($params);
- $signature = md5(serialize(array($driver, $params)));
+ $sig = hash('md5', serialize(array($driver, $params)));
- if (!isset(self::$_instances[$signature])) {
- self::$_instances[$signature] = IMP_Quota::getInstance($driver, $params);
+ if (!isset(self::$_instances[$sig])) {
+ self::$_instances[$sig] = IMP_Quota::getInstance($driver, $params);
}
- return self::$_instances[$signature];
+ return self::$_instances[$sig];
}
/**
static public function getInstance($driver, $params = array())
{
$driver = basename($driver);
- $class = 'IMP_Quota_' . $driver;
+ $class = 'IMP_Quota_' . ucfirst($driver);
if (class_exists($class)) {
return new $class($params);
return array($calc, $unit);
}
+
}
--- /dev/null
+<?php
+/**
+ * Implementation of IMP_Quota API for IMAP servers with a *nix quota command.
+ * This requires a modified "quota" command that allows the httpd server
+ * account to get quotas for other users. It also requires that your
+ * web server and imap server be the same server or at least have shared
+ * 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 horde/imp/config/servers.php. The
+ * driver supports the following parameters:
+ * 'quota_path' => Path to the quota binary - REQUIRED
+ * 'grep_path' => Path to the grep binary - REQUIRED
+ * 'partition' => 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.
+ *
+ * Copyright 2002-2009 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 Eric Rostetter <eric.rostetter@physics.utexas.edu>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Command extends IMP_Quota
+{
+ /**
+ * Constructor.
+ *
+ * @param array $params Hash containing connection parameters.
+ */
+ protected function __construct($params = array())
+ {
+ $params = array_merge(array(
+ 'quota_path' => 'quota',
+ 'grep_path' => 'grep',
+ 'partition' => null
+ ), $params);
+
+ parent::__construct($params);
+ }
+
+ /**
+ * Get the disk block size, if possible.
+ *
+ * We try to find out the disk block size from stat(). If not
+ * available, stat() should return -1 for this value, in which
+ * case we default to 1024 (for historical reasons). There are a
+ * large number of reasons this may fail, such as OS support,
+ * SELinux interference, the file being > 2 GB in size, the file
+ * we're referring to not being readable, etc.
+ *
+ * @return integer The disk block size.
+ */
+ protected function _blockSize()
+ {
+ $results = stat(__FILE__);
+ return ($results['blksize'] > 1)
+ ? $results['blksize']
+ : 1024;
+ }
+
+ /**
+ * 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()
+ {
+ if (empty($this->_params['partition'])) {
+ $passwd_array = posix_getpwnam($_SESSION['imp']['user']);
+ list($junk, $search_string, $junk) = explode('/', $passwd_array['dir']);
+ } else {
+ $search_string = $this->_params['partition'];
+ }
+ $cmdline = $this->_params['quota_path'] . ' -u ' . $_SESSION['imp']['user'] . ' | ' . $this->_params['grep_path'] . ' ' . $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);
+ }
+
+ throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of IMP_Quota API for a generic hook function. This
+ * requires hook_get_quota to be set in config/hooks.php . The
+ * function takes an array as argument and returns an array where the
+ * first item is the disk space used in bytes and the second the
+ * maximum diskspace in bytes. See there for an example.
+ *
+ * You must configure this driver in horde/imp/config/servers.php. The
+ * driver supports the following parameters:
+ * 'params' => Array of parameters to pass to the quota function.
+ *
+ * Copyright 2002-2009 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 Redinger <Michael.Redinger@uibk.ac.at>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Hook extends IMP_Quota
+{
+ /**
+ * 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()
+ {
+ $quota = Horde::callHook('_imp_hook_quota', $this->_params, 'imp');
+
+ if (count($quota) != 2) {
+ Horde::logMessage('Incorrect number of return values from quota hook.', __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
+ }
+
+ return array('usage' => $quota[0], 'limit' => $quota[1]);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of the IMP_Quota API for IMAP servers.
+ *
+ * Copyright 2002-2009 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 Mike Cochrane <mike@graftonhall.co.nz>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Imap extends IMP_Quota
+{
+ /**
+ * 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()
+ {
+ try {
+ $quota = $GLOBALS['imp_imap']->ob->getQuotaRoot($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp_mbox']['mailbox']) ? 'INBOX' : $GLOBALS['imp_mbox']['mailbox']);
+ } catch (Horde_Imap_Client_Exception $e) {
+ throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
+ }
+
+ $quota_val = reset($quota);
+ return array('usage' => $quota['storage']['usage'] * 1024, 'limit' => $quota['storage']['limit'] * 1024);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of the Quota API for servers where IMAP Quota is not
+ * supported, but it appears in the servers messages log for the IMAP
+ * server.
+ *
+ * Requires the following parameter settings in imp/servers.php:
+ * <pre>
+ * 'quota' => array(
+ * 'driver' => 'logfile',
+ * 'params' => array(
+ * 'logfile' => '/path/to/log/file',
+ * 'taillines' => 10,
+ * 'FTPmail' => 'FTP',
+ * 'beginocc' => 'usage = ',
+ * 'midocc' => ' of ',
+ * 'endocc' => ' bytes'
+ * )
+ * );
+ *
+ * logfile - The path/to/filename of the log file to use.
+ * taillines - The number of lines to look at in the tail of the logfile.
+ * FTPmail - If you want to show what FTP space is available (IMAP folder)
+ * or what mail space is available (INBOX).
+ * Defines the search string to username:
+ * FTPmail to identify the line with QUOTA info.
+ * beginocc - String that designates the characters before the usage
+ * number.
+ * midocc - String between usage and total storage space.
+ * endocc - String after the storage number.
+ * </pre>
+ *
+ * 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 Tim Gorter <email@teletechnics.co.nz>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Logfile extends IMP_Quota
+{
+ /**
+ * Constructor
+ *
+ * @param array $params Hash containing connection parameters.
+ */
+ protected function __construct($params = array())
+ {
+ parent::__construct(array_merge(array(
+ 'logfile' => '',
+ 'taillines' => 10,
+ 'FTPmail' => 'FTP',
+ 'beginocc' => 'usage = ',
+ 'midocc' => ' of ',
+ 'endocc' => ' bytes'
+ ), $params));
+ }
+
+ /**
+ * 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()
+ {
+ if (!is_file($this->_params['logfile'])) {
+ throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
+ }
+
+ $full = file($this->_params['logfile']);
+ for (; $this->_params['taillines'] > 0; --$this->_params['taillines']) {
+ $tail[] = $full[count($full) - $this->_params['taillines']];
+ }
+
+ $uname = $_SESSION['imp']['user'];
+ $FTPmail = $this->_params['FTPmail'];
+ $virtline = preg_grep("[$uname: $FTPmail]", $tail);
+ $virtline = array_values($virtline);
+ $usage = substr($virtline[0], strpos($virtline[0], $this->_params['beginocc']) + strlen($this->_params['beginocc']), strpos($virtline[0], $this->_params['midocc']));
+ $storage = substr($virtline[0], strpos($virtline[0], $this->_params['midocc']) + strlen($this->_params['midocc']), strpos($virtline[0], $this->_params['endocc']));
+
+ return array('usage' => $usage, 'limit' => $storage);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of the Quota API for servers using Maildir++ quota files on
+ * the local filesystem. Currently only supports storage limit, but should be
+ * expanded to be configurable to support storage or message limits in the
+ * configuration array.
+ *
+ * Requires the following parameter settings in imp/servers.php:
+ * <pre>
+ * 'quota' => array(
+ * 'driver' => 'maildir',
+ * 'params' => array(
+ * 'path' => '/path/to/users/Maildir'
+ * // TODO: Add config param for storage vs message quota
+ * )
+ * );
+ *
+ * path - 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>
+ *
+ * Copyright 2007-2009 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 Eric Rostetter <eric.rostetter@physics.utexas.edu>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Maildir extends IMP_Quota
+{
+ /**
+ * Constructor.
+ *
+ * @param array $params Hash containing connection parameters.
+ */
+ protected function __construct($params = array())
+ {
+ parent::__construct(array_merge(array('path' => ''), $params));
+ }
+
+ /**
+ * Returns 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()
+ {
+ $storage_limit = $message_limit = $storage_used = $message_used = 0;
+
+ // Get the full path to the quota file.
+ $full = $this->_params['path'] . '/maildirsize';
+
+ // Substitute the username in the string if needed.
+ $uname = $_SESSION['imp']['user'];
+ $full = str_replace('~U', $uname, $full);
+
+ // Read in the quota file and parse it, if possible.
+ if (!is_file($full)) {
+ throw new Horde_Exception(_("Unable to retrieve quota"));
+ }
+
+ // Read in maildir quota file.
+ $lines = file($full);
+
+ // Parse the lines.
+ foreach ($lines as $line_number => $line) {
+ if ($line_number == 0) {
+ // First line, quota header.
+ $line = preg_replace('/[ \t\n\r\0\x0B]/', '', $line);
+ list($v1, $t1, $v2, $t2) = sscanf($line, '%ld%[CS],%ld%[CS]');
+ if (is_null($v1) || is_null($t1)) {
+ $v1 = 0;
+ }
+ if (is_null($v2) || is_null($t2)) {
+ $v2 = 0;
+ }
+
+ if ($t1 == 'S') {
+ $storage_limit = $v1;
+ }
+ if ($t1 == 'C') {
+ $message_limit = $v1;
+ }
+ if ($t2 == 'S') {
+ $storage_limit = $v2;
+ }
+ if ($t2 == 'C') {
+ $message_limit = $v2;
+ }
+ } else {
+ // Any line other than the first line.
+ // The quota used is the sum of all lines found.
+ list($storage, $message) = sscanf(trim($line), '%ld %d');
+ if (!is_null($storage)) {
+ $storage_used += $storage;
+ }
+ if (!is_null($message)) {
+ $message_used += $message;
+ }
+ }
+ }
+
+ return array('usage' => $storage_used, 'limit' => $storage_limit);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of the Quota API for MDaemon servers.
+ *
+ * Parameters required:
+ * <pre>
+ * 'app_location' -- TODO
+ * </pre>
+ *
+ * Copyright 2002-2009 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 Mike Cochrane <mike@graftonhall.co.nz>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Mdaemon extends IMP_Quota
+{
+ /**
+ * 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()
+ {
+ $userDetails = $this->_getUserDetails($_SESSION['imp']['user'], $_SESSION['imp']['maildomain']);
+
+ if ($userDetails !== false) {
+ $userHome = trim(substr($userDetails, 105, 90));
+ $total = intval(substr($userDetails, 229, 6)) * 1024;
+
+ if ($total == 0) {
+ return array('usage' => 0, 'limit' => 0);
+ }
+
+ if (($taken = $this->_mailboxSize($userHome)) !== false) {
+ return array('usage' => $taken, 'limit' => $total);
+ }
+ }
+
+ throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
+ }
+
+ /**
+ * Get the size of a mailbox
+ *
+ * @param string $path The full path of the mailbox to fetch the quota
+ * for including trailing backslash.
+ *
+ * @return mixed The number of bytes in the mailbox (integer) or false
+ * (boolean) on error.
+ */
+ protected function _mailboxSize($path)
+ {
+ $contents = file_get_contents($path . '\imap.mrk');
+
+ $pointer = 36;
+ $size = 0;
+ while ($pointer < strlen($contents)) {
+ $details = unpack('a17Filename/a11Crap/VSize', substr($contents, $pointer, 36));
+ $size += $details['Size'];
+ $pointer += 36;
+ }
+
+ /* Recursivly check subfolders. */
+ $d = dir($path);
+ while (($entry = $d->read()) !== false) {
+ if (($entry != '.') &&
+ ($entry != '..') &&
+ (substr($entry, -5, 5) == '.IMAP')) {
+ $size += $this->_mailboxSize($path . $entry . '\\');
+ }
+ }
+ $d->close();
+
+ return $size;
+ }
+
+ /**
+ * Retrieve relevant line from userlist.dat.
+ *
+ * @param string $user The username for which to retrieve detals.
+ * @param string $realm The realm (domain) for the user.
+ *
+ * @return mixed Line from userlist.dat (string) or false (boolean).
+ */
+ protected function _getUserDetails($user, $realm)
+ {
+ $searchString = str_pad($realm, 45) . str_pad($user, 30);
+
+ if (!($fp = fopen($this->_params['app_location'] . '/userlist.dat', 'rb'))) {
+ return false;
+ }
+
+ while (!feof($fp)) {
+ $line = fgets($fp, 4096);
+ if (substr($line, 0, strlen($searchString)) == $searchString) {
+ fclose($fp);
+ return $line;
+ }
+ }
+ fclose($fp);
+
+ return false;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of the Quota API for Mercury/32 IMAP servers.
+ * For reading Quota, read size folder user.
+ *
+ * Requires the following parameter settings in imp/servers.php:
+ * <pre>
+ * 'quota' => array(
+ * 'driver' => 'mercury32',
+ * 'params' => array(
+ * 'mail_user_folder' => 'c:/mercry/mail'
+ * )
+ * );
+ *
+ * 'mail_user_folder' -- The path to folder mail mercury
+ * </pre>
+ *
+ *****************************************************************************
+ * PROBLEM TO ACCESS NETWORK DIRECOTRY
+ *****************************************************************************
+ * Matt Grimm
+ * 06-Jun-2003 10:25
+ *
+ * Thought I could help clarify something with accessing network shares on a
+ * Windows network (2000 in this case), running PHP 4.3.2 under Apache 2.0.44.
+ * However you are logged into the Windows box, your Apache service must be
+ * running under an account which has access to the share. The easiest (and
+ * probably least safe) way for me was to change the user for the Apache
+ * service to the computer administrator (do this in the service properties,
+ * under the "Log On" tab). After restarting Apache, I could access mapped
+ * drives by their assigned drive letter ("z:\\") or regular shares by their
+ * UNC path ("\\\\shareDrive\\shareDir").
+ *****************************************************************************
+ *
+ * Copyright 2002-2009 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 Frank Lupo <frank_lupo@email.it>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Mercury32 extends IMP_Quota
+{
+ /**
+ * 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)
+ */
+ public function getQuota()
+ {
+ $quota = null;
+
+ $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);
+
+ if (!is_null($quota)) {
+ return array('usage' => $quota, 'limit' => 0);
+ }
+ }
+
+ throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implementation of the Quota API for servers keeping quota information in a
+ * custom SQL database.
+ *
+ * Driver must be configured in imp/config/servers.php. Parameters supported:
+ * <pre>
+ * phptype -- Database type to connect to
+ * hostspec -- Database host
+ * username -- User name for DB connection
+ * password -- Password for DB connection
+ * database -- Database name
+ * query_quota -- 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 -- SQL query which returns single row/column with user used
+ * space (in bytes). Placeholders are the same like in
+ * query_quota.
+ * </pre>
+ *
+ * Example how to reuse Horde's global SQL configuration:
+ * <code>
+ * 'quota' => array(
+ * 'driver' => 'sql',
+ * 'params' => array_merge(
+ * $GLOBALS['conf']['sql'],
+ * array(
+ * 'query_quota' => 'SELECT quota FROM quotas WHERE user = ?',
+ * 'query_used' => 'SELECT used FROM quotas WHERE user = ?'
+ * )
+ * )
+ * ),
+ * </code>
+ *
+ * Copyright 2006-2007 Tomas Simonaitis <haden@homelan.lt>
+ * Copyright 2006-2009 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 Tomas Simonaitis <haden@homelan.lt>
+ * @author Jan Schneider <jan@horde.org>
+ * @package IMP_Quota
+ */
+class IMP_Quota_Sql extends IMP_Quota
+{
+ /**
+ * SQL connection object.
+ *
+ * @var DB
+ */
+ protected $_db;
+
+ /**
+ * Connects to the database
+ *
+ * @throws Horde_Exception
+ */
+ protected function _connect()
+ {
+ if ($this->_db) {
+ return;
+ }
+
+ $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 Horde_Exception(_("Unable to connect to SQL server."));
+ }
+ }
+
+ /**
+ * Returns quota information.
+ *
+ * @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()
+ {
+ $this->_connect();
+
+ $user = $_SESSION['imp']['user'];
+ $quota = array('limit' => 0, 'usage' => 0);
+
+ if (!empty($this->_params['query_quota'])) {
+ @list($bare_user, $domain) = explode('@', $user, 2);
+ $query = str_replace(array('?', '%u', '%U', '%d'),
+ array($this->_db->quote($user),
+ $this->_db->quote($user),
+ $this->_db->quote($bare_user),
+ $this->_db->quote($domain)),
+ $this->_params['query_quota']);
+ $result = $this->_db->query($query);
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Exception($result);
+ }
+
+ $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+ if (is_array($row)) {
+ $quota['limit'] = current($row);
+ }
+ } else {
+ Horde::logMessage('IMP_Quota_Sql: query_quota SQL query not set', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ }
+
+ if (!empty($this->_params['query_used'])) {
+ @list($bare_user, $domain) = explode('@', $user, 2);
+ $query = str_replace(array('?', '%u', '%U', '%d'),
+ array($this->_db->quote($user),
+ $this->_db->quote($user),
+ $this->_db->quote($bare_user),
+ $this->_db->quote($domain)),
+ $this->_params['query_used']);
+ $result = $this->_db->query($query);
+ if ($result instanceof PEAR_Error) {
+ throw new Horde_Exception($result);
+ }
+
+ $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+ if (is_array($row)) {
+ $quota['usage'] = current($row);
+ }
+ } else {
+ Horde::logMessage('IMP_Quota_Sql: query_used SQL query not set', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ }
+
+ return $quota;
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * Implementation of IMP_Quota API for IMAP servers with a *nix quota command.
- * This requires a modified "quota" command that allows the httpd server
- * account to get quotas for other users. It also requires that your
- * web server and imap server be the same server or at least have shared
- * 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 horde/imp/config/servers.php. The
- * driver supports the following parameters:
- * 'quota_path' => Path to the quota binary - REQUIRED
- * 'grep_path' => Path to the grep binary - REQUIRED
- * 'partition' => 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.
- *
- * Copyright 2002-2009 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 Eric Rostetter <eric.rostetter@physics.utexas.edu>
- * @package IMP_Quota
- */
-class IMP_Quota_command extends IMP_Quota
-{
- /**
- * Constructor
- *
- * @param array $params Hash containing connection parameters.
- */
- protected function __construct($params = array())
- {
- $params = array_merge(array('quota_path' => 'quota',
- 'grep_path' => 'grep',
- 'partition' => null),
- $params);
- parent::__construct($params);
- }
-
- /**
- * Get the disk block size, if possible.
- *
- * We try to find out the disk block size from stat(). If not
- * available, stat() should return -1 for this value, in which
- * case we default to 1024 (for historical reasons). There are a
- * large number of reasons this may fail, such as OS support,
- * SELinux interference, the file being > 2 GB in size, the file
- * we're referring to not being readable, etc.
- *
- * @return integer The disk block size.
- */
- protected function _blockSize()
- {
- $results = stat(__FILE__);
- return ($results['blksize'] > 1)
- ? $results['blksize']
- : 1024;
- }
-
- /**
- * 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()
- {
- if (empty($this->_params['partition'])) {
- $passwd_array = posix_getpwnam($_SESSION['imp']['user']);
- list($junk, $search_string, $junk) = explode('/', $passwd_array['dir']);
- } else {
- $search_string = $this->_params['partition'];
- }
- $cmdline = $this->_params['quota_path'] . ' -u ' . $_SESSION['imp']['user'] . ' | ' . $this->_params['grep_path'] . ' ' . $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);
- }
-
- throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of IMP_Quota API for a generic hook function. This
- * requires hook_get_quota to be set in config/hooks.php . The
- * function takes an array as argument and returns an array where the
- * first item is the disk space used in bytes and the second the
- * maximum diskspace in bytes. See there for an example.
- *
- * You must configure this driver in horde/imp/config/servers.php. The
- * driver supports the following parameters:
- * 'params' => Array of parameters to pass to the quota function.
- *
- * Copyright 2002-2009 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 Redinger <Michael.Redinger@uibk.ac.at>
- * @package IMP_Quota
- */
-class IMP_Quota_hook extends IMP_Quota
-{
- /**
- * 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()
- {
- $quota = Horde::callHook('_imp_hook_quota', $this->_params, 'imp');
-
- if (count($quota) != 2) {
- Horde::logMessage('Incorrect number of return values from quota hook.', __FILE__, __LINE__, PEAR_LOG_ERR);
- throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
- }
-
- return array('usage' => $quota[0], 'limit' => $quota[1]);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of the IMP_Quota API for IMAP servers.
- *
- * Copyright 2002-2009 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 Mike Cochrane <mike@graftonhall.co.nz>
- * @package IMP_Quota
- */
-class IMP_Quota_imap extends IMP_Quota
-{
- /**
- * 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()
- {
- try {
- $quota = $GLOBALS['imp_imap']->ob->getQuotaRoot($GLOBALS['imp_search']->isSearchMbox($GLOBALS['imp_mbox']['mailbox']) ? 'INBOX' : $GLOBALS['imp_mbox']['mailbox']);
- } catch (Horde_Imap_Client_Exception $e) {
- throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
- }
-
- $quota_val = reset($quota);
- return array('usage' => $quota['storage']['usage'] * 1024, 'limit' => $quota['storage']['limit'] * 1024);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of the Quota API for servers where IMAP Quota is not
- * supported, but it appears in the servers messages log for the IMAP
- * server.
- *
- * Requires the following parameter settings in imp/servers.php:
- * 'quota' => array(
- * 'driver' => 'logfile',
- * 'params' => array(
- * 'logfile' => '/path/to/log/file',
- * 'taillines' => 10,
- * 'FTPmail' => 'FTP',
- * 'beginocc' => 'usage = ',
- * 'midocc' => ' of ',
- * 'endocc' => ' bytes'
- * )
- * );
- *
- * logfile - The path/to/filename of the log file to use.
- * taillines - The number of lines to look at in the tail of the logfile.
- * FTPmail - If you want to show what FTP space is available (IMAP folder)
- * or what mail space is available (INBOX).
- * Defines the search string to username:
- * FTPmail to identify the line with QUOTA info.
- * beginocc - String that designates the characters before the usage
- * number.
- * midocc - String between usage and total storage space.
- * endocc - String after the storage number.
- *
- * 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 Tim Gorter <email@teletechnics.co.nz>
- * @package IMP_Quota
- */
-class IMP_Quota_logfile extends IMP_Quota
-{
- /**
- * Constructor
- *
- * @param array $params Hash containing connection parameters.
- */
- protected function __construct($params = array())
- {
- parent::__construct(array_merge(array(
- 'logfile' => '',
- 'taillines' => 10,
- 'FTPmail' => 'FTP',
- 'beginocc' => 'usage = ',
- 'midocc' => ' of ',
- 'endocc' => ' bytes'
- ), $params));
- }
-
- /**
- * 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()
- {
- if (!is_file($this->_params['logfile'])) {
- throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
- }
-
- $full = file($this->_params['logfile']);
- for (; $this->_params['taillines'] > 0; --$this->_params['taillines']) {
- $tail[] = $full[count($full) - $this->_params['taillines']];
- }
-
- $uname = $_SESSION['imp']['user'];
- $FTPmail = $this->_params['FTPmail'];
- $virtline = preg_grep("[$uname: $FTPmail]", $tail);
- $virtline = array_values($virtline);
- $usage = substr($virtline[0], strpos($virtline[0], $this->_params['beginocc']) + strlen($this->_params['beginocc']), strpos($virtline[0], $this->_params['midocc']));
- $storage = substr($virtline[0], strpos($virtline[0], $this->_params['midocc']) + strlen($this->_params['midocc']), strpos($virtline[0], $this->_params['endocc']));
-
- return array('usage' => $usage, 'limit' => $storage);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of the Quota API for servers using Maildir++ quota files on
- * the local filesystem. Currently only supports storage limit, but should be
- * expanded to be configurable to support storage or message limits in the
- * configuration array.
- *
- * Requires the following parameter settings in imp/servers.php:
- * 'quota' => array(
- * 'driver' => 'maildir',
- * 'params' => array(
- * 'path' => '/path/to/users/Maildir'
- * // TODO: Add config param for storage vs message quota
- * )
- * );
- *
- * path - 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/'
- *
- * Copyright 2007-2009 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 Eric Rostetter <eric.rostetter@physics.utexas.edu>
- * @package IMP_Quota
- */
-class IMP_Quota_Maildir extends IMP_Quota
-{
- /**
- * Constructor.
- *
- * @param array $params Hash containing connection parameters.
- */
- protected function __construct($params = array())
- {
- parent::__construct(array_merge(array('path' => ''), $params));
- }
-
- /**
- * Returns 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()
- {
- $storage_limit = $message_limit = $storage_used = $message_used = 0;
-
- // Get the full path to the quota file.
- $full = $this->_params['path'] . '/maildirsize';
-
- // Substitute the username in the string if needed.
- $uname = $_SESSION['imp']['user'];
- $full = str_replace('~U', $uname, $full);
-
- // Read in the quota file and parse it, if possible.
- if (!is_file($full)) {
- throw new Horde_Exception(_("Unable to retrieve quota"));
- }
-
- // Read in maildir quota file.
- $lines = file($full);
-
- // Parse the lines.
- foreach ($lines as $line_number => $line) {
- if ($line_number == 0) {
- // First line, quota header.
- $line = preg_replace('/[ \t\n\r\0\x0B]/', '', $line);
- list($v1, $t1, $v2, $t2) = sscanf($line, '%ld%[CS],%ld%[CS]');
- if (is_null($v1) || is_null($t1)) {
- $v1 = 0;
- }
- if (is_null($v2) || is_null($t2)) {
- $v2 = 0;
- }
-
- if ($t1 == 'S') {
- $storage_limit = $v1;
- }
- if ($t1 == 'C') {
- $message_limit = $v1;
- }
- if ($t2 == 'S') {
- $storage_limit = $v2;
- }
- if ($t2 == 'C') {
- $message_limit = $v2;
- }
- } else {
- // Any line other than the first line.
- // The quota used is the sum of all lines found.
- list($storage, $message) = sscanf(trim($line), '%ld %d');
- if (!is_null($storage)) {
- $storage_used += $storage;
- }
- if (!is_null($message)) {
- $message_used += $message;
- }
- }
- }
-
- return array('usage' => $storage_used, 'limit' => $storage_limit);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of the Quota API for MDaemon servers.
- *
- * Parameters required:
- * 'app_location' -- TODO
- *
- * Copyright 2002-2009 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 Mike Cochrane <mike@graftonhall.co.nz>
- * @package IMP_Quota
- */
-class IMP_Quota_mdaemon extends IMP_Quota
-{
- /**
- * 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()
- {
- $userDetails = $this->_getUserDetails($_SESSION['imp']['user'], $_SESSION['imp']['maildomain']);
-
- if ($userDetails !== false) {
- $userHome = trim(substr($userDetails, 105, 90));
- $total = intval(substr($userDetails, 229, 6)) * 1024;
-
- if ($total == 0) {
- return array('usage' => 0, 'limit' => 0);
- }
-
- if (($taken = $this->_mailboxSize($userHome)) !== false) {
- return array('usage' => $taken, 'limit' => $total);
- }
- }
-
- throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
- }
-
- /**
- * Get the size of a mailbox
- *
- * @param string $path The full path of the mailbox to fetch the quota
- * for including trailing backslash.
- *
- * @return mixed The number of bytes in the mailbox (integer) or false
- * (boolean) on error.
- */
- protected function _mailboxSize($path)
- {
- $contents = file_get_contents($path . '\imap.mrk');
-
- $pointer = 36;
- $size = 0;
- while ($pointer < strlen($contents)) {
- $details = unpack('a17Filename/a11Crap/VSize', substr($contents, $pointer, 36));
- $size += $details['Size'];
- $pointer += 36;
- }
-
- /* Recursivly check subfolders. */
- $d = dir($path);
- while (($entry = $d->read()) !== false) {
- if (($entry != '.') &&
- ($entry != '..') &&
- (substr($entry, -5, 5) == '.IMAP')) {
- $size += $this->_mailboxSize($path . $entry . '\\');
- }
- }
- $d->close();
-
- return $size;
- }
-
- /**
- * Retrieve relevant line from userlist.dat.
- *
- * @param string $user The username for which to retrieve detals.
- * @param string $realm The realm (domain) for the user.
- *
- * @return mixed Line from userlist.dat (string) or false (boolean).
- */
- protected function _getUserDetails($user, $realm)
- {
- $searchString = str_pad($realm, 45) . str_pad($user, 30);
-
- if (!($fp = fopen($this->_params['app_location'] . '/userlist.dat', 'rb'))) {
- return false;
- }
-
- while (!feof($fp)) {
- $line = fgets($fp, 4096);
- if (substr($line, 0, strlen($searchString)) == $searchString) {
- fclose($fp);
- return $line;
- }
- }
- fclose($fp);
-
- return false;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of the Quota API for Mercury/32 IMAP servers.
- * For reading Quota, read size folder user.
- *
- * Requires the following parameter settings in imp/servers.php:
- * 'quota' => array(
- * 'driver' => 'mercury32',
- * 'params' => array(
- * 'mail_user_folder' => 'c:/mercry/mail'
- * )
- * );
- *
- * 'mail_user_folder' -- The path to folder mail mercury
- *
- *****************************************************************************
- * PROBLEM TO ACCESS NETWORK DIRECOTRY
- *****************************************************************************
- * Matt Grimm
- * 06-Jun-2003 10:25
- *
- * Thought I could help clarify something with accessing network shares on a
- * Windows network (2000 in this case), running PHP 4.3.2 under Apache 2.0.44.
- * However you are logged into the Windows box, your Apache service must be
- * running under an account which has access to the share. The easiest (and
- * probably least safe) way for me was to change the user for the Apache
- * service to the computer administrator (do this in the service properties,
- * under the "Log On" tab). After restarting Apache, I could access mapped
- * drives by their assigned drive letter ("z:\\") or regular shares by their
- * UNC path ("\\\\shareDrive\\shareDir").
- *****************************************************************************
- *
- * Copyright 2002-2009 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 Frank Lupo <frank_lupo@email.it>
- * @package IMP_Quota
- */
-class IMP_Quota_mercury32 extends IMP_Quota
-{
- /**
- * 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)
- */
- public function getQuota()
- {
- $quota = null;
-
- $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);
-
- if (!is_null($quota)) {
- return array('usage' => $quota, 'limit' => 0);
- }
- }
-
- throw new Horde_Exception(_("Unable to retrieve quota"), 'horde.error');
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implementation of the Quota API for servers keeping quota information in a
- * custom SQL database.
- *
- * Driver must be configured in imp/config/servers.php. Parameters supported:
- * <pre>
- * phptype -- Database type to connect to
- * hostspec -- Database host
- * username -- User name for DB connection
- * password -- Password for DB connection
- * database -- Database name
- * query_quota -- 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 -- SQL query which returns single row/column with user used
- * space (in bytes). Placeholders are the same like in
- * query_quota.
- * </pre>
- *
- * Example how to reuse Horde's global SQL configuration:
- * <code>
- * 'quota' => array(
- * 'driver' => 'sql',
- * 'params' => array_merge(
- * $GLOBALS['conf']['sql'],
- * array(
- * 'query_quota' => 'SELECT quota FROM quotas WHERE user = ?',
- * 'query_used' => 'SELECT used FROM quotas WHERE user = ?'
- * )
- * )
- * ),
- * </code>
- *
- * Copyright 2006-2007 Tomas Simonaitis <haden@homelan.lt>
- * Copyright 2006-2009 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 Tomas Simonaitis <haden@homelan.lt>
- * @author Jan Schneider <jan@horde.org>
- * @package IMP_Quota
- */
-class IMP_Quota_sql extends IMP_Quota
-{
- /**
- * SQL connection object.
- *
- * @var DB
- */
- protected $_db;
-
- /**
- * State of SQL connection.
- *
- * @var boolean
- */
- protected $_connected = false;
-
- /**
- * Connects to the database
- *
- * @throws Horde_Exception
- */
- protected function _connect()
- {
- if (!$this->_connected) {
- $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 Horde_Exception(_("Unable to connect to SQL server."));
- }
-
- $this->_connected = true;
- }
-
- return true;
- }
-
- /**
- * Returns quota information.
- *
- * @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()
- {
- $conn = $this->_connect();
- $user = $_SESSION['imp']['user'];
- $quota = array('limit' => 0, 'usage' => 0);
-
- if (!empty($this->_params['query_quota'])) {
- @list($bare_user, $domain) = explode('@', $user, 2);
- $query = str_replace(array('?', '%u', '%U', '%d'),
- array($this->_db->quote($user),
- $this->_db->quote($user),
- $this->_db->quote($bare_user),
- $this->_db->quote($domain)),
- $this->_params['query_quota']);
- $result = $this->_db->query($query);
- if (is_a($result, 'PEAR_Error')) {
- throw new Horde_Exception($result);
- }
-
- $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
- if (is_array($row)) {
- $quota['limit'] = current($row);
- }
- } else {
- Horde::logMessage('IMP_Quota_sql: query_quota SQL query not set', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- }
-
- if (!empty($this->_params['query_used'])) {
- @list($bare_user, $domain) = explode('@', $user, 2);
- $query = str_replace(array('?', '%u', '%U', '%d'),
- array($this->_db->quote($user),
- $this->_db->quote($user),
- $this->_db->quote($bare_user),
- $this->_db->quote($domain)),
- $this->_params['query_used']);
- $result = $this->_db->query($query);
- if (is_a($result, 'PEAR_Error')) {
- throw new Horde_Exception($result);
- }
-
- $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
- if (is_array($row)) {
- $quota['usage'] = current($row);
- }
- } else {
- Horde::logMessage('IMP_Quota_sql: query_used SQL query not set', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- }
-
- return $quota;
- }
-
-}
$params = Horde::getDriverConfig('sentmail', $driver);
}
- $driver = basename($driver);
- $class = 'IMP_Sentmail_' . $driver;
+ $class = 'IMP_Sentmail_' . ucfirst(basename($driver));
if (class_exists($class)) {
try {
*
* @throws Horde_Exception
*/
- public function __construct($params = array())
+ protected function __construct($params = array())
{
$this->_params = $params;
}
--- /dev/null
+<?php
+/**
+ * IMP_Sentmail implementation for PHP's PEAR database abstraction layer.
+ *
+ * Required values for $params:<pre>
+ * 'phptype' The database type (e.g. 'pgsql', 'mysql', etc.).
+ * 'table' The name of the foo table in 'database'.</pre>
+ *
+ * Required by some database implementations:<pre>
+ * 'database' The name of the database.
+ * 'hostspec' The hostname of the database server.
+ * 'protocol' The communication protocol ('tcp', 'unix', etc.).
+ * 'username' The username with which to connect to the database.
+ * 'password' The password associated with 'username'.
+ * 'options' Additional options to pass to the database.
+ * 'tty' The TTY on which to connect to the database.
+ * 'port' The port on which to connect to the database.</pre>
+ *
+ * The table structure can be created by the scripts/sql/imp_sentmail.sql
+ * script.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package IMP
+ */
+class IMP_Sentmail_Sql extends IMP_Sentmail
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var DB
+ */
+ protected $_db;
+
+ /**
+ * Constructor.
+ *
+ * @param array $params A hash containing connection parameters.
+ *
+ * @throws Horde_Exception
+ */
+ protected function __construct($params = array())
+ {
+ parent::__construct($params);
+
+ Horde::assertDriverConfig($this->_params, 'storage', array('phptype', 'table'));
+
+ if (!isset($this->_params['database'])) {
+ $this->_params['database'] = '';
+ }
+ if (!isset($this->_params['username'])) {
+ $this->_params['username'] = '';
+ }
+ if (!isset($this->_params['hostspec'])) {
+ $this->_params['hostspec'] = '';
+ }
+
+ /* Connect to the SQL server using the supplied parameters. */
+ $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 Horde_Exception($this->_db);
+ }
+
+ /* Set DB portability options. */
+ switch ($this->_db->phptype) {
+ case 'mssql':
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+ break;
+
+ default:
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ }
+ }
+
+ /**
+ * Logs an attempt to send a message per recipient.
+ *
+ * @param string $action Why the message was sent, i.e. "new",
+ * "reply", "forward", etc.
+ * @param string $message_id The Message-ID.
+ * @param string $recipients A message recipient.
+ * @param boolean $success Whether the attempt was successful.
+ */
+ protected function _log($action, $message_id, $recipient, $success)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('INSERT INTO %s (sentmail_id, sentmail_who, sentmail_ts, sentmail_messageid, sentmail_action, sentmail_recipient, sentmail_success) VALUES (?, ?, ?, ?, ?, ?, ?)',
+ $this->_params['table']);
+ $values = array($this->_db->nextId($this->_params['table']),
+ Horde_Auth::getAuth(),
+ time(),
+ $message_id,
+ $action,
+ $recipient,
+ (int)$success);
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('IMP_Sentmail_sql::_log(): %s', $query),
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = $this->_db->query($query, $values);
+
+ /* Log errors. */
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ }
+ }
+
+ /**
+ * Returns the most favourite recipients.
+ *
+ * @param integer $limit Return this number of recipients.
+ * @param array $filter A list of messages types that should be returned.
+ * A value of null returns all message types.
+ *
+ * @return array A list with the $limit most favourite recipients.
+ * @throws Horde_Exception
+ */
+ public function favouriteRecipients($limit,
+ $filter = array('new', 'forward', 'reply', 'redirect'))
+ {
+ /* Build the SQL query. */
+ $where = '';
+ if (!empty($filter)) {
+ $filter = array_map(array($this->_db, 'quote'), $filter);
+ $where = sprintf(' AND sentmail_action in (%s)',
+ implode(', ', $filter));
+ }
+ $query = sprintf('SELECT sentmail_recipient, count(*) AS sentmail_count FROM %s WHERE sentmail_who = %s AND sentmail_success = 1%s GROUP BY sentmail_recipient ORDER BY sentmail_count DESC LIMIT %d',
+ $this->_params['table'],
+ $this->_db->quote(Horde_Auth::getAuth()),
+ $where,
+ $limit);
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('IMP_Sentmail_sql::favouriteRecipients(): %s', $query),
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $recipients = $this->_db->getAll($query);
+ if ($recipients instanceof PEAR_Error) {
+ Horde::logMessage($recipients, __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw new Horde_Exception($recipients);
+ }
+
+ /* Extract email addresses. */
+ $favourites = array();
+ foreach ($recipients as $recipient) {
+ $favourites[] = $recipient[0];
+ }
+
+ return $favourites;
+ }
+
+ /**
+ * Returns the number of recipients within a certain time period.
+ *
+ * @param integer $hours Time period in hours.
+ * @param boolean $user Return the number of recipients for the current
+ * user?
+ *
+ * @return integer The number of recipients in the given time period.
+ * @throws Horde_Exception
+ */
+ public function numberOfRecipients($hours, $user = false)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('SELECT COUNT(*) FROM %s WHERE sentmail_ts > ?',
+ $this->_params['table']);
+ if ($user) {
+ $query .= sprintf(' AND sentmail_who = %s', $this->_db->quote(Horde_Auth::getAuth()));
+ }
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('IMP_Sentmail_sql::numberOfRecipients(): %s', $query),
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $recipients = $this->_db->getOne($query, array(time() - $hours * 3600));
+ if ($recipients instanceof PEAR_Error) {
+ Horde::logMessage($recipients, __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw new Horde_Exception($recipients);
+ }
+
+ return $recipients;
+ }
+
+ /**
+ * Deletes all log entries older than a certain date.
+ *
+ * @param integer $before Unix timestamp before that all log entries
+ * should be deleted.
+ *
+ * @throw Horde_Exception
+ */
+ protected function _deleteOldEntries($before)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE sentmail_ts < ?',
+ $this->_params['table']);
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('IMP_Sentmail_sql::_deleteOldEntries(): %s', $query),
+ __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = $this->_db->query($query, array($before));
+ if ($result instanceof PEAR_Error) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ throw new Horde_Exception($result);
+ }
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * IMP_Sentmail implementation for PHP's PEAR database abstraction layer.
- *
- * Required values for $params:<pre>
- * 'phptype' The database type (e.g. 'pgsql', 'mysql', etc.).
- * 'table' The name of the foo table in 'database'.</pre>
- *
- * Required by some database implementations:<pre>
- * 'database' The name of the database.
- * 'hostspec' The hostname of the database server.
- * 'protocol' The communication protocol ('tcp', 'unix', etc.).
- * 'username' The username with which to connect to the database.
- * 'password' The password associated with 'username'.
- * 'options' Additional options to pass to the database.
- * 'tty' The TTY on which to connect to the database.
- * 'port' The port on which to connect to the database.</pre>
- *
- * The table structure can be created by the scripts/sql/imp_sentmail.sql
- * script.
- *
- * @author Jan Schneider <jan@horde.org>
- * @package IMP
- */
-class IMP_Sentmail_sql extends IMP_Sentmail
-{
- /**
- * Handle for the current database connection.
- *
- * @var DB
- */
- protected $_db;
-
- /**
- * Constructor.
- *
- * @param array $params A hash containing connection parameters.
- *
- * @throws Horde_Exception
- */
- function __construct($params = array())
- {
- parent::__construct($params);
-
- Horde::assertDriverConfig($this->_params, 'storage', array('phptype', 'table'));
-
- if (!isset($this->_params['database'])) {
- $this->_params['database'] = '';
- }
- if (!isset($this->_params['username'])) {
- $this->_params['username'] = '';
- }
- if (!isset($this->_params['hostspec'])) {
- $this->_params['hostspec'] = '';
- }
-
- /* Connect to the SQL server using the supplied parameters. */
- $this->_db = DB::connect($this->_params,
- array('persistent' => !empty($this->_params['persistent']),
- 'ssl' => !empty($this->_params['ssl'])));
- if (is_a($this->_db, 'PEAR_Error')) {
- throw new Horde_Exception($this->_db);
- }
-
- /* Set DB portability options. */
- switch ($this->_db->phptype) {
- case 'mssql':
- $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
- break;
-
- default:
- $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- }
- }
-
- /**
- * Logs an attempt to send a message per recipient.
- *
- * @param string $action Why the message was sent, i.e. "new",
- * "reply", "forward", etc.
- * @param string $message_id The Message-ID.
- * @param string $recipients A message recipient.
- * @param boolean $success Whether the attempt was successful.
- */
- protected function _log($action, $message_id, $recipient, $success)
- {
- /* Build the SQL query. */
- $query = sprintf('INSERT INTO %s (sentmail_id, sentmail_who, sentmail_ts, sentmail_messageid, sentmail_action, sentmail_recipient, sentmail_success) VALUES (?, ?, ?, ?, ?, ?, ?)',
- $this->_params['table']);
- $values = array($this->_db->nextId($this->_params['table']),
- Horde_Auth::getAuth(),
- time(),
- $message_id,
- $action,
- $recipient,
- (int)$success);
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('IMP_Sentmail_sql::_log(): %s', $query),
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = $this->_db->query($query, $values);
-
- /* Log errors. */
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- }
- }
-
- /**
- * Returns the most favourite recipients.
- *
- * @param integer $limit Return this number of recipients.
- * @param array $filter A list of messages types that should be returned.
- * A value of null returns all message types.
- *
- * @return array A list with the $limit most favourite recipients.
- * @throws Horde_Exception
- */
- public function favouriteRecipients($limit,
- $filter = array('new', 'forward', 'reply', 'redirect'))
- {
- /* Build the SQL query. */
- $where = '';
- if (!empty($filter)) {
- $filter = array_map(array($this->_db, 'quote'), $filter);
- $where = sprintf(' AND sentmail_action in (%s)',
- implode(', ', $filter));
- }
- $query = sprintf('SELECT sentmail_recipient, count(*) AS sentmail_count FROM %s WHERE sentmail_who = %s AND sentmail_success = 1%s GROUP BY sentmail_recipient ORDER BY sentmail_count DESC LIMIT %d',
- $this->_params['table'],
- $this->_db->quote(Horde_Auth::getAuth()),
- $where,
- $limit);
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('IMP_Sentmail_sql::favouriteRecipients(): %s', $query),
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $recipients = $this->_db->getAll($query);
- if (is_a($recipients, 'PEAR_Error')) {
- Horde::logMessage($recipients, __FILE__, __LINE__, PEAR_LOG_ERR);
- throw new Horde_Exception($recipients);
- }
-
- /* Extract email addresses. */
- $favourites = array();
- foreach ($recipients as $recipient) {
- $favourites[] = $recipient[0];
- }
-
- return $favourites;
- }
-
- /**
- * Returns the number of recipients within a certain time period.
- *
- * @param integer $hours Time period in hours.
- * @param boolean $user Return the number of recipients for the current
- * user?
- *
- * @return integer The number of recipients in the given time period.
- * @throws Horde_Exception
- */
- public function numberOfRecipients($hours, $user = false)
- {
- /* Build the SQL query. */
- $query = sprintf('SELECT COUNT(*) FROM %s WHERE sentmail_ts > ?',
- $this->_params['table']);
- if ($user) {
- $query .= sprintf(' AND sentmail_who = %s', $this->_db->quote(Horde_Auth::getAuth()));
- }
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('IMP_Sentmail_sql::numberOfRecipients(): %s', $query),
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $recipients = $this->_db->getOne($query, array(time() - $hours * 3600));
- if (is_a($recipients, 'PEAR_Error')) {
- Horde::logMessage($recipients, __FILE__, __LINE__, PEAR_LOG_ERR);
- throw new Horde_Exception($recipients);
- }
-
- return $recipients;
- }
-
- /**
- * Deletes all log entries older than a certain date.
- *
- * @param integer $before Unix timestamp before that all log entries
- * should be deleted.
- *
- * @throw Horde_Exception
- */
- protected function _deleteOldEntries($before)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE sentmail_ts < ?',
- $this->_params['table']);
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('IMP_Sentmail_sql::_deleteOldEntries(): %s', $query),
- __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = $this->_db->query($query, array($before));
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- throw new Horde_Exception($result);
- }
- }
-
-}