Overview

Packages

  • IMP

Classes

  • IMP
  • IMP_Ajax_Addresses
  • IMP_Ajax_Application
  • IMP_Ajax_Application_Compose
  • IMP_Ajax_Application_Handler_Common
  • IMP_Ajax_Application_Handler_ComposeAttach
  • IMP_Ajax_Application_Handler_Draft
  • IMP_Ajax_Application_Handler_Dynamic
  • IMP_Ajax_Application_Handler_ImageUnblock
  • IMP_Ajax_Application_Handler_Mboxtoggle
  • IMP_Ajax_Application_Handler_Passphrase
  • IMP_Ajax_Application_Handler_Remote
  • IMP_Ajax_Application_Handler_RemotePrefs
  • IMP_Ajax_Application_Handler_Search
  • IMP_Ajax_Application_Handler_Smartmobile
  • IMP_Ajax_Application_ListMessages
  • IMP_Ajax_Application_ShowMessage
  • IMP_Ajax_Application_Viewport
  • IMP_Ajax_Application_Viewport_Error
  • IMP_Ajax_Imple_ImportEncryptKey
  • IMP_Ajax_Imple_ItipRequest
  • IMP_Ajax_Imple_PassphraseDialog
  • IMP_Ajax_Imple_VcardImport
  • IMP_Ajax_Queue
  • IMP_Api
  • IMP_Application
  • IMP_Auth
  • IMP_Basic_Base
  • IMP_Basic_Compose
  • IMP_Basic_Contacts
  • IMP_Basic_Error
  • IMP_Basic_Folders
  • IMP_Basic_Listinfo
  • IMP_Basic_Mailbox
  • IMP_Basic_Message
  • IMP_Basic_Pgp
  • IMP_Basic_Saveimage
  • IMP_Basic_Search
  • IMP_Basic_Searchbasic
  • IMP_Basic_Smime
  • IMP_Basic_Thread
  • IMP_Block_Newmail
  • IMP_Block_Summary
  • IMP_Compose
  • IMP_Compose_Attachment
  • IMP_Compose_Attachment_Linked_Metadata
  • IMP_Compose_Attachment_Metadata
  • IMP_Compose_Attachment_Storage
  • IMP_Compose_Attachment_Storage_AutoDetermine
  • IMP_Compose_Attachment_Storage_Temp
  • IMP_Compose_Attachment_Storage_VfsLinked
  • IMP_Compose_Exception
  • IMP_Compose_Exception_Address
  • IMP_Compose_HtmlSignature
  • IMP_Compose_Link
  • IMP_Compose_LinkedAttachment
  • IMP_Compose_Ui
  • IMP_Compose_View
  • IMP_Contacts
  • IMP_Contacts_Avatar_Addressbook
  • IMP_Contacts_Avatar_Gravatar
  • IMP_Contacts_Avatar_Unknown
  • IMP_Contacts_Flag_Host
  • IMP_Contacts_Image
  • IMP_Contents
  • IMP_Contents_InlineOutput
  • IMP_Contents_View
  • IMP_Crypt_Pgp
  • IMP_Crypt_Smime
  • IMP_Dynamic_AddressList
  • IMP_Dynamic_Base
  • IMP_Dynamic_Compose
  • IMP_Dynamic_Compose_Common
  • IMP_Dynamic_Helper_Base
  • IMP_Dynamic_Mailbox
  • IMP_Dynamic_Message
  • IMP_Exception
  • IMP_Factory_AuthImap
  • IMP_Factory_Compose
  • IMP_Factory_ComposeAtc
  • IMP_Factory_Contacts
  • IMP_Factory_Contents
  • IMP_Factory_Flags
  • IMP_Factory_Ftree
  • IMP_Factory_Identity
  • IMP_Factory_Imap
  • IMP_Factory_Mail
  • IMP_Factory_MailAutoconfig
  • IMP_Factory_Mailbox
  • IMP_Factory_MailboxCache
  • IMP_Factory_MailboxList
  • IMP_Factory_Maillog
  • IMP_Factory_MimeViewer
  • IMP_Factory_Pgp
  • IMP_Factory_PrefsSort
  • IMP_Factory_Quota
  • IMP_Factory_Search
  • IMP_Factory_Sentmail
  • IMP_Factory_Smime
  • IMP_Factory_Spam
  • IMP_Filter
  • IMP_Flag_Base
  • IMP_Flag_Imap
  • IMP_Flag_Imap_Answered
  • IMP_Flag_Imap_Deleted
  • IMP_Flag_Imap_Draft
  • IMP_Flag_Imap_Flagged
  • IMP_Flag_Imap_Forwarded
  • IMP_Flag_Imap_Junk
  • IMP_Flag_Imap_NotJunk
  • IMP_Flag_Imap_Seen
  • IMP_Flag_System_Attachment
  • IMP_Flag_System_Encrypted
  • IMP_Flag_System_HighPriority
  • IMP_Flag_System_List
  • IMP_Flag_System_LowPriority
  • IMP_Flag_System_Match_Address
  • IMP_Flag_System_Match_Flag
  • IMP_Flag_System_Match_Header
  • IMP_Flag_System_Personal
  • IMP_Flag_System_Signed
  • IMP_Flag_System_Unseen
  • IMP_Flag_User
  • IMP_Flags
  • IMP_Ftree
  • IMP_Ftree_Account
  • IMP_Ftree_Account_Imap
  • IMP_Ftree_Account_Inboxonly
  • IMP_Ftree_Account_Remote
  • IMP_Ftree_Account_Vfolder
  • IMP_Ftree_Element
  • IMP_Ftree_Eltdiff
  • IMP_Ftree_Iterator
  • IMP_Ftree_Iterator_Ancestors
  • IMP_Ftree_IteratorFilter
  • IMP_Ftree_IteratorFilter_Children
  • IMP_Ftree_IteratorFilter_Containers
  • IMP_Ftree_IteratorFilter_Expanded
  • IMP_Ftree_IteratorFilter_Invisible
  • IMP_Ftree_IteratorFilter_Mailboxes
  • IMP_Ftree_IteratorFilter_Nonimap
  • IMP_Ftree_IteratorFilter_Polled
  • IMP_Ftree_IteratorFilter_Remote
  • IMP_Ftree_IteratorFilter_Special
  • IMP_Ftree_IteratorFilter_Subscribed
  • IMP_Ftree_IteratorFilter_Vfolder
  • IMP_Ftree_Prefs
  • IMP_Ftree_Prefs_Expanded
  • IMP_Ftree_Prefs_Poll
  • IMP_Ftree_Select
  • IMP_Images
  • IMP_Imap
  • IMP_Imap_Acl
  • IMP_Imap_Cache_Wrapper
  • IMP_Imap_Config
  • IMP_Imap_Exception
  • IMP_Imap_Password
  • IMP_Imap_PermanentFlags
  • IMP_Imap_Remote
  • IMP_Indices
  • IMP_Indices_Mailbox
  • IMP_LoginTasks_SystemTask_GarbageCollection
  • IMP_LoginTasks_SystemTask_Upgrade
  • IMP_LoginTasks_SystemTask_UpgradeAuth
  • IMP_LoginTasks_Task_Autocreate
  • IMP_LoginTasks_Task_DeleteAttachmentsMonthly
  • IMP_LoginTasks_Task_DeleteSentmailMonthly
  • IMP_LoginTasks_Task_FilterOnLogin
  • IMP_LoginTasks_Task_PurgeSentmail
  • IMP_LoginTasks_Task_PurgeSpam
  • IMP_LoginTasks_Task_PurgeTrash
  • IMP_LoginTasks_Task_RecoverDraft
  • IMP_LoginTasks_Task_RenameSentmailMonthly
  • IMP_Mailbox
  • IMP_Mailbox_List
  • IMP_Mailbox_List_Pop3
  • IMP_Mailbox_List_Thread
  • IMP_Mailbox_List_Virtual
  • IMP_Mailbox_SessionCache
  • IMP_Mailbox_Ui
  • IMP_Maillog
  • IMP_Maillog_Log_Base
  • IMP_Maillog_Log_Forward
  • IMP_Maillog_Log_Mdn
  • IMP_Maillog_Log_Redirect
  • IMP_Maillog_Log_Reply
  • IMP_Maillog_Log_Replyall
  • IMP_Maillog_Log_Replylist
  • IMP_Maillog_Message
  • IMP_Maillog_Storage_Base
  • IMP_Maillog_Storage_Composite
  • IMP_Maillog_Storage_History
  • IMP_Maillog_Storage_Mdnsent
  • IMP_Maillog_Storage_Null
  • IMP_Mbox_Generate
  • IMP_Mbox_Import
  • IMP_Mbox_Size
  • IMP_Message
  • IMP_Message_Date
  • IMP_Message_Ui
  • IMP_Mime_Headers
  • IMP_Mime_Status
  • IMP_Mime_Status_RenderIssue
  • IMP_Mime_Status_RenderIssue_Display
  • IMP_Mime_Viewer_Alternative
  • IMP_Mime_Viewer_Appledouble
  • IMP_Mime_Viewer_Audio
  • IMP_Mime_Viewer_Enriched
  • IMP_Mime_Viewer_Externalbody
  • IMP_Mime_Viewer_Html
  • IMP_Mime_Viewer_Images
  • IMP_Mime_Viewer_Itip
  • IMP_Mime_Viewer_Mdn
  • IMP_Mime_Viewer_Partial
  • IMP_Mime_Viewer_Pdf
  • IMP_Mime_Viewer_Pgp
  • IMP_Mime_Viewer_Plain
  • IMP_Mime_Viewer_Related
  • IMP_Mime_Viewer_Rfc822
  • IMP_Mime_Viewer_Smil
  • IMP_Mime_Viewer_Smime
  • IMP_Mime_Viewer_Status
  • IMP_Mime_Viewer_Vcard
  • IMP_Mime_Viewer_Video
  • IMP_Mime_Viewer_Zip
  • IMP_Minimal_Base
  • IMP_Minimal_Compose
  • IMP_Minimal_Error
  • IMP_Minimal_Folders
  • IMP_Minimal_Mailbox
  • IMP_Minimal_Message
  • IMP_Minimal_Messagepart
  • IMP_Minimal_Search
  • IMP_Notification_Event_Status
  • IMP_Notification_Handler_Decorator_ImapAlerts
  • IMP_Notification_Handler_Decorator_NewmailNotify
  • IMP_Perms
  • IMP_Prefs_AttribText
  • IMP_Prefs_Identity
  • IMP_Prefs_Sort
  • IMP_Prefs_Sort_FixedDate
  • IMP_Prefs_Sort_None
  • IMP_Prefs_Sort_Sortpref
  • IMP_Prefs_Sort_Sortpref_Locked
  • IMP_Prefs_Special_Acl
  • IMP_Prefs_Special_ComposeTemplates
  • IMP_Prefs_Special_Drafts
  • IMP_Prefs_Special_Encrypt
  • IMP_Prefs_Special_Flag
  • IMP_Prefs_Special_HtmlSignature
  • IMP_Prefs_Special_ImageReplacement
  • IMP_Prefs_Special_InitialPage
  • IMP_Prefs_Special_Mailto
  • IMP_Prefs_Special_NewmailSound
  • IMP_Prefs_Special_PgpPrivateKey
  • IMP_Prefs_Special_PgpPublicKey
  • IMP_Prefs_Special_Remote
  • IMP_Prefs_Special_Searches
  • IMP_Prefs_Special_Sentmail
  • IMP_Prefs_Special_SmimePrivateKey
  • IMP_Prefs_Special_SmimePublicKey
  • IMP_Prefs_Special_Sourceselect
  • IMP_Prefs_Special_Spam
  • IMP_Prefs_Special_SpecialMboxes
  • IMP_Prefs_Special_Trash
  • IMP_Quota
  • IMP_Quota_Hook
  • IMP_Quota_Imap
  • IMP_Quota_Null
  • IMP_Quota_Ui
  • IMP_Remote
  • IMP_Remote_Account
  • IMP_Script_Package_Autocomplete
  • IMP_Script_Package_ComposeBase
  • IMP_Script_Package_DynamicBase
  • IMP_Script_Package_Editor
  • IMP_Script_Package_Imp
  • IMP_Search
  • IMP_Search_Element
  • IMP_Search_Element_Attachment
  • IMP_Search_Element_Autogenerated
  • IMP_Search_Element_Bulk
  • IMP_Search_Element_Contacts
  • IMP_Search_Element_Daterange
  • IMP_Search_Element_Flag
  • IMP_Search_Element_Header
  • IMP_Search_Element_Mailinglist
  • IMP_Search_Element_Or
  • IMP_Search_Element_Personal
  • IMP_Search_Element_Recipient
  • IMP_Search_Element_Size
  • IMP_Search_Element_Text
  • IMP_Search_Element_Within
  • IMP_Search_Filter
  • IMP_Search_Filter_Attachment
  • IMP_Search_Filter_Autogenerated
  • IMP_Search_Filter_Builtin
  • IMP_Search_Filter_Bulk
  • IMP_Search_Filter_Contacts
  • IMP_Search_Filter_Mailinglist
  • IMP_Search_Filter_Personal
  • IMP_Search_IteratorFilter
  • IMP_Search_Query
  • IMP_Search_Ui
  • IMP_Search_Vfolder
  • IMP_Search_Vfolder_Builtin
  • IMP_Search_Vfolder_Vinbox
  • IMP_Search_Vfolder_Vtrash
  • IMP_Sentmail
  • IMP_Sentmail_Mongo
  • IMP_Sentmail_Null
  • IMP_Sentmail_Sql
  • IMP_Smartmobile
  • IMP_Spam
  • IMP_Spam_Email
  • IMP_Spam_Null
  • IMP_Spam_Program
  • IMP_Test
  • IMP_Tree_Flist
  • IMP_Tree_Jquerymobile
  • IMP_Tree_Simplehtml
  • IMP_View_Subinfo

