/** * * @param type $mailboxes * @param boolean $fetchAllWithSubscribedFlag Get all children with the "Subscribed" flag * @return type */ private function _getMailboxTreeNodes($mailboxes, $fetchAllWithSubscribedFlag = false) { $nodes = array(); foreach ($mailboxes as $mailbox) { //skip mailboxes with nonexistent flags if we're not listing subscribtions if (!$fetchAllWithSubscribedFlag && !$mailbox->isVisible()) { // && !$mailbox->haschildren) continue; } /* @var $mailbox \GO\Email\Model\ImapMailbox */ // if (!$mailbox->subscribed) // continue; $nodeId = base64_encode('f_' . $mailbox->getAccount()->id . '_' . $mailbox->name); $text = $mailbox->getDisplayName(); if (!$fetchAllWithSubscribedFlag) { if ($mailbox->unseen > 0) { $text .= ' <span class="em-folder-status" id="status_' . $nodeId . '">(' . $mailbox->unseen . ')</span>'; } else { $text .= ' <span class="em-folder-status" id="status_' . $nodeId . '"></span>'; } } // \GO::debug($mailbox); // $children = $this->_getMailboxTreeNodes($mailbox->getChildren()); $node = array('text' => $text, 'mailbox' => $mailbox->name, 'name' => $mailbox->getDisplayName(), 'account_id' => $mailbox->getAccount()->id, 'iconCls' => 'folder-default', 'id' => $nodeId, 'draggable' => $mailbox->getAccount()->getPermissionLevel() > \GO\Base\Model\Acl::READ_PERMISSION, 'permission_level' => $mailbox->getAccount()->getPermissionLevel(), 'noselect' => $mailbox->noselect, 'disabled' => $fetchAllWithSubscribedFlag && $mailbox->noselect, 'noinferiors' => $mailbox->noinferiors, 'children' => !$mailbox->haschildren ? array() : null, 'expanded' => !$mailbox->haschildren, 'permittedFlags' => $mailbox->areFlagsPermitted(), 'cls' => $mailbox->noselect == 1 ? 'em-tree-node-noselect' : ""); if (!$fetchAllWithSubscribedFlag && $mailbox->unseen > 0) { $node['cls'] .= ' ml-folder-unseen'; } // \GO::debug($node); if ($mailbox->name == 'INBOX') { $node['usage'] = $this->_getUsage($mailbox->getAccount()); $node['acl_supported'] = $mailbox->getAccount()->openImapConnection()->has_capability('ACL'); } if ($mailbox->haschildren && $this->_isExpanded($nodeId)) { $node['children'] = $this->_getMailboxTreeNodes($mailbox->getChildren(false, !$fetchAllWithSubscribedFlag), $fetchAllWithSubscribedFlag); $node['expanded'] = true; } if ($fetchAllWithSubscribedFlag) { $node['checked'] = $mailbox->subscribed; } //if($mailbox->hasnochildren) $sortIndex = 5; switch ($mailbox->name) { case 'INBOX': $node['iconCls'] = 'email-folder-inbox'; $sortIndex = 0; break; case $mailbox->getAccount()->sent: $node['iconCls'] = 'email-folder-sent'; $sortIndex = 1; break; case $mailbox->getAccount()->trash: $node['iconCls'] = 'email-folder-trash'; $sortIndex = 3; break; case $mailbox->getAccount()->drafts: $node['iconCls'] = 'email-folder-drafts'; $sortIndex = 2; break; case 'INBOX/Spam': case 'INBOX.Spam': case 'Spam': $node['iconCls'] = 'email-folder-spam'; $sortIndex = 4; break; } //don't return empty namespaces if (!$node['noselect'] || empty($node['expanded']) || !empty($node['children'])) { $nodes[$sortIndex . '-' . $mailbox->name] = $node; } } \GO\Base\Util\ArrayUtil::caseInsensitiveSort($nodes); return array_values($nodes); }
public function list_folders($listSubscribed = true, $withStatus = false, $namespace = '', $pattern = '*', $isRoot = false) { \GO::debug("list_folders({$listSubscribed}, {$withStatus}, {$namespace}, {$pattern})"); //$delim = false; //unset($this->_subscribedFoldersCache); // $listStatus = $this->has_capability('LIST-STATUS'); $listCmd = $listSubscribed ? 'LSUB' : 'LIST'; // if($listSubscribed && $this->has_capability("LIST-EXTENDED")) //// $listCmd = "LIST (SUBSCRIBED)"; // $listCmd = "LIST"; $cmd = $listCmd . ' "' . $this->addslashes($this->utf7_encode($namespace)) . '" "' . $this->addslashes($this->utf7_encode($pattern)) . '"'; // if($listSubscribed && $this->has_capability("LIST-EXTENDED")) // $listCmd = 'LIST'; // if($listStatus && $withStatus){ // $cmd .= ' RETURN (CHILDREN SUBSCRIBED STATUS (MESSAGES UNSEEN))'; // } if ($this->has_capability("LIST-EXTENDED") && !$listSubscribed) { $cmd .= ' RETURN (CHILDREN'; if ($withStatus) { $cmd .= ' STATUS (MESSAGES UNSEEN)'; } $cmd .= ')'; } // \GO::debug($cmd); $cmd .= "\r\n"; $this->send_command($cmd); $result = $this->get_response(false, true); if (!$this->check_response($result, true, false) && $this->has_capability("LIST-EXTENDED")) { //some servers pretend to support list-extended but fail on the commands. //work around by disabling support and try again. \GO::session()->values['imap_disable_capabilites_' . $this->server] = 'LIST-EXTENDED'; return $this->list_folders($listSubscribed, $withStatus, $namespace, $pattern, $isRoot); } // \GO::debug($result); $delim = false; $folders = array(); foreach ($result as $vals) { if (!isset($vals[0])) { continue; } if ($vals[0] == 'A' . $this->command_count) { continue; } if ($vals[1] == $listCmd) { $flags = false; //$count = count($vals); $folder = false; //$vals[($count - 1)]; $flag = false; $delim_flag = false; $delim = false; $parent = ''; $no_select = false; $can_have_kids = true; $has_no_kids = false; $has_kids = false; $marked = false; //$subscribed=$listSubscribed; foreach ($vals as $v) { if ($v == '(') { $flag = true; } elseif ($v == ')') { $flag = false; $delim_flag = true; } else { if ($flag) { $flags .= ' ' . $v; } if ($delim_flag && !$delim) { $delim = $v; $delim_flag = false; } elseif ($delim && !$folder) { $folder = $v; } } } if (strtoupper($folder) == 'INBOX') { $folder = 'INBOX'; } //fix lowercase or mixed case inbox strings if ($folder == 'dovecot') { continue; } if (!$this->delimiter) { $this->set_mailbox_delimiter($delim); } //in some case the mailserver return the mailbox twice when it has subfolders: //R: * LIST ( ) / Drafts //R: * LIST ( ) / Folder3 //R: * LIST ( ) / Trash //R: * LIST ( ) / Sent //R: * LIST ( ) / Folder2 //R: * LIST ( ) / INBOX //R: * LIST ( ) / INBOX/ //R: * LIST ( ) / Test &- test/ //R: * LIST ( ) / Test &- test //We trim the delimiter of the folder to fix that. $folder = trim($folder, $this->delimiter); if (stristr($flags, 'marked')) { $marked = true; } if (!stristr($flags, 'noinferiors')) { $can_have_kids = false; } if (stristr($flags, 'haschildren')) { $has_kids = true; } if (stristr($flags, 'hasnochildren')) { $has_no_kids = true; } $subscribed = $listSubscribed || $this->_isSubscribed($folder, $flags); $nonexistent = stristr($flags, 'NonExistent'); if ($folder != 'INBOX' && (stristr($flags, 'noselect') || $nonexistent)) { $no_select = true; } if (!isset($folders[$folder]) && $folder) { $folders[$folder] = array('delimiter' => $delim, 'name' => $this->utf7_decode($folder), 'marked' => $marked, 'noselect' => $no_select, 'nonexistent' => $nonexistent, 'noinferiors' => $can_have_kids, 'haschildren' => $has_kids, 'hasnochildren' => $has_no_kids, 'subscribed' => $subscribed); } } else { $lastProp = false; foreach ($vals as $v) { if ($v == '(') { $flag = true; } elseif ($v == ')') { break; } else { if ($lastProp == 'MESSAGES') { $folders[$folder]['messages'] = intval($v); } elseif ($lastProp == 'UNSEEN') { $folders[$folder]['unseen'] = intval($v); } } $lastProp = $v; } } } // if($namespace=="" && $pattern=="%" && $listSubscribed && !isset($folders['INBOX'])){ // //inbox is not subscribed. Let's fix that/ // if(!$this->subscribe('INBOX')) // throw new \Exception("Could not subscribe to INBOX folder!"); // return $this->list_folders($listSubscribed, $withStatus, $namespace, $pattern); // } //sometimes shared folders like "Other user.shared" are in the folder list //but there's no "Other user" parent folder. We create a dummy folder here. if (!isset($folders['INBOX']) && $isRoot) { $folders["INBOX"] = array('delimiter' => $delim, 'name' => 'INBOX', 'marked' => true, 'nonexistent' => false, 'noselect' => false, 'haschildren' => false, 'hasnochildren' => true, 'noinferiors' => false, 'subscribed' => true); } if ($withStatus) { //no support for list status. Get the status for each folder //with seperate status calls foreach ($folders as $name => $folder) { if (!isset($folders[$name]['unseen'])) { if ($folders[$name]['nonexistent'] || $folders[$name]['noselect']) { $folders[$name]['messages'] = 0; $folders[$name]['unseen'] = 0; } else { $status = $this->get_status($folder["name"]); $folders[$name]['messages'] = $status['messages']; $folders[$name]['unseen'] = $status['unseen']; } } } } \GO\Base\Util\ArrayUtil::caseInsensitiveSort($folders); // \GO::debug($folders); return $folders; }