Changeset 90f81a6 in github


Ignore:
Timestamp:
Dec 8, 2010 7:52:04 AM (2 years ago)
Author:
alecpl <alec@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
4064452
Parents:
5be0d00
Message:
  • Better support for READ-ONLY and NOPERM responses handling (#1487083)
  • Add confirmation message on purge/expunge commands response
  • Fix CLOSE was called on unselected mailbox
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r0e11940 r90f81a6  
    1717- Fix plaintext versions of HTML messages don't contain placeholders for emotions (#1485206) 
    1818- Improve performance of folder rename and delete actions 
     19- Better support for READ-ONLY and NOPERM responses handling (#1487083) 
     20- Add confirmation message on purge/expunge command response 
    1921 
    2022RELEASE 0.5-BETA 
  • program/include/main.inc

    r7472893 r90f81a6  
    16171617 
    16181618/** 
     1619 * Outputs error message according to server error/response codes 
     1620 * 
     1621 * @param string Fallback message label 
     1622 * @param string Fallback message label arguments 
     1623 * 
     1624 * @return void 
     1625 */ 
     1626function rcmail_display_server_error($fallback=null, $fallback_args=null) 
     1627{ 
     1628    global $RCMAIL; 
     1629 
     1630    $err_code = $RCMAIL->imap->get_error_code(); 
     1631    $res_code = $RCMAIL->imap->get_response_code(); 
     1632 
     1633    if ($res_code == rcube_imap::NOPERM) { 
     1634        $RCMAIL->output->show_message('errornoperm', 'error'); 
     1635    } 
     1636    else if ($res_code == rcube_imap::READONLY) { 
     1637        $RCMAIL->output->show_message('errorreadonly', 'error'); 
     1638    } 
     1639    else if ($err_code && ($err_str = $RCMAIL->imap->get_error_str())) { 
     1640        $RCMAIL->output->show_message('servererrormsg', 'error', array('msg' => $err_str)); 
     1641    } 
     1642    else if ($fallback) { 
     1643        $RCMAIL->output->show_message($fallback, 'error', $fallback_args); 
     1644    } 
     1645 
     1646    return true; 
     1647} 
     1648 
     1649 
     1650/** 
    16191651 * Output HTML editor scripts 
    16201652 * 
  • program/include/rcube_imap.php

    rdd83549 r90f81a6  
    101101    ); 
    102102 
     103    const UNKNOWN       = 0; 
     104    const NOPERM        = 1; 
     105    const READONLY      = 2; 
     106    const TRYCREATE     = 3; 
     107    const INUSE         = 4; 
     108    const OVERQUOTA     = 5; 
     109    const ALREADYEXISTS = 6; 
     110    const NONEXISTENT   = 7; 
     111    const CONTACTADMIN  = 8; 
     112 
    103113 
    104114    /** 
     
    221231    function get_error_str() 
    222232    { 
    223         return ($this->conn) ? $this->conn->error : ''; 
     233        return ($this->conn) ? $this->conn->error : null; 
     234    } 
     235 
     236 
     237    /** 
     238     * Returns code of last command response 
     239     * 
     240     * @return int Response code 
     241     */ 
     242    function get_response_code() 
     243    { 
     244        if (!$this->conn) 
     245            return self::UNKNOWN; 
     246 
     247        switch ($this->conn->resultcode) { 
     248            case 'NOPERM': 
     249                return self::NOPERM; 
     250            case 'READ-ONLY': 
     251                return self::READONLY; 
     252            case 'TRYCREATE': 
     253                return self::TRYCREATE; 
     254            case 'INUSE': 
     255                return self::INUSE; 
     256            case 'OVERQUOTA': 
     257                return self::OVERQUOTA; 
     258            case 'ALREADYEXISTS': 
     259                return self::ALREADYEXISTS; 
     260            case 'NONEXISTENT': 
     261                return self::NONEXISTENT; 
     262            case 'CONTACTADMIN': 
     263                return self::CONTACTADMIN; 
     264            default: 
     265                return self::UNKNOWN; 
     266        } 
     267    } 
     268 
     269 
     270    /** 
     271     * Returns last command response 
     272     * 
     273     * @return string Response 
     274     */ 
     275    function get_response_str() 
     276    { 
     277        return ($this->conn) ? $this->conn->result : null; 
    224278    } 
    225279 
     
    296350     * @access public 
    297351     */ 
    298     function select_mailbox($mailbox) 
    299     { 
    300         $mailbox = $this->mod_mailbox($mailbox); 
     352    function select_mailbox($mailbox=null) 
     353    { 
     354        $mailbox = strlen($mailbox) ? $this->mod_mailbox($mailbox) : $this->mailbox; 
    301355 
    302356        $selected = $this->conn->select($mailbox); 
     
    27692823        else 
    27702824            $a_uids = NULL; 
     2825 
     2826        // force mailbox selection and check if mailbox is writeable 
     2827        // to prevent a situation when CLOSE is executed on closed 
     2828        // or EXPUNGE on read-only mailbox 
     2829        $result = $this->conn->select($mailbox); 
     2830        if (!$result) { 
     2831            return false; 
     2832        } 
     2833        if (!$this->conn->data['READ-WRITE']) { 
     2834            $this->conn->setError(rcube_imap_generic::ERROR_READONLY, "Mailbox is read-only"); 
     2835            return false; 
     2836        } 
    27712837 
    27722838        // CLOSE(+SELECT) should be faster than EXPUNGE 
  • program/include/rcube_imap_generic.php

    rd7e83d3 r90f81a6  
    8686    public $error; 
    8787    public $errornum; 
     88    public $result; 
     89    public $resultcode; 
    8890    public $data = array(); 
    8991    public $flags = array( 
     
    113115    const ERROR_BAD = -2; 
    114116    const ERROR_BYE = -3; 
     117    const ERROR_UNKNOWN = -4; 
    115118    const ERROR_COMMAND = -5; 
    116     const ERROR_UNKNOWN = -4; 
     119    const ERROR_READONLY = -6; 
    117120 
    118121    const COMMAND_NORESPONSE = 1; 
     
    303306 
    304307                    if ($res == 'OK') { 
    305                             return $this->errornum = self::ERROR_OK; 
     308                            $this->errornum = self::ERROR_OK; 
    306309                    } else if ($res == 'NO') { 
    307310                $this->errornum = self::ERROR_NO; 
     
    314317                    } 
    315318 
    316             if ($str) 
    317                 $this->error = $err_prefix ? $err_prefix.$str : $str; 
     319            if ($str) { 
     320                $str = trim($str); 
     321                // get response string and code (RFC5530) 
     322                if (preg_match("/^\[([a-z-]+)\]/i", $str, $m)) { 
     323                    $this->resultcode = strtoupper($m[1]); 
     324                    $str = trim(substr($str, strlen($m[1]) + 2)); 
     325                } 
     326                else { 
     327                    $this->resultcode = null; 
     328                } 
     329                $this->result = $str; 
     330 
     331                if ($this->errornum != self::ERROR_OK) { 
     332                    $this->error = $err_prefix ? $err_prefix.$str : $str; 
     333                } 
     334            } 
    318335 
    319336                return $this->errornum; 
     
    322339    } 
    323340 
    324     private function setError($code, $msg='') 
     341    function setError($code, $msg='') 
    325342    { 
    326343        $this->errornum = $code; 
     
    839856            } 
    840857 
     858            $this->data['READ-WRITE'] = $this->resultcode != 'READ-ONLY'; 
     859 
    841860                    $this->selected = $mailbox; 
    842861                        return true; 
     
    907926        } 
    908927 
     928        if (!$this->data['READ-WRITE']) { 
     929            $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'EXPUNGE'); 
     930            return false; 
     931        } 
     932 
    909933        // Clear internal status cache 
    910934        unset($this->data['STATUS:'.$mailbox]); 
     
    10021026            $num_in_trash = $this->countMessages($mailbox); 
    10031027            if ($num_in_trash > 0) { 
    1004                     $this->delete($mailbox, '1:*'); 
    1005             } 
    1006  
    1007         $res = $this->close(); 
    1008 //          $res = $this->expunge($mailbox); 
     1028                    $res = $this->delete($mailbox, '1:*'); 
     1029            } 
     1030 
     1031        if ($res) { 
     1032            if ($this->selected == $mailbox) 
     1033                $res = $this->close(); 
     1034            else 
     1035                $res = $this->expunge($mailbox); 
     1036        } 
    10091037 
    10101038            return $res; 
     
    17161744            } 
    17171745 
     1746        if (!$this->data['READ-WRITE']) { 
     1747            $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE'); 
     1748            return false; 
     1749        } 
     1750 
    17181751        // Clear internal status cache 
    17191752        if ($flag == 'SEEN') { 
     
    17591792    function move($messages, $from, $to) 
    17601793    { 
     1794            if (!$this->select($from)) { 
     1795                return false; 
     1796            } 
     1797 
     1798        if (!$this->data['READ-WRITE']) { 
     1799            $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE'); 
     1800            return false; 
     1801        } 
     1802 
    17611803        $r = $this->copy($messages, $from, $to); 
    17621804 
     
    29643006            } 
    29653007 
    2966         // return last line only (without command tag and result) 
     3008        // return last line only (without command tag, result and response code) 
    29673009        if ($line && ($options & self::COMMAND_LASTLINE)) { 
    2968             $response = preg_replace("/^$tag (OK|NO|BAD|BYE|PREAUTH)?\s*/i", '', trim($line)); 
     3010            $response = preg_replace("/^$tag (OK|NO|BAD|BYE|PREAUTH)?\s*(\[[a-z-]+\])?\s*/i", '', trim($line)); 
    29693011        } 
    29703012 
  • program/localization/en_US/messages.inc

    raf3c045e r90f81a6  
    2525$messages['servererror'] = 'Server Error!'; 
    2626$messages['servererrormsg'] = 'Server Error: $msg'; 
     27$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only'; 
     28$messages['errornoperm'] = 'Unable to perform operation. Permission denied'; 
    2729$messages['invalidrequest'] = 'Invalid request! No data was saved.'; 
    2830$messages['nomessagesfound'] = 'No messages found in this mailbox'; 
     
    8284$messages['folderunsubscribed'] = 'Folder successfully unsubscribed'; 
    8385$messages['folderpurged'] = 'Folder successfully purged'; 
     86$messages['folderexpunged'] = 'Folder successfully emptied'; 
    8487$messages['deletedsuccessfully'] = 'Successfully deleted'; 
    8588$messages['converting'] = 'Removing formatting...'; 
  • program/localization/pl_PL/messages.inc

    raf3c045e r90f81a6  
    181181$messages['folderunsubscribed'] = 'Folder pomyślnie odsubskrybowany'; 
    182182$messages['folderpurged'] = 'Folder pomyślnie wyczyszczony'; 
     183$messages['folderexpunged'] = 'Folder pomyślnie opróŌniony'; 
    183184$messages['namecannotbeempty'] = 'Nazwa nie moÅŒe być pusta'; 
    184185$messages['nametoolong'] = 'Name jest zbyt długa'; 
    185186$messages['folderupdated'] = 'Folder pomyślnie zaktualizowany'; 
    186187$messages['foldercreated'] = 'Folder pomyślnie utworzony'; 
     188$messages['errorreadonly'] = 'Nie moÅŒna wykonać operacji. Folder tylko do odczytu'; 
     189$messages['errornoperm'] = 'Nie moÅŒna wykonać operacji. Brak uprawnień'; 
    187190 
    188191?> 
  • program/steps/mail/copy.inc

    rb72e2f9 r90f81a6  
    3434    if (!$copied) { 
    3535        // send error message 
    36         $OUTPUT->show_message('errorcopying', 'error'); 
     36        rcmail_display_server_error('errorcopying'); 
    3737        $OUTPUT->send(); 
    3838        exit; 
     
    5353// send response 
    5454$OUTPUT->send(); 
    55  
    56  
  • program/steps/mail/folders.inc

    rb46edc0f r90f81a6  
    2121// only process ajax requests 
    2222if (!$OUTPUT->ajax_call) 
    23   return; 
     23    return; 
    2424 
    2525$mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true); 
    2626 
    2727// send EXPUNGE command 
    28 if ($RCMAIL->action=='expunge') 
    29 { 
    30   $success = $IMAP->expunge($mbox); 
     28if ($RCMAIL->action == 'expunge') { 
    3129 
    32   // reload message list if current mailbox 
    33   if ($success && !empty($_REQUEST['_reload'])) 
    34   { 
    35     $OUTPUT->command('set_quota', rcmail_quota_content()); 
    36     $OUTPUT->command('message_list.clear'); 
    37     $RCMAIL->action = 'list'; 
    38     return; 
    39   } 
    40   else 
    41     $commands = "// expunged: $success\n"; 
     30    $success = $IMAP->expunge($mbox); 
     31 
     32    // reload message list if current mailbox 
     33    if ($success) { 
     34        $OUTPUT->show_message('folderexpunged', 'confirmation'); 
     35 
     36        if (!empty($_REQUEST['_reload'])) { 
     37            $OUTPUT->command('set_quota', rcmail_quota_content()); 
     38            $OUTPUT->command('message_list.clear'); 
     39            $RCMAIL->action = 'list'; 
     40            return; 
     41        } 
     42    } 
     43    else { 
     44        rcmail_display_server_error(); 
     45    } 
    4246} 
    4347 
    4448// clear mailbox 
    45 else if ($RCMAIL->action=='purge') 
     49else if ($RCMAIL->action == 'purge') 
    4650{ 
    47   $delimiter = $IMAP->get_hierarchy_delimiter(); 
    48   $trash_regexp = '/^' . preg_quote($CONFIG['trash_mbox'] . $delimiter, '/') . '/'; 
    49   $junk_regexp = '/^' . preg_quote($CONFIG['junk_mbox'] . $delimiter, '/') . '/'; 
     51    $delimiter = $IMAP->get_hierarchy_delimiter(); 
     52    $trash_regexp = '/^' . preg_quote($CONFIG['trash_mbox'] . $delimiter, '/') . '/'; 
     53    $junk_regexp = '/^' . preg_quote($CONFIG['junk_mbox'] . $delimiter, '/') . '/'; 
    5054 
    51   // we should only be purging trash and junk (or their subfolders) 
    52   if ($mbox == $CONFIG['trash_mbox'] || $mbox == $CONFIG['junk_mbox'] 
    53     || preg_match($trash_regexp, $mbox) || preg_match($junk_regexp, $mbox)) 
    54   { 
    55     $success = $IMAP->clear_mailbox($mbox); 
     55    // we should only be purging trash and junk (or their subfolders) 
     56    if ($mbox == $CONFIG['trash_mbox'] || $mbox == $CONFIG['junk_mbox'] 
     57        || preg_match($trash_regexp, $mbox) || preg_match($junk_regexp, $mbox) 
     58    ) { 
     59        $success = $IMAP->clear_mailbox($mbox); 
    5660 
    57     if ($success && !empty($_REQUEST['_reload'])) 
    58     { 
    59       $OUTPUT->set_env('messagecount', 0); 
    60       $OUTPUT->set_env('pagecount', 0); 
    61       $OUTPUT->command('message_list.clear'); 
    62       $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text()); 
    63       $OUTPUT->command('set_unread_count', $mbox, 0); 
    64       $OUTPUT->command('set_quota', rcmail_quota_content()); 
    65       rcmail_set_unseen_count($mbox, 0); 
     61        if ($success) { 
     62            $OUTPUT->show_message('folderpurged', 'confirmation'); 
     63 
     64            if (!empty($_REQUEST['_reload'])) { 
     65                $OUTPUT->set_env('messagecount', 0); 
     66                $OUTPUT->set_env('pagecount', 0); 
     67                $OUTPUT->command('message_list.clear'); 
     68                $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text()); 
     69                $OUTPUT->command('set_unread_count', $mbox, 0); 
     70                $OUTPUT->command('set_quota', rcmail_quota_content()); 
     71                rcmail_set_unseen_count($mbox, 0); 
     72            } 
     73        } 
     74        else { 
     75            rcmail_display_server_error(); 
     76        } 
    6677    } 
    67     else 
    68       $commands = "// purged: $success"; 
    69   } 
    7078} 
    7179 
    72 $OUTPUT->send($commands); 
    73  
    74  
     80$OUTPUT->send(); 
  • program/steps/mail/list.inc

    r2d1d68b r90f81a6  
    107107  // handle IMAP errors (e.g. #1486905) 
    108108  if ($err_code = $IMAP->get_error_code()) { 
    109     $err_str = $IMAP->get_error_str(); 
    110     $OUTPUT->show_message('servererrormsg', 'error', array('msg' => $err_str)); 
     109    rcmail_display_server_error(); 
    111110  } 
    112111  else if ($search_request) 
  • program/steps/mail/mark.inc

    rb46edc0f r90f81a6  
    4848    if ($_POST['_from'] != 'show') 
    4949      $OUTPUT->command('list_mailbox'); 
    50     $OUTPUT->show_message('errormarking', 'error'); 
     50    rcmail_display_server_error('errormarking'); 
    5151    $OUTPUT->send(); 
    5252    exit; 
  • program/steps/mail/move_del.inc

    rb46edc0f r90f81a6  
    4040            if ($_POST['_from'] != 'show') 
    4141            $OUTPUT->command('list_mailbox'); 
    42         $OUTPUT->show_message('errormoving', 'error'); 
     42        rcmail_display_server_error('errormoving'); 
    4343        $OUTPUT->send(); 
    4444        exit; 
     
    6161            if ($_POST['_from'] != 'show') 
    6262            $OUTPUT->command('list_mailbox'); 
    63         $OUTPUT->show_message('errordeleting', 'error'); 
     63        rcmail_display_server_error('errordeleting'); 
    6464        $OUTPUT->send(); 
    6565        exit; 
  • program/steps/mail/search.inc

    r2d1d68b r90f81a6  
    125125// handle IMAP errors (e.g. #1486905) 
    126126else  if ($err_code = $IMAP->get_error_code()) { 
    127   $err_str = $IMAP->get_error_str(); 
    128   $OUTPUT->show_message('servererrormsg', 'error', array('msg' => $err_str)); 
     127  rcmail_display_server_error(); 
    129128} 
    130129else { 
  • program/steps/settings/folders.inc

    r0e11940 r90f81a6  
    3535        // Handle virtual (non-existing) folders 
    3636        if (!$result && $IMAP->get_error_code() == -1 && 
    37             strpos($IMAP->get_error_str(), '[TRYCREATE]') 
     37            $IMAP->get_response_code() == rcube_imap::TRYCREATE 
    3838        ) { 
    3939            $result = $IMAP->create_mailbox($mbox, true); 
     
    4646            $OUTPUT->show_message('foldersubscribed', 'confirmation'); 
    4747        else 
    48             $OUTPUT->show_message('errorsaving', 'error'); 
     48            rcmail_display_server_error('errorsaving'); 
    4949    } 
    5050} 
     
    5959            $OUTPUT->show_message('folderunsubscribed', 'confirmation'); 
    6060        else 
    61             $OUTPUT->show_message('errorsaving', 'error'); 
     61            rcmail_display_server_error('errorsaving'); 
    6262    } 
    6363} 
     
    9393    } 
    9494    else if (!$deleted) { 
    95         $OUTPUT->show_message('errorsaving', 'error'); 
     95        rcmail_display_server_error('errorsaving'); 
    9696    } 
    9797} 
     
    142142    } 
    143143    else if (!$rename) { 
    144         $OUTPUT->show_message('errorsaving', 'error'); 
     144        rcmail_display_server_error('errorsaving'); 
    145145    } 
    146146} 
     
    180180    } 
    181181    else { 
    182         $OUTPUT->show_message('errorsaving', 'error'); 
     182        rcmail_display_server_error('errorsaving'); 
    183183    } 
    184184} 
     
    195195    if ($size !== false) { 
    196196        $OUTPUT->command('folder_size_update', show_bytes($size)); 
     197    } 
     198    else { 
     199        rcmail_display_server_error(); 
    197200    } 
    198201} 
Note: See TracChangeset for help on using the changeset viewer.