[[toc]]
##red|This information is valid for Horde 5 and later only. See AltQuotaH4 for Horde 4 or AltQuotaH3 for Horde 3.##
+++ Notes
IMP 6, Horde 5
Modifies basic and dynamic views to display quotas.
This describes modifications to IMP 6 (Horde 5) quota
to use two different partitions (file systems) with quota enabled.
One is used for INBOX and the other is used for IMAP folders.
This allows different quota values for INBOX and IMAP folders.
It uses modified quota Imap driver and related Imp files.
Tested on Debian 7 (wheezy, stable) with Dovecot (wheezy distribution), Horde 5.1.5-IMP 6.1.6
+++ Modifications
||~ File ||~ Variables, Function(s) ||
|| imp/config/backends.local.php || quota ||
|| imp/lib/Quota/Imap.php || getQuota ||
|| imp/lib/Quota/Ui.php || quota ||
|| imp/lib/Quota.php || construct ||
|| imp/lib/Ajax/Queue.php || m, p, l, add ||
|| imp/lib/View/Subinfo.php || construct ||
|| imp/js/dimpbase.js || r.m, r.l, quotaCallback ||
|| imp/templates/basic/subinfo.html.php || quotaClass, quotaText ||
|| imp/templates/dynamic/mailbox_subinfo.html.php || quota-text ||
//Last updated 2014-01-01//
[[image Qfolders90.png alt="Image of IMP showing quotas and 90% warning"]]
++++ Configuration example (imp/config/backends.local.php)
$servers['imap'] = array(
...
'quota' => array(
'driver' => 'imap',
'params' => array(
'hide_when_unlimited' => false,
'unit' => 'GB'
)
...
);
++++ imp/lib/Quota/Imap.php
$quotavar, usagevar, limitvar.
$quotahome, usagehome, limithome.
Backup your original imp/lib/Quota/Imap.php and create a new Imap.php with the following code:
* Updated 2013 December 18
*/
/**
* Common code dealing with quota UI display.
*
* @author Michael Slusarz
* @category Horde
* @copyright 2012-2013 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
class IMP_Quota_Ui
{
/**
* Returns data needed to output quota.
*
* @param string $mailbox Mailbox to query.
*
* @return array Array with these keys: class, message, percent.
*/
public function quota($mailbox = null)
{
global $injector;
if (!$injector->getInstance('IMP_Imap')->config->quota) {
return false;
}
if (!is_null($mailbox)) {
$mailbox = IMP_Mailbox::get($mailbox);
if ($mailbox->nonimap) {
return false;
}
}
try {
$quotaDriver = $injector->getInstance('IMP_Quota');
$quota = $quotaDriver->getQuota($mailbox);
} catch (IMP_Exception $e) {
Horde::log($e, 'ERR');
return false;
}
if (empty($quota)) {
return false;
}
$strings = $quotaDriver->getMessages();
list($calc, $unit) = $quotaDriver->getUnit();
$ret = array(
'classvar' => '',
'percentvar' => 0,
'classhome' => '',
'percenthome' => 0
);
/* Quota for dev_fldrs */
unset($ret['messagehome']);
if ($quota['limithome'] != 0) {
$quota['usagehome'] = $quota['usagehome'] / $calc;
$quota['limithome'] = $quota['limithome'] / $calc;
$ret['percenthome'] = ($quota['usagehome'] * 100) / $quota['limithome'];
if ($ret['percenthome'] >= 100) {
$ret['classhome'] = 'quotaalert';
} elseif ($ret['percenthome'] >= 90) {
$ret['classhome'] = 'quotawarn';
}
if ($quota['usagevar'] != 0) {
$ret['messagehome'] = sprintf($strings['shorth'], $ret['percenthome'], $quota['limithome'], $unit);
$ret['percenthome'] = sprintf("%.2f", $ret['percenthome']);
} else {
$ret['messagehome'] = sprintf($strings['sshorth'], $ret['percenthome'], $quota['limithome'], $unit);
$ret['percenthome'] = sprintf("%.2f", $ret['percenthome']);
}
} else {
if ($quota['usagehome'] != 0) {
if ($quota['usagevar'] != 0) {
$quota['usagehome'] = $quota['usagehome'] / $calc;
$ret['messagehome'] = sprintf($strings['nolimit_shorth'], $quota['usagehome'], $unit);
} else {
$quota['usagehome'] = $quota['usagehome'] / $calc;
$ret['messagehome'] = sprintf($strings['nolimit_sshorth'], $quota['usagehome'], $unit);
}
} else {
$ret['messagehome'] = _(" ");
}
}
/* Quota for dev_inbx */
if ($quota['limitvar'] != 0) {
$quota['usagevar'] = $quota['usagevar'] / $calc;
$quota['limitvar'] = $quota['limitvar'] / $calc;
$ret['percentvar'] = ($quota['usagevar'] * 100) / $quota['limitvar'];
if ($ret['percentvar'] >= 100) {
$ret['classvar'] = 'quotaalert';
} elseif ($ret['percentvar'] >= 90) {
$ret['classvar'] = 'quotawarn';
}
$ret['messagevar'] = sprintf($strings['shortv'], $ret['percentvar'], $quota['limitvar'], $unit);
$ret['percentvar'] = sprintf("%.2f", $ret['percentvar']);
} else {
if ($quota['usagevar'] != 0) {
$quota['usagevar'] = $quota['usagevar'] / $calc;
$ret['messagevar'] = sprintf($strings['nolimit_shortv'], $quota['usagevar'], $unit);
} else {
$ret['messagevar'] = _(" ");
}
}
return $ret;
}
}
----
++++ imp/lib/Quota.php
* Only short formats.
Backup your original imp/lib/Quota.php and replace function construct with the following code:
public function __construct(array $params = array())
{
$this->_params = array_merge($this->_params, $params);
$this->_params['format'] = array(
'shortv' => isset($this->_params['format']['short'])
? $this->_params['format']['short']
: _("Inbox: %.0f%% of %.1f %s"),
'shorth' => isset($this->_params['format']['shorth'])
? $this->_params['format']['shorth']
: _(" - Folders: %.0f%% of %.1f %s"),
'sshorth' => isset($this->_params['format']['sshorth'])
? $this->_params['format']['sshorth']
: _("Folders: %.0f%% of %.1f %s"),
'nolimit_shortv' => isset($this->_params['format']['nolimit_short'])
? $this->_params['format']['nolimit_short']
: _("Inbox: %.1f %s"),
'nolimit_shorth' => isset($this->_params['format']['nolimit_shorth'])
? $this->_params['format']['nolimit_shorth']
: _(" - Folders: %.1f %s"),
'nolimit_sshorth' => isset($this->_params['format']['nolimit_sshorth'])
? $this->_params['format']['nolimit_sshorth']
: _("Folders: %.1f %s"),
);
}
----
++++ imp/lib/Ajax/Queue.php
* mv, pv, lv: quota message, percentage and class for Inbox.
* mh, ph, lh: quota message, percentage and class for folders.
* merrov, mvclasse, merroh, mhclasse: Message when usage > 90%.
Backup your original imp/lib/Ajax/Queue.php and replace function add with the following code:
public function add(IMP_Ajax_Application $ajax)
{
global $injector, $registry;
/* Add compose attachment information. */
if (!empty($this->_atc)) {
$ajax->addTask('compose-atc', $this->_atc);
$this->_atc = array();
}
/* Add compose information. */
if (!is_null($this->_compose)) {
$compose = new stdClass;
if (!$this->_compose->additionalAttachmentsAllowed()) {
$compose->atclimit = 1;
}
$compose->cacheid = $this->_compose->getCacheId();
$ajax->addTask('compose', $compose);
$this->_compose = null;
}
/* Add flag information. */
if (!empty($this->_flag)) {
$ajax->addTask('flag', $this->_flag);
$this->_flag = array();
}
/* Add flag configuration. */
if ($this->_flagconfig) {
$flags = array();
foreach ($injector->getInstance('IMP_Flags')->getList() as $val) {
$flags[] = array_filter(array(
'a' => $val->canset,
'b' => $val->bgdefault ? null : $val->bgcolor,
'c' => $val->css,
'f' => $val->fgcolor,
'i' => $val->css ? null : $val->cssicon,
'id' => $val->id,
'l' => $val->label,
's' => intval($val instanceof IMP_Flag_Imap),
'u' => intval($val instanceof IMP_Flag_User)
));
}
$ajax->addTask('flag-config', $flags);
}
/* Add folder tree information. */
$imptree = $injector->getInstance('IMP_Imap_Tree');
$imptree->setIteratorFilter(
($registry->getView() == $registry::VIEW_DYNAMIC)
? $imptree::FLIST_NOSPECIALMBOXES
: 0
);
$out = $imptree->getAjaxResponse();
if (!empty($out)) {
$ajax->addTask('mailbox', array_merge($out, $this->_mailboxOpts));
}
/* Add mail log information. */
if (!empty($this->_maillog)) {
$imp_maillog = $injector->getInstance('IMP_Maillog');
$maillog = array();
foreach ($this->_maillog as $val) {
if ($tmp = $imp_maillog->getLogObs($val['msg_id'])) {
$log_ob = new stdClass;
$log_ob->buid = intval($val['buid']);
$log_ob->log = $tmp;
$log_ob->mbox = $val['mailbox']->form_to;
$maillog[] = $log_ob;
}
}
if (!empty($maillog)) {
$ajax->addTask('maillog', $maillog);
}
}
/* Add message information. */
if (!empty($this->_messages)) {
$ajax->addTask('message', $this->_messages);
$this->_messages = array();
}
/* Add poll information. */
$poll = $poll_list = array();
foreach ($this->_poll as $val) {
$poll_list[strval($val)] = 1;
}
if (count($poll_list)) {
$imap_ob = $injector->getInstance('IMP_Imap');
if ($imap_ob->init) {
foreach ($imap_ob->statusMultiple(array_keys($poll_list), Horde_Imap_Client::STATUS_UNSEEN) as $key => $val) {
$poll[IMP_Mailbox::formTo($key)] = intval($val['unseen']);
}
}
if (!empty($poll)) {
$ajax->addTask('poll', $poll);
$this->_poll = array();
}
}
/* Add quota information. */
if (($this->_quota !== false) &&
($quotadata = $injector->getInstance('IMP_Quota_Ui')->quota($this->_quota))) {
/* Quota for dev_inbx */
$merrov = null;
if (round($quotadata['percentvar']) >= 100) {
$mvclasse = 'horde.error';
$merrov = sprintf("Inbox above limit.");
} else if ($quotadata['percentvar'] >= 90) {
$merrov = sprintf("Inbox above 90%%.");
$mvclasse = 'horde.warning';
}
/* Quota for dev_fldrs */
$merroh = null;
if (round($quotadata['percenthome'] >= 100)) {
$mhclasse = 'horde.error';
$merroh = sprintf("Folders above limit.");
} elseif ($quotadata['percenthome'] >= 90) {
$merroh = sprintf("Folders above 90%%.");
$mhclasse = 'horde.warning';
}
if (!empty($merrov)) {
$GLOBALS['notification']->push($merrov, $mvclasse);
}
if (!empty($merroh)) {
$GLOBALS['notification']->push($merroh, $mhclasse);
}
$ajax->addTask('quota', array(
'mv' => $quotadata['messagevar'],
'pv' => round($quotadata['percentvar']),
'lv' => $quotadata['percentvar'] >= 100
? 'alert'
: ($quotadata['percentvar'] >= 90 ? 'warn' : 'control'),
'mh' => $quotadata['messagehome'],
'ph' => round($quotadata['percenthome']),
'lh' => $quotadata['percenthome'] >= 100
? 'alert'
: ($quotadata['percenthome'] >= 90 ? 'warn' : 'control')
));
$this->_quota = false;
}
}
----
++++ imp/lib/View/Subinfo.php
* function __construct: quotaClassV, quotaTextV, quotaClassH, quotaTextH.
Backup your original imp/lib/View/Subinfo.php and replace function construct with the following code:
public function __construct(array $config = array())
{
$config['templatePath'] = IMP_TEMPLATES . '/basic';
parent::__construct($config);
$quotadata = $GLOBALS['injector']->getInstance('IMP_Quota_Ui')->quota(isset($config['mailbox']) ? $config['mailbox'] : null);
if (!empty($quotadata)) {
$this->quotaClassV = $quotadata['classvar'];
$this->quotaTextV = $quotadata['messagevar'];
$this->quotaClassH = $quotadata['classhome'];
$this->quotaTextH = $quotadata['messagehome'];
}
}
----
++++ imp/js/dimpbase.js
* quotaCallback
> quotaV, mv, lv.
> quotaH, mh, lh.
Backup your original imp/js/dimpbase.js. Edit dimpbase.js and replace quotaCallback with the following code:
quotaCallback: function(r)
{
var quotaV = $('quota-textV');
var quotaH = $('quota-textH');
quotaV.removeClassName('quotaalert').
removeClassName('quotawarn').
setText(r.mv);
quotaH.removeClassName('quotaalert').
removeClassName('quotawarn').
setText(r.mh);
switch (r.lv) {
case 'alert':
case 'warn':
quotaV.addClassName('quota' + r.lv);
break;
}
switch (r.lh) {
case 'alert':
case 'warn':
quotaH.addClassName('quota' + r.lh);
break;
}
},
----
++++ imp/templates/basic/subinfo.html.php
* quotaTextV, quotaClassV, quotaTextH, quotaClassH.
Backup your original imp/templates/basic/subinfo.html.php and replace the following code:
From:
quotaText): ?>
quotaText ?>
To:
quotaTextV ?>
quotaTextH): ?>quotaTextH ?>
---- ++++ imp/templates/dynamic/mailbox_subinfo.html.php * quota-textV, quota-textH.Backup your original imp/templates/dynamic/mailbox_subinfo.html.php and replace the following code:
From:
To: