6.0.0-git
2024-04-19
Last Modified 2013-09-04 by Jan Schneider

This information is valid for Horde 4 only. See AltQuotaH3 for Horde 3 or AltQuota for Horde 5 and later.

Notes

IMP 5, Horde 4
Modifies traditional and dynamic views to display quotas.

This describes modifications to IMP 5 (Horde 4) quota to use two different devices (file systems) with quota enabled. One is for INBOX and the other is for IMAP folders.

This allows different quota values for INBOX and IMAP folders.

It uses system quota command.

Tested on Debian 6.0 (squeeze), horde-4.0.8 and imp-5.0.9.


Modifications

File Variables, Function(s)
imp/config/backends.php quota
imp/lib/Quota/Command.php blocksize, getQuota
imp/lib/Quota/Base.php _params, __construct
imp/lib/Ajax/Queue.php _quotah, _quotav, generate, quota
imp/lib/IMP.php quota, quotaData
imp/templates/dimp/index.inc if ($show_quota)
imp/templates/quota/quota.html
imp/themes/default/dimp/screen.css ini header
imp/js/dimpbase.js pollCallback, _displayQuota, _folderLoadCallback

You must modify the nine files. Don't forget to change permission to each of them:

chown www-data Command.php

Where www-data is the web user (Apache or equivalent).

You may need to give permission to your web user to execute quota:

chmod  +s  /usr/bin/quota

Last updated 2011-08-16


Descriptions


Configuration example

(imp/config/backends.php)

  • Two devices (file systems)
See Comand.php bellow for parameters.
Quota command must support "w" (do not wrap).

$servers['imap'] = array(
    ...

    'quota' => array(
        'driver' => 'command',
        'params' => array(
            'quota_path' => '/usr/bin/quota -w',
            'grep_path' => '/bin/grep',
            'dev_inbx' => '/dev/disk/by-uuid/734e96a4-af8f-4c83-a12c-4ab11b139a13',
            'dev_fldrs' => '/dev/sdb2',
            'unit' => 'GB',
        )
    ),
    ...
);

Command.php

  • blocksize = 1024.
  • Have INBOX and IMAP folders in different devices and quota enabled on them.
  • Function IMP_Quota_command accepts 2 new parameters:
'dev_inbx' (string) [REQUIRED] User´s INBOX file system device.
Usually maps to /var/mail, /var/spool/mail.
Examples: '/dev/hda6', '/dev/sdb2', '/dev/md2', '/dev/mapper/VOL1-VarM'.
'dev_fldrs' (string) [REQUIRED] User´s home file system device. Used for IMAP folders. Usually maps to /home.
Examples: '/dev/hda7', '/dev/sda3', '/dev/md1', '/dev/mapper/VOL2-Home'.
Obsolete parameter: partition
* function getQuota:
Function now takes care of exceeded quotas and quota not defined for that user.

Backup your original imp/lib/Quota/Command.php and create a new Command.php with the following code:
<?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.
 *
 * Copyright 2002-2011 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>
 * @category Horde
 * @license  http://www.fsf.org/copyleft/gpl.html GPL
 * @package  IMP
 * 
 * Modified by Mauricio Jose T. Tecles <mtecles@biof.ufrj.br>
 * Updated 2011 August 4
 */
