Changeset 4198 in subversion


Ignore:
Timestamp:
Nov 9, 2010 2:54:34 AM (3 years ago)
Author:
alec
Message:
  • Add support for shared folders (#1403507)
Location:
trunk/roundcubemail
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r4194 r4198  
    6666- Add option for minimum length of autocomplete's string (#1486428) 
    6767- Fix operations on messages in unsubscribed folder (#1487107) 
     68- Add support for shared folders (#1403507) 
    6869 
    6970RELEASE 0.4.2 
  • trunk/roundcubemail/config/main.inc.php.dist

    r4190 r4198  
    7575$rcmail_config['imap_auth_type'] = null; 
    7676 
    77 // If you know your imap's root directory and its folder delimiter, 
    78 // you can specify them here. Otherwise they will be determined automatically. 
    79 $rcmail_config['imap_root'] = null; 
     77// If you know your imap's folder delimiter, you can specify it here. 
     78// Otherwise it will be determined automatically 
    8079$rcmail_config['imap_delimiter'] = null; 
     80 
     81// If IMAP server doesn't support NAMESPACE extension, but you're 
     82// using shared folders or personal root folder is non-empty, you'll need to 
     83// set these options. All can be strings or arrays of strings. 
     84$rcmail_config['imap_ns_personal'] = null; 
     85$rcmail_config['imap_ns_other']    = null; 
     86$rcmail_config['imap_ns_shared']   = null; 
    8187 
    8288// By default IMAP capabilities are readed after connection to IMAP server 
  • trunk/roundcubemail/installer/rcube_install.php

    r3989 r4198  
    3939    'multiple_identities' => 'identities_level', 
    4040    'addrbook_show_images' => 'show_images', 
     41    'imap_root' => 'imap_ns_personal', 
    4142  ); 
    4243   
     
    170171        $value = '%p'; 
    171172      } 
    172       else if ($prop == 'default_imap_folders'){ 
    173         $value = Array(); 
    174         foreach($this->config['default_imap_folders'] as $_folder){ 
    175           switch($_folder) { 
    176           case 'Drafts': $_folder = $this->config['drafts_mbox']; break; 
    177           case 'Sent':   $_folder = $this->config['sent_mbox']; break; 
    178           case 'Junk':   $_folder = $this->config['junk_mbox']; break; 
    179           case 'Trash':  $_folder = $this->config['trash_mbox']; break; 
     173      else if ($prop == 'default_imap_folders') { 
     174            $value = Array(); 
     175            foreach ($this->config['default_imap_folders'] as $_folder) { 
     176              switch($_folder) { 
     177              case 'Drafts': $_folder = $this->config['drafts_mbox']; break; 
     178              case 'Sent':   $_folder = $this->config['sent_mbox']; break; 
     179              case 'Junk':   $_folder = $this->config['junk_mbox']; break; 
     180              case 'Trash':  $_folder = $this->config['trash_mbox']; break; 
    180181          } 
    181           if (!in_array($_folder, $value))  $value[] = $_folder; 
     182            if (!in_array($_folder, $value)) 
     183              $value[] = $_folder; 
    182184        } 
    183185      } 
  • trunk/roundcubemail/program/include/rcmail.php

    r4124 r4198  
    504504      'auth_cid'    => $this->config->get('imap_auth_cid'), 
    505505      'auth_pw'     => $this->config->get('imap_auth_pw'), 
    506       'delimiter'   => isset($_SESSION['imap_delimiter']) ? $_SESSION['imap_delimiter'] : $this->config->get('imap_delimiter'), 
    507       'rootdir'     => isset($_SESSION['imap_root']) ? $_SESSION['imap_root'] : $this->config->get('imap_root'), 
    508506      'debug_mode'  => (bool) $this->config->get('imap_debug', 0), 
    509507      'force_caps'  => (bool) $this->config->get('imap_force_caps'), 
     
    791789      $this->imap->set_page($_SESSION['page']); 
    792790    } 
    793  
    794     // cache IMAP root and delimiter in session for performance reasons 
    795     $_SESSION['imap_root'] = $this->imap->root_dir; 
    796     $_SESSION['imap_delimiter'] = $this->imap->delimiter; 
    797791  } 
    798792 
  • trunk/roundcubemail/program/include/rcube_imap.php

    r4194 r4198  
    3434    public $debug_level = 1; 
    3535    public $skip_deleted = false; 
    36     public $root_dir = ''; 
    3736    public $page_size = 10; 
    3837    public $list_page = 1; 
    39     public $delimiter = NULL; 
    4038    public $threading = false; 
    4139    public $fetch_add_headers = ''; 
     
    5553     */ 
    5654    private $db; 
    57     private $root_ns = ''; 
    5855    private $mailbox = 'INBOX'; 
     56    private $delimiter = NULL; 
     57    private $namespace = NULL; 
    5958    private $sort_field = ''; 
    6059    private $sort_order = 'DESC'; 
     
    157156        $this->ssl  = $use_ssl; 
    158157 
    159         // print trace messages 
    160158        if ($this->conn->connected()) { 
     159            // print trace messages 
    161160            if ($this->conn->message && ($this->debug_level & 8)) { 
    162161                console($this->conn->message); 
    163162            } 
    164  
    165             // get server properties 
    166             $rootdir = $this->conn->getRootDir(); 
    167             if (!empty($rootdir)) 
    168                 $this->set_rootdir($rootdir); 
    169             if (empty($this->delimiter)) 
    170                     $this->get_hierarchy_delimiter(); 
     163            // get namespace and delimiter 
     164            $this->set_env(); 
    171165 
    172166            return true; 
     
    244238    { 
    245239        $this->options = array_merge($this->options, (array)$opt); 
    246     } 
    247  
    248  
    249     /** 
    250      * Set a root folder for the IMAP connection. 
    251      * 
    252      * Only folders within this root folder will be displayed 
    253      * and all folder paths will be translated using this folder name 
    254      * 
    255      * @param  string   $root Root folder 
    256      * @access public 
    257      */ 
    258     function set_rootdir($root) 
    259     { 
    260         if (preg_match('/[.\/]$/', $root)) //(substr($root, -1, 1)==='/') 
    261             $root = substr($root, 0, -1); 
    262  
    263         $this->root_dir = $root; 
    264         $this->options['rootdir'] = $root; 
    265  
    266         if (empty($this->delimiter)) 
    267             $this->get_hierarchy_delimiter(); 
    268240    } 
    269241 
     
    483455    function get_hierarchy_delimiter() 
    484456    { 
    485         if ($this->conn && empty($this->delimiter)) 
    486             $this->delimiter = $this->conn->getHierarchyDelimiter(); 
    487  
    488         if (empty($this->delimiter)) 
    489             $this->delimiter = '/'; 
    490  
    491457        return $this->delimiter; 
     458    } 
     459 
     460 
     461    /** 
     462     * Get namespace 
     463     * 
     464     * @return  array  Namespace data 
     465     * @access  public 
     466     */ 
     467    function get_namespace() 
     468    { 
     469        return $this->namespace; 
     470    } 
     471 
     472 
     473    /** 
     474     * Sets delimiter and namespaces 
     475     * 
     476     * @access private 
     477     */ 
     478    private function set_env() 
     479    { 
     480        if ($this->delimiter !== null && $this->namespace !== null) { 
     481            return; 
     482        } 
     483 
     484        if (isset($_SESSION['imap_namespace']) && isset($_SESSION['imap_delimiter'])) { 
     485            $this->namespace = $_SESSION['imap_namespace']; 
     486            $this->delimiter = $_SESSION['imap_delimiter']; 
     487            return; 
     488        } 
     489 
     490        $config = rcmail::get_instance()->config; 
     491        $imap_personal  = $config->get('imap_ns_personal'); 
     492        $imap_other     = $config->get('imap_ns_other'); 
     493        $imap_shared    = $config->get('imap_ns_shared'); 
     494        $imap_delimiter = $config->get('imap_delimiter'); 
     495 
     496        if ($imap_delimiter) { 
     497            $this->delimiter = $imap_delimiter; 
     498        } 
     499 
     500        if (!$this->conn) 
     501            return; 
     502 
     503        $ns = $this->conn->getNamespace(); 
     504 
     505        // NAMESPACE supported 
     506        if (is_array($ns)) { 
     507            $this->namespace = $ns; 
     508 
     509            if (empty($this->delimiter)) 
     510                $this->delimiter = $ns['personal'][0][1]; 
     511            if (empty($this->delimiter)) 
     512                $this->delimiter = $this->conn->getHierarchyDelimiter(); 
     513            if (empty($this->delimiter)) 
     514                $this->delimiter = '/'; 
     515        } 
     516        // not supported, get namespace from config 
     517        else if ($imap_personal !== null || $imap_shared !== null || $imap_other !== null) { 
     518            if (empty($this->delimiter)) 
     519                $this->delimiter = $this->conn->getHierarchyDelimiter(); 
     520            if (empty($this->delimiter)) 
     521                $this->delimiter = '/'; 
     522 
     523            $this->namespace = array( 
     524                'personal' => NULL, 
     525                'other'    => NULL, 
     526                'shared'   => NULL, 
     527            ); 
     528 
     529            if ($imap_personal !== null) { 
     530                foreach ((array)$imap_personal as $dir) { 
     531                    $this->namespace['personal'][] = array($dir, $this->delimiter); 
     532                } 
     533            } 
     534            if ($imap_other !== null) { 
     535                foreach ((array)$imap_other as $dir) { 
     536                    if ($dir) { 
     537                        $this->namespace['other'][] = array($dir, $this->delimiter); 
     538                    } 
     539                } 
     540            } 
     541            if ($imap_shared !== null) { 
     542                foreach ((array)$imap_shared as $dir) { 
     543                    if ($dir) { 
     544                        $this->namespace['shared'][] = array($dir, $this->delimiter); 
     545                    } 
     546                } 
     547            } 
     548        } 
     549 
     550        $_SESSION['imap_namespace'] = $this->namespace; 
     551        $_SESSION['imap_delimiter'] = $this->delimiter; 
    492552    } 
    493553 
     
    892952        // @TODO: fetch children only in expanded mode (?) 
    893953        $all_ids = array(); 
    894         foreach($msg_index as $root) { 
     954        foreach ($msg_index as $root) { 
    895955            $all_ids[] = $root; 
    896956            if (!empty($thread_tree[$root])) 
     
    14641524        // flatten threads array 
    14651525        $all_ids = array(); 
    1466         foreach($msg_index as $root) { 
     1526        foreach ($msg_index as $root) { 
    14671527            $all_ids[] = $root; 
    14681528            if (!empty($thread_tree[$root])) { 
     
    30743134 
    30753135        if (is_array($a_mboxes)) { 
     3136            $delimiter = $this->get_hierarchy_delimiter(); 
     3137         
    30763138            foreach ($a_mboxes as $mbox_name) { 
    30773139                $mailbox = $this->mod_mailbox($mbox_name); 
    3078                 $sub_mboxes = $this->conn->listMailboxes($this->mod_mailbox(''), 
    3079                         $mbox_name . $this->delimiter . '*'); 
     3140                $sub_mboxes = $this->conn->listMailboxes('', $mbox_name . $delimiter . '*'); 
    30803141 
    30813142                // unsubscribe mailbox before deleting 
     
    31383199                return true; 
    31393200 
    3140             $key = $subscription ? 'subscribed' : 'existing'; 
    3141             if (is_array($this->icache[$key]) && in_array($mbox_name, $this->icache[$key])) 
     3201            $key  = $subscription ? 'subscribed' : 'existing'; 
     3202            $mbox = $this->mod_mailbox($mbox_name) 
     3203            if (is_array($this->icache[$key]) && in_array($mbox, $this->icache[$key])) 
    31423204                return true; 
    31433205 
    31443206            if ($subscription) { 
    3145                 $a_folders = $this->conn->listSubscribed($this->mod_mailbox(''), $mbox_name); 
     3207                $a_folders = $this->conn->listSubscribed('', $mbox); 
    31463208            } 
    31473209            else { 
    3148                 $a_folders = $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); 
     3210                $a_folders = $this->conn->listMailboxes('', $mbox); 
    31493211                } 
    31503212 
    3151             if (is_array($a_folders) && in_array($this->mod_mailbox($mbox_name), $a_folders)) { 
    3152                 $this->icache[$key][] = $mbox_name; 
     3213            if (is_array($a_folders) && in_array($mbox, $a_folders)) { 
     3214                $this->icache[$key][] = $mbox; 
    31533215                return true; 
    31543216            } 
     
    31683230    function mod_mailbox($mbox_name, $mode='in') 
    31693231    { 
    3170         if ($mbox_name == 'INBOX') 
    3171             return $mbox_name; 
    3172  
    3173         if (!empty($this->root_dir)) { 
    3174             if ($mode=='in') 
    3175                 $mbox_name = $this->root_dir.$this->delimiter.$mbox_name; 
    3176             else if (!empty($mbox_name)) // $mode=='out' 
    3177                 $mbox_name = substr($mbox_name, strlen($this->root_dir)+1); 
     3232        if (empty($mbox_name)) 
     3233            return ''; 
     3234 
     3235        if ($mode == 'in') { 
     3236            // If folder contains namespace prefix, don't modify it 
     3237            if (is_array($this->namespace['shared'])) { 
     3238                foreach ($this->namespace['shared'] as $ns) { 
     3239                    foreach ((array)$ns as $root) { 
     3240                        if (strpos($mbox_name, $root[0]) === 0) { 
     3241                            return $mbox_name; 
     3242                        } 
     3243                    } 
     3244                } 
     3245            } 
     3246            if (is_array($this->namespace['other'])) { 
     3247                foreach ($this->namespace['other'] as $ns) { 
     3248                    foreach ((array)$ns as $root) { 
     3249                        if (strpos($mbox_name, $root[0]) === 0) { 
     3250                            return $mbox_name; 
     3251                        } 
     3252                    } 
     3253                } 
     3254            } 
     3255            if (is_array($this->namespace['personal'])) { 
     3256                foreach ($this->namespace['personal'] as $ns) { 
     3257                    foreach ((array)$ns as $root) { 
     3258                        if ($root[0] && strpos($mbox_name, $root[0]) === 0) { 
     3259                            return $mbox_name; 
     3260                        } 
     3261                    } 
     3262                } 
     3263                // Add prefix if first personal namespace is non-empty 
     3264                if ($this->namespace['personal'][0][0]) { 
     3265                    return $this->namespace['personal'][0][0].$mbox_name; 
     3266                } 
     3267            } 
     3268        } 
     3269        else { 
     3270            // Remove prefix if folder is from first ("non-empty") personal namespace 
     3271            if (is_array($this->namespace['personal'])) { 
     3272                if ($prefix = $this->namespace['personal'][0][0]) { 
     3273                    if (strpos($mbox_name, $prefix) === 0) { 
     3274                        return substr($mbox_name, strlen($prefix)); 
     3275                    } 
     3276                } 
     3277            } 
    31783278        } 
    31793279 
     
    32013301        if (!is_array($this->conn->data['LIST']) || !is_array($this->conn->data['LIST'][$mbox])) { 
    32023302            if ($force) { 
    3203                 $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name); 
     3303                $this->conn->listMailboxes('', $mbox_name); 
    32043304            } 
    32053305            else { 
  • trunk/roundcubemail/program/include/rcube_imap_generic.php

    r4187 r4198  
    550550 
    551551    /** 
    552      * Gets the root directory and delimiter (of personal namespace) 
    553      * 
    554      * @return mixed A root directory name, or false. 
    555      */ 
    556     function getRootDir() 
    557     { 
    558             if (isset($this->prefs['rootdir']) && is_string($this->prefs['rootdir'])) { 
    559                 return $this->prefs['rootdir']; 
    560             } 
    561  
    562             if (!is_array($data = $this->getNamespace())) { 
    563                 return false; 
    564             } 
    565  
    566             $user_space_data = $data['personal']; 
    567             if (!is_array($user_space_data)) { 
    568                 return false; 
    569             } 
    570  
    571             $first_userspace = $user_space_data[0]; 
    572             if (count($first_userspace) !=2) { 
    573                 return false; 
    574             } 
    575  
    576         $rootdir                  = $first_userspace[0]; 
    577             $this->prefs['delimiter'] = $first_userspace[1]; 
    578             $this->prefs['rootdir']   = $rootdir ? substr($rootdir, 0, -1) : ''; 
    579  
    580             return $this->prefs['rootdir']; 
    581     } 
    582  
    583     /** 
    584      * Gets the delimiter, for example: 
    585      * INBOX.foo -> . 
    586      * INBOX/foo -> / 
    587      * INBOX\foo -> \ 
    588      * 
    589      * @return mixed A delimiter (string), or false. 
    590      * @see connect() 
     552     * Gets the delimiter 
     553     * 
     554     * @return string The delimiter 
    591555     */ 
    592556    function getHierarchyDelimiter() 
     
    594558            if ($this->prefs['delimiter']) { 
    595559                return $this->prefs['delimiter']; 
    596             } 
    597             if (!empty($this->prefs['delimiter'])) { 
    598             return $this->prefs['delimiter']; 
    599560            } 
    600561 
     
    612573        } 
    613574 
    614             // if that fails, try namespace extension 
    615             // try to fetch namespace data 
    616             if (!is_array($data = $this->getNamespace())) { 
    617             return false; 
    618         } 
    619  
    620             // extract user space data (opposed to global/shared space) 
    621             $user_space_data = $data['personal']; 
    622             if (!is_array($user_space_data)) { 
    623                 return false; 
    624             } 
    625  
    626             // get first element 
    627             $first_userspace = $user_space_data[0]; 
    628             if (!is_array($first_userspace)) { 
    629                 return false; 
    630             } 
    631  
    632             // extract delimiter 
    633             return $this->prefs['delimiter'] = $first_userspace[1]; 
     575        return NULL; 
    634576    } 
    635577 
     
    831773                            $this->clearCapability(); 
    832774            } 
    833                     $this->getRootDir(); 
    834775            $this->logged = true; 
    835776 
     
    19441885            } 
    19451886 
    1946             if (empty($ref) && $this->prefs['rootdir']) { 
    1947                 $ref = $this->prefs['rootdir']; 
    1948             } 
    1949  
    19501887        $args = array(); 
    19511888 
Note: See TracChangeset for help on using the changeset viewer.