/** * AJAX action: Login to a remote account. * * Variables used: * - password: (string) Remote server password. * - password_base64: (boolean) If true, password is base64 encoded. * - password_save: (boolean) If true, password is saved (encrypted) * to config data. * - remoteid: (string) Remote server ID (base64url encoded). * - unsub: (boolean) If true, show unsubscribed mailboxes. * * @return boolean An object with the following properties: * - success: (boolean) True if login was successful. */ public function remoteLogin() { global $injector, $notification, $prefs; $remote = $injector->getInstance('IMP_Remote'); $remoteid = IMP_Mailbox::formFrom($this->vars->remoteid); $res = new stdClass(); $res->success = false; if (!isset($remote[$remoteid])) { $notification->push(_("Could not find remote server configuration."), 'horde.error'); return $res; } $password = $this->vars->password; if ($this->vars->password_base64) { $password = base64_decode($password); } $remote_ob = $remote[$remoteid]; try { switch ($remote_ob->login($password, $this->vars->password_save)) { case $remote_ob::LOGIN_BAD_CHANGED: $remote[$remoteid] = $remote_ob; // Fall-through // Fall-through case $remote_ob::LOGIN_BAD: throw new Exception(); case $remote_ob::LOGIN_OK_CHANGED: $remote[$remoteid] = $remote_ob; break; } $res->success = true; $notification->push(sprintf(_("Successfully authenticated to %s."), $remote_ob->label), 'horde.success'); $ftree = $injector->getInstance('IMP_Ftree'); $ftree->delete($remote_ob); $ftree->insert($remote_ob); $ftree[$remote_ob]->open = true; $this->_base->queue->setMailboxOpt('expand', 1); $iterator = new IMP_Ftree_IteratorFilter(new IMP_Ftree_Iterator($ftree[$remote_ob])); if ($this->vars->unsub) { $ftree->loadUnsubscribed(); $iterator->remove($iterator::UNSUB); } switch ($prefs->getValue('nav_expanded')) { case IMP_Ftree_Prefs_Expanded::NO: $iterator->add($iterator::CHILDREN); break; case IMP_Ftree_Prefs_Expanded::LAST: $iterator->add($iterator::EXPANDED); break; } array_map(array($ftree->eltdiff, 'add'), iterator_to_array($iterator, false)); } catch (Exception $e) { $notification->push(sprintf(_("Could not authenticate to %s."), $remote_ob->label), 'horde.error'); } return $res; }
/** * URL Parameters: * - ts: (integer) Toggle subscribe view. */ protected function _init() { global $injector, $notification, $prefs, $session; $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create(); /* Redirect back to the mailbox if folder use is not allowed. */ if (!$imp_imap->access(IMP_Imap::ACCESS_FOLDERS)) { $notification->push(_("The folder view is not enabled."), 'horde.error'); IMP_Minimal_Mailbox::url()->redirect(); } /* Decide whether or not to show all the unsubscribed mailboxes. */ $subscribe = $prefs->getValue('subscribe'); $showAll = !$subscribe || $session->get('imp', 'showunsub'); /* Toggle subscribed view, if necessary. */ if ($subscribe && $this->vars->ts) { $showAll = !$showAll; $session->set('imp', 'showunsub', $showAll); } /* Initialize the IMP_Ftree object. */ $ftree = $injector->getInstance('IMP_Ftree'); $iterator = new IMP_Ftree_IteratorFilter($ftree); $iterator->add($iterator::REMOTE); if ($showAll) { $ftree->loadUnsubscribed(); $iterator->remove($iterator::UNSUB); } $tree = $ftree->createTree('mimp_folders', array('iterator' => $iterator, 'poll_info' => true, 'render_type' => 'IMP_Tree_Simplehtml')); $selfurl = self::url(); $menu = array(array(_("Refresh"), $selfurl)); if ($subscribe) { $menu[] = array($showAll ? _("Show Subscribed Mailboxes") : _("Show All Mailboxes"), $selfurl->copy()->add('ts', 1)); } $this->title = _("Folders"); $this->view->menu = $this->getMenu('folders', $menu); $this->view->title = $this->title; $this->view->tree = $tree->getTree(true); $this->_pages[] = 'folders'; $this->_pages[] = 'menu'; }
/** * Create SELECT list of mailboxes for advanced search page. * * @param boolean $unsub Include unsubcribed mailboxes? * * @return object Object with the following properties: * - mbox_list: (array) Mapping of mailbox name (key) to display * string (values). * - tree: (IMP_Tree_Flist) Tree object. */ public function getSearchMboxList($unsub = false) { global $injector, $registry; $ob = new stdClass(); $view = new Horde_View(array('templatePath' => IMP_TEMPLATES . '/search')); $view->allsearch = IMP_Mailbox::formTo(IMP_Search_Query::ALLSEARCH); $ftree = $injector->getInstance('IMP_Ftree'); $iterator = new IMP_Ftree_IteratorFilter($ftree); if ($unsub) { $ftree->loadUnsubscribed(); $iterator->remove($iterator::UNSUB); } if ($registry->getView() != $registry::VIEW_DYNAMIC) { $iterator->add($iterator::REMOTE); } $ob->tree = $ftree->createTree('imp_search', array('iterator' => $iterator, 'render_params' => array('abbrev' => 0, 'container_select' => true, 'customhtml' => $view->render('search-all'), 'heading' => _("Add search mailbox:")), 'render_type' => 'IMP_Tree_Flist')); $mbox_list = array(); foreach ($iterator as $val) { $mbox_ob = $val->mbox_ob; $mbox_list[$mbox_ob->form_to] = $mbox_ob->display; } $ob->mbox_list = $mbox_list; return $ob; }
/** * Return the number of mailboxes on the server. */ public function count() { $this->loadUnsubscribed(); $iterator = new IMP_Ftree_IteratorFilter($this); $iterator->add($iterator::NONIMAP); $iterator->remove($iterator::UNSUB); return iterator_count($iterator); }
/** * AJAX action: List mailboxes. * * Variables used: * - all: (integer) 1 to show all mailboxes. * - base: (string) The base mailbox. * - expall: (boolean) 1 to expand all (requires 'all'). * - initial: (string) 1 to indicate the initial request for mailbox * list. * - mboxes: (string) The list of mailboxes to process (JSON encoded * array; mailboxes are base64url encoded). * - reload: (integer) 1 to force reload of mailboxes. * - unsub: (integer) 1 to show unsubscribed mailboxes. * * @return boolean True. */ public function listMailboxes() { global $injector, $prefs, $session; $ftree = $injector->getInstance('IMP_Ftree'); $iterator = new AppendIterator(); /* This might be a long running operation. */ if ($this->vars->initial) { $session->close(); $ftree->eltdiff->clear(); /* @todo: Correctly handle unsubscribed mailboxes in ftree. */ if ($ftree->unsubscribed_loaded && !$this->vars->reload) { $ftree->init(); } } if ($this->vars->reload) { $ftree->init(); } $filter = new IMP_Ftree_IteratorFilter($ftree); if ($this->vars->unsub) { $ftree->loadUnsubscribed(); $filter->remove($filter::UNSUB); } if (isset($this->vars->base)) { $this->_base->queue->setMailboxOpt('base', $this->vars->base); } if ($this->vars->all) { $this->_base->queue->setMailboxOpt('all', 1); $iterator->append($filter); if ($this->vars->expall) { $this->vars->action = 'expand'; $this->_base->callAction('toggleMailboxes'); } } elseif ($this->vars->initial || $this->vars->reload) { $special = new ArrayIterator(); $special->append($ftree['INBOX']); /* Add special mailboxes explicitly to the initial folder list, * since they are ALWAYS displayed, may appear outside of the * folder slice requested, and need to be sorted logically. */ $s_elts = array(); foreach (IMP_Mailbox::getSpecialMailboxesSort() as $val) { if (isset($ftree[$val])) { $special->append($val); $s_elts[] = $ftree[$val]; } } $iterator->append($special); /* Go through and find any parent elements that contain only * special mailbox children - this need to be suppressed in * display. */ $filter2 = clone $filter; $filter2->add(array($filter2::CONTAINERS, $filter2::SPECIALMBOXES)); $no_children = array(); foreach (array_unique($s_elts) as $val) { while (($val = $val->parent) && !$val->base_elt) { $filter2->iterator = new IMP_Ftree_Iterator($val); foreach ($filter2 as $val) { /* If we found at least one viewable mailbox, this * element needs its children to be displayed. */ break 2; } $no_children[] = strval($val); } } if (!empty($no_children)) { $this->_base->queue->ftreeCallback = function ($id, $ob) use($no_children) { if (in_array($id, $no_children)) { unset($ob->ch); } }; } /* Add regular mailboxes. */ $no_mbox = false; switch ($prefs->getValue('nav_expanded')) { case IMP_Ftree_Prefs_Expanded::NO: $filter->add($filter::CHILDREN); break; case IMP_Ftree_Prefs_Expanded::YES: $this->_base->queue->setMailboxOpt('expand', 1); $no_mbox = true; break; case IMP_Ftree_Prefs_Expanded::LAST: $filter->add($filter::EXPANDED); $this->_base->queue->setMailboxOpt('expand', 1); break; } $filter->mboxes = array('INBOX'); $iterator->append($filter); if (!$no_mbox) { $mboxes = IMP_Mailbox::formFrom(json_decode($this->vars->mboxes)); foreach ($mboxes as $val) { if (!$val->inbox) { $ancestors = new IMP_Ftree_IteratorFilter(new IMP_Ftree_Iterator_Ancestors($val->tree_elt)); if ($this->vars->unsub) { $ancestors->remove($ancestors::UNSUB); } $iterator->append($ancestors); } } } } else { $filter->add($filter::EXPANDED); $this->_base->queue->setMailboxOpt('expand', 1); foreach (array_filter(IMP_Mailbox::formFrom(json_decode($this->vars->mboxes))) as $val) { $filter->iterator = new IMP_Ftree_Iterator($val->tree_elt); $iterator->append($filter); $ftree->expand($val); } } array_map(array($ftree->eltdiff, 'add'), array_unique(iterator_to_array($iterator, false))); if ($this->vars->initial) { $session->start(); /* We need at least 1 changed mailbox. If not, something went * wrong and we should reinitialize the folder list. */ if (!$ftree->eltdiff->changed_elts) { $this->vars->reload = true; $this->listMailboxes(); $this->vars->reload = false; } } return true; }
/** */ protected function _init() { global $injector, $notification, $page_output, $prefs, $registry, $session; /* Redirect back to the mailbox if folder use is not allowed. */ $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create(); if (!$imp_imap->access(IMP_Imap::ACCESS_FOLDERS)) { $notification->push(_("The folder view is not enabled."), 'horde.error'); Horde::url('mailbox', true)->redirect(); } /* Decide whether or not to show all the unsubscribed mailboxes. */ $subscribe = $prefs->getValue('subscribe'); $showAll = !$subscribe || $session->get('imp', 'showunsub'); $page_output->addScriptFile('hordecore.js', 'horde'); $page_output->addScriptFile('folders.js'); /* Get the base URL for this page. */ $folders_url = self::url()->setRaw(true); /* These JS defines are required by all sub-pages. */ $page_output->addInlineJsVars(array('ImpFolders.folders_url' => strval($folders_url), 'ImpFolders.text' => array('download1' => _("All messages in the following mailbox(es) will be downloaded into one MBOX file:"), 'download2' => _("This may take some time. Are you sure you want to continue?"), 'oneselect' => _("Only one mailbox should be selected for this action."), 'rename1' => _("You are renaming the mailbox:"), 'rename2' => _("Please enter the new name:"), 'select' => _("Please select a mailbox before you perform this action."), 'subfolder1' => _("You are creating a subfolder to"), 'subfolder2' => _("Please enter the name of the new mailbox:"), 'toplevel' => _("You are creating a top-level mailbox.") . "\n" . _("Please enter the name of the new mailbox:")))); /* Initialize the IMP_Ftree object. */ $ftree = $injector->getInstance('IMP_Ftree'); /* $mbox_list entries are urlencoded. */ $mbox_list = isset($this->vars->mbox_list) ? IMP_Mailbox::formFrom($this->vars->mbox_list) : array(); /* META refresh time (might be altered by actionID). */ $refresh_time = $prefs->getValue('refresh_time'); /* Set up the master View object. */ $view = new Horde_View(array('templatePath' => IMP_TEMPLATES . '/basic/folders')); $view->addHelper('FormTag'); $view->addHelper('Tag'); $token = $session->getToken(); $view->token = $token; /* Run through the action handlers. */ if ($this->vars->actionID) { try { $session->checkToken($this->vars->token); } catch (Horde_Exception $e) { $notification->push($e); $this->vars->actionID = null; } } switch ($this->vars->actionID) { case 'expand_all_folders': $ftree->expandAll(); break; case 'collapse_all_folders': $ftree->collapseAll(); break; case 'rebuild_tree': $ftree->init(); break; case 'expunge_mbox': if (!empty($mbox_list)) { $injector->getInstance('IMP_Message')->expungeMailbox(array_fill_keys($mbox_list, null)); } break; case 'delete_mbox': foreach ($mbox_list as $val) { $val->delete(); } break; case 'download_mbox': case 'download_mbox_zip': IMP_Contents_View::downloadUrl('mbox', array('actionID' => 'download_mbox', 'mbox_list' => $this->vars->mbox_list, 'type' => $this->vars->actionID == 'download_mbox' ? 'mbox' : 'mboxzip'))->redirect(); exit; case 'import_mbox': if ($this->vars->import_mbox) { try { $notification->push($injector->getInstance('IMP_Mbox_Import')->import($this->vars->import_mbox, 'mbox_upload'), 'horde.success'); } catch (Horde_Exception $e) { $notification->push($e); } $this->vars->actionID = null; } else { $refresh_time = null; } break; case 'create_mbox': if (isset($this->vars->new_mailbox)) { try { $parent = empty($mbox_list) ? IMP_Mailbox::get(IMP_Ftree::BASE_ELT) : $mbox_list[0]; $new_mbox = $parent->createMailboxName($this->vars->new_mailbox); if ($new_mbox->exists) { $notification->push(sprintf(_("Mailbox \"%s\" already exists."), $new_mbox->display), 'horde.warning'); } else { $new_mbox->create(); } } catch (Horde_Exception $e) { $notification->push($e); } } break; case 'rename_mbox': // $old_names may be URL encoded. $old_names = array_map('trim', explode("\n", $this->vars->old_names)); $new_names = array_map('trim', explode("\n", $this->vars->new_names)); $iMax = count($new_names); if (!empty($new_names) && !empty($old_names) && $iMax == count($old_names)) { for ($i = 0; $i < $iMax; ++$i) { $old_name = IMP_Mailbox::formFrom($old_names[$i]); $old_ns = $old_name->namespace_info; $new = trim($new_names[$i], $old_ns->delimiter); /* If this is a personal namespace, then anything goes as * far as the input. Just append the personal namespace to * it. */ if ($old_ns->type === $old_ns::NS_PERSONAL || strlen($old_ns->name) && stripos($new_names[$i], $old_ns->name) !== 0) { $new = $old_ns->name . $new; } $old_name->rename($new); } } break; case 'subscribe_mbox': case 'unsubscribe_mbox': if (empty($mbox_list)) { $notification->push(_("No mailboxes were specified"), 'horde.message'); } else { foreach ($mbox_list as $val) { $val->subscribe($this->vars->actionID == 'subscribe_mbox'); } } break; case 'toggle_subscribed_view': if ($subscribe) { $showAll = !$showAll; $session->set('imp', 'showunsub', $showAll); } break; case 'poll_mbox': if (!empty($mbox_list)) { $ftree->poll->addPollList($mbox_list); } break; case 'nopoll_mbox': if (!empty($mbox_list)) { $ftree->poll->removePollList($mbox_list); } break; case 'empty_mbox': if (!empty($mbox_list)) { $injector->getInstance('IMP_Message')->emptyMailbox($mbox_list); } break; case 'mark_mbox_seen': case 'mark_mbox_unseen': if (!empty($mbox_list)) { $injector->getInstance('IMP_Message')->flagAllInMailbox(array('\\seen'), $mbox_list, $this->vars->actionID == 'mark_mbox_seen'); } break; case 'delete_mbox_confirm': case 'empty_mbox_confirm': if (!empty($mbox_list)) { $loop = array(); foreach ($mbox_list as $val) { switch ($this->vars->actionID) { case 'delete_mbox_confirm': if (!$val->access_deletembox) { $notification->push(sprintf(_("The mailbox \"%s\" may not be deleted."), $val->display), 'horde.error'); continue 2; } break; case 'empty_mbox_confirm': if (!$val->access_empty) { $notification->push(sprintf(_("The mailbox \"%s\" may not be emptied."), $val->display), 'horde.error'); continue 2; } break; } try { $elt_info = $imp_imap->status($val, Horde_Imap_Client::STATUS_MESSAGES); } catch (IMP_Imap_Exception $e) { $elt_info = null; } $data = array('name' => $val->display, 'msgs' => $elt_info ? $elt_info['messages'] : 0, 'val' => $val->form_to); $loop[] = $data; } if (!count($loop)) { break; } $page_output->addScriptFile('stripe.js', 'horde'); $this->title = _("Folder Actions - Confirmation"); $v = clone $view; if ($this->vars->actionID == 'delete_mbox_confirm') { $v->actionID = 'delete_mbox'; $v->delete = true; } elseif ($this->vars->actionID == 'empty_mbox_confirm') { $v->actionID = 'empty_mbox'; $v->empty = true; } $v->mboxes = $loop; $v->folders_url = $folders_url; $this->output = $v->render('folders_confirm'); return; } break; case 'mbox_size': if (!empty($mbox_list)) { $loop = array(); $sum = 0; foreach ($mbox_list as $val) { $size = $val->size; $data = array('name' => $val->display, 'size' => sprintf(_("%.2fMB"), $size / (1024 * 1024)), 'sort' => $size); $sum += $size; $loop[] = $data; } /* Prepare the topbar. */ $injector->getInstance('Horde_View_Topbar')->subinfo = $injector->getInstance('IMP_View_Subinfo')->render(); $v = clone $view; $v->folders_url = $folders_url; $v->mboxes = $loop; $v->mboxes_sum = sprintf(_("%.2fMB"), $sum / (1024 * 1024)); $page_output->addScriptFile('stripe.js', 'horde'); $page_output->addScriptFile('tables.js', 'horde'); $this->title = _("Mailbox Sizes"); $this->output = $v->render('folders_size'); return; } break; case 'search': if (!empty($mbox_list)) { IMP_Basic_Search::url()->add(array('mailbox_list' => IMP_Mailbox::formTo($mbox_list), 'subfolder' => 1))->redirect(); } break; } $this->title = _("Folder Navigator"); $folders_url->add('token', $token); /* Prepare the topbar. */ $injector->getInstance('Horde_View_Topbar')->subinfo = $injector->getInstance('IMP_View_Subinfo')->render(); if ($session->get('imp', 'file_upload') && $this->vars->actionID == 'import_mbox') { /* Prepare import template. */ $v = clone $view; $v->folders_url = $folders_url; $v->import_mbox = $mbox_list[0]; $this->output = $v->render('import'); return; } /* Prepare the header template. */ $head_view = clone $view; $head_view->folders_url = $folders_url; /* Prepare the actions template. */ $actions = clone $view; $actions->addHelper('Horde_Core_View_Helper_Accesskey'); $actions->addHelper('Horde_Core_View_Helper_Help'); $actions->id = 0; $actions->refresh = Horde::widget(array('title' => _("_Refresh"), 'url' => $folders_url->copy())); $actions->create_mbox = $imp_imap->access(IMP_Imap::ACCESS_CREATEMBOX) && $imp_imap->access(IMP_Imap::ACCESS_CREATEMBOX_MAX); if ($prefs->getValue('subscribe')) { $actions->subscribe = true; $subToggleText = $showAll ? _("Hide Unsubscribed") : _("Show All"); $actions->toggle_subscribe = Horde::widget(array('url' => $folders_url->copy()->add(array('actionID' => 'toggle_subscribed_view', 'token' => $token)), 'title' => $subToggleText, 'nocheck' => true)); } $actions->nav_poll = !$prefs->isLocked('nav_poll') && !$prefs->getValue('nav_poll_all'); $actions->notrash = !$prefs->getValue('use_trash'); $actions->file_upload = $session->get('imp', 'file_upload'); $actions->expand_all = Horde::widget(array('url' => $folders_url->copy()->add(array('actionID' => 'expand_all_folders', 'token' => $token)), 'title' => _("Expand All"), 'nocheck' => true)); $actions->collapse_all = Horde::widget(array('url' => $folders_url->copy()->add(array('actionID' => 'collapse_all_folders', 'token' => $token)), 'title' => _("Collapse All"), 'nocheck' => true)); /* Build the folder tree. */ $iterator = new IMP_Ftree_IteratorFilter($ftree); $iterator->add(array($iterator::REMOTE, $iterator::VFOLDER)); if ($showAll) { $ftree->loadUnsubscribed(); $iterator->remove($iterator::UNSUB); } $tree = $ftree->createTree('imp_folders', array('checkbox' => true, 'editvfolder' => true, 'iterator' => $iterator, 'poll_info' => true)); $displayNames = $fullNames = array(); foreach ($ftree as $val) { $mbox_ob = $val->mbox_ob; $tmp = $displayNames[] = $mbox_ob->display; $tmp2 = $mbox_ob->display_notranslate; if ($tmp != $tmp2) { $fullNames[strval($val)] = $tmp2; } } $page_output->addInlineJsVars(array('ImpFolders.ajax' => $registry->getServiceLink('ajax', 'imp')->url, 'ImpFolders.displayNames' => $displayNames, 'ImpFolders.fullNames' => $fullNames, '-ImpFolders.mbox_expand' => intval($prefs->getValue('nav_expanded') == 2))); $page_output->metaRefresh($refresh_time, $this->url()); Horde::startBuffer(); $tree->renderTree(); $this->output = $head_view->render('head') . $actions->render('actions') . Horde::endBuffer(); if (count($tree) > 10) { $actions->id = 1; $this->output .= $actions->render('actions'); } /* No need for extra template - close out the tags here. */ $this->output .= '</form>'; }
/** * Returns the list of mailboxes. * * @param array $opts Additional options: * <pre> * - unsub: (boolean) If true, return unsubscribed mailboxes. * </pre> * * @return array The list of IMAP mailboxes. A list of arrays with the * following keys: * <pre> * - d: (string) The namespace delimiter. * - label: (string) Human readable label (UTF-8). * - level: (integer) The child level of this element. * - ob: (Horde_Imap_Client_Mailbox) A mailbox object. * - subscribed: (boolean) True if mailbox is subscribed. * </pre> */ public function mailboxList(array $opts = array()) { global $injector; $ftree = $injector->getInstance('IMP_Ftree'); if (!empty($opts['unsub'])) { /* Make sure unsubscribed mailboxes are loaded. */ $ftree->loadUnsubscribed(); } $iterator = new IMP_Ftree_IteratorFilter($ftree); $iterator->add(array($iterator::CONTAINERS, $iterator::REMOTE, $iterator::VFOLDER)); if (!empty($opts['unsub'])) { $iterator->remove($iterator::UNSUB); } $mboxes = array(); foreach ($iterator as $val) { $mbox_ob = $val->mbox_ob; $sub = $mbox_ob->sub; $mboxes[] = array('d' => $mbox_ob->namespace_delimiter, 'label' => $mbox_ob->label, 'level' => $val->level, 'ob' => $mbox_ob->imap_mbox_ob, 'subscribed' => $sub); } return $mboxes; }