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 2008-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 2008-2014 Horde LLC
 10:  * @license   http://www.horde.org/licenses/gpl GPL
 11:  * @package   IMP
 12:  */
 13: 
 14: /**
 15:  * Provides common functions for interaction with IMAP/POP3 servers via the
 16:  * Horde_Imap_Client package.
 17:  *
 18:  * @author    Michael Slusarz <slusarz@horde.org>
 19:  * @category  Horde
 20:  * @copyright 2008-2014 Horde LLC
 21:  * @license   http://www.horde.org/licenses/gpl GPL
 22:  * @package   IMP
 23:  *
 24:  * @property-read boolean $changed  If true, this object has changed.
 25:  * @property-read Horde_Imap_Client_Base $client_ob  The IMAP client object.
 26:  * @property-read IMP_Imap_Config $config  Base backend config settings.
 27:  * @property-read boolean $init  Has the IMAP object been initialized?
 28:  * @property-read integer $max_compose_bodysize  The maximum size (in bytes)
 29:  *                                               of the compose message body.
 30:  * @property-read integer $max_compose_recipients  The maximum number of
 31:  *                                                 recipients to send to per
 32:  *                                                 compose message.
 33:  * @property-read integer $max_compose_timelimit  The maximum number of
 34:  *                                                recipients to send to in the
 35:  *                                                configured timelimit.
 36:  * @property-read integer $max_create_mboxes  The maximum number of mailboxes
 37:  *                                            a user can create.
 38:  * @property-read string $server_key  Server key used to login.
 39:  * @property-read string $thread_algo  The threading algorithm to use.
 40:  * @property-read Horde_Imap_Client_Url $url  A URL object.
 41:  */
 42: class IMP_Imap implements Serializable
 43: {
 44:     /* Access constants. */
 45:     const ACCESS_FOLDERS = 1;
 46:     const ACCESS_SEARCH = 2;
 47:     const ACCESS_FLAGS = 3;
 48:     const ACCESS_UNSEEN = 4;
 49:     const ACCESS_TRASH = 5;
 50:     const ACCESS_CREATEMBOX = 6;
 51:     const ACCESS_CREATEMBOX_MAX = 7;
 52:     const ACCESS_COMPOSE_BODYSIZE = 13;
 53:     const ACCESS_COMPOSE_RECIPIENTS = 8;
 54:     const ACCESS_COMPOSE_TIMELIMIT = 9;
 55:     const ACCESS_ACL = 10;
 56:     const ACCESS_DRAFTS = 11;
 57:     const ACCESS_REMOTE = 12;
 58:     const ACCESS_IMPORT = 14;
 59:     const ACCESS_SORT = 15;
 60: 
 61:     /* Default namespace. */
 62:     const NS_DEFAULT = "\0default";
 63: 
 64:     /**
 65:      * Cached backend configuration.
 66:      *
 67:      * @var array
 68:      */
 69:     protected static $_backends = array();
 70: 
 71:     /**
 72:      * Has this object changed?
 73:      *
 74:      * @var boolean
 75:      */
 76:     protected $_changed = false;
 77: 
 78:     /**
 79:      * Backend config.
 80:      *
 81:      * @var IMP_Imap_Config
 82:      */
 83:     protected $_config;
 84: 
 85:     /**
 86:      * Object identifier.
 87:      *
 88:      * @var string
 89:      */
 90:     protected $_id;
 91: 
 92:     /**
 93:      * The IMAP client object.
 94:      *
 95:      * @var Horde_Imap_Client_Base
 96:      */
 97:     protected $_ob;
 98: 
 99:     /**
100:      * Temporary data cache (destroyed at end of request).
101:      *
102:      * @var array
103:      */
104:     protected $_temp = array();
105: 
106:     /**
107:      * Constructor.
108:      *
109:      * @param string $id  Object identifier.
110:      */
111:     public function __construct($id)
112:     {
113:         $this->_id = strval($id);
114:     }
115: 
116:     /**
117:      */
118:     public function __get($key)
119:     {
120:         switch ($key) {
121:         case 'changed':
122:             return $this->_changed;
123: 
124:         case 'client_ob':
125:             return $this->init
126:                 ? $this->_ob
127:                 : null;
128: 
129:         case 'config':
130:             return isset($this->_config)
131:                 ? $this->_config
132:                 : new Horde_Support_Stub();
133: 
134:         case 'init':
135:             return isset($this->_ob);
136: 
137:         case 'max_compose_bodysize':
138:         case 'max_compose_recipients':
139:         case 'max_compose_timelimit':
140:             $perm = $GLOBALS['injector']->getInstance('Horde_Perms')->getPermissions('imp:' . str_replace('max_compose', 'max', $key), $GLOBALS['registry']->getAuth());
141:             return intval($perm[0]);
142: 
143:         case 'max_create_mboxes':
144:             $perm = $GLOBALS['injector']->getInstance('Horde_Perms')->getPermissions('imp:' . $this->_getPerm($key), $GLOBALS['registry']->getAuth());
145:             return intval($perm[0]);
146: 
147:         case 'server_key':
148:             return $this->init
149:                 ? $this->_ob->getParam('imp:backend')
150:                 : null;
151: 
152:         case 'thread_algo':
153:             if (!$this->init) {
154:                 return 'ORDEREDSUBJECT';
155:             }
156: 
157:             if ($thread = $this->_ob->getParam('imp:thread_algo')) {
158:                 return $thread;
159:             }
160: 
161:             $thread = $this->config->thread;
162:             $thread_cap = $this->queryCapability('THREAD');
163:             if (!in_array($thread, is_array($thread_cap) ? $thread_cap : array())) {
164:                 $thread = 'ORDEREDSUBJECT';
165:             }
166: 
167:             $this->_ob->setParam('imp:thread_algo', $thread);
168:             $this->_changed = true;
169: 
170:             return $thread;
171: 
172:         case 'url':
173:             /* @todo: This is available in Horde_Imap_Client 2.24.0 */
174:             $url = new Horde_Imap_Client_Url();
175:             if ($this->init) {
176:                 $url->hostspec = $this->getParam('hostspec');
177:                 $url->port = $this->getParam('port');
178:                 $url->protocol = $this->isImap() ? 'imap' : 'pop';
179:             }
180:             return $url;
181:         }
182:     }
183: 
184:     /**
185:      */
186:     public function __toString()
187:     {
188:         return $this->_id;
189:     }
190: 
191:     /**
192:      * Get the full permission name for a permission.
193:      *
194:      * @param string $perm  The permission.
195:      *
196:      * @return string  The full (backend-specific) permission name.
197:      */
198:     protected function _getPerm($perm)
199:     {
200:         return 'backends:' . ($this->init ? $this->server_key . ':' : '') . $perm;
201:     }
202: 
203:     /**
204:      * Determine if this is a connection to an IMAP server.
205:      *
206:      * @return boolean  True if connected to IMAP server.
207:      */
208:     public function isImap()
209:     {
210:         return ($this->init &&
211:                 ($this->_ob instanceof Horde_Imap_Client_Socket));
212:     }
213: 
214:     /**
215:      * Determine if this is a connection to an IMAP server.
216:      *
217:      * @return boolean  True if connected to IMAP server.
218:      */
219:     public function isPop3()
220:     {
221:         return ($this->init &&
222:                 ($this->_ob instanceof Horde_Imap_Client_Socket_Pop3));
223:     }
224: 
225:     /**
226:      * Create the base Horde_Imap_Client object (from an entry in
227:      * backends.php).
228:      *
229:      * @param string $username  The username to authenticate with.
230:      * @param string $password  The password to authenticate with.
231:      * @param string $skey      Create a new object using this server key.
232:      *
233:      * @return Horde_Imap_Client_Base  Client object.
234:      * @throws IMP_Imap_Exception
235:      */
236:     public function createBaseImapObject($username, $password, $skey)
237:     {
238:         if ($this->init) {
239:             return $this->client_ob;
240:         }
241: 
242:         if (($config = $this->loadServerConfig($skey)) === false) {
243:             $error = new IMP_Imap_Exception('Could not load server configuration.');
244:             Horde::log($error);
245:             throw $error;
246:         }
247: 
248:         $imap_config = array(
249:             'hostspec' => $config->hostspec,
250:             'id' => $config->id,
251:             'password' => new IMP_Imap_Password($password),
252:             'port' => $config->port,
253:             'secure' => (($secure = $config->secure) ? $secure : false),
254:             'username' => $username,
255:             // IMP specific config
256:             'imp:backend' => $skey
257:         );
258: 
259:         /* Needed here to set config information in createImapObject(). */
260:         $this->_config = $config;
261: 
262:         try {
263:             return $this->createImapObject($imap_config, ($config->protocol == 'imap'));
264:         } catch (IMP_Imap_Exception $e) {
265:             unset($this->_config);
266:             throw $e;
267:         }
268:     }
269: 
270:     /**
271:      * Create a Horde_Imap_Client object.
272:      *
273:      * @param array $config  The IMAP configuration.
274:      * @param boolean $imap  True if IMAP connection, false if POP3.
275:      *
276:      * @return Horde_Imap_Client_Base  Client object.
277:      * @throws IMP_Imap_Exception
278:      */
279:     public function createImapObject($config, $imap = true)
280:     {
281:         if ($this->init) {
282:             return $this->_ob;
283:         }
284: 
285:         $sconfig = $this->config;
286:         $config = array_merge(array(
287:             'cache' => $sconfig->cache_params,
288:             'capability_ignore' => $sconfig->capability_ignore,
289:             'comparator' => $sconfig->comparator,
290:             'debug' => $sconfig->debug,
291:             'debug_literal' => $sconfig->debug_raw,
292:             'lang' => $sconfig->lang,
293:             'timeout' => $sconfig->timeout,
294:             // 'imp:login' - Set in __call()
295:         ), $config);
296: 
297:         try {
298:             $this->_ob = $imap
299:                 ? new Horde_Imap_Client_Socket($config)
300:                 : new Horde_Imap_Client_Socket_Pop3($config);
301:             return $this->_ob;
302:         } catch (Horde_Imap_Client_Exception $e) {
303:             Horde::log($e->raw_msg);
304:             throw new IMP_Imap_Exception($e);
305:         }
306:     }
307: 
308:     /**
309:      * Perform post-login tasks.
310:      */
311:     public function doPostLoginTasks()
312:     {
313:         global $prefs;
314: 
315:         switch ($this->_config->protocol) {
316:         case 'imap':
317:             /* Overwrite default special mailbox names. */
318:             foreach ($this->_config->special_mboxes as $key => $val) {
319:                 if ($key != IMP_Mailbox::MBOX_USERSPECIAL) {
320:                     $prefs->setValue($key, $val, array(
321:                         'force' => true,
322:                         'nosave' => true
323:                     ));
324:                 }
325:             }
326:             break;
327: 
328:         case 'pop':
329:             /* Turn some options off if we are working with POP3. */
330:             foreach (array('newmail_notify', 'save_sent_mail') as $val) {
331:                 $prefs->setValue($val, false, array(
332:                     'force' => true,
333:                     'nosave' => true
334:                 ));
335:                 $prefs->setLocked($val, true);
336:             }
337:             $prefs->setLocked(IMP_Mailbox::MBOX_DRAFTS, true);
338:             $prefs->setLocked(IMP_Mailbox::MBOX_SENT, true);
339:             $prefs->setLocked(IMP_Mailbox::MBOX_SPAM, true);
340:             $prefs->setLocked(IMP_Mailbox::MBOX_TEMPLATES, true);
341:             $prefs->setLocked(IMP_Mailbox::MBOX_TRASH, true);
342:             break;
343:         }
344: 
345:         $this->updateFetchIgnore();
346:     }
347: 
348:     /**
349:      * Update the list of mailboxes to ignore when caching FETCH data in the
350:      * IMAP client object.
351:      */
352:     public function updateFetchIgnore()
353:     {
354:         if ($this->isImap()) {
355:             $special = IMP_Mailbox::getSpecialMailboxes();
356:             $cache = $this->_ob->getParam('cache');
357:             $cache['fetch_ignore'] = array_filter(array(
358:                 strval($special[IMP_Mailbox::SPECIAL_SPAM]),
359:                 strval($special[IMP_Mailbox::SPECIAL_TRASH])
360:             ));
361:             $this->_ob->setParam('cache', $cache);
362:         }
363:     }
364: 
365:     /**
366:      * Checks access rights for a server.
367:      *
368:      * @param integer $right  Access right.
369:      *
370:      * @return boolean  Does the access right exist?
371:      */
372:     public function access($right)
373:     {
374:         global $injector;
375: 
376:         if (!$this->init) {
377:             return false;
378:         }
379: 
380:         switch ($right) {
381:         case self::ACCESS_ACL:
382:             return ($this->config->acl && $this->queryCapability('ACL'));
383: 
384:         case self::ACCESS_CREATEMBOX:
385:             return ($this->isImap() &&
386:                     $injector->getInstance('Horde_Core_Perms')->hasAppPermission($this->_getPerm('create_mboxes')));
387: 
388:         case self::ACCESS_CREATEMBOX_MAX:
389:             return ($this->isImap() &&
390:                     $injector->getInstance('Horde_Core_Perms')->hasAppPermission($this->_getPerm('max_create_mboxes')));
391: 
392:         case self::ACCESS_DRAFTS:
393:         case self::ACCESS_FLAGS:
394:         case self::ACCESS_IMPORT:
395:         case self::ACCESS_SEARCH:
396:         case self::ACCESS_UNSEEN:
397:             return $this->isImap();
398: 
399:         case self::ACCESS_FOLDERS:
400:         case self::ACCESS_TRASH:
401:             return ($this->isImap() &&
402:                     $injector->getInstance('Horde_Core_Perms')->hasAppPermission($this->_getPerm('allow_folders')));
403: 
404:         case self::ACCESS_REMOTE:
405:             return $injector->getInstance('Horde_Core_Perms')->hasAppPermission($this->_getPerm('allow_remote'));
406: 
407:         case self::ACCESS_SORT:
408:             return ($this->isImap() &&
409:                     ($this->config->sort_force || $this->_ob->queryCapability('SORT')));
410:         }
411: 
412:         return false;
413:     }
414: 
415:     /**
416:      * Checks compose access rights for a server.
417:      *
418:      * @param integer $right  Access right.
419:      * @param integer $data   Data required to check the rights:
420:      *   - ACCESS_COMPOSE_BODYSIZE
421:      *     The size of the body data.
422:      *
423:      *   - ACCESS_COMPOSE_RECIPIENTS
424:      *   - ACCESS_COMPOSE_TIMELIMIT
425:      *     The number of e-mail recipients.
426:      *
427:      * @return boolean  Is the access allowed?
428:      */
429:     public function accessCompose($right, $data)
430:     {
431:         switch ($right) {
432:         case self::ACCESS_COMPOSE_BODYSIZE:
433:             $perm_name = 'max_bodysize';
434:             break;
435: 
436:         case self::ACCESS_COMPOSE_RECIPIENTS:
437:             $perm_name = 'max_recipients';
438:             break;
439: 
440:         case self::ACCESS_COMPOSE_TIMELIMIT:
441:             $perm_name = 'max_timelimit';
442:             break;
443: 
444:         default:
445:             return false;
446:         }
447: 
448:         return $GLOBALS['injector']->getInstance('Horde_Core_Perms')->hasAppPermission(
449:             $perm_name,
450:             array(
451:                 'opts' => array(
452:                     'value' => $data
453:                 )
454:             )
455:         );
456:     }
457: 
458:     /**
459:      * Get namespace info for a full mailbox path.
460:      *
461:      * @param string $mailbox    The mailbox path. (self:NS_DEFAULT will
462:      *                           return the default personal namespace.)
463:      * @param boolean $personal  If true, will return empty namespace only
464:      *                           if it is a personal namespace.
465:      *
466:      * @return mixed  The namespace info for the mailbox path or null if the
467:      *                path doesn't exist.
468:      */
469:     public function getNamespace($mailbox, $personal = false)
470:     {
471:         if ($this->isImap()) {
472:             $ns = $this->getNamespaces();
473:             if ($mailbox !== self::NS_DEFAULT) {
474:                 return $ns->getNamespace($mailbox, $personal);
475:             }
476: 
477:             foreach ($ns as $val) {
478:                 if ($val->type === $val::NS_PERSONAL) {
479:                     return $val;
480:                 }
481:             }
482:         }
483: 
484:         return null;
485:     }
486: 
487:     /**
488:      * Return the cache ID for this mailbox.
489:      *
490:      * @param string $mailbox  The mailbox name (UTF-8).
491:      * @param array $addl      Local IMP metadata to add to the cache ID.
492:      *
493:      * @return string  The cache ID.
494:      */
495:     public function getCacheId($mailbox, array $addl = array())
496:     {
497:         return $this->getSyncToken($mailbox) .
498:             (empty($addl) ? '' : ('|' . implode('|', $addl)));
499:     }
500: 
501:     /**
502:      * Parses the cache ID for this mailbox.
503:      *
504:      * @param string $id  Cache ID generated by getCacheId().
505:      *
506:      * @return array  Two element array:
507:      *   - date: (integer) Date information (day of year), if embedded in
508:      *           cache ID.
509:      *   - token: (string) Mailbox sync token.
510:      */
511:     public function parseCacheId($id)
512:     {
513:         $out = array('date' => null);
514: 
515:         if ((($pos = strrpos($id, '|')) !== false) &&
516:             (substr($id, $pos + 1, 1) == 'D')) {
517:             $out['date'] = substr($id, $pos + 2);
518:         }
519: 
520:         $out['token'] = (($pos = strpos($id, '|')) === false)
521:             ? $id
522:             : substr($id, 0, $pos);
523: 
524:         return $out;
525:     }
526: 
527:     /**
528:      * Returns a list of messages, split into slices based on the total
529:      * message size.
530:      *
531:      * @param string $mbox                IMAP mailbox.
532:      * @param Horde_Imap_Client_Ids $ids  ID list.
533:      * @param integer $size               Maximum size of a slice.
534:      *
535:      * @return array  An array of Horde_Imap_Client_Ids objects.
536:      */
537:     public function getSlices(
538:         $mbox, Horde_Imap_Client_Ids $ids, $size = 5242880
539:     )
540:     {
541:         $imp_imap = IMP_Mailbox::get($mbox)->imp_imap;
542: 
543:         $query = new Horde_Imap_Client_Fetch_Query();
544:         $query->size();
545: 
546:         try {
547:             $res = $imp_imap->fetch($mbox, $query, array(
548:                 'ids' => $ids,
549:                 'nocache' => true
550:             ));
551:         } catch (IMP_Imap_Exception $e) {
552:             return array();
553:         }
554: 
555:         $curr = $slices = array();
556:         $curr_size = 0;
557: 
558:         foreach ($res as $key => $val) {
559:             $curr_size += $val->getSize();
560:             if ($curr_size > $size) {
561:                 $slices[] = $imp_imap->getIdsOb($curr, $ids->sequence);
562:                 $curr = array();
563:             }
564:             $curr[] = $key;
565:         }
566: 
567:         $slices[] = $imp_imap->getIdsOb($curr, $ids->sequence);
568: 
569:         return $slices;
570:     }
571: 
572:     /**
573:      * Handle status() calls. This call may hit multiple servers.
574:      *
575:      * @see Horde_Imap_Client_Base#status()
576:      */
577:     protected function _status($args)
578:     {
579:         global $injector;
580: 
581:         $accounts = $mboxes = $out = array();
582:         $imap_factory = $injector->getInstance('IMP_Factory_Imap');
583: 
584:         foreach (IMP_Mailbox::get($args[0]) as $val) {
585:             if ($raccount = $val->remote_account) {
586:                 $accounts[strval($raccount)] = $raccount;
587:             }
588:             $mboxes[strval($raccount)][] = $val;
589:         }
590: 
591:         foreach ($mboxes as $key => $val) {
592:             $imap = $imap_factory->create($key);
593:             if ($imap->init) {
594:                 foreach (call_user_func_array(array($imap, 'impStatus'), array($val) + $args) as $key2 => $val2) {
595:                     $out[isset($accounts[$key]) ? $accounts[$key]->mailbox($key2) : $key2] = $val2;
596:                 }
597:             }
598:         }
599: 
600:         return $out;
601:     }
602: 
603:     /**
604:      * All other calls to this class are routed to the underlying
605:      * Horde_Imap_Client_Base object.
606:      *
607:      * @param string $method  Method name.
608:      * @param array $params   Method parameters.
609:      *
610:      * @return mixed  The return from the requested method.
611:      * @throws BadMethodCallException
612:      * @throws IMP_Imap_Exception
613:      */
614:     public function __call($method, $params)
615:     {
616:         global $injector;
617: 
618:         if (!$this->init) {
619:             /* Fallback for these methods. */
620:             switch ($method) {
621:             case 'getIdsOb':
622:                 $ob = new Horde_Imap_Client_Ids();
623:                 call_user_func_array(array($ob, 'add'), $params);
624:                 return $ob;
625:             }
626: 
627:             throw new Horde_Exception_AuthenticationFailure(
628:                 'IMP is marked as authenticated, but no credentials can be found in the session.',
629:                 Horde_Auth::REASON_SESSION
630:             );
631:         }
632: 
633:         switch ($method) {
634:         case 'append':
635:         case 'createMailbox':
636:         case 'deleteMailbox':
637:         case 'expunge':
638:         case 'fetch':
639:         case 'getACL':
640:         case 'getMetadata':
641:         case 'getMyACLRights':
642:         case 'getQuota':
643:         case 'getQuotaRoot':
644:         case 'getSyncToken':
645:         case 'setMetadata':
646:         case 'setQuota':
647:         case 'store':
648:         case 'subscribeMailbox':
649:         case 'sync':
650:         case 'thread':
651:             // Horde_Imap_Client_Mailbox: these calls all have the mailbox as
652:             // their first parameter.
653:             $params[0] = IMP_Mailbox::getImapMboxOb($params[0]);
654:             break;
655: 
656:         case 'copy':
657:         case 'renameMailbox':
658:             // These calls may hit multiple servers.
659:             $source = IMP_Mailbox::get($params[0]);
660:             $dest = IMP_Mailbox::get($params[1]);
661:             if ($source->remote_account != $dest->remote_account) {
662:                 return call_user_func_array(array($this, '_' . $method), $params);
663:             }
664: 
665:             // Horde_Imap_Client_Mailbox: these calls all have the mailbox as
666:             // their first two parameters.
667:             $params[0] = $source->imap_mbox_ob;
668:             $params[1] = $dest->imap_mbox_ob;
669:             break;
670: 
671:         case 'getNamespaces':
672:             if (isset($this->_temp['ns'])) {
673:                 return $this->_temp['ns'];
674:             }
675:             $nsconfig = $this->config->namespace;
676:             $params[0] = is_null($nsconfig) ? array() : $nsconfig;
677:             $params[1] = array('ob_return' => true);
678:             break;
679: 
680:         case 'impStatus':
681:             /* Internal method: allows status call with array of mailboxes,
682:              * guaranteeing they are all on this server. */
683:             $params[0] = IMP_Mailbox::getImapMboxOb($params[0]);
684:             $method = 'status';
685:             break;
686: 
687:         case 'openMailbox':
688:             $mbox = IMP_Mailbox::get($params[0]);
689:             if ($mbox->search) {
690:                 /* Can't open a search mailbox. */
691:                 return;
692:             }
693:             $params[0] = $mbox->imap_mbox_ob;
694:             break;
695: 
696:         case 'search':
697:             $params = call_user_func_array(array($this, '_search'), $params);
698:             break;
699: 
700:         case 'status':
701:             if (is_array($params[0])) {
702:                 return $this->_status($params);
703:             }
704:             $params[0] = IMP_Mailbox::getImapMboxOb($params[0]);
705:             break;
706: 
707:         default:
708:             if (!method_exists($this->_ob, $method)) {
709:                 throw new BadMethodCallException(
710:                     sprintf('%s: Invalid method call "%s".', __CLASS__, $method)
711:                 );
712:             }
713:             break;
714:         }
715: 
716:         try {
717:             $result = call_user_func_array(array($this->_ob, $method), $params);
718:         } catch (Horde_Imap_Client_Exception $e) {
719:             switch ($method) {
720:             case 'getNamespaces':
721:                 return new Horde_Imap_Client_Namespace_List();
722:             }
723: 
724:             Horde::log(
725:                 new Exception(
726:                     sprintf('[%s] %s', $method, $e->raw_msg),
727:                     $e->getCode(),
728:                     $e
729:                 ),
730:                 'WARN'
731:             );
732:             $error = new IMP_Imap_Exception($e);
733:             throw ($auth_e = $error->authException(false))
734:                 ? $auth_e
735:                 : $error;
736:         }
737: 
738:         /* Special handling for various methods. */
739:         switch ($method) {
740:         case 'createMailbox':
741:         case 'deleteMailbox':
742:         case 'renameMailbox':
743:             $injector->getInstance('IMP_Mailbox_SessionCache')->expire(
744:                 null,
745:                 // Mailbox is first parameter.
746:                 IMP_Mailbox::get($params[0])
747:             );
748:             break;
749: 
750:         case 'getNamespaces':
751:             $this->_temp['ns'] = $result;
752:             break;
753: 
754:         case 'login':
755:             if (!$this->_ob->getParam('imp:login')) {
756:                 /* Check for POP3 UIDL support. */
757:                 if ($this->isPop3() && !$this->queryCapability('UIDL')) {
758:                     Horde::log(
759:                         sprintf(
760:                             'The POP3 server does not support the REQUIRED UIDL capability. [server key: %s]',
761:                             $this->server_key
762:                         ),
763:                         'CRIT'
764:                     );
765:                     throw new Horde_Exception_AuthenticationFailure(
766:                         _("The mail server is not currently avaliable."),
767:                         Horde_Auth::REASON_MESSAGE
768:                     );
769:                 }
770: 
771:                 $this->_ob->setParam('imp:login', true);
772:                 $this->_changed = true;
773:             }
774:             break;
775: 
776:         case 'setACL':
777:             $injector->getInstance('IMP_Mailbox_SessionCache')->expire(
778:                 IMP_Mailbox_SessionCache::CACHE_ACL,
779:                 IMP_Mailbox::get($params[0])
780:             );
781:             break;
782:         }
783: 
784:         return $result;
785:     }
786: 
787:     /**
788:      * Prepares an IMAP search query.  Needed because certain configuration
789:      * parameters may need to be dynamically altered before passed to the
790:      * Imap_Client object.
791:      *
792:      * @param string $mailbox                        The mailbox to search.
793:      * @param Horde_Imap_Client_Search_Query $query  The search query object.
794:      * @param array $opts                            Additional options.
795:      *
796:      * @return array  Parameters to use in the search() call.
797:      */
798:     protected function _search($mailbox, $query = null, array $opts = array())
799:     {
800:         $mailbox = IMP_Mailbox::get($mailbox);
801: 
802:         if (!empty($opts['sort']) && $mailbox->access_sort) {
803:             /* If doing a from/to search, use display sorting if possible.
804:              * Although there is a fallback to a PHP-based display sort, for
805:              * performance reasons only do a display sort if it is supported
806:              * on the server. */
807:             foreach ($opts['sort'] as $key => $val) {
808:                 switch ($val) {
809:                 case Horde_Imap_Client::SORT_FROM:
810:                     $opts['sort'][$key] = Horde_Imap_Client::SORT_DISPLAYFROM_FALLBACK;
811:                     break;
812: 
813:                 case Horde_Imap_Client::SORT_TO:
814:                     $opts['sort'][$key] = Horde_Imap_Client::SORT_DISPLAYTO_FALLBACK;
815:                     break;
816:                 }
817:             }
818:         }
819: 
820:         if (!is_null($query)) {
821:             $query->charset('UTF-8', false);
822:         }
823: 
824:         return array($mailbox->imap_mbox_ob, $query, $opts);
825:     }
826: 
827:     /**
828:      * Handle copy() calls that hit multiple servers.
829:      *
830:      * @see Horde_Imap_Client_Base#copy()
831:      */
832:     protected function _copy()
833:     {
834:         global $injector;
835: 
836:         $args = func_get_args();
837:         $imap_factory = $injector->getInstance('IMP_Factory_Imap');
838:         $source_imap = $imap_factory->create($args[0]);
839:         $dest_imap = $imap_factory->create($args[1]);
840: 
841:         $create = !empty($args[2]['create']);
842:         $ids = isset($args[2]['ids'])
843:             ? $args[2]['ids']
844:             : $source_imap->getIdsOb(Horde_Imap_Client_Ids::ALL);
845:         $move = !empty($args[2]['move']);
846:         $retval = true;
847: 
848:         $query = new Horde_Imap_Client_Fetch_Query();
849:         $query->fullText(array(
850:             'peek' => true
851:         ));
852: 
853:         foreach ($this->getSlices($args[0], $ids) as $val) {
854:             try {
855:                 $res = $source_imap->fetch($args[0], $query, array(
856:                     'ids' => $val,
857:                     'nocache' => true
858:                 ));
859: 
860:                 $append = array();
861:                 foreach ($res as $msg) {
862:                     $append[] = array(
863:                         'data' => $msg->getFullMsg(true)
864:                     );
865:                 }
866: 
867:                 $dest_imap->append($args[1], $append, array(
868:                     'create' => $create
869:                 ));
870: 
871:                 if ($move) {
872:                     $source_imap->expunge($args[0], array(
873:                         'delete' => true,
874:                         'ids' => $val
875:                     ));
876:                 }
877:             } catch (IMP_Imap_Exception $e) {
878:                 $retval = false;
879:             }
880:         }
881: 
882:         return $retval;
883:     }
884: 
885:     /**
886:      * Handle copy() calls. This call may hit multiple servers, so
887:      * need to handle separately from other IMAP calls.
888:      *
889:      * @see Horde_Imap_Client_Base#renameMailbox()
890:      */
891:     protected function _renameMailbox()
892:     {
893:         $args = func_get_args();
894:         $source = IMP_Mailbox::get($args[0]);
895: 
896:         if ($source->create() && $this->copy($source, $args[1])) {
897:             $source->delete();
898:         } else {
899:             throw new IMP_Imap_Exception(_("Could not move all messages between mailboxes, so the original mailbox was not removed."));
900:         }
901:     }
902: 
903:     /* Static methods. */
904: 
905:     /**
906:      * Loads the IMP server configuration from backends.php.
907:      *
908:      * @param string $server  Returns this labeled entry only.
909:      *
910:      * @return mixed  If $server is set return this entry; else, return the
911:      *                entire servers array. Returns false on error.
912:      */
913:     public static function loadServerConfig($server = null)
914:     {
915:         global $registry;
916: 
917:         if (empty(self::$_backends)) {
918:             try {
919:                 $s = $registry->loadConfigFile('backends.php', 'servers', 'imp')->config['servers'];
920:             } catch (Horde_Exception $e) {
921:                 Horde::log($e, 'ERR');
922:                 return false;
923:             }
924: 
925:             foreach ($s as $key => $val) {
926:                 if (empty($val['disabled'])) {
927:                     self::$_backends[$key] = new IMP_Imap_Config($val);
928:                 }
929:             }
930:         }
931: 
932:         return is_null($server)
933:             ? self::$_backends
934:             : (isset(self::$_backends[$server]) ? self::$_backends[$server] : false);
935:     }
936: 
937:     /* Serializable methods. */
938: 
939:     /**
940:      */
941:     public function serialize()
942:     {
943:         return $GLOBALS['injector']->getInstance('Horde_Pack')->pack(
944:             array(
945:                 $this->_ob,
946:                 $this->_id,
947:                 $this->_config
948:             ),
949:             array(
950:                 'compression' => false,
951:                 'phpob' => true
952:             )
953:         );
954:     }
955: 
956:     /**
957:      */
958:     public function unserialize($data)
959:     {
960:         list(
961:             $this->_ob,
962:             $this->_id,
963:             $this->_config
964:         ) = $GLOBALS['injector']->getInstance('Horde_Pack')->unpack($data);
965:     }
966: 
967: }
968: 
API documentation generated by ApiGen