class IMP_Quota_Command extends IMP_Quota_Base
{
    /**
     * Constructor.
     *
     * @param array $params  Parameters:
     * <pre>
     * 'grep_path' - (string) [REQUIRED] Path to the grep binary.
     * 'quota_path' - (string) [REQUIRED] Path to the quota binary.
     * 'dev_inbx'   - (string) [REQUIRED] User´s INBOX file system device
     *                   Usually: /,  /var/mail,  /var/spool/mail
     *                   Examples: '/dev/hda6', '/dev/sdb2', '/dev/md2', 
     *                             '/dev/mapper/VOL1-VarM'
     * 'dev_fldrs'  - (string) [REQUIRED] User´s home file system device
     *                   Have INBOX and IMAP folders in different
     *                   devices and quota enabled on them.
     *                   For IMAP folders. Usually: /home
     *                   Examples: '/dev/hda7', '/dev/sda3', '/dev/md1', 
     *                             '/dev/mapper/VOL2-Home'
     * </pre>
     */
    public function __construct(array $params = array())
    {
        $params = array_merge(array(
            'quota_path' => 'quota',
            'grep_path'  => 'grep',
            'dev_inbx'  => null,
            'dev_fldrs'  => 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 IMP_Exception
     */
    public function getQuota()
    {

        $cmdline = $this->_params['quota_path'] . ' -u ' . escapeshellarg($this->_params['username']);
        exec($cmdline, $quota_data, $return_code);
        
        $junk = count( $quota_data);
        $blocksize = 1024;

        /* 
        * Is quota exceeded? 
        */

        if ($return_code == 0) {
            /* 
            * Quota not exceeded 
            * Is quota defined? 
            */
            if (ereg("none$", $quota_data[0])) {
                /*
                * Quota not defined or user does not own any files.
                */
                if (empty($this->_params['dev_fldrs'])) {
                    return array('usagehome' => -1, 'soflimithome' => -1, 'usagevar' => 0, 'soflimitvar' => 0);
                } else {
                    return array('usagehome' => 0, 'soflimithome' => 0, 'usagevar' => 0, 'soflimitvar' => 0);
                }
            } else {
                /*
                * Quota defined
                */
                if ( $junk == 4 ) {
                    /*
                    * Quotas defined for dev_fldrs and dev_inbx
                    */
                    if (ereg($this->_params['dev_fldrs'], $quota_data[2])) {
                        $quotahome = split("[[:blank:]]+", trim($quota_data[2]));
                        $quotavar = split("[[:blank:]]+", trim($quota_data[3]));
                        return array('usagehome' => $quotahome[1] * $blocksize, 'soflimithome' => $quotahome[2] * $blocksize, 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize);
                    } elseif (ereg($this->_params['dev_inbx'], $quota_data[2])) {
                        $quotahome = split("[[:blank:]]+", trim($quota_data[3]));
                        $quotavar = split("[[:blank:]]+", trim($quota_data[2]));
                        return array('usagehome' => $quotahome[1] * $blocksize, 'soflimithome' => $quotahome[2] * $blocksize, 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize);
                    } 
                } else {
                    /*
                    * Either quota is defined only for dev_fldrs or dev_inbx
                    * or user owns file in only one file system.
                    */
                    if (ereg($this->_params['dev_inbx'], $quota_data[2])) {
                        $quotavar = split("[[:blank:]]+", trim($quota_data[2]));
                        if (!empty($this->_params['dev_fldrs'])) {
                            return array('usagehome' => 0, 'soflimithome' => 0, 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize);
                        } else {
                            return array('usagehome' => -1, 'soflimithome' => -1, 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize);
                        }
                    } elseif (!empty($this->_params['dev_fldrs'])) {
                        if (ereg($this->_params['dev_fldrs'], $quota_data[2])) {
                            $quotahome = split("[[:blank:]]+", trim($quota_data[2]));
                            return array('usagehome' => $quotahome[1] * $blocksize, 'soflimithome' => $quotahome[2] * $blocksize, 'usagevar' => 0, 'soflimitvar' => 0);
                        }    
                    }
                }
            }
        } else {
            /*
            * Some quota exceeded
            */
            if ( $junk == 4 ) {
                /*
                * Quotas defined for dev_fldrs and dev_inbx
                */
                if (ereg($this->_params['dev_fldrs'], $quota_data[2])) {
                    $quotahome = split("[[:blank:]]+", trim($quota_data[2]));
                    $quotavar = split("[[:blank:]]+", trim($quota_data[3]));
                } elseif (ereg($this->_params['dev_inbx'], $quota_data[2])) {
                    $quotahome = split("[[:blank:]]+", trim($quota_data[3]));
                    $quotavar = split("[[:blank:]]+", trim($quota_data[2]));
                }
                /*
                * 
                * Quota exceeded in dev_fldrs?
                */
                if (ereg("\*$", $quotahome[1])) {
                    $quotahome[1] = ereg_replace ("\*", "", $quotahome[1]);
                    $quotahome[4] = ereg_replace ("days", "", $quotahome[4]);
                } else {
                    $quotahome[4] == "";
                }
                /* 
                * Quota exceeded in dev_inbx?
                */
                if (ereg("\*$", $quotavar[1])) {
                    $quotavar[1] = ereg_replace ("\*", "", $quotavar[1]);
                    $quotavar[4] = ereg_replace ("days", "", $quotavar[4]);
                } else {
                    $quotavar[4] == "";
                }
                return array('usagehome' => $quotahome[1] * $blocksize, 'soflimithome' => $quotahome[2] * $blocksize, 'gracehome' => $quotahome[4], 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize, 'gracevar' => $quotavar[4]);
            } else {
                /*
                * Either quota is defined only for dev_fldrs or dev_inbx
                * or user owns file in only one file system.
                */
                if (ereg($this->_params[dev_inbx], $quota_data[2])) {
                    /** 
                    * Quota exceeded in dev_inbx.
                    */
                    $quotavar = split("[[:blank:]]+", trim($quota_data[2]));
                    $quotavar[1] = ereg_replace ("\*", "", $quotavar[1]);
                    $quotavar[4] = ereg_replace ("days", "", $quotavar[4]);
                    if (!empty($this->_params['dev_fldrs'])) {
                        return array('usagehome' => 0, 'soflimithome' => 0, 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize, 'gracevar' => $quotavar[4]);
                    } else {
                        return array('usagehome' => -1, 'soflimithome' => -1, 'usagevar' => $quotavar[1] * $blocksize, 'soflimitvar' => $quotavar[2] * $blocksize, 'gracevar' => $quotavar[4]);
                    }
                } else {
                    /* 
                    * Quota exceeded in dev_fldrs
                    */
                    $quotahome = split("[[:blank:]]+", trim($quota_data[2]));
                    $quotahome[1] = ereg_replace ("\*", "", $quotahome[1]);
                    $quotahome[4] = ereg_replace ("days", "", $quotahome[4]);
                    return array('usagehome' => $quotahome[1] * $blocksize, 'soflimithome' => $quotahome[2] * $blocksize, 'gracehome' => $quotahome[4], 'usagevar' => 0, 'soflimitvar' => 0);
                }
            }
        }

        throw new IMP_Exception(_("Unable to retrieve quota"));
    }

}

Base.php

  • New formats.
Only short formats.
* Defaults unit to GB:
$_params = array('unit' => 'GB')

Backup your original imp/lib/Quota/Base.php and create a new Base.php with the following code:
<?php
/**
 * The IMP_Quota_Base:: class is the abstract class that all drivers inherit
 * from.
 *
 * Copyright 2010-2011 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>
 * @category Horde
 * @license  http://www.fsf.org/copyleft/gpl.html GPL
 * @package  IMP
 */
abstract class IMP_Quota_Base
{
    /**
     * Driver parameters.
     *
     * @var array
     */
    protected $_params = array(
        'unit' => 'GB'
    );

    /**
     * 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'.
     * 'username' - (string) The username to query.
     * </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%% de %.1f %s"),
            'shorth' => isset($this->_params['format']['shorth'])
                ? $this->_params['format']['shorth']
                : _("Folders: %.0f%% de %.1f %s"),
            'shortv' => isset($this->_params['format']['shortv'])
                ? $this->_params['format']['shortv']
                : _("Inbox: %.0f%% de %.1f %s"),
            'longe' => isset($this->_params['format']['longe'])
                ? $this->_params['format']['longe']
                : _("Quota status: %.2f %s / %.2f %s  (%.2f%%) Solve in %s day(s)"),
            'longee' => isset($this->_params['format']['longee'])
                ? $this->_params['format']['longee']
                : _("Quota status: %.2f %s / %.2f %s  (%.2f%%) Grace time expired."),
            'shorte' => isset($this->_params['format']['shorte'])
                ? $this->_params['format']['shorte']
                : _("%.0f%% de %.1f %s Solve in %s day(s)"),
            'shorthe' => isset($this->_params['format']['shortee'])
                ? $this->_params['format']['shortee']
                : _("%.0f%% de %.1f %s Folders above limit. Solve in %s day(s)"),
            'shortve' => isset($this->_params['format']['shorte'])
                ? $this->_params['format']['shorte']
                : _("%.0f%% de %.1f %s Inbox above limit. Solve in %s day(s)"),
            'shortee' => isset($this->_params['format']['shortee'])
                ? $this->_params['format']['shortee']
                : _("%.0f%% de %.1f %s Grace time expired."),
            'shorthee' => isset($this->_params['format']['shortee'])
                ? $this->_params['format']['shortee']
                : _("%.0f%% de %.1f %s Folders above limit. Grace time expired."),
            'shortvee' => isset($this->_params['format']['shortee'])
                ? $this->_params['format']['shortee']
                : _("%.0f%% de %.1f %s Inbox above limit. Grace time expired."),
            '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']
                : _("%.1f %s"),
            'nolimit_shorth' => isset($this->_params['format']['nolimit_shorth'])
                ? $this->_params['format']['nolimit_shorth']
                : _("Folders: %.1f %s"),
            'nolimit_shortv' => isset($this->_params['format']['nolimit_shortv'])
                ? $this->_params['format']['nolimit_shortv']
                : _("Inbox: %.1f %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);
    }

}

Queue.php

  • quotah, mh (quota message for "home") and ph (quota percentage for "home")
  • quotav, mv (quota message for Inbox) and pv (quota percentage for Inbox)

Backup your original imp/lib/Ajax/Queue.php and create a new Queue.php with the following code:

<?php
/**
 * Defines an AJAX variable queue for IMP.  These are variables that may be
 * generated by various IMP code that should be added to the eventual output
 * to the browser.
 *
 * Copyright 2011 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>
 * @category Horde
 * @license  http://www.fsf.org/copyleft/gpl.html GPL
 * @package  IMP
 * 
 * Modified by Mauricio Jose T. Tecles <mtecles@biof.ufrj.br>
 * Updated 2011 August 4
 */
class IMP_Ajax_Queue
{
    /**
     * Flag entries to add to response.
     *
     * @var array
     */
    protected $_flag = array();

    /**
     * Poll mailboxes.
     *
     * @var array
     */
    protected $_poll = array();

    /**
     * Add quota information to response?
     *
     * @var boolean
     */
    protected $_quota = false;
    protected $_quotah = false;
    protected $_quotav = false;

    /**
     * Generates variable data from the queue.
     *
     * @return array  Queue data.
     * <pre>
     * For flag data (key: 'flag'), an array of objects with these properties:
     *   - add: (array) The list of flags that were added.
     *   - remove: (array) The list of flags that were removed.
     *   - uids: (string) Indices of the messages that have changed (IMAP
     *           sequence string).
     *
     * For poll data (key: 'poll'), an array with keys as mailbox names,
     * values as the number of unseen messages.
     *
     * For quota data (key: 'quota'), an array with these keys:
     *   - m: (string) Quota message.
     *   - p: (integer) Quota percentage.
     * </pre>
     */
    public function generate()
    {
        $res = array();

        /* Add flag information. */
        if (!empty($this->_flag)) {
            $res['flag'] = $this->_flag;
            $this->_flag = array();
        }

        /* Add poll information. */
        $poll = $poll_list = array();
        foreach ($this->_poll as $val) {
            $poll_list[strval($val)] = 1;
        }

        foreach ($GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->statusMultiple(array_keys($poll_list), Horde_Imap_Client::STATUS_UNSEEN) as $key => $val) {
            $poll[$key] = intval($val['unseen']);
        }

        if (!empty($poll)) {
            $res['poll'] = $poll;
            $this->_poll = array();
        }

        /* Add quota information. */
        if ($this->_quotah && $this->_quotav &&
            $GLOBALS['session']->get('imp', 'imap_quota') &&
            ($quotadata = IMP::quotaData(false))) {
            $res['quotah'] = array(
                'mh' => $quotadata['messagehome'],
                'ph' => round($quotadata['percenth'])
                );
            $res['quotav'] = array(
                'mv' => $quotadata['messagevar'],
                'pv' => round($quotadata['percentv'])
                );
            $this->_quotav = false;
            $this->_quotah = false;
        }

        return $res;
    }

    /**
     * Add flag entry to response queue.
     *
     * @param array $flags          List of flags that have changed.
     * @param boolean $add          Were the flags added?
     * @param IMP_Indices $indices  Indices object.
     */
    public function flag($flags, $add, $indices)
    {
        global $injector;

        if (!$injector->getInstance('IMP_Factory_Imap')->create()->access(IMP_Imap::ACCESS_FLAGS)) {
            return;
        }

        $changed = $injector->getInstance('IMP_Flags')->changed($flags, $add);

        $result = new stdClass;
        if (!empty($changed['add'])) {
            $result->add = array_map('strval', $changed['add']);
        }
        if (!empty($changed['remove'])) {
            $result->remove = array_map('strval', $changed['remove']);
        }
        $result->uids = strval($indices);

        $this->_flag[] = $result;
    }

    /**
     * Add poll entry to response queue.
     *
     * @param mixed $mboxes  A mailbox name or list of mailbox names.
     */
    public function poll($mboxes)
    {
        if (!is_array($mboxes)) {
            $mboxes = array($mboxes);
        }

        foreach (IMP_Mailbox::get($mboxes) as $val) {
            if ($val->polled) {
                $this->_poll[] = $val;
            }
        }
    }

    /**
     * Add quota entry to response queue.
     */
    public function quota()
    {
        $this->_quotah = true;
        $this->_quotav = true;
    }

}


IMP.php

  • For folders:
classh, messageh, soflimithome, usagehome, messagehome, percenth, merroh, mhclasse.
* Inbox:
classv, messagev, soflimitvar, usagevar, messagevar, percentv, merrov, mvclasse.
* Advertizes if quota >= 90%
Traditional view: quotawarn
Dynamic view: notification message (horde.warning), in addition to the colored bar.
* Advertizes if quota >= 100%
Traditional view: quotaalert, message including gracetime.
Dynamic view: notification message including gracetime (horde.error), in addition to the colored bar.

Backup your original imp/lib/IMP.php. Edit IMP.php and replace functions "quota" and "quotaData" with the following code:
    /**
     * Outputs IMP's quota information.
     * Modified by Mauricio Jose T. Tecles <mtecles@biof.ufrj.br>
     * Updated 2011 August 4
     */

     static public function quota()
    {
        $quotadata = self::quotaData(true);
        if (!empty($quotadata)) {
            $t = $GLOBALS['injector']->createInstance('Horde_Template');
            $t->set('classh', $quotadata['classhome']);
            $t->set('messageh', $quotadata['messagehome']);
            $t->set('classv', $quotadata['classvar']);
            $t->set('messagev', $quotadata['messagevar']);

            echo $t->fetch(IMP_TEMPLATES . '/quota/quota.html');
        }
    }

    /**
     * Returns data needed to output quota.
     *
     * @param boolean $long not used (false) -> short format.
     *
     * @return array  Array with these keys: classhome, classvar, messagehome, messagevar, percenth, percentv.
     *
     * Modified by Mauricio Jose T. Tecles <mtecles@biof.ufrj.br>
     * Updated 2011 August 4
     */

    static public function quotaData($long = true)
    {
        if (!$GLOBALS['session']->get('imp', 'imap_quota')) {
            return false;
        }

        try {
            $quotaDriver = $GLOBALS['injector']->getInstance('IMP_Quota');
            $quota = $quotaDriver->getQuota();
        } catch (IMP_Exception $e) {
            Horde::logMessage($e, 'ERR');
            return false;
        }

        if (empty($quota)) {
            return false;
        }

        $strings = $quotaDriver->getMessages();
        list($calc, $unit) = $quotaDriver->getUnit();
        $ret = array('percenth' => 0, 'percentv' => 0);

        $long = false;

        $view = self::getViewMode();

        switch ($view) {
        case 'dimp':
            /* Quota for dev_fldrs */
            unset($ret['messagehome']);
            if ($quota['soflimithome'] > 0) {
                $quota['usagehome'] = $quota['usagehome'] / $calc;
                $quota['soflimithome'] = $quota['soflimithome'] / $calc;
                $ret['percenth'] = ($quota['usagehome'] * 100) / $quota['soflimithome'];

                $merroh = null;
                $ret['messagehome'] = sprintf($strings['short'], $ret['percenth'], $quota['soflimithome'], $unit);
                $ret['percenth'] = sprintf("%.2f", $ret['percenth']);

                if ($ret['percenth'] >= 100) {
                    $mhclasse = 'horde.error';
                    if (ereg("none", $quota['gracehome'])) {
                        $merroh = sprintf("Folders above limit. Grace time expired");
                    } else {
                        $merroh = sprintf("Folders above limit. Solve in %s day(s)", $quota['gracehome']);
                    }
                } elseif ($ret['percenth'] >= 90) {
                    $merroh = sprintf("Folders above 90%%.");
                    $mhclasse = 'horde.warning';
                }
            } else {
                if ($quota['usagehome'] > 0) {
                    $quota['usagehome'] = $quota['usagehome'] / $calc;
                    $ret['messagehome'] = sprintf($strings['nolimit_short'], $quota['usagehome'], $unit);
                    $ret['percenth'] = 1;
                } else {
                    $ret['messagehome'] = _("No limit");
                    $ret['percenth'] = 1;
                }
            }

            /* Quota for dev_inbx */
            if ($quota['soflimitvar'] != 0) {
                $quota['usagevar'] = $quota['usagevar'] / $calc;
                $quota['soflimitvar'] = $quota['soflimitvar'] / $calc;
                $ret['percentv'] = ($quota['usagevar'] * 100) / $quota['soflimitvar'];

                $merrov = null;
                $ret['messagevar'] = sprintf($strings['short'], $ret['percentv'], $quota['soflimitvar'], $unit);
                $ret['percentv'] = sprintf("%.2f", $ret['percentv']);

                if ($ret['percentv'] >= 100) {
                    $mvclasse = 'horde.error';
                    if (ereg("none", $quota['gracevar'])) {
                        $merrov = sprintf("Inbox above limit. Grace time expired.");
                    } else {
                        $merrov = sprintf("Inbox above limit. Solve in %s day(s)", $quota['gracevar']);
                    }
                } else {
                    if ($ret['percentv'] >= 90) {
                        $merrov = sprintf("Inbox above 90%%.");
                        $mvclasse = 'horde.warning';
                    }
                }
            } else {
                if ($quota['usagevar'] != 0) {
                    $quota['usagevar'] = $quota['usagevar'] / $calc;
                    $ret['messagevar'] = sprintf($strings['nolimit_short'], $quota['usagevar'], $unit);
                    $ret['percentv'] = 1;
                } else {
                    $ret['messagevar'] = _("No limit");
                    $ret['percentv'] = 1;
                }
            }

            if (!empty($merrov)) {
                $GLOBALS['notification']->push($merrov, $mvclasse);
            }
            if (!empty($merroh)) {
                $GLOBALS['notification']->push($merroh, $mhclasse);
            }
            return $ret;

        case 'imp':
            /* Quota for dev_fldrs */
            unset($ret['messagehome']);
            if ($quota['soflimithome'] > 0) {
                $quota['usagehome'] = $quota['usagehome'] / $calc;
                $quota['soflimithome'] = $quota['soflimithome'] / $calc;
                $ret['percenth'] = ($quota['usagehome'] * 100) / $quota['soflimithome'];

                if ($ret['percenth'] >= 100) {
                    $ret['classhome'] = 'quotaalert';
                    if (ereg("none", $quota['gracehome'])) {
                        $ret['messagehome'] = sprintf($strings['shorthee'], $ret['percenth'], $quota['soflimithome'], $unit);
                        $ret['percenth'] = sprintf("%.2f", $ret['percenth']);
                    } else {
                        $ret['messagehome'] = sprintf($strings['shorthe'], $ret['percenth'], $quota['soflimithome'], $unit, $quota['gracehome']);
                        $ret['percenth'] = sprintf("%.2f", $ret['percenth']);
                    }
                } else {
                    if ($ret['percenth'] >= 90) {
                        $ret['classhome'] = 'quotawarn';
                    } else {
                        $ret['classhome'] = 'control';
                    }
                    $ret['messagehome'] = sprintf($strings['shorth'], $ret['percenth'], $quota['soflimithome'], $unit);
                    $ret['percenth'] = sprintf("%.2f", $ret['percenth']);
                }
            } else {
                $ret['classhome'] = 'control';
                if ($quota['usagehome'] > 0) {
                    $quota['usagehome'] = $quota['usagehome'] / $calc;
                    $ret['messagehome'] = sprintf($strings['nolimit_shorth'], $quota['usagehome'], $unit);
                } else {
                    $ret['messagehome'] = _("Folders: No limit");
                }
            }

            /* Quota for dev_inbx */
            if ($quota['soflimitvar'] != 0) {
                $quota['usagevar'] = $quota['usagevar'] / $calc;
                $quota['soflimitvar'] = $quota['soflimitvar'] / $calc;
                $ret['percentv'] = ($quota['usagevar'] * 100) / $quota['soflimitvar'];
                if ($ret['percentv'] >= 100) {
                    $ret['classvar'] = 'quotaalert';
                    if (ereg("none", $quota['gracevar'])) {
                        $ret['messagevar'] = sprintf($strings['shortvee'], $ret['percentv'], $quota['soflimitvar'], $unit);
                        $ret['percentv'] = sprintf("%.2f", $ret['percentv']);
                    } else {
                        $ret['messagevar'] = sprintf($strings['shortve'], $ret['percentv'], $quota['soflimitvar'], $unit, $quota['gracevar']);
                        $ret['percentv'] = sprintf("%.2f", $ret['percentv']);
                    }
                } else {
                    if ($ret['percentv'] >= 90) {
                        $ret['classvar'] = 'quotawarn';
                    } else {
                        $ret['classvar'] = 'control';
                    }
                    $ret['messagevar'] = sprintf($strings['shortv'], $ret['percentv'], $quota['soflimitvar'], $unit);
                    $ret['percentv'] = sprintf("%.2f", $ret['percentv']);
                }
            } else {
                $ret['classvar'] = 'control';
                if ($quota['usagevar'] != 0) {
                    $quota['usagevar'] = $quota['usagevar'] / $calc;
                    $ret['messagevar'] = sprintf($strings['nolimit_shortv'], $quota['usagevar'], $unit);
                } else {
                    $ret['messagevar'] = _("Inbox: No limit");
                }
            }
            return $ret;
        }
    
        
    }

index.inc

  • quotav, quotav-text
  • quotah, quotah-text

Backup your original imp/templates/dimp/index.inc. Edit index.inc and replace the following code (line 58):
Form:

<?php if ($show_quota): ?>
   <div id="quota">
    <div id="quota-text"></div>
    <?php echo $show_quota ?>
   </div>
<?php endif; ?>

To:
<?php if ($show_quota): ?>
   <div id="entrada">
   <?php echo _("Inbox:") ?>
   </div>
   <div id="quotav">
    <div id="quotav-text"></div>
    <?php echo $show_quota ?>
   </div>
   <div id="pastas">
   <?php echo _("Folders:") ?>
   </div>
   <div id="quotah">
    <div id="quotah-text"></div>
    <?php echo $show_quota ?>
   </div>
<?php endif; ?>


quota.html

  • classh, messageh
  • classv, messagev

Backup your original imp/templates/quota/quota.html and create a new quota.html with the following code:

<table id="quota">
 <tr>
  <td class="<tag:classh />">
   <tag:messageh />
  </td>
 </tr>
 <tr>
  <td class="<tag:classv />">
   <tag:messagev />
  </td>
 </tr></table>


screen.css

Backup your original imp/themes/default/dimp/screen.css. Edit screen.css and replace from "#quota" to "#quota-text" (including) with the following code (line 37):

#quota {
    font-weight: normal;
    padding-bottom: 3px;
}
#quotah {
    font-weight: normal;
    padding-bottom: 3px;
}
#quotav {
    font-weight: normal;
    padding-bottom: 3px;
}
div#quota {
    margin-top: 3px;
    border-top-width: 0;
    height: 14px;
}
div#quotah {
    margin-top: 3px;
    border-top-width: 0;
    height: 14px;
}
div#quotav {
    margin-top: 3px;
    border-top-width: 0;
    height: 14px;
}
div#entrada {
    margin-top: 1px;
    border-top-width: 0;
    height: 13px;
    font-weight: 12px;
    padding-bottom: 0px;
}
div#pastas {
    margin-top: 1px;
    border-top-width: 0;
    height: 13px;
    font-size: 12px;
    padding-bottom: 0px;
}
#quota .used {
    float: left;
    width: 99px;
    background: maroon url("../graphics/quotaback.jpg") repeat-y;
    text-align: right;
    border: 1px #000 solid;
    margin-right: 2px;
}
#quotah .used {
    float: left;
    width: 99px;
    background: maroon url("../graphics/quotaback.jpg") repeat-y;
    text-align: right;
    border: 1px #000 solid;
    margin-right: 2px;
}
#quotav .used {
    float: left;
    width: 99px;
    background: maroon url("../graphics/quotaback.jpg") repeat-y;
    text-align: right;
    border: 1px #000 solid;
    margin-right: 2px;
}
#quota .used img {
    display: inline;
    float: none;
    padding: 0;
    border-left: 1px #000 solid;
    height: 14px;
}
#quotah .used img {
    display: inline;
    float: none;
    padding: 0;
    border-left: 1px #000 solid;
    height: 14px;
}
#quotav .used img {
    display: inline;
    float: none;
    padding: 0;
    border-left: 1px #000 solid;
    height: 14px;
}
.tabset li#quota {
    border-top: 0;
}
.tabset li#quotah {
    border-top: 0;
}
.tabset li#quotav {
    border-top: 0;
}
#quota-text {
    position: absolute;
    margin-left: 2px;
    font-size: 95%;
}
#quotah-text {
    position: absolute;
    margin-left: 2px;
    font-size: 95%;
}
#quotav-text {
    position: absolute;
    margin-left: 2px;
    font-size: 95%;
}


