alecpl
2011-10-19 c041d57036d4a30730408c8fbba2d4e12778d2d5
program/include/rcube_imap.php
@@ -911,19 +911,18 @@
        }
        // fetch specified header for all messages and sort
        else if ($msg_index = $this->conn->fetchHeaderIndex($mailbox, "1:*",
            $this->sort_field, $this->skip_deleted, true)
            $this->sort_field, $this->skip_deleted)
        ) {
            asort($msg_index); // ASC
            $msg_index = array_keys($msg_index);
            list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
            $msg_index = array_slice($msg_index, $begin, $end-$begin);
            $is_uid    = true;
            if ($slice)
                $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice);
            // fetch reqested headers from server
            $a_msg_headers = $this->fetch_headers($mailbox, $msg_index, true);
            $a_msg_headers = $this->fetch_headers($mailbox, $msg_index);
        }
        // return empty array if no messages found
@@ -2397,7 +2396,11 @@
           if (!$skip_charset_conv) {
                if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') {
                    $o_part->charset = $this->default_charset;
                    // try to extract charset information from HTML meta tag (#1488125)
                    if ($o_part->ctype_secondary == 'html' && preg_match('/<meta[^>]+charset=([a-z0-9-]+)/i', $body, $m))
                        $o_part->charset = strtoupper($m[1]);
                    else
                        $o_part->charset = $this->default_charset;
                }
                $body = rcube_charset_convert($body, $o_part->charset);
            }
