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 2009-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 2009-2014 Horde LLC
 10:  * @license   http://www.horde.org/licenses/gpl GPL
 11:  * @package   IMP
 12:  */
 13: 
 14: /**
 15:  * Provides an interface to deal with display of flags/keywords/labels on
 16:  * messages.
 17:  *
 18:  * @author    Michael Slusarz <slusarz@horde.org>
 19:  * @category  Horde
 20:  * @copyright 2009-2014 Horde LLC
 21:  * @license   http://www.horde.org/licenses/gpl GPL
 22:  * @package   IMP
 23:  */
 24: class IMP_Flags implements ArrayAccess, Serializable
 25: {
 26:     /**
 27:      * Has the object data changed?
 28:      *
 29:      * @var boolean
 30:      */
 31:     public $changed = false;
 32: 
 33:     /**
 34:      * Does the msglist_flags hook exist?
 35:      *
 36:      * @var boolean
 37:      */
 38:     protected $_flaghook = true;
 39: 
 40:     /**
 41:      * The list of internal flags.
 42:      *
 43:      * @var array
 44:      */
 45:     protected $_flags = array();
 46: 
 47:     /**
 48:      * The list of user flags.
 49:      *
 50:      * @var array
 51:      */
 52:     protected $_userflags = array();
 53: 
 54:     /**
 55:      * Constructor.
 56:      */
 57:     public function __construct()
 58:     {
 59:         /* Build list of default flags. */
 60:         foreach (array('Imap', 'System') as $type) {
 61:             $di = new DirectoryIterator(IMP_BASE . '/lib/Flag/' . $type);
 62:             foreach ($di as $val) {
 63:                 if ($val->isFile()) {
 64:                     $cname = 'IMP_Flag_' . $type . '_' . $val->getBasename('.php');
 65:                     if (class_exists($cname)) {
 66:                         $ob = new $cname();
 67:                         $this->_flags[$ob->id] = $ob;
 68:                     }
 69:                 }
 70:             }
 71:         }
 72: 
 73:         if ($f_list = $GLOBALS['prefs']->getValue('msgflags')) {
 74:             $f_list = @unserialize($f_list);
 75:             if (is_array($f_list)) {
 76:                 foreach ($f_list as $val) {
 77:                     $this->_userflags[$val->id] = $val;
 78:                 }
 79:             }
 80:         }
 81: 
 82:         $this->changed = true;
 83:     }
 84: 
 85:     /**
 86:      * Save the flag list to the prefs backend.
 87:      */
 88:     protected function _save()
 89:     {
 90:         global $prefs;
 91: 
 92:         if (!$prefs->isLocked('msgflags')) {
 93:             $prefs->setValue('msgflags', serialize($this->_userflags));
 94:         }
 95: 
 96:         $this->changed = true;
 97:     }
 98: 
 99:     /**
100:      * Return the raw list of flags.
101:      *
102:      * @param array $opts  Additional options:
103:      *   - imap: (boolean) If true, only return IMAP flags that can be set by
104:      *           the user.
105:      *            DEFAULT: false
106:      *   - mailbox: (string) A real (not virtual) IMAP mailbox. If set, will
107:      *              determine what flags are available in the mailbox.
108:      *              DEFAULT: '' (no mailbox check)
109:      *
110:      * @return array  An array of IMP_Flag_Base elements.
111:      */
112:     public function getList(array $opts = array())
113:     {
114:         if (!$GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create()->access(IMP_Imap::ACCESS_FLAGS)) {
115:             return array();
116:         }
117: 
118:         $ret = array_merge($this->_flags, $this->_userflags);
119: 
120:         if (!empty($opts['imap'])) {
121:             foreach ($ret as $key => $val) {
122:                 if (!($val instanceof IMP_Flag_Imap)) {
123:                     unset($ret[$key]);
124:                 }
125:             }
126:         }
127: 
128:         if (!isset($opts['mailbox']) ||
129:             !strlen($opts['mailbox']) ||
130:             IMP_Mailbox::get($opts['mailbox'])->search) {
131:             return array_values($ret);
132:         }
133: 
134:         /* Alter the list of flags for a mailbox depending on the mailbox's
135:          * PERMANENTFLAGS status. */
136:         $permflags = IMP_Mailbox::get($opts['mailbox'])->permflags;
137: 
138:         /* Limited flags allowed in mailbox. */
139:         foreach ($ret as $key => $val) {
140:             if (($val instanceof IMP_Flag_Imap) &&
141:                 !$permflags->allowed($val->imapflag)) {
142:                 unset($ret[$key]);
143:             }
144:         }
145: 
146:         /* Get list of unknown flags. */
147:         if ($GLOBALS['prefs']->getValue('show_all_flags')) {
148:             /* Get list of IMAP flags. */
149:             $imapflags = array();
150:             foreach ($ret as $val) {
151:                 if ($val instanceof IMP_Flag_Imap) {
152:                     $imapflags[] = $val->imapflag;
153:                 }
154:             }
155: 
156:             foreach ($permflags as $val) {
157:                 if (!in_array($val, $imapflags)) {
158:                     $ret[] = new IMP_Flag_User($val);
159:                 }
160:             }
161:         }
162: 
163:         return array_values($ret);
164:     }
165: 
166:     /**
167:      * Add a user-defined IMAP flag.
168:      *
169:      * @param string $label  The label to use for the new flag.
170:      *
171:      * @return string  The IMAP flag name.
172:      * @throws IMP_Exception
173:      */
174:     public function addFlag($label)
175:     {
176:         if (strlen($label) === 0) {
177:             throw new IMP_Exception(_("Flag name must not be empty."));
178:         }
179: 
180:         $ob = new IMP_Flag_User($label);
181: 
182:         if (isset($this->_userflags[$ob->id])) {
183:             throw new IMP_Exception(_("Flag name already exists."));
184:         }
185: 
186:         $this->_userflags[$ob->id] = $ob;
187:         $this->_save();
188: 
189:         return $ob->imapflag;
190:     }
191: 
192:     /**
193:      * Updates flag properties.
194:      *
195:      * @param string $key   The flag key.
196:      * @param string $type  The property to update. Either 'bgcolor' or
197:      *                      'label'.
198:      * @param string $data  The updated data.
199:      */
200:     public function updateFlag($key, $type, $data)
201:     {
202:         if (isset($this->_userflags[$key])) {
203:             $ob = clone $this->_userflags[$key];
204:         } elseif (isset($this->_flags[$key])) {
205:             $ob = clone $this->_flags[$key];
206:         } else {
207:             return;
208:         }
209: 
210:         $ob->$type = $data;
211: 
212:         if (isset($this->_flags[$key]) && ($this->_flags[$key] == $ob)) {
213:             unset($this->_userflags[$key]);
214:         } else {
215:             $this->_userflags[$key] = $ob;
216:         }
217: 
218:         $this->_save();
219:     }
220: 
221:     /**
222:      * Parse a list of flag information.
223:      *
224:      * @param array $opts  Options:
225:      *   - flags: (array) IMAP flag info. A lowercase list of flags returned
226:      *            by the IMAP server.
227:      *   - headers: (Horde_Mime_Headers) Determines message information
228:      *              from a headers object.
229:      *   - runhook: (array) Run the msglist_flags hook? If yes, input is
230:      *              return from IMP_Mailbox_List#getMailboxArray().
231:      *   - personal: (mixed) Personal message info. Either a list of To
232:      *               addresses (Horde_Mail_Rfc822_List object) or the identity
233:      *               that matched the address list.
234:      *
235:      * @return array  A list of IMP_Flag_Base objects.
236:      */
237:     public function parse(array $opts = array())
238:     {
239:         global $injector;
240: 
241:         $opts = array_merge(array(
242:             'flags' => array(),
243:             'headers' => null,
244:             'personal' => null
245:         ), $opts);
246: 
247:         if (!empty($opts['runhook']) && $this->_flaghook) {
248:             try {
249:                 $opts['flags'] = array_merge(
250:                     $opts['flags'],
251:                     $injector->getInstance('Horde_Core_Hooks')->callHook(
252:                         'msglist_flags',
253:                         'imp',
254:                         array($opts['runhook'])
255:                     )
256:                 );
257:             } catch (Horde_Exception_HookNotSet $e) {
258:                 $this->_flaghook = false;
259:             }
260:         }
261: 
262:         $ret = array();
263: 
264:         foreach (array_merge($this->_flags, $this->_userflags) as $val) {
265:             if ($val instanceof IMP_Flag_System_Match_Address) {
266:                 if (!is_null($opts['personal']) &&
267:                     $val->match($opts['personal'])) {
268:                     $ret[] = $val;
269:                 }
270:             } elseif (($val instanceof IMP_Flag_Imap) ||
271:                       ($val instanceof IMP_Flag_System_Match_Flag)) {
272:                 if ($val->match($opts['flags'])) {
273:                     $ret[] = $val;
274:                 }
275:             } elseif ($val instanceof IMP_Flag_System_Match_Header) {
276:                 if (!is_null($opts['headers']) &&
277:                     $val->match($opts['headers'])) {
278:                     $ret[] = $val;
279:                 }
280:             }
281:         }
282: 
283:         return $ret;
284:     }
285: 
286:     /**
287:      * Process a flag ID formatted for use in form data.
288:      *
289:      * @param string $id  The ID from form data.
290:      *
291:      * @return array  Two element array:
292:      *   - flag: (string) The flag name.
293:      *   - set: (boolean) Whether the flag should be set or not.
294:      */
295:     public function parseFormId($id)
296:     {
297:         return (strpos($id, '0\\') === 0)
298:             ? array('flag' => substr($id, 2), 'set' => false)
299:             : array('flag' => $id, 'set' => true);
300:     }
301: 
302:     /**
303:      * Returns a list of flags that have changed due to IMAP flag changes.
304:      *
305:      * @param array $flags  The list of IMAP flags added/removed.
306:      * @param boolean $add  True if these flags were added, false if they were
307:      *                      removed.
308:      *
309:      * @return array  Array with two keys: 'add' and 'remove'. Each key
310:      *                contains a list of IMP_Flag_Base objects.
311:      */
312:     public function changed($flags, $add)
313:     {
314:         $ret = array(
315:             'add' => array(),
316:             'remove' => array()
317:         );
318: 
319:         $obs = array();
320:         foreach ($flags as $val) {
321:             if ($tmp = $this[$val]) {
322:                 $obs[] = $tmp;
323:             }
324:         }
325: 
326:         if ($add) {
327:             $ret['add'] = $obs;
328:         } else {
329:             $ret['remove'] = $obs;
330:         }
331: 
332:         foreach (array_merge($this->_flags, $this->_userflags) as $val) {
333:             $res = $val->changed($obs, $add);
334: 
335:             if ($res === false) {
336:                 $ret['remove'][] = $val;
337:             } elseif ($res === true) {
338:                 $ret['add'][] = $val;
339:             }
340:         }
341: 
342:         return $ret;
343:     }
344: 
345:     /* ArrayAccess methods. */
346: 
347:     /**
348:      */
349:     public function offsetExists($offset)
350:     {
351:         return isset($this->_flags[$offset]) ||
352:                isset($this->_userflags[$offset]);
353:     }
354: 
355:     /**
356:      */
357:     public function offsetGet($offset)
358:     {
359:         if (isset($this->_flags[$offset])) {
360:             return $this->_flags[$offset];
361:         } elseif (isset($this->_userflags[$offset])) {
362:             return $this->_userflags[$offset];
363:         }
364: 
365:         return null;
366:     }
367: 
368:     /**
369:      * @throws InvalidArgumentException
370:      */
371:     public function offsetSet($offset, $value)
372:     {
373:         throw new InvalidArgumentException('Use addFlag()/updateFlag()');
374:     }
375: 
376:     /**
377:      */
378:     public function offsetUnset($offset)
379:     {
380:         if (isset($this->_userflags[$offset])) {
381:             unset($this->_userflags[$offset]);
382:             $this->_save();
383:         }
384:     }
385: 
386:     /* Serializable methods. */
387: 
388:     /**
389:      */
390:     public function serialize()
391:     {
392:         return $GLOBALS['injector']->getInstance('Horde_Pack')->pack(
393:             array(
394:                 $this->_flags,
395:                 $this->_userflags
396:             ), array(
397:                 'compression' => false,
398:                 'phpob' => true
399:             )
400:         );
401:     }
402: 
403:     /**
404:      */
405:     public function unserialize($data)
406:     {
407:         list(
408:             $this->_flags,
409:             $this->_userflags
410:         ) = $GLOBALS['injector']->getInstance('Horde_Pack')->unpack($data);
411:     }
412: 
413: }
414: 
API documentation generated by ApiGen