Interfaces

  • IMP_Compose_Attachment_Linked
  • IMP_Contacts_Avatar_Backend
  • IMP_Contacts_Flag_Backend
  • IMP_Spam_Base
  • Overview
  • Package
  • Class
  • Tree
   1: <?php
   2: /**
   3:  * Copyright 2011-2014 Horde LLC (http://www.horde.org/)
   4:  *
   5:  * See the enclosed file COPYING for license information (GPL). If you
   6:  * did not receive this file, see http://www.horde.org/licenses/gpl.
   7:  *
   8:  * @category  Horde
   9:  * @copyright 2011-2014 Horde LLC
  10:  * @license   http://www.horde.org/licenses/gpl GPL
  11:  * @package   IMP
  12:  */
  13: 
  14: /**
  15:  * This object is a clearinghouse for actions related to an IMP mailbox.
  16:  *
  17:  * @author    Michael Slusarz <slusarz@horde.org>
  18:  * @category  Horde
  19:  * @copyright 2011-2014 Horde LLC
  20:  * @license   http://www.horde.org/licenses/gpl GPL
  21:  * @package   IMP
  22:  *
  23:  * @property-read string $abbrev_label  Abbreviated version of $label -
  24:  *                                      displays only the bare mailbox name
  25:  *                                      (no parents).
  26:  * @property-read boolean $access_creatembox  Can sub mailboxes be created?
  27:  * @property-read boolean $access_deletembox  Can this mailbox be deleted?
  28:  * @property-read boolean $access_deletembox_acl  Can this mailbox be deleted
  29:  *                                                according to ACL rules?
  30:  * @property-read boolean $access_deletemsgs  Can messages be deleted in this
  31:  *                                            mailbox?
  32:  * @property-read boolean $access_empty  Can this mailbox be emptied?
  33:  * @property-read boolean $access_expunge  Can messages be expunged in this
  34:  *                                    mailbox?
  35:  * @property-read boolean $access_filters  Is filtering available?
  36:  * @property-read boolean $access_flags  Are flags available?
  37:  * @property-read boolean $access_search  Is searching available?
  38:  * @property-read boolean $access_sort  Is sorting available?
  39:  * @property-read boolean $access_sortthread  Is thread sort available?
  40:  * @property-read mixed $acl  Either an ACL object for the mailbox, or null if
  41:  *                            no ACL found for the mailbox.
  42:  * @property-read string $basename  The basename of the mailbox (UTF-8).
  43:  * @property-read string $cacheid  Cache ID for the mailbox.
  44:  * @property-read string $cacheid_date  Cache ID for the mailbox, with added
  45:  *                                      data information.
  46:  * @property-read boolean $children  Does the element have children?
  47:  * @property-read boolean $container  Is this a container element?
  48:  * @property string $display  Display version of mailbox. Special mailboxes
  49:  *                            are replaced with localized strings and
  50:  *                            namespace information is removed.
  51:  * @property-read string $display_html  $display that has been HTML encoded.
  52:  * @property-read boolean $drafts  Is this a Drafts mailbox?
  53:  * @property-read boolean $editquery  Can this search query be edited?
  54:  * @property-read boolean $editvfolder  Can this virtual folder be edited?
  55:  * @property-read boolean $exists  Does this mailbox exist on the IMAP server?
  56:  * @property-read string $form_to  Converts this mailbox to a form
  57:  *                                 representation.
  58:  * @property-read object $icon  Icon information for the mailbox. Properties:
  59:  *   - alt: (string) The alt text for the icon.
  60:  *   - class: (string) The CSS class name.
  61:  *   - icon: (Horde_Themes_Image) The icon graphic to use.
  62:  *   - iconopen: (Horde_Themes_Image) The openicon to use.
  63:  *   - user_icon: (boolean) Use a user defined icon?
  64:  * @property-read IMP_Imap $imp_imap  The IMP_Imap object for this mailbox.
  65:  * @property-read string $imap_mbox  The actual name of the underlying IMAP
  66:  *                                   mailbox.
  67:  * @property-read Horde_Imap_Client_Mailbox $imap_mbox_ob  Convert this object
  68:  *                                                         tp an
  69:  *                                                         Imap_Client mailbox
  70:  *                                                         object.
  71:  * @property-read boolean $inbox  Is this the INBOX?
  72:  * @property-read boolean $innocent_show  Show the innocent action in this
  73:  *                                        mailbox?
  74:  * @property-read boolean $invisible  Is this mailbox invisible?
  75:  * @property-read boolean $is_imap  Is this an IMAP mailbox?
  76:  * @property-read boolean $is_open  Is this level expanded?
  77:  * @property-read string $label  The mailbox label. Essentially is $display
  78:  *                               that can be modified by user hook.
  79:  * @property-read integer $level  The child level of this element.
  80:  * @property-read IMP_Mailbox_List $list_ob  Returns the List object for the
  81:  *                                           mailbox.
  82:  * @property-read string $namespace  Is this a namespace element?
  83:  * @property-read IMP_Mailbox $namespace_append  The mailbox with necessary
  84:  *                                               namespace information appended.
  85:  * @property-read string $namespace_delimiter  The delimiter for this
  86:  *                                             namespace.
  87:  * @property-read Horde_Imap_Client_Data_Namespace $namespace_info  Namespace
  88:  *                                                                  info.
  89:  * @property-read boolean $nonimap  Is this a non-IMAP element?
  90:  * @property-read IMP_Mailbox $parent  The parent element. Returns null if no
  91:  *                                     parent. (Base of tree is returned as
  92:  *                                     a special element).
  93:  * @property-read string $parent_imap  The IMAP parent name.
  94:  * @property-read IMP_Imap_PermanentFlags $permflags  Return the list of
  95:  *                                                    permanent flags
  96:  *                                                    available to set in the
  97:  *                                                    mailbox.
  98:  * @property-read boolean $polled  Show polled information?
  99:  * @property-read object $poll_info  Poll information for the mailbox.
 100:  *                                   Properties:
 101:  *   - msgs: (integer) The number of total messages in the element, if polled.
 102:  *   - recent: (integer) The number of new messages in the element, if polled.
 103:  *   - unseen: (integer) The number of unseen messages in the element, if
 104:  *             polled.
 105:  * @property-read string $pref_from  Convert mailbox name from preference
 106:  *                                   storage.
 107:  * @property-read string $pref_to  Convert mailbox name to preference storage.
 108:  * @property-read boolean $query  Is this a search query?
 109:  * @property-read boolean $readonly  Is this mailbox read-only?
 110:  * @property-read boolean $remote  Is this a remote element?
 111:  * @property-read IMP_Remote_Account $remote_account  Return the account
 112:  *                                                    object for this element
 113:  *                                                    (null if not a remote
 114:  *                                                    element).
 115:  * @property-read boolean $remote_container  Is this mailbox a remote special
 116:  *                                           element?
 117:  * @property-read boolean $remote_mbox  Is this mailbox on a remote server?
 118:  * @property-read boolean $search  Is this a search mailbox?
 119:  * @property-read string $size  Human readable size of the mailbox.
 120:  * @property-read IMP_Prefs_Sort $sortob  Sort ob for use with this mailbox.
 121:  * @property-read boolean $spam  Is this a Spam mailbox?
 122:  * @property-read boolean $spam_show  Show the spam action in this mailbox?
 123:  * @property-read boolean $special  Is this is a "special" element?
 124:  * @property-read boolean $special_outgoing  Is this a "special" element
 125:  *                                           dealing with outgoing messages?
 126:  * @property-read boolean $specialvfolder  Is this a "special" virtual folder?
 127:  * @property-read boolean $sub  Is this mailbox subscribed to?
 128:  * @property-read array $subfolders  Returns the list of subfolders as mailbox
 129:  *                                   objects (including the current mailbox).
 130:  * @property-read array $subfolders_only  Returns the list of subfolders as
 131:  *                                        mailbox objects (NOT including the
 132:  *                                        current mailbox).
 133:  * @property-read boolean $systemquery  Is this a system (built-in) search
 134:  *                                      query?
 135:  * @property-read boolean $templates  Is this a Templates mailbox?
 136:  * @property-read boolean $trash  Is this a Trash mailbox?
 137:  * @property-read IMP_Ftree_Element $tree_elt  The tree element (null if it
 138:  *                                             doesn't exist in the tree).
 139:  * @property-read string $uidvalid  Returns the UIDVALIDITY string. Throws an
 140:  *                                  IMP_Exception on error.
 141:  * @property-read string $utf7imap  The UTF7-IMAP representation of this
 142:  *                                  object.
 143:  * @property-read string $value  The value of this element (IMAP mailbox name;
 144:  *                               UTF-8).
 145:  * @property-read boolean $vfolder  Is this a virtual folder?
 146:  * @property-read boolean $vfolder_container  Is this the virtual folder
 147:  *                                            container?
 148:  * @property-read boolean $vinbox  Is this the virtual inbox?
 149:  * @property-read boolean $vtrash  Is this the virtual trash?
 150:  */
 151: class IMP_Mailbox
 152: {
 153:     /* Special mailbox prefs. */
 154:     const MBOX_DRAFTS = 'drafts_folder';
 155:     const MBOX_SENT = 'sent_mail_folder';
 156:     const MBOX_SPAM = 'spam_folder';
 157:     const MBOX_TEMPLATES = 'composetemplates_mbox';
 158:     const MBOX_TRASH = 'trash_folder';
 159:     // This is just a placeholder - this pref doesn't exist.
 160:     const MBOX_USERSPECIAL = 'user_special';
 161: 
 162:     /* Special mailbox identifiers. */
 163:     const SPECIAL_COMPOSETEMPLATES = 'composetemplates';
 164:     const SPECIAL_DRAFTS = 'drafts';
 165:     const SPECIAL_SENT = 'sent';
 166:     const SPECIAL_SPAM = 'spam';
 167:     const SPECIAL_TRASH = 'trash';
 168:     const SPECIAL_USER = 'userspecial';
 169: 
 170:     /**
 171:      * The IMAP mailbox name (UTF-8).
 172:      *
 173:      * @var string
 174:      */
 175:     protected $_mbox;
 176: 
 177:     /**
 178:      * Shortcut to obtaining mailbox object(s).
 179:      *
 180:      * @param mixed $mbox  The full IMAP mailbox name(s).
 181:      *
 182:      * @return mixed  The IMP_Mailbox object(s).
 183:      */
 184:     public static function get($mbox)
 185:     {
 186:         if (is_array($mbox)) {
 187:             return array_filter(array_map(array(__CLASS__, 'get'), $mbox));
 188:         }
 189: 
 190:         if ($mbox instanceof IMP_Mailbox) {
 191:             return $mbox;
 192:         }
 193: 
 194:         try {
 195:             return $GLOBALS['injector']
 196:                 ->getInstance('IMP_Factory_Mailbox')
 197:                 ->create(strval($mbox));
 198:         } catch (IMP_Exception $e) {
 199:             return null;
 200:         }
 201:     }
 202: 
 203:     /**
 204:      * Shortcut to obtaining Horde_Imap_Client_Mailbox object(s).
 205:      *
 206:      * @param mixed $mbox  The full IMAP mailbox name(s).
 207:      *
 208:      * @return mixed  The Horde_Imap_Client_Mailbox object(s).
 209:      */
 210:     public static function getImapMboxOb($mbox)
 211:     {
 212:         if (is_array($mbox)) {
 213:             return array_filter(array_map(array(__CLASS__, 'getImapMboxOb'), $mbox));
 214:         }
 215: 
 216:         if ($mbox instanceof Horde_Imap_Client_Mailbox) {
 217:             return $mbox;
 218:         }
 219: 
 220:         // Mailbox names are always UTF-8 within IMP.
 221:         $mbox_ob = new self($mbox);
 222:         return Horde_Imap_Client_Mailbox::get($mbox_ob->imap_mbox);
 223:     }
 224: 
 225:     /**
 226:      * Shortcut to obtaining a mailbox object from a preference name.
 227:      *
 228:      * @var string $pref  The preference name.
 229:      *
 230:      * @return IMP_Mailbox  The IMP_Mailbox object.
 231:      */
 232:     public static function getPref($pref)
 233:     {
 234:         return self::get(self::prefFrom($GLOBALS['prefs']->getValue($pref)));
 235:     }
 236: 
 237:     /**
 238:      * Constructor.
 239:      *
 240:      * @var string $mbox  The full IMAP mailbox name.
 241:      *
 242:      * @throws IMP_Exception
 243:      */
 244:     public function __construct($mbox)
 245:     {
 246:         if (strlen($mbox) === 0) {
 247:             throw new IMP_Exception('Mailbox name must not be empty.');
 248:         }
 249: 
 250:         $this->_mbox = $mbox;
 251:     }
 252: 
 253:     /**
 254:      */
 255:     public function __toString()
 256:     {
 257:         return strval(
 258:             ($this->_mbox == IMP_Ftree::BASE_ELT) ? '' : $this->_mbox
 259:         );
 260:     }
 261: 
 262:     /**
 263:      */
 264:     public function __get($key)
 265:     {
 266:         global $injector;
 267: 
 268:         switch ($key) {
 269:         case 'abbrev_label':
 270:             $label = $this->label;
 271:             return ($this->nonimap || ($pos = strrpos($label, $this->namespace_delimiter)) === false)
 272:                 ? $label
 273:                 : substr($label, $pos + 1);
 274: 
 275:         case 'access_creatembox':
 276:             return (!($acl = $this->acl) ||
 277:                     ($acl[Horde_Imap_Client::ACL_CREATEMBOX]));
 278: 
 279:         case 'access_deletembox':
 280:             return ($this->access_deletembox_acl);
 281: 
 282:         case 'access_deletembox_acl':
 283:             return (!($acl = $this->acl) ||
 284:                     ($acl[Horde_Imap_Client::ACL_DELETEMBOX]));
 285: 
 286:         case 'access_deletemsgs':
 287:             return (!($acl = $this->acl) ||
 288:                     ($acl[Horde_Imap_Client::ACL_DELETEMSGS]));
 289: 
 290:         case 'access_empty':
 291:             if ($this->access_deletemsgs && $this->access_expunge) {
 292:                 $special = $this->getSpecialMailboxes();
 293:                 return empty($special[self::SPECIAL_TRASH]) ||
 294:                     !$special[self::SPECIAL_TRASH]->vtrash ||
 295:                     ($special[self::SPECIAL_TRASH] == $this);
 296:             }
 297:             return false;
 298: 
 299:         case 'access_expunge':
 300:             return (!($acl = $this->acl) ||
 301:                     ($acl[Horde_Imap_Client::ACL_EXPUNGE]));
 302: 
 303:         case 'access_filters':
 304:             return !$this->search && $this->is_imap;
 305: 
 306:         case 'access_flags':
 307:             return $this->is_imap;
 308: 
 309:         case 'access_search':
 310:             return $this->is_imap;
 311: 
 312:         case 'access_sort':
 313:             /* Although possible to abstract other sorting methods, all other
 314:              * non-sequence methods require a download of ALL messages, which
 315:              * is too much overhead.*/
 316:             return $this->is_imap;
 317: 
 318:         case 'access_sortthread':
 319:             /* Thread sort is always available for IMAP servers, since
 320:              * Horde_Imap_Client_Socket has a built-in ORDEREDSUBJECT
 321:              * implementation. We will always prefer REFERENCES, but will
 322:              * fallback to ORDEREDSUBJECT if the server doesn't support THREAD
 323:              * sorting. */
 324:             return $this->is_imap;
 325: 
 326:         case 'acl':
 327:             $cache = $injector->getInstance('IMP_Mailbox_SessionCache');
 328:             if (($acl = $cache->getAcl($this->_mbox)) !== false) {
 329:                 return $acl;
 330:             }
 331: 
 332:             if ($this->nonimap) {
 333:                 $acl = null;
 334:             } else {
 335:                 $acl = $injector->getInstance('IMP_Imap_Acl')->getACL($this, true);
 336:                 $hooks = $injector->getInstance('Horde_Core_Hooks');
 337: 
 338:                 if ($hooks->hookExists('mbox_acl', 'imp')) {
 339:                     $hooks->callHook('mbox_acl', 'imp', array($this, $acl));
 340:                 }
 341:             }
 342: 
 343:             $cache->setAcl($this->_mbox, $acl);
 344: 
 345:             return $acl;
 346: 
 347:         case 'basename':
 348:             if ($this->nonimap) {
 349:                 return $this->label;
 350:             }
 351: 
 352:             $mbox = $this->remote_mbox
 353:                 ? $this->label
 354:                 : $this->_mbox;
 355: 
 356:             return (($pos = strrpos($mbox, $this->namespace_delimiter)) === false)
 357:                 ? strval($mbox)
 358:                 : substr($mbox, $pos + 1);
 359: 
 360:         case 'cacheid':
 361:         case 'cacheid_date':
 362:             return $this->_getCacheID($key == 'cacheid_date');
 363: 
 364:         case 'children':
 365:             return (($elt = $this->tree_elt) && $elt->children);
 366: 
 367:         case 'container':
 368:             return (($elt = $this->tree_elt) && $elt->container);
 369: 
 370:         case 'display':
 371:             return $this->nonimap
 372:                 ? $this->label
 373:                 : $this->_getDisplay();
 374: 
 375:         case 'display_html':
 376:             return htmlspecialchars($this->display);
 377: 
 378:         case 'display_notranslate':
 379:             return $this->nonimap
 380:                 ? $this->label
 381:                 : $this->_getDisplay(true);
 382: 
 383:         case 'drafts':
 384:             $special = $this->getSpecialMailboxes();
 385:             return ($this->_mbox == $special[self::SPECIAL_DRAFTS]);
 386: 
 387:         case 'editquery':
 388:             return $injector->getInstance('IMP_Search')->isQuery($this->_mbox, true);
 389: 
 390:         case 'editvfolder':
 391:             return $injector->getInstance('IMP_Search')->isVFolder($this->_mbox, true);
 392: 
 393:         case 'exists':
 394:             return $injector->getInstance('IMP_Mailbox_SessionCache')->exists($this);
 395: 
 396:         case 'form_to':
 397:             return $this->formTo($this->_mbox);
 398: 
 399:         case 'icon':
 400:             return $this->_getIcon();
 401: 
 402:         case 'imp_imap':
 403:             return $injector->getInstance('IMP_Factory_Imap')->create(strval($this));
 404: 
 405:         case 'imap_mbox':
 406:             return strval(
 407:                 $injector->getInstance('IMP_Remote')->getMailboxById($this->_mbox) ?: $this->_mbox
 408:             );
 409: 
 410:         case 'imap_mbox_ob':
 411:             return self::getImapMboxOb($this->_mbox);
 412: 
 413:         case 'inbox':
 414:             return (strcasecmp($this->_mbox, 'INBOX') === 0);
 415: 
 416:         case 'innocent_show':
 417:             $p = $this->imp_imap->config->innocent_params;
 418:             return (!empty($p) &&
 419:                     ((isset($p['display']) && empty($p['display'])) || $this->spam));
 420: 
 421:         case 'invisible':
 422:             return (($elt = $this->tree_elt) && $elt->invisible);
 423: 
 424:         case 'is_imap':
 425:             return $this->imp_imap->isImap();
 426: 
 427:         case 'is_open':
 428:             return (($elt = $this->tree_elt) && $elt->open);
 429: 
 430:         case 'label':
 431:             $cache = $injector->getInstance('IMP_Mailbox_SessionCache');
 432:             if (($label = $cache->getLabel($this->_mbox)) !== false) {
 433:                 return $label;
 434:             }
 435: 
 436:             /* Returns the plain text label that is displayed for the
 437:              * current mailbox, replacing virtual search mailboxes with an
 438:              * appropriate description, removing namespace and mailbox
 439:              * prefix information from what is shown to the user, and
 440:              * passing the label through a user-defined hook. */
 441:             $imp_search = $injector->getInstance('IMP_Search');
 442:             $label = ($ob = $imp_search[$this->_mbox])
 443:                 ? $ob->label
 444:                 : $this->_getDisplay();
 445: 
 446:             $hooks = $injector->getInstance('Horde_Core_Hooks');
 447:             if ($hooks->hookExists('mbox_label' ,'imp')) {
 448:                 $label = $hooks->callHook(
 449:                     'mbox_label',
 450:                     'imp',
 451:                     array($this->_mbox, $label)
 452:                 );
 453:             }
 454: 
 455:             $cache->setLabel($this->_mbox, $label);
 456: 
 457:             return $label;
 458: 
 459:         case 'level':
 460:             return ($elt = $this->tree_elt) ? $elt->level : 0;
 461: 
 462:         case 'list_ob':
 463:             return $injector->getInstance('IMP_Factory_MailboxList')->create($this);
 464: 
 465:         case 'namespace':
 466:             return (($elt = $this->tree_elt) && $elt->namespace);
 467: 
 468:         case 'namespace_append':
 469:             $imp_imap = $this->imp_imap;
 470:             $def_ns = $imp_imap->getNamespace($imp_imap::NS_DEFAULT);
 471:             if (is_null($def_ns)) {
 472:                 return $this;
 473:             }
 474:             $empty_ns = $imp_imap->getNamespace('');
 475: 
 476:             /* If default namespace is empty, or there is no empty namespace,
 477:              * then we can auto-detect namespace from input.
 478:              * If a non-default namespace is empty, then we must always use
 479:              * default namespace. */
 480:             if (!is_null($empty_ns) &&
 481:                 ($def_ns->name == $empty_ns->name)) {
 482:                 return $this;
 483:             }
 484: 
 485:             $ns_info = $this->namespace_info;
 486: 
 487:             if (is_null($ns_info) || !is_null($empty_ns)) {
 488:                 return self::get($def_ns->name . $this->_mbox);
 489:             }
 490: 
 491:             return $this;
 492: 
 493:         case 'namespace_delimiter':
 494:             $ns_info = $this->namespace_info;
 495:             return is_null($ns_info)
 496:                 ? ''
 497:                 : $ns_info->delimiter;
 498: 
 499:         case 'namespace_info':
 500:             return $this->imp_imap->getNamespace(strlen($this) ? $this->_mbox : IMP_Imap::NS_DEFAULT);
 501: 
 502:         case 'nonimap':
 503:             return ($this->search ||
 504:                     (($elt = $this->tree_elt) && $elt->nonimap));
 505: 
 506:         case 'parent':
 507:             return ($elt = $this->tree_elt) ? $elt->parent->mbox_ob : null;
 508: 
 509:         case 'parent_imap':
 510:             return (is_null($p = $this->parent) || !strlen($p))
 511:                 ? null
 512:                 : $p;
 513: 
 514:         case 'permflags':
 515:             if ($this->access_flags) {
 516:                 $imp_imap = $this->imp_imap;
 517:                 try {
 518:                     /* Make sure we are in R/W mailbox mode (SELECT). No flags
 519:                      * are allowed in EXAMINE mode. */
 520:                     $imp_imap->openMailbox($this, Horde_Imap_Client::OPEN_READWRITE);
 521:                     $status = $imp_imap->status($this->_mbox, Horde_Imap_Client::STATUS_FLAGS | Horde_Imap_Client::STATUS_PERMFLAGS);
 522:                     return new IMP_Imap_PermanentFlags($status['permflags'], $status['flags']);
 523:                 } catch (Exception $e) {}
 524:             }
 525: 
 526:             return new IMP_Imap_PermanentFlags();
 527: 
 528:         case 'poll_info':
 529:             $info = new stdClass;
 530:             $info->msgs = 0;
 531:             $info->recent = 0;
 532:             $info->unseen = 0;
 533: 
 534:             try {
 535:                 if ($msgs_info = $this->imp_imap->status($this->_mbox, Horde_Imap_Client::STATUS_RECENT_TOTAL | Horde_Imap_Client::STATUS_UNSEEN | Horde_Imap_Client::STATUS_MESSAGES)) {
 536:                     if (!empty($msgs_info['recent_total'])) {
 537:                         $info->recent = intval($msgs_info['recent_total']);
 538:                     }
 539:                     $info->msgs = intval($msgs_info['messages']);
 540:                     $info->unseen = intval($msgs_info['unseen']);
 541:                 }
 542:             } catch (IMP_Imap_Exception $e) {}
 543: 
 544:             return $info;
 545: 
 546:         case 'polled':
 547:             return (!$this->search &&
 548:                     (($elt = $this->tree_elt) && $elt->polled));
 549: 
 550:         case 'pref_from':
 551:             return $this->prefFrom($this->_mbox);
 552: 
 553:         case 'pref_to':
 554:             return $this->prefTo($this->_mbox);
 555: 
 556:         case 'query':
 557:             return $injector->getInstance('IMP_Search')->isQuery($this->_mbox);
 558: 
 559:         case 'readonly':
 560:             return (($acl = $this->acl) &&
 561:                     !$acl[Horde_Imap_Client::ACL_DELETEMBOX] &&
 562:                     !$acl[Horde_Imap_Client::ACL_DELETEMSGS] &&
 563:                     !$acl[Horde_Imap_Client::ACL_EXPUNGE] &&
 564:                     !$acl[Horde_Imap_Client::ACL_INSERT] &&
 565:                     !$acl[Horde_Imap_Client::ACL_SEEN] &&
 566:                     !$acl[Horde_Imap_Client::ACL_WRITE]);
 567: 
 568:         case 'remote':
 569:             return $injector->getInstance('IMP_Remote')->isRemoteMbox($this->_mbox);
 570: 
 571:         case 'remote_account':
 572:             $remote = $injector->getInstance('IMP_Remote');
 573:             $account = ($this->remote_container)
 574:                 ? $remote[$this->_mbox]
 575:                 : $remote->getRemoteById($this->_mbox);
 576:             return $account ?: null;
 577: 
 578:         case 'remote_container':
 579:             return (($elt = $this->tree_elt) && $elt->remote);
 580: 
 581:         case 'remote_mbox':
 582:             return (($elt = $this->tree_elt) && $elt->remote_mbox);
 583: 
 584:         case 'search':
 585:             return $injector->getInstance('IMP_Search')->isSearchMbox($this->_mbox);
 586: 
 587:         case 'size':
 588:             return $injector->getInstance('IMP_Mbox_Size')->getSize($this);
 589: 
 590:         case 'sortob':
 591:             return $this->imp_imap->access(IMP_Imap::ACCESS_SORT)
 592:                 ? $injector->getInstance('IMP_Prefs_Sort')
 593:                 : $injector->getInstance('IMP_Prefs_Sort_None');
 594: 
 595:         case 'spam':
 596:             $special = $this->getSpecialMailboxes();
 597:             return ($this->_mbox == $special[self::SPECIAL_SPAM]);
 598: 
 599:         case 'spam_show':
 600:             $p = $this->imp_imap->config->spam_params;
 601:             return (!empty($p) && (!empty($p['display']) || !$this->spam));
 602: 
 603:         case 'special':
 604:             $special = $this->getSpecialMailboxes();
 605: 
 606:             switch ($this->_mbox) {
 607:             case $special[self::SPECIAL_COMPOSETEMPLATES]:
 608:             case $special[self::SPECIAL_DRAFTS]:
 609:             case $special[self::SPECIAL_SPAM]:
 610:             case $special[self::SPECIAL_TRASH]:
 611:                 return true;
 612:             }
 613: 
 614:             return in_array($this->_mbox, array_merge(
 615:                 $special[self::SPECIAL_SENT],
 616:                 $special[self::SPECIAL_USER]
 617:             ));
 618: 
 619:         case 'special_outgoing':
 620:             $special = $this->getSpecialMailboxes();
 621: 
 622:             return in_array($this->_mbox, array_merge(
 623:                 array(
 624:                     $special[self::SPECIAL_COMPOSETEMPLATES],
 625:                     $special[self::SPECIAL_DRAFTS]
 626:                 ),
 627:                 $special[self::SPECIAL_SENT]
 628:             ));
 629: 
 630:         case 'specialvfolder':
 631:             return !$this->editvfolder;
 632: 
 633:         case 'sub':
 634:             return (($elt = $this->tree_elt) && $elt->subscribed);
 635: 
 636:         case 'subfolders':
 637:             return $this->get(array_merge(array($this->_mbox), $this->subfolders_only));
 638: 
 639:         case 'subfolders_only':
 640:             return $this->get($this->imp_imap->listMailboxes($this->imap_mbox_ob->list_escape . $this->namespace_delimiter . '*', null, array('flat' => true)));
 641: 
 642:         case 'systemquery':
 643:             return $injector->getInstance('IMP_Search')->isSystemQuery($this->_mbox);
 644: 
 645:         case 'templates':
 646:             $special = $this->getSpecialMailboxes();
 647:             return ($this->_mbox == $special[self::SPECIAL_COMPOSETEMPLATES]);
 648: 
 649:         case 'trash':
 650:             $special = $this->getSpecialMailboxes();
 651:             return ($this->_mbox == $special[self::SPECIAL_TRASH]);
 652: 
 653:         case 'tree_elt':
 654:             $ftree = $injector->getInstance('IMP_Ftree');
 655:             return $ftree[$this->_mbox];
 656: 
 657:         case 'uidvalid':
 658:             $cache = $injector->getInstance('IMP_Mailbox_SessionCache');
 659:             $uidvalid = $cache->getUidvalidity($this->_mbox);
 660:             if ($uidvalid === 0) {
 661:                 return;
 662:             }
 663: 
 664:             // POP3 and non-IMAP mailboxes do not support UIDVALIDITY.
 665:             if (!$this->is_imap || $this->nonimap) {
 666:                 $cache->setUidvalidity($this->_mbox, 0);
 667:                 return false;
 668:             }
 669: 
 670:             $status = $this->imp_imap->status($this->_mbox, Horde_Imap_Client::STATUS_UIDVALIDITY);
 671: 
 672:             if (($first = ($uidvalid === false)) ||
 673:                 ($status['uidvalidity'] != $uidvalid)) {
 674:                 $uidvalid = $status['uidvalidity'];
 675:                 $cache->setUidvalidity($this->_mbox, $uidvalid);
 676: 
 677:                 if (!$first) {
 678:                     throw new IMP_Exception(_("Mailbox structure on server has changed."));
 679:                 }
 680:             }
 681: 
 682:             return $uidvalid;
 683: 
 684:         case 'utf7imap':
 685:             return Horde_String::convertCharset($this->_mbox, 'UTF-8', 'UTF7-IMAP');
 686: 
 687:         case 'value':
 688:             return $this->_mbox;
 689: 
 690:         case 'vfolder':
 691:             return $injector->getInstance('IMP_Search')->isVFolder($this->_mbox);
 692: 
 693:         case 'vfolder_container':
 694:             return ($this->_mbox == IMP_Ftree_Account_Vfolder::VFOLDER_KEY);
 695: 
 696:         case 'vinbox':
 697:             return $injector->getInstance('IMP_Search')->isVinbox($this->_mbox);
 698: 
 699:         case 'vtrash':
 700:             return $injector->getInstance('IMP_Search')->isVTrash($this->_mbox);
 701:         }
 702: 
 703:         return false;
 704:     }
 705: 
 706:     /**
 707:      */
 708:     public function __set($key, $value)
 709:     {
 710:         global $injector;
 711: 
 712:         switch ($key) {
 713:         case 'display':
 714:             $injector->getInstance('IMP_Mailbox_SessionCache')->setDisplay($this->_mbox, $value);
 715:             break;
 716:         }
 717:     }
 718: 
 719:     /**
 720:      * Create this mailbox on the server.
 721:      *
 722:      * @param array $opts  Additional options:
 723:      *   - special_use: (array) An array of special-use attributes to attempt
 724:      *                  to add to the mailbox.
 725:      *                  DEFAULT: NONE
 726:      *   - subscribe: (boolean) Override preference value of subscribe.
 727:      *
 728:      * @return boolean  True on success.
 729:      * @throws Horde_Exception
 730:      */
 731:     public function create(array $opts = array())
 732:     {
 733:         global $injector, $notification, $prefs;
 734: 
 735:         if ($this->exists) {
 736:             return true;
 737:         }
 738: 
 739:         $imp_imap = $this->imp_imap;
 740: 
 741:         /* Check permissions. */
 742:         if (!$imp_imap->access(IMP_Imap::ACCESS_CREATEMBOX)) {
 743:             Horde::permissionDeniedError(
 744:                 'imp',
 745:                 'create_mboxes',
 746:                 _("You are not allowed to create mailboxes.")
 747:             );
 748:             return false;
 749:         }
 750:         if (!$imp_imap->access(IMP_Imap::ACCESS_CREATEMBOX_MAX)) {
 751:             Horde::permissionDeniedError(
 752:                 'imp',
 753:                 'max_create_mboxes',
 754:                 sprintf(_("You are not allowed to create more than %d mailboxes."), $imp_imap->max_create_mboxes)
 755:             );
 756:             return false;
 757:         }
 758: 
 759:         /* Special use flags. */
 760:         $special_use = isset($opts['special_use'])
 761:             ? $opts['special_use']
 762:             : array();
 763: 
 764:         /* Attempt to create the mailbox. */
 765:         try {
 766:             $imp_imap->createMailbox($this->_mbox, array('special_use' => $special_use));
 767:         } catch (IMP_Imap_Exception $e) {
 768:             if ($e->getCode() == $e::USEATTR) {
 769:                 unset($opts['special_use']);
 770:                 return $this->create($opts);
 771:             }
 772: 
 773:             $e->notify(sprintf(_("The mailbox \"%s\" was not created. This is what the server said"), $this->display) . ': ' . $e->getMessage());
 774:             return false;
 775:         }
 776: 
 777:         $notification->push(sprintf(_("The mailbox \"%s\" was successfully created."), $this->display), 'horde.success');
 778: 
 779:         /* Subscribe, if requested. */
 780:         if ((!isset($opts['subscribe']) && $prefs->getValue('subscribe')) ||
 781:             !empty($opts['subscribe'])) {
 782:             try {
 783:                 $imp_imap->subscribeMailbox($this->_mbox, true);
 784:             } catch (IMP_Imap_Exception $e) {}
 785:         }
 786: 
 787:         /* Update the mailbox tree. */
 788:         $injector->getInstance('IMP_Ftree')->insert($this->_mbox);
 789: 
 790:         return true;
 791:     }
 792: 
 793:     /**
 794:      * Deletes mailbox.
 795:      *
 796:      * @param array $opts  Addtional options:
 797:      *   - subfolders: (boolean) Delete all subfolders?
 798:      *     DEFAULT: false
 799:      *   - subfolders_only: (boolean) If deleting subfolders, delete only
 800:      *                      subfolders (not current mailbox)?
 801:      *     DEFAULT: false
 802:      *
 803:      * @return boolean  True on success.
 804:      */
 805:     public function delete(array $opts = array())
 806:     {
 807:         global $injector, $notification;
 808: 
 809:         if ($this->vfolder) {
 810:             if ($this->editvfolder) {
 811:                 $imp_search = $injector->getInstance('IMP_Search');
 812:                 $label = $imp_search[$this->_mbox]->label;
 813:                 unset($imp_search[$this->_mbox]);
 814:                 $notification->push(sprintf(_("Deleted Virtual Folder \"%s\"."), $label), 'horde.success');
 815:                 return true;
 816:             }
 817: 
 818:             $notification->push(sprintf(_("Could not delete Virtual Folder \"%s\"."), $this->label), 'horde.error');
 819:             return false;
 820:         }
 821: 
 822:         $deleted = array();
 823:         $imp_imap = $this->imp_imap;
 824:         if (empty($opts['subfolders'])) {
 825:             $to_delete = array($this);
 826:         } else {
 827:             $to_delete = empty($opts['subfolders_only'])
 828:                 ? $this->subfolders
 829:                 : $this->subfolders_only;
 830:         }
 831: 
 832:         foreach ($to_delete as $val) {
 833:             if (!$val->access_deletembox_acl) {
 834:                 $notification->push(sprintf(_("The mailbox \"%s\" may not be deleted."), $val->display), 'horde.error');
 835:                 continue;
 836:             }
 837: 
 838:             try {
 839:                 $imp_imap->deleteMailbox($val->value);
 840:                 $notification->push(sprintf(_("The mailbox \"%s\" was successfully deleted."), $val->display), 'horde.success');
 841:                 $deleted[] = $val;
 842:             } catch (IMP_Imap_Exception $e) {
 843:                 $e->notify(sprintf(_("The mailbox \"%s\" was not deleted. This is what the server said"), $val->display) . ': ' . $e->getMessage());
 844:             }
 845:         }
 846: 
 847:         if (!empty($deleted)) {
 848:             $injector->getInstance('IMP_Ftree')->delete($deleted);
 849:             $this->_onDelete($deleted);
 850:         }
 851: 
 852:         return (count($deleted) == count($to_delete));
 853:     }
 854: 
 855:     /**
 856:      * Rename this mailbox on the server. The subscription status remains the
 857:      * same.  All subfolders will also be renamed.
 858:      *
 859:      * @param string $new_name  The new mailbox name (UTF-8).
 860:      *
 861:      * @return boolean  True on success
 862:      */
 863:     public function rename($new_name)
 864:     {
 865:         global $injector, $notification;
 866: 
 867:         /* Don't try to rename to an empty string. */
 868:         if (!strlen($new_name)) {
 869:             return false;
 870:         }
 871: 
 872:         if (!$this->access_deletembox_acl) {
 873:             $notification->push(sprintf(_("The mailbox \"%s\" may not be renamed."), $this->display), 'horde.error');
 874:             return false;
 875:         }
 876: 
 877:         $new_mbox = $this->get($new_name);
 878:         $old_list = $this->subfolders;
 879: 
 880:         try {
 881:             $this->imp_imap->renameMailbox($this->_mbox, $new_mbox);
 882:         } catch (IMP_Imap_Exception $e) {
 883:             $e->notify(sprintf(_("Renaming \"%s\" to \"%s\" failed. This is what the server said"), $this->display, $new_mbox->display) . ': ' . $e->getMessage());
 884:             return false;
 885:         }
 886: 
 887:         $notification->push(sprintf(_("The mailbox \"%s\" was successfully renamed to \"%s\"."), $this->display, $new_mbox->display), 'horde.success');
 888: 
 889:         $injector->getInstance('IMP_Ftree')->rename($this->_mbox, $new_mbox);
 890:         $this->_onDelete($old_list);
 891: 
 892:         return true;
 893:     }
 894: 
 895:     /**
 896:      * Subscribe/unsubscribe to an IMAP mailbox.
 897:      *
 898:      * @param boolean $sub  True to subscribe, false to unsubscribe.
 899:      * @param array $opts   Additional options:
 900:      *   - subfolders: (boolean) If true, applies actions to all subfolders.
 901:      *
 902:      * @return boolean  True on success.
 903:      */
 904:     public function subscribe($sub, array $opts = array())
 905:     {
 906:         global $injector, $notification, $prefs;
 907: 
 908:         /* Skip non-IMAP/container mailboxes. */
 909:         if (!$prefs->getValue('subscribe') ||
 910:             $this->nonimap ||
 911:             $this->container) {
 912:             return false;
 913:         }
 914: 
 915:         if (!$sub && $this->inbox) {
 916:             $notification->push(sprintf(_("You cannot unsubscribe from \"%s\"."), $this->display), 'horde.error');
 917:             return false;
 918:         }
 919: 
 920:         $imp_imap = $this->imp_imap;
 921: 
 922:         try {
 923:             $imp_imap->subscribeMailbox($this->_mbox, $sub);
 924:         } catch (IMP_Imap_Exception $e) {
 925:             if ($sub) {
 926:                 $e->notify(sprintf(_("You were not subscribed to \"%s\". Here is what the server said"), $this->display) . ': ' . $e->getMessage());
 927:             } else {
 928:                 $e->notify(sprintf(_("You were not unsubscribed from \"%s\". Here is what the server said"), $this->display) . ': ' . $e->getMessage());
 929:             }
 930:             return false;
 931:         }
 932: 
 933:         $imap_tree = $injector->getInstance('IMP_Ftree');
 934:         if ($sub) {
 935:             $imap_tree->subscribe($this->_mbox);
 936:         } else {
 937:             $imap_tree->unsubscribe($this->_mbox);
 938:         }
 939: 
 940:         if (empty($opts['subfolders'])) {
 941:             $notify = $sub
 942:                 ? sprintf(_("You were successfully subscribed to \"%s\"."), $this->display)
 943:                 : sprintf(_("You were successfully unsubscribed from \"%s\"."), $this->display);
 944:         } else {
 945:             $action = false;
 946: 
 947:             foreach ($this->subfolders_only as $val) {
 948:                 try {
 949:                     $imp_imap->subscribeMailbox($val, $sub);
 950:                     if ($sub) {
 951:                         $imap_tree->subscribe($val);
 952:                     } else {
 953:                         $imap_tree->unsubscribe($val);
 954:                     }
 955: 
 956:                     $action = true;
 957:                 } catch (IMP_Imap_Exception $e) {
 958:                     // Ignore errors for sub-mailboxes.
 959:                 }
 960:             }
 961: 
 962:             if ($action) {
 963:                 $notify = $sub
 964:                     ? sprintf(_("You were successfully subscribed to \"%s\" and all subfolders."), $this->display)
 965:                     : sprintf(_("You were successfully unsubscribed from \"%s\" and all subfolders."), $this->display);
 966:             }
 967:         }
 968: 
 969:         $notification->push($notify, 'horde.success');
 970: 
 971:         return true;
 972:     }
 973: 
 974:     /**
 975:      * Runs filters on this mailbox.
 976:      */
 977:     public function filter()
 978:     {
 979:         if (!$this->search) {
 980:             $GLOBALS['injector']->getInstance('IMP_Filter')->filter($this);
 981:         }
 982:     }
 983: 
 984:     /**
 985:      * Filters this mailbox if it is the INBOX and the filter on display pref
 986:      * is active.
 987:      *
 988:      * @return boolean  True if filter() was called.
 989:      */
 990:     public function filterOnDisplay()
 991:     {
 992:         if ($this->inbox &&
 993:             $GLOBALS['prefs']->getValue('filter_on_display')) {
 994:             $this->filter();
 995:             return true;
 996:         }
 997: 
 998:         return false;
 999:     }
1000: 
1001:     /**
1002:      * Return the search query object for this mailbox.
1003:      *
1004:      * @return IMP_Search_Query  The search query object.
1005:      */
1006:     public function getSearchOb()
1007:     {
1008:         $imp_search = $GLOBALS['injector']->getInstance('IMP_Search');
1009:         return $imp_search[$this->_mbox];
1010:     }
1011: 
1012:     /**
1013:      * Return an indices object for this mailbox.
1014:      *
1015:      * @param mixed $in  Either a single UID, array of UIDs, or a
1016:      *                   Horde_Imap_Client_Ids object.
1017:      *
1018:      * @return IMP_Indices  An indices object.
1019:      */
1020:     public function getIndicesOb($in)
1021:     {
1022:         return new IMP_Indices($this, $in);
1023:     }
1024: 
1025:     /**
1026:      * Return the sorting preference for this mailbox.
1027:      *
1028:      * @param boolean $convert  Convert 'by' to a Horde_Imap_Client constant?
1029:      *
1030:      * @return IMP_Prefs_Sort_Sortpref  Sortpref object.
1031:      */
1032:     public function getSort($convert = false)
1033:     {
1034:         global $prefs;
1035: 
1036:         $mbox = $this->search
1037:             ? $this
1038:             : self::get($this->pref_from);
1039: 
1040:         $ob = $this->sortob[strval($mbox)];
1041:         $ob->convertSortby();
1042: 
1043:         if ($convert && ($ob->sortby == IMP::IMAP_SORT_DATE)) {
1044:             $ob->sortby = $prefs->getValue('sortdate');
1045:         }
1046: 
1047:         return $ob;
1048:     }
1049: 
1050:     /**
1051:      * Set the sorting preference for this mailbox.
1052:      *
1053:      * @param integer $by      The sort type.
1054:      * @param integer $dir     The sort direction.
1055:      * @param boolean $delete  Delete the entry?
1056:      */
1057:     public function setSort($by = null, $dir = null, $delete = false)
1058:     {
1059:         $mbox = $this->search
1060:             ? $this
1061:             : self::get($this->pref_from);
1062: 
1063:         if ($delete) {
1064:             unset($this->sortob[strval($mbox)]);
1065:         } else {
1066:             $change = array();
1067:             if (!is_null($by)) {
1068:                 $change['by'] = $by;
1069:             }
1070:             if (!is_null($dir)) {
1071:                 $change['dir'] = $dir;
1072:             }
1073:             $this->sortob[strval($mbox)] = $change;
1074:         }
1075:     }
1076: 
1077:     /**
1078:      * Are deleted messages hidden in this mailbox?
1079:      *
1080:      * @param boolean $deleted  Return value is what should be done with
1081:      *                          deleted messages in general, as opposed to any
1082:      *                          deleted message in the mailbox.
1083:      *
1084:      * @return boolean  True if deleted messages should be hidden.
1085:      */
1086:     public function hideDeletedMsgs($deleted = false)
1087:     {
1088:         global $prefs;
1089: 
1090:         if (!$this->access_flags) {
1091:             return true;
1092:         }
1093: 
1094:         if ($prefs->getValue('use_trash')) {
1095:             /* If using Virtual Trash, only show deleted messages in
1096:              * the Virtual Trash mailbox. */
1097:             return $this->get($prefs->getValue(self::MBOX_TRASH))->vtrash
1098:                 ? !$this->vtrash
1099:                 : ($prefs->getValue('delhide_trash') ? true : $deleted);
1100:         }
1101: 
1102:         return $prefs->getValue('delhide');
1103:     }
1104: 
1105:     /**
1106:      * Sets the 'delhide' preference and clears necessary cached data.
1107:      *
1108:      * @param boolean $value  The value to set 'delhide' to.
1109:      */
1110:     public function setHideDeletedMsgs($value)
1111:     {
1112:         $GLOBALS['prefs']->setValue('delhide', $value);
1113:         $GLOBALS['injector']->getInstance('IMP_Factory_MailboxList')->expireAll();
1114:     }
1115: 
1116:     /**
1117:      * Run a search query on this mailbox that is not stored in the current
1118:      * session. Allows custom queries with custom sorts to be used without
1119:      * affecting cached mailboxes.
1120:      *
1121:      * @param Horde_Imap_Client_Search_Query $query  The search query object.
1122:      * @param integer $sortby                        The sort criteria.
1123:      * @param integer $sortdir                       The sort directory.
1124:      *
1125:      * @return IMP_Indices  An indices object.
1126:      */
1127:     public function runSearchQuery(Horde_Imap_Client_Search_Query $query,
1128:                                    $sortby = null, $sortdir = null)
1129:     {
1130:         try {
1131:             $results = $this->imp_imap->search($this, $query, array(
1132:                 'sort' => is_null($sortby) ? null : array($sortby)
1133:             ));
1134:             if ($sortdir) {
1135:                 $results['match']->reverse();
1136:             }
1137:             return $this->getIndicesOb($results['match']);
1138:         } catch (IMP_Imap_Exception $e) {
1139:             return new IMP_Indices();
1140:         }
1141:     }
1142: 
1143:     /**
1144:      * Generate a URL using the current mailbox.
1145:      *
1146:      * @param string|Horde_Url $page  Page name to link to.
1147:      * @param string $buid            The BUID to use on the linked page.
1148:      * @param boolean $encode         Encode the argument separator?
1149:      *
1150:      * @return Horde_Url  URL to $page with any necessary mailbox information
1151:      *                    added to the parameter list of the URL.
1152:      */
1153:     public function url($page, $buid = null, $encode = true)
1154:     {
1155:         if ($page instanceof Horde_Url) {
1156:             return $page->add($this->urlParams($buid))->setRaw(!$encode);
1157:         }
1158: 
1159:         switch ($GLOBALS['registry']->getView()) {
1160:         case Horde_Registry::VIEW_BASIC:
1161:             switch ($page) {
1162:             case 'message':
1163:                 return IMP_Basic_Message::url(array(
1164:                     'buid' => $buid,
1165:                     'mailbox' => $this->_mbox
1166:                 ))->setRaw(!$encode);
1167: 
1168:             case 'mailbox':
1169:                 return IMP_Basic_Mailbox::url(array(
1170:                     'mailbox' => $this->_mbox
1171:                 ))->setRaw(!$encode);
1172:             }
1173:             break;
1174: 
1175:         case Horde_Registry::VIEW_DYNAMIC:
1176:             $anchor = is_null($buid)
1177:                 ? ('mbox:' . $this->form_to)
1178:                 : ('msg:' . $this->form_to . ';' . $buid);
1179:             return Horde::url('index.php')->setAnchor($anchor);
1180: 
1181:         case Horde_Registry::VIEW_MINIMAL:
1182:             switch ($page) {
1183:             case 'message':
1184:                 return IMP_Minimal_Message::url(array(
1185:                     'buid' => $buid,
1186:                     'mailbox' => $this->_mbox
1187:                 ))->setRaw(!$encode);
1188: 
1189:             case 'mailbox':
1190:                 return IMP_Minimal_Mailbox::url(array(
1191:                     'mailbox' => $this->_mbox
1192:                 ))->setRaw(!$encode);
1193:             }
1194:             break;
1195: 
1196:         case Horde_Registry::VIEW_SMARTMOBILE:
1197:             $url = Horde::url('smartmobile.php');
1198:             $anchor = is_null($buid)
1199:                 ? ('mbox=' . $this->form_to)
1200:                 : ('msg=' . $this->form_to . ';' . $buid);
1201:             $url->setAnchor('mailbox?' . $anchor);
1202:             return $url;
1203:         }
1204: 
1205:         return Horde::url($page . '.php')->add($this->urlParams($buid))->setRaw(!$encode);
1206:     }
1207: 
1208:     /**
1209:      * Returns list of URL parameters necessary to indicate current mailbox
1210:      * status.
1211:      *
1212:      * @param string $buid  The BUID to use on the linked page.
1213:      *
1214:      * @return array  The list of parameters needed to indicate the current
1215:      *                mailbox status.
1216:      */
1217:     public function urlParams($buid = null)
1218:     {
1219:         $params = array('mailbox' => $this->form_to);
1220:         if (!is_null($buid)) {
1221:             $params['buid'] = $buid;
1222:         }
1223:         return $params;
1224:     }
1225: 
1226:     /**
1227:      * Determines if this mailbox is equal to the given mailbox.
1228:      * Needed because directly comparing two mailbox objects may fail (the
1229:      * member variables may be different).
1230:      *
1231:      * @param mixed $mbox  The mailbox to compare to.
1232:      *
1233:      * @return boolean  True if the mailboxes are the same.
1234:      */
1235:     public function equals($mbox)
1236:     {
1237:         return ($mbox == $this->_mbox);
1238:     }
1239: 
1240:     /**
1241:      * Create an indices object from a list of browser-UIDs.
1242:      *
1243:      * @param IMP_Indices|array $buids  Browser-UIDs.
1244:      *
1245:      * @return IMP_Indices  An indices object.
1246:      */
1247:     public function fromBuids($buids)
1248:     {
1249:         if (is_array($buids)) {
1250:             $buids = new IMP_Indices($this->_mbox, $buids);
1251:         }
1252:         $buid_list = $buids->getSingle(true);
1253: 
1254:         $out = new IMP_Indices();
1255: 
1256:         if ($buid_list[1]) {
1257:             $list_ob = $this->list_ob;
1258:             foreach ($buid_list[1] as $buid) {
1259:                 if ($resolve = $list_ob->resolveBuid($buid)) {
1260:                     $out->add($resolve['m'], $resolve['u']);
1261:                 }
1262:             }
1263:         }
1264: 
1265:         return $out;
1266:     }
1267: 
1268:     /**
1269:      * Create a BUID indices object from a list of UIDs.
1270:      *
1271:      * @param IMP_Indices $uids  UIDs.
1272:      *
1273:      * @return IMP_Indices  An indices object.
1274:      */
1275:     public function toBuids(IMP_Indices $uids)
1276:     {
1277:         $list_ob = $this->list_ob;
1278:         $out = new IMP_Indices();
1279: 
1280:         foreach ($uids as $val) {
1281:             foreach ($val->uids as $val2) {
1282:                 $out->add($this->_mbox, $list_ob->getBuid($val->mbox, $val2));
1283:             }
1284:         }
1285: 
1286:         return $out;
1287:     }
1288: 
1289:     /**
1290:      * Return the mailbox name to create given a submailbox name.
1291:      *
1292:      * @param string $new  The submailbox name (UTF-8).
1293:      *
1294:      * @return IMP_Mailbox  The mailbox to create.
1295:      */
1296:     public function createMailboxName($new)
1297:     {
1298:         if ($this->remote_container) {
1299:             $new = $this->remote_account->mailbox($new);
1300:         } else {
1301:             $ns_info = $this->namespace_info;
1302:             $new = strlen($this)
1303:                 ? ($this->_mbox . $ns_info->delimiter . $new)
1304:                 : $ns_info->name . $new;
1305:         }
1306: 
1307:         return self::get($new);
1308:     }
1309: 
1310:     /* Static methods. */
1311: 
1312:     /**
1313:      * Converts a mailbox string from a form representation.
1314:      * Needed because null characters (used for various internal non-IMAP
1315:      * mailbox representations) will not work in form elements.
1316:      *
1317:      * @param mixed $mbox  The mailbox name(s).
1318:      *
1319:      * @return mixed  The mailbox object(s).
1320:      */
1321:     public static function formFrom($mbox)
1322:     {
1323:         return is_array($mbox)
1324:             ? array_filter(array_map(array(__CLASS__, 'formFrom'), $mbox))
1325:               // Base64url (RFC 4648 [5]) encoding
1326:             : self::get(base64_decode(strtr($mbox, '-_', '+/')));
1327:     }
1328: 
1329:     /**
1330:      * Converts a mailbox string to a form representation.
1331:      * Needed because null characters (used for various internal non-IMAP
1332:      * mailbox representations) will not work in form elements.
1333:      *
1334:      * @param mixed $mbox  The mailbox name(s).
1335:      *
1336:      * @return mixed  The converted mailbox string(s).
1337:      */
1338:     public static function formTo($mbox)
1339:     {
1340:         return is_array($mbox)
1341:             ? array_filter(array_map(array(__CLASS__, 'formTo'), $mbox))
1342:               // Base64url (RFC 4648 [5]) encoding
1343:             : strtr(rtrim(base64_encode($mbox), '='), '+/', '-_');
1344:     }
1345: 
1346:     /**
1347:      * Return the list of special mailboxes.
1348:      *
1349:      * @return array  A list of mailboxes, with the self::SPECIAL_* constants
1350:      *                as keys and values containing the IMP_Mailbox objects or
1351:      *                null if the mailbox doesn't exist (self::SPECIAL_SENT
1352:      *                contains an array of objects).
1353:      */
1354:     public static function getSpecialMailboxes()
1355:     {
1356:         global $injector;
1357: 
1358:         return $injector->getInstance('IMP_Mailbox_SessionCache')->getSpecialMailboxes();
1359:     }
1360: 
1361:     /**
1362:      * Return the list of sorted special mailboxes.
1363:      *
1364:      * @return array  The list of sorted special mailboxes (IMP_Mailbox
1365:      *                objects).
1366:      */
1367:     public static function getSpecialMailboxesSort()
1368:     {
1369:         $out = array();
1370: 
1371:         foreach (array_filter(self::getSpecialMailboxes()) as $val) {
1372:             if (is_array($val)) {
1373:                 $out = array_merge($out, $val);
1374:             } else {
1375:                 $out[] = $val;
1376:             }
1377:         }
1378: 
1379:         $tmp = array();
1380:         foreach ($out as $val) {
1381:             $tmp[strval($val)] = $val->abbrev_label;
1382:         }
1383:         asort($tmp, SORT_LOCALE_STRING);
1384: 
1385:         return self::get(array_keys($tmp));
1386:     }
1387: 
1388:     /**
1389:      * Converts a mailbox name from a value stored in the preferences.
1390:      *
1391:      * @param string $mbox  The mailbox name as stored in a preference.
1392:      *
1393:      * @return string  The full IMAP mailbox name (UTF-8).
1394:      */
1395:     public static function prefFrom($mbox)
1396:     {
1397:         $imp_imap = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create();
1398:         if ($imp_imap->isImap()) {
1399:             $empty_ns = $imp_imap->getNamespace('');
1400: 
1401:             if (!is_null($empty_ns) &&
1402:                 (strpos($mbox, $empty_ns->delimiter) === 0)) {
1403:                 /* Prefixed with delimiter => from empty namespace. */
1404:                 return substr($mbox, strlen($empty_ns->delimiter));
1405:             } elseif ($imp_imap->getNamespace($mbox, true) === null) {
1406:                 /* No namespace prefix => from personal namespace. */
1407:                 $def_ns = $imp_imap->getNamespace($imp_imap::NS_DEFAULT);
1408:                 return $def_ns->name . $mbox;
1409:             }
1410:         }
1411: 
1412:         return $mbox;
1413:     }
1414: 
1415:     /**
1416:      * Converts a mailbox name to a value to be stored in a preference.
1417:      *
1418:      * @param string $mbox  The full IMAP mailbox name (UTF-8).
1419:      *
1420:      * @return string  The value to store in a preference.
1421:      */
1422:     public static function prefTo($mbox)
1423:     {
1424:         global $injector;
1425: 
1426:         $cache = $injector->getInstance('IMP_Mailbox_SessionCache');
1427:         $mbox_str = strval($mbox);
1428: 
1429:         if (($pref_to = $cache->getPrefTo($mbox_str)) !== false) {
1430:             return $pref_to;
1431:         }
1432: 
1433:         if (($ns = self::get($mbox)->namespace_info) !== null) {
1434:             $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create();
1435:             $def_ns = $imp_imap->getNamespace($imp_imap::NS_DEFAULT);
1436: 
1437:             if ($ns->name == $def_ns->name) {
1438:                 /* From personal namespace => strip namespace. */
1439:                 $ret = substr($mbox_str, strlen($def_ns->name));
1440:             } else {
1441:                 $empty_ns = $imp_imap->getNamespace('');
1442:                 if ($ns->name == $empty_ns->name) {
1443:                     /* From empty namespace => prefix with delimiter. */
1444:                     $ret = $empty_ns->delimiter . $mbox_str;
1445:                 }
1446:             }
1447:         }
1448: 
1449:         $cache->setPrefTo($mbox_str, $ret);
1450: 
1451:         return $ret;
1452:     }
1453: 
1454:     /* Internal methods. */
1455: 
1456:     /**
1457:      * Returns a unique identifier for this mailbox's status.
1458:      *
1459:      * This cache ID is guaranteed to change if messages are added/deleted
1460:      * from the mailbox. Additionally, if CONDSTORE is available on the remote
1461:      * IMAP server, this ID will change if flag information changes.
1462:      *
1463:      * For search mailboxes, this value never changes (search mailboxes must
1464:      * be forcibly refreshed).
1465:      *
1466:      * @param boolean $date  If true, adds date information to ID.
1467:      *
1468:      * @return string  The cache ID string, which will change when the
1469:      *                 composition of this mailbox changes.
1470:      */
1471:     protected function _getCacheID($date = false)
1472:     {
1473:         $date = $date
1474:             ? 'D' . date('z')
1475:             : '';
1476: 
1477:         if ($this->search) {
1478:             return '1' . ($date ? '|' . $date : '');
1479:         }
1480: 
1481:         $sortpref = $this->getSort(true);
1482:         $addl = array($sortpref->sortby, $sortpref->sortdir);
1483:         if ($date) {
1484:             $addl[] = $date;
1485:         }
1486: 
1487:         try {
1488:             return $this->imp_imap->getCacheId($this->_mbox, $addl);
1489:         } catch (IMP_Imap_Exception $e) {
1490:             /* Assume an error means that a mailbox can not be trusted. */
1491:             return strval(new Horde_Support_Randomid());
1492:         }
1493:     }
1494: 
1495:     /**
1496:      * If there is information available to tell us about a prefix in front of
1497:      * mailbox names that shouldn't be displayed to the user, then use it to
1498:      * strip that prefix out. Additionally, translate prefix text if this
1499:      * is a special mailbox.
1500:      *
1501:      * @param boolean $notranslate  Don't translate the mailbox prefix?
1502:      *
1503:      * @return string  The mailbox, with any prefix gone/translated.
1504:      */
1505:     protected function _getDisplay($notranslate = false)
1506:     {
1507:         global $injector;
1508: 
1509:         $cache = $injector->getInstance('IMP_Mailbox_SessionCache');
1510:         if (!$notranslate &&
1511:             (($display = $cache->getDisplay($this->_mbox)) !== false)) {
1512:             return $display;
1513:         }
1514: 
1515:         /* Handle special container mailboxes. */
1516:         if (($elt = $this->tree_elt) && $elt->nonimap && $elt->container) {
1517:             if ($elt->remote) {
1518:                 return _("Remote Accounts");
1519:             } elseif ($elt->vfolder) {
1520:                 return _("Virtual Folders");
1521:             } elseif ($elt->namespace_other) {
1522:                 return _("Other Users");
1523:             } elseif ($elt->namespace_shared) {
1524:                 return _("Shared");
1525:             }
1526:         }
1527: 
1528:         /* Handle remote mailboxes. */
1529:         if ($this->remote) {
1530:             return $injector->getInstance('IMP_Remote')->label($this->_mbox);
1531:         }
1532: 
1533:         $ns_info = $this->namespace_info;
1534:         $out = $this->_mbox;
1535: 
1536:         if (!is_null($ns_info)) {
1537:             /* Return translated namespace information. */
1538:             if (strlen($ns_info->translation) && $this->namespace) {
1539:                 $cache->setDisplay($this->_mbox, $ns_info->translation);
1540:                 return $ns_info->translation;
1541:             }
1542: 
1543:             /* Strip personal namespace information. */
1544:             if ($ns_info->type === $ns_info::NS_PERSONAL) {
1545:                 $out = $ns_info->stripNamespace($this->_mbox);
1546:             }
1547:         }
1548: 
1549:         if ($notranslate) {
1550:             return $out;
1551:         }
1552: 
1553:         /* Bug #9971: Special mailboxes can be empty IMP_Mailbox objects -
1554:          * catch this with the strlen check below. */
1555:         foreach ($this->getSpecialMailboxes() as $key => $val) {
1556:             switch ($key) {
1557:             case self::SPECIAL_COMPOSETEMPLATES:
1558:                 if (strval($val) == $this->_mbox) {
1559:                     $out = _("Templates");
1560:                 }
1561:                 break;
1562: 
1563:             case self::SPECIAL_DRAFTS:
1564:                 if (strval($val) == $this->_mbox) {
1565:                     $out = _("Drafts");
1566:                 }
1567:                 break;
1568: 
1569:             case self::SPECIAL_SENT:
1570:                 if (in_array($this->_mbox, $val)) {
1571:                     $out = _("Sent");
1572: 
1573:                     /* Add identity information to label, if sent-mail mailbox
1574:                      * is unique to an identity. */
1575:                     $identity = $injector->getInstance('IMP_Identity');
1576:                     $sm_all = $identity->getAllSentmail(false);
1577:                     if (count($sm_all) > 1) {
1578:                         $sm = array_keys($sm_all, $this->_mbox);
1579:                         if (count($sm) === 1) {
1580:                             $out .= ' (' . $identity->getValue('id', reset($sm)) . ')';
1581:                         }
1582:                     }
1583:                 }
1584:                 break;
1585: 
1586:             case self::SPECIAL_SPAM:
1587:                 if (strval($val) == $this->_mbox) {
1588:                     $out = _("Spam");
1589:                 }
1590:                 break;
1591: 
1592:             case self::SPECIAL_TRASH:
1593:                 if (strval($val) == $this->_mbox) {
1594:                     $out = _("Trash");
1595:                 }
1596:                 break;
1597:             }
1598:         }
1599: 
1600:         if ($this->inbox) {
1601:             $out = _("Inbox");
1602:         } elseif (($this->_mbox == $out) &&
1603:             !is_null($ns_info) &&
1604:             (strpos($out, 'INBOX' . $ns_info->delimiter) === 0)) {
1605:             $out = substr_replace($out, _("Inbox"), 0, 5);
1606:         }
1607: 
1608:         $cache->setDisplay($this->_mbox, $out);
1609: 
1610:         return $out;
1611:     }
1612: 
1613:     /**
1614:      * Return icon information.
1615:      *
1616:      * @return object  Object with the following properties:
1617:      *   - alt
1618:      *   - class
1619:      *   - icon
1620:      *   - iconopen
1621:      *   - user_icon
1622:      */
1623:     protected function _getIcon()
1624:     {
1625:         global $injector;
1626: 
1627:         $info = new stdClass;
1628:         $info->iconopen = null;
1629:         $info->user_icon = false;
1630: 
1631:         if ($this->container) {
1632:             /* We are dealing with folders here. */
1633:             if ($this->is_open) {
1634:                 $info->alt = _("Opened Folder");
1635:                 $info->class = 'folderopenImg';
1636:                 $info->icon = 'folders/open.png';
1637:             } else {
1638:                 $info->alt = _("Folder");
1639:                 $info->class = 'folderImg';
1640:                 $info->icon = 'folders/folder.png';
1641:                 $info->iconopen = Horde_Themes::img('folders/open.png');
1642:             }
1643:         } elseif ($this->remote_container) {
1644:             $info->alt = _("Remote Account");
1645:             $info->class = 'remoteImg';
1646:             $info->icon = 'shared.png';
1647:         } else {
1648:             $special = $this->getSpecialMailboxes();
1649: 
1650:             switch ($this->_mbox) {
1651:             case 'INBOX':
1652:                 $info->alt = _("Inbox");
1653:                 $info->class = 'inboxImg';
1654:                 $info->icon = 'folders/inbox.png';
1655:                 break;
1656: 
1657:             case $special[self::SPECIAL_COMPOSETEMPLATES]:
1658:                 $info->alt = ("Templates");
1659:                 $info->class = 'composetemplatesImg';
1660:                 $info->icon = 'folders/drafts.png';
1661:                 break;
1662: 
1663:             case $special[self::SPECIAL_DRAFTS]:
1664:                 $info->alt = _("Drafts");
1665:                 $info->class = 'draftsImg';
1666:                 $info->icon = 'folders/drafts.png';
1667:                 break;
1668: 
1669:             case $special[self::SPECIAL_SPAM]:
1670:                 $info->alt = _("Spam");
1671:                 $info->class = 'spamImg';
1672:                 $info->icon = 'folders/spam.png';
1673:                 break;
1674: 
1675:             case $special[self::SPECIAL_TRASH]:
1676:                 $info->alt = _("Trash");
1677:                 $info->class = 'trashImg';
1678:                 $info->icon = 'folders/trash.png';
1679:                 break;
1680: 
1681:             default:
1682:                 if (in_array($this->_mbox, $special[self::SPECIAL_SENT])) {
1683:                     $info->alt = _("Sent");
1684:                     $info->class = 'sentImg';
1685:                     $info->icon = 'folders/sent.png';
1686:                 } else {
1687:                     $info->alt = in_array($this->_mbox, $special[self::SPECIAL_USER])
1688:                         ? $this->display
1689:                         : _("Mailbox");
1690:                     if ($this->is_open) {
1691:                         $info->class = 'folderopenImg';
1692:                         $info->icon = 'folders/open.png';
1693:                     } else {
1694:                         $info->class = 'folderImg';
1695:                         $info->icon = 'folders/folder.png';
1696:                     }
1697:                 }
1698:                 break;
1699:             }
1700: 
1701:             /* Virtual folders. */
1702:             if ($this->vfolder) {
1703:                 $imp_search = $injector->getInstance('IMP_Search');
1704:                 if ($imp_search->isVTrash($this->_mbox)) {
1705:                     $info->alt = $imp_search[$this->_mbox]->label;
1706:                     $info->class = 'trashImg';
1707:                     $info->icon = 'folders/trash.png';
1708:                 } elseif ($imp_search->isVinbox($this->_mbox)) {
1709:                     $info->alt = $imp_search[$this->_mbox]->label;
1710:                     $info->class = 'inboxImg';
1711:                     $info->icon = 'folders/inbox.png';
1712:                 }
1713:             }
1714:         }
1715: 
1716:         /* Overwrite the icon information now. */
1717:         $mi = $injector->getInstance('IMP_Mailbox_SessionCache')->getIcons($this->_mbox);
1718:         if (!empty($mi)) {
1719:             if (isset($mi['alt'])) {
1720:                 $info->alt = $mi['alt'];
1721:             }
1722:             $info->icon = strval($mi['icon']);
1723:             $info->user_icon = true;
1724:         } elseif ($info->icon) {
1725:             $info->icon = Horde_Themes::img($info->icon);
1726:         }
1727: 
1728:         return $info;
1729:     }
1730: 
1731:     /**
1732:      * Do the necessary cleanup/cache updates when deleting mailboxes.
1733:      *
1734:      * @param array $deleted  The list of deleted mailboxes.
1735:      */
1736:     protected function _onDelete($deleted)
1737:     {
1738:         /* Clear the mailboxes from the sort prefs. */
1739:         foreach ($this->get($deleted) as $val) {
1740:             $val->setSort(null, null, true);
1741:         }
1742:     }
1743: 
1744: }
1745: 
API documentation generated by ApiGen