@@ -2532,7 +2535,7 @@
     * @param string  $headers Headers string if $message contains only the body
     * @param boolean $is_file True if $message is a filename
     *
     * @return boolean True on success, False on error
     * @return int|bool Appended message UID or True on success, False on error
     */
    function save_message($mailbox, &$message, $headers='', $is_file=false)
    {
@@ -2583,10 +2586,14 @@
        // make sure mailbox exists
        if ($to_mbox != 'INBOX' && !$this->mailbox_exists($to_mbox)) {
            if (in_array($to_mbox, $this->default_folders))
                $this->create_mailbox($to_mbox, true);
            else
            if (in_array($to_mbox, $this->default_folders)) {
                if (!$this->create_mailbox($to_mbox, true)) {
                    return false;
                }
            }
            else {
                return false;
            }
        }
        $config = rcmail::get_instance()->config;
@@ -2664,10 +2671,14 @@
        // make sure mailbox exists
        if ($to_mbox != 'INBOX' && !$this->mailbox_exists($to_mbox)) {
            if (in_array($to_mbox, $this->default_folders))
                $this->create_mailbox($to_mbox, true);
            else
            if (in_array($to_mbox, $this->default_folders)) {
                if (!$this->create_mailbox($to_mbox, true)) {
                    return false;
                }
            }
            else {
                return false;
            }
        }
        // copy messages
@@ -2915,24 +2926,53 @@
    /**
     * Public method for listing subscribed folders
     *
     * @param   string  $root   Optional root folder
     * @param   string  $name   Optional name pattern
     * @param   string  $filter Optional filter
     * @param   string  $root      Optional root folder
     * @param   string  $name      Optional name pattern
     * @param   string  $filter    Optional filter
     * @param   string  $rights    Optional ACL requirements
     * @param   bool    $skip_sort Enable to return unsorted list (for better performance)
     *
     * @return  array   List of mailboxes/folders
     * @return  array   List of folders
     * @access  public
     */
    function list_mailboxes($root='', $name='*', $filter=null)
    function list_mailboxes($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
    {
        $a_mboxes = $this->_list_mailboxes($root, $name, $filter);
        $cache_key = $root.':'.$name;
        if (!empty($filter)) {
            $cache_key .= ':'.(is_string($filter) ? $filter : serialize($filter));
        }
        $cache_key .= ':'.$rights;
        $cache_key = 'mailboxes.'.md5($cache_key);
        // get cached folder list
        $a_mboxes = $this->get_cache($cache_key);
        if (is_array($a_mboxes)) {
            return $a_mboxes;
        }
        $a_mboxes = $this->_list_mailboxes($root, $name, $filter, $rights);
        if (!is_array($a_mboxes)) {
            return array();
        }
        // filter folders list according to rights requirements
        if ($rights && $this->get_capability('ACL')) {
            $a_mboxes = $this->filter_rights($a_mboxes, $rights);
        }
        // INBOX should always be available
        if ((!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) {
            array_unshift($a_mboxes, 'INBOX');
        }
        // sort mailboxes
        $a_mboxes = $this->_sort_mailbox_list($a_mboxes);
        // sort mailboxes (always sort for cache)
        if (!$skip_sort || $this->cache) {
            $a_mboxes = $this->_sort_mailbox_list($a_mboxes);
        }
        // write mailboxlist to cache
        $this->update_cache($cache_key, $a_mboxes);
        return $a_mboxes;
    }
@@ -2944,26 +2984,14 @@
     * @param   string  $root   Optional root folder
     * @param   string  $name   Optional name pattern
     * @param   mixed   $filter Optional filter
     * @param   string  $rights Optional ACL requirements
     *
     * @return  array   List of mailboxes/folders
     * @see     rcube_imap::list_mailboxes()
     * @access  private
     */
    private function _list_mailboxes($root='', $name='*', $filter=null)
    private function _list_mailboxes($root='', $name='*', $filter=null, $rights=null)
    {
        $cache_key = $root.':'.$name;
        if (!empty($filter)) {
            $cache_key .= ':'.(is_string($filter) ? $filter : serialize($filter));
        }
        $cache_key = 'mailboxes.'.md5($cache_key);
        // get cached folder list
        $a_mboxes = $this->get_cache($cache_key);
        if (is_array($a_mboxes)) {
            return $a_mboxes;
        }
        $a_defaults = $a_out = array();
        // Give plugins a chance to provide a list of mailboxes
@@ -2974,7 +3002,7 @@
            $a_folders = $data['folders'];
        }
        else if (!$this->conn->connected()) {
           return array();
           return null;
        }
        else {
            // Server supports LIST-EXTENDED, we can use selection options
@@ -3022,9 +3050,6 @@
            $a_folders = array();
        }
        // write mailboxlist to cache
        $this->update_cache($cache_key, $a_folders);
        return $a_folders;
    }
@@ -3032,13 +3057,15 @@
    /**
     * Get a list of all folders available on the IMAP server
     *
     * @param string $root   IMAP root dir
     * @param string  $name   Optional name pattern
     * @param mixed   $filter Optional filter
     * @param string  $root      IMAP root dir
     * @param string  $name      Optional name pattern
     * @param mixed   $filter    Optional filter
     * @param string  $rights    Optional ACL requirements
     * @param bool    $skip_sort Enable to return unsorted list (for better performance)
     *
     * @return array Indexed array with folder names
     */
    function list_unsubscribed($root='', $name='*', $filter=null)
    function list_unsubscribed($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
    {
        // @TODO: caching
        // Give plugins a chance to provide a list of mailboxes
@@ -3062,10 +3089,33 @@
            array_unshift($a_mboxes, 'INBOX');
        }
        // filter folders list according to rights requirements
        if ($rights && $this->get_capability('ACL')) {
            $a_folders = $this->filter_rights($a_folders, $rights);
        }
        // filter folders and sort them
        $a_mboxes = $this->_sort_mailbox_list($a_mboxes);
        if (!$skip_sort) {
            $a_mboxes = $this->_sort_mailbox_list($a_mboxes);
        }
        return $a_mboxes;
    }
    /**
     * Filter the given list of folders according to access rights
     */
    private function filter_rights($a_folders, $rights)
    {
        $regex = '/('.$rights.')/';
        foreach ($a_folders as $idx => $folder) {
            $myrights = join('', (array)$this->my_rights($folder));
            if ($myrights !== null && !preg_match($regex, $myrights))
                unset($a_folders[$idx]);
        }
        return $a_folders;
    }
@@ -3747,7 +3797,7 @@
            // @TODO: Honor MAXSIZE and DEPTH options
            foreach ($queries as $attrib => $entry)
                if ($result = $this->conn->getAnnotation($mailbox, $entry, $attrib))
                    $res = array_merge($res, $result);
                    $res = array_merge_recursive($res, $result);
            return $res;
        }