\documentclass{article}
\usepackage{ulem}
\usepackage{graphicx}
\usepackage{hyperref}
\pagestyle{headings}
\begin{document}
\textbf{This information is valid for Horde 4 only. See <a href="https://wiki.horde.org/AltQuotaH3">AltQuotaH3</a> for Horde 3 or <a href="https://wiki.horde.org/AltQuota">AltQuota</a> for Horde 5 and later.}

\subsection{Notes}
\textbf{IMP 5, Horde 4}<br />
\textbf{Modifies traditional and dynamic views to display quotas}.

This describes modifications to IMP 5 (Horde 4) quota \textbackslash\{\}<br />
to use two different devices (file systems) with quota enabled. \textbackslash\{\}<br />
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.

\section{Tested on Debian 6.0 (squeeze), horde-4.0.8 and imp-5.0.9.}
\subsection{Modifications}
<table class="horde-table">File & Variables, Function(s) \\
\hline
imp/config/backends.php & quota \\
\hline
imp/lib/Quota/Command.php & blocksize, getQuota \\
\hline
imp/lib/Quota/Base.php & \_params, \_\_construct \\
\hline
imp/lib/Ajax/Queue.php & \_quotah, \_quotav, generate, quota \\
\hline
imp/lib/IMP.php & quota, quotaData \\
\hline
imp/templates/dimp/index.inc & if (\$show\_quota) \\
\hline
imp/templates/quota/quota.html &  \\
\hline
imp/themes/default/dimp/screen.css & ini header \\
\hline
imp/js/dimpbase.js & pollCallback, \_displayQuota, \_folderLoadCallback \\
\hline
</table>
You must modify the nine files. Don't forget to change permission to each of them:

<pre><code>
chown www-data Command.php
</code></pre>
Where www-data is the web user (Apache or equivalent).

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

<pre><code>
chmod  +s  /usr/bin/quota
</code></pre>
\section{\textit{Last updated 2011-08-16}}
\subsection{Descriptions}

\noindent\rule{\textwidth}{1pt}
\subsubsection{Configuration example}
(imp/config/backends.php)

\begin{itemize}
\item Two devices (file systems)


\end{itemize}
\begin{quote}
See Comand.php bellow for parameters.<br />
Quota command must support "w" (do not wrap).


\end{quote}
<pre><code class="language-php">
\$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',
        )
    ),
    ...
);
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{Command.php}
\begin{itemize}
\item blocksize = 1024.


\item Have INBOX and IMAP folders in different devices and quota enabled on them.


\item Function IMP\_Quota\_command accepts 2 new parameters:


\end{itemize}
\begin{quote}
'\textbf{dev\_inbx}' (string) [\textbf{REQUIRED}] User´s INBOX file system device.<br />
Usually maps to /var/mail, /var/spool/mail.<br />
Examples: '/dev/hda6', '/dev/sdb2', '/dev/md2', '/dev/mapper/VOL1-VarM'.<br />
'\textbf{dev\_fldrs}' (string) [\textbf{REQUIRED}] User´s home file system device. \textbackslash\{\}<br />
Used for IMAP folders. Usually maps to /home.<br />
Examples: '/dev/hda7', '/dev/sda3', '/dev/md1', '/dev/mapper/VOL2-Home'.<br />
\textbf{Obsolete} parameter: partition


\end{quote}
\begin{itemize}
\item function getQuota:


\end{itemize}
\begin{quote}
Function now takes care of exceeded quotas and quota not defined for that user.


\end{quote}
Backup your original imp/lib/Quota/Command.php and create a new Command.php with the following code:

<pre><code class="language-php">
<?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("\textbackslash\{\}*\$", \$quotahome[1])) \{
                    \$quotahome[1] = ereg\_replace ("\textbackslash\{\}*", "", \$quotahome[1]);
                    \$quotahome[4] = ereg\_replace ("days", "", \$quotahome[4]);
                \} else \{
                    \$quotahome[4] == "";
                \}
                /* 
                * Quota exceeded in dev\_inbx?
                */
                if (ereg("\textbackslash\{\}*\$", \$quotavar[1])) \{
                    \$quotavar[1] = ereg\_replace ("\textbackslash\{\}*", "", \$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 ("\textbackslash\{\}*", "", \$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 ("\textbackslash\{\}*", "", \$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"));
    \}

\}
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{Base.php}
\begin{itemize}
\item New formats.


\end{itemize}
\begin{quote}
Only short formats.


\end{quote}
\begin{itemize}
\item Defaults unit to GB:


\end{itemize}
\begin{quote}
\$\_params = array('unit' => 'GB')


\end{quote}
Backup your original imp/lib/Quota/Base.php and create a new Base.php with the following code:

<pre><code class="language-php">
<?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);
    \}

\}
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{Queue.php}
\begin{itemize}
\item quotah, mh (quota message for "home") and ph (quota percentage for "home")


\item quotav, mv (quota message for Inbox) and pv (quota percentage for Inbox)


\end{itemize}
Backup your original imp/lib/Ajax/Queue.php and create a new Queue.php with the following code:

<pre><code class="language-php">
<?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;
    \}

\}
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{IMP.php}
\begin{itemize}
\item For folders:


\end{itemize}
\begin{quote}
classh, messageh, soflimithome, usagehome, messagehome, percenth, merroh, mhclasse.


\end{quote}
\begin{itemize}
\item Inbox:


\end{itemize}
\begin{quote}
classv, messagev, soflimitvar, usagevar, messagevar, percentv, merrov, mvclasse.


\end{quote}
\begin{itemize}
\item Advertizes if quota >= 90\%


\end{itemize}
\begin{quote}
Traditional view: quotawarn<br />
Dynamic view: notification message (horde.warning), in addition to the colored bar.


\end{quote}
\begin{itemize}
\item Advertizes if quota >= 100\%


\end{itemize}
\begin{quote}
Traditional view: quotaalert, message including gracetime.<br />
Dynamic view: notification message including gracetime (horde.error), in addition to the colored bar.


\end{quote}
Backup your original imp/lib/IMP.php. Edit IMP.php and replace functions "quota" and "quotaData" with the following code:

<pre><code class="language-php">
    /**
     * 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;
        \}
	
        
    \}
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{index.inc}
\begin{itemize}
\item quotav, quotav-text


\item quotah, quotah-text


\end{itemize}
Backup your original imp/templates/dimp/index.inc. Edit index.inc and replace the following code (line 58):<br />
\textbf{Form:}

<pre><code class="language-php">
<?php if (\$show\_quota): ?>
   <div id="quota">
    <div id="quota-text"></div>
    <?php echo \$show\_quota ?>
   </div>
<?php endif; ?>
</code></pre>
\textbf{To:}

<pre><code class="language-php">
<?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; ?>
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{quota.html}
\begin{itemize}
\item classh, messageh


\item classv, messagev


\end{itemize}
Backup your original imp/templates/quota/quota.html and create a new quota.html with the following code:

<pre><code class="language-php">
<table id="quota">
 <tr>
  <td class="<tag:classh />">
   <tag:messageh />
  </td>
 </tr>
 <tr>
  <td class="<tag:classv />">
   <tag:messagev />
  </td>
 </tr></table>
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{screen.css}
Backup your original imp/themes/default/dimp/screen.css. Edit screen.css and replace \textbackslash\{\}<br />
from "\#quota" to "\#quota-text" (including) with the following code (line 37):

<pre><code class="language-php">
\#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\%;
\}
</code></pre>

\noindent\rule{\textwidth}{1pt}
\subsubsection{dimpbase.js}
\begin{itemize}
\item \_displayQuotah, mh, ph


\item \_displayQuotav, mv, pv


\end{itemize}
Backup your original imp/js/dimpbase.js. Edit dimpbase.js and and replace the following codes:<br />
\textbf{Form:} (pollCallback)

<pre><code class="language-php">
        if (r.quota) \{
            this.\_displayQuota(r.quota);
        \}
</code></pre>
\textbf{To:}

<pre><code class="language-php">
        if (r.quotah) \{
            this.\_displayQuotav(r.quotav);
            this.\_displayQuotah(r.quotah);
			\}
</code></pre>
\textbf{Form:} (\_displayQuota)

<pre><code class="language-php">
    \_displayQuota: function(r)
    \{
        var q = \$('quota').cleanWhitespace();
        \$('quota-text').setText(r.m);
        q.down('SPAN.used IMG').writeAttribute('width', 99 - r.p);
    \},
</code></pre>
\textbf{To:}

<pre><code class="language-php">
    \_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);
    \},
</code></pre>
\textbf{Form:} (\_folderLoadCallback)

<pre><code class="language-php">
        if (r.response.quota) \{
            this.\_displayQuota(r.response.quota);
        \}
</code></pre>
\textbf{To:}

<pre><code class="language-php">
        if (r.response.quotah) \{
            this.\_displayQuotah(r.response.quotah);
            this.\_displayQuotav(r.response.quotav);
		\}
</code></pre>
\end{document}