dimpbase.js

  • _displayQuotah, mh, ph
  • _displayQuotav, mv, pv

Backup your original imp/js/dimpbase.js. Edit dimpbase.js and and replace the following codes:
Form: (pollCallback)

        if (r.quota) {
            this._displayQuota(r.quota);
        }

To:
        if (r.quotah) {
            this._displayQuotav(r.quotav);
            this._displayQuotah(r.quotah);
            }

Form: (_displayQuota)
    _displayQuota: function(r)
    {
        var q = $('quota').cleanWhitespace();
        $('quota-text').setText(r.m);
        q.down('SPAN.used IMG').writeAttribute('width', 99 - r.p);
    },

To:
    _displayQuotah: function(r)
    {
        var q = $('quotah').cleanWhitespace();
        $('quotah-text').setText(r.mh);
        q.down('SPAN.used IMG').writeAttribute('width', 99 - r.ph);
    },

    _displayQuotav: function(r)
    {
        var q = $('quotav').cleanWhitespace();
        $('quotav-text').setText(r.mv);
        q.down('SPAN.used IMG').writeAttribute('width', 99 - r.pv);
    },

Form: (_folderLoadCallback)
        if (r.response.quota) {
            this._displayQuota(r.response.quota);
        }

To:
        if (r.response.quotah) {
            this._displayQuotah(r.response.quotah);
            this._displayQuotav(r.response.quotav);
        }