Overview

Packages

  • Kolab
    • Storage

Classes

  • Horde_Kolab_Storage_Base
  • Horde_Kolab_Storage_Cache
  • Horde_Kolab_Storage_Cache_Data
  • Horde_Kolab_Storage_Cache_List
  • Horde_Kolab_Storage_Cached
  • Horde_Kolab_Storage_Data_Base
  • Horde_Kolab_Storage_Data_Cached
  • Horde_Kolab_Storage_Data_Decorator_Log
  • Horde_Kolab_Storage_Data_Format_Mime
  • Horde_Kolab_Storage_Data_Modifiable
  • Horde_Kolab_Storage_Data_Old
  • Horde_Kolab_Storage_Data_Parser_Structure
  • Horde_Kolab_Storage_Data_Query_History_Base
  • Horde_Kolab_Storage_Data_Query_History_Cache
  • Horde_Kolab_Storage_Data_Query_Preferences_Base
  • Horde_Kolab_Storage_Data_Query_Preferences_Cache
  • Horde_Kolab_Storage_Decorator_Synchronization
  • Horde_Kolab_Storage_Driver_Base
  • Horde_Kolab_Storage_Driver_Cclient
  • Horde_Kolab_Storage_Driver_Decorator_Base
  • Horde_Kolab_Storage_Driver_Decorator_Log
  • Horde_Kolab_Storage_Driver_Decorator_Timer
  • Horde_Kolab_Storage_Driver_Imap
  • Horde_Kolab_Storage_Driver_Mock
  • Horde_Kolab_Storage_Driver_Mock_Data
  • Horde_Kolab_Storage_Driver_Pear
  • Horde_Kolab_Storage_Driver_Rcube
  • Horde_Kolab_Storage_Exception
  • Horde_Kolab_Storage_Exception_Pear
  • Horde_Kolab_Storage_Factory
  • Horde_Kolab_Storage_Folder_Base
  • Horde_Kolab_Storage_Folder_Decorator_Base
  • Horde_Kolab_Storage_Folder_Decorator_Trigger
  • Horde_Kolab_Storage_Folder_Namespace
  • Horde_Kolab_Storage_Folder_Namespace_Config
  • Horde_Kolab_Storage_Folder_Namespace_Element
  • Horde_Kolab_Storage_Folder_Namespace_Element_Other
  • Horde_Kolab_Storage_Folder_Namespace_Element_Personal
  • Horde_Kolab_Storage_Folder_Namespace_Element_Shared
  • Horde_Kolab_Storage_Folder_Namespace_Element_SharedWithPrefix
  • Horde_Kolab_Storage_Folder_Namespace_Fixed
  • Horde_Kolab_Storage_Folder_Namespace_Imap
  • Horde_Kolab_Storage_Folder_Stamp_Uids
  • Horde_Kolab_Storage_Folder_Type
  • Horde_Kolab_Storage_List_Base
  • Horde_Kolab_Storage_List_Decorator_Cache
  • Horde_Kolab_Storage_List_Decorator_Log
  • Horde_Kolab_Storage_List_Query_Acl_Base
  • Horde_Kolab_Storage_List_Query_Acl_Cache
  • Horde_Kolab_Storage_List_Query_ActiveSync_Base
  • Horde_Kolab_Storage_List_Query_ActiveSync_Cache
  • Horde_Kolab_Storage_List_Query_List_Base
  • Horde_Kolab_Storage_List_Query_List_Cache
  • Horde_Kolab_Storage_List_Query_Share_Base
  • Horde_Kolab_Storage_List_Query_Share_Cache
  • Horde_Kolab_Storage_QuerySet_Base
  • Horde_Kolab_Storage_QuerySet_Cached
  • Horde_Kolab_Storage_QuerySet_Uncached
  • Horde_Kolab_Storage_Synchronization
  • Horde_Kolab_Storage_Translation
  • Horde_Kolab_Storage_Uncached

Interfaces

  • Horde_Kolab_Storage
  • Horde_Kolab_Storage_Data
  • Horde_Kolab_Storage_Data_Format
  • Horde_Kolab_Storage_Data_Parser
  • Horde_Kolab_Storage_Data_Query
  • Horde_Kolab_Storage_Data_Query_History
  • Horde_Kolab_Storage_Data_Query_Preferences
  • Horde_Kolab_Storage_Driver
  • Horde_Kolab_Storage_Folder
  • Horde_Kolab_Storage_Folder_Stamp
  • Horde_Kolab_Storage_List
  • Horde_Kolab_Storage_List_Query
  • Horde_Kolab_Storage_List_Query_Acl
  • Horde_Kolab_Storage_List_Query_ActiveSync
  • Horde_Kolab_Storage_List_Query_List
  • Horde_Kolab_Storage_List_Query_Share
  • Horde_Kolab_Storage_Queriable
  • Horde_Kolab_Storage_Query
  • Horde_Kolab_Storage_QuerySet
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * An PEAR-Net_Imap based Kolab storage driver.
  4:  *
  5:  * PHP version 5
  6:  *
  7:  * @category Kolab
  8:  * @package  Kolab_Storage
  9:  * @author   Gunnar Wrobel <wrobel@pardus.de>
 10:  * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
 11:  * @link     http://pear.horde.org/index.php?package=Kolab_Storage
 12:  */
 13: 
 14: /**
 15:  * An PEAR-Net_Imap based Kolab storage driver.
 16:  *
 17:  * Copyright 2010-2012 Horde LLC (http://www.horde.org/)
 18:  *
 19:  * See the enclosed file COPYING for license information (LGPL). If you
 20:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 21:  *
 22:  * @category Kolab
 23:  * @package  Kolab_Storage
 24:  * @author   Gunnar Wrobel <wrobel@pardus.de>
 25:  * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
 26:  * @link     http://pear.horde.org/index.php?package=Kolab_Storage
 27:  */
 28: class Horde_Kolab_Storage_Driver_Pear
 29: extends Horde_Kolab_Storage_Driver_Base
 30: {
 31:     /**
 32:      * Create the backend driver.
 33:      *
 34:      * @return mixed The backend driver.
 35:      */
 36:     public function createBackend()
 37:     {
 38:         $config = $this->getParams();
 39:         if (isset($config['secure']) && $config['secure'] == 'ssl') {
 40:             $prefix = 'ssl://';
 41:         } else {
 42:             $prefix = '';
 43:         }
 44:         $client = new Net_IMAP(
 45:             $prefix . $config['host'],
 46:             $config['port'],
 47:             isset($config['secure']) && $config['secure'] == 'tls'
 48:         );
 49:         $client->_useUTF_7 = false;
 50:         if (isset($config['debug'])) {
 51:             if ($config['debug'] == 'STDOUT') {
 52:                 $client->setDebug(true);
 53:             } else {
 54:                 throw new Horde_Kolab_Storage_Exception('This driver does not support debug logging into a file.');
 55:             }
 56:         }
 57:         Horde_Kolab_Storage_Exception_Pear::catchError(
 58:             $client->login($config['username'], $config['password'], true, false)
 59:         );
 60:         return $client;
 61:     }
 62: 
 63:     /**
 64:      * Retrieves a list of folders on the server.
 65:      *
 66:      * @return array The list of folders.
 67:      */
 68:     public function listFolders()
 69:     {
 70:         $list = Horde_Kolab_Storage_Exception_Pear::catchError(
 71:             $this->getBackend()->getMailboxes()
 72:         );
 73:         return $this->decodeList($list);
 74:     }
 75: 
 76:     /**
 77:      * Create the specified folder.
 78:      *
 79:      * @param string $folder The folder to create.
 80:      *
 81:      * @return NULL
 82:      */
 83:     public function create($folder)
 84:     {
 85:         Horde_Kolab_Storage_Exception_Pear::catchError(
 86:             $this->getBackend()->createMailbox($this->encodePath($folder))
 87:         );
 88:     }
 89: 
 90:     /**
 91:      * Delete the specified folder.
 92:      *
 93:      * @param string $folder  The folder to delete.
 94:      *
 95:      * @return NULL
 96:      */
 97:     public function delete($folder)
 98:     {
 99:         Horde_Kolab_Storage_Exception_Pear::catchError(
100:             $this->getBackend()->deleteMailbox($this->encodePath($folder))
101:         );
102:     }
103: 
104:     /**
105:      * Rename the specified folder.
106:      *
107:      * @param string $old  The folder to rename.
108:      * @param string $new  The new name of the folder.
109:      *
110:      * @return NULL
111:      */
112:     public function rename($old, $new)
113:     {
114:         Horde_Kolab_Storage_Exception_Pear::catchError(
115:             $this->getBackend()->renameMailbox(
116:                 $this->encodePath($old),
117:                 $this->encodePath($new)
118:             )
119:         );
120:     }
121: 
122:     /**
123:      * Does the backend support ACL?
124:      *
125:      * @return boolean True if the backend supports ACLs.
126:      */
127:     public function hasAclSupport()
128:     {
129:         return $this->getBackend()->hasCapability('ACL');
130:     }
131: 
132:     /**
133:      * Retrieve the access rights for a folder.
134:      *
135:      * @param string $folder The folder to retrieve the ACL for.
136:      *
137:      * @return array An array of rights.
138:      */
139:     public function getAcl($folder)
140:     {
141:         $result = Horde_Kolab_Storage_Exception_Pear::catchError(
142:             $this->getBackend()->getACL($this->encodePath($folder))
143:         );
144:         $acl = array();
145:         foreach ($result as $user) {
146:             $acl[$user['USER']] = $user['RIGHTS'];
147:         }
148:         return $acl;
149:     }
150: 
151:     /**
152:      * Retrieve the access rights the current user has on a folder.
153:      *
154:      * @param string $folder The folder to retrieve the user ACL for.
155:      *
156:      * @return string The user rights.
157:      */
158:     public function getMyAcl($folder)
159:     {
160:         return Horde_Kolab_Storage_Exception_Pear::catchError(
161:             $this->getBackend()->getMyRights($this->encodePath($folder))
162:         );
163:     }
164: 
165:     /**
166:      * Set the access rights for a folder.
167:      *
168:      * @param string $folder  The folder to act upon.
169:      * @param string $user    The user to set the ACL for.
170:      * @param string $acl     The ACL.
171:      *
172:      * @return NULL
173:      */
174:     public function setAcl($folder, $user, $acl)
175:     {
176:         Horde_Kolab_Storage_Exception_Pear::catchError(
177:             $this->getBackend()->setACL($this->encodePath($folder), $user, $acl)
178:         );
179:     }
180: 
181:     /**
182:      * Delete the access rights for user on a folder.
183:      *
184:      * @param string $folder  The folder to act upon.
185:      * @param string $user    The user to delete the ACL for
186:      *
187:      * @return NULL
188:      */
189:     public function deleteAcl($folder, $user)
190:     {
191:         Horde_Kolab_Storage_Exception_Pear::catchError(
192:             $this->getBackend()->deleteACL($this->encodePath($folder), $user)
193:         );
194:     }
195: 
196:     /**
197:      * Retrieves the specified annotation for the complete list of folders.
198:      *
199:      * @param string $annotation The name of the annotation to retrieve.
200:      *
201:      * @return array An associative array combining the folder names as key with
202:      *               the corresponding annotation value.
203:      */
204:     public function listAnnotation($annotation)
205:     {
206:         list($entry, $value) = $this->_getAnnotateMoreEntry($annotation);
207:         $list = array();
208:         $result = Horde_Kolab_Storage_Exception_Pear::catchError(
209:             $this->getBackend()->getAnnotation($entry, $value, '*')
210:         );
211:         foreach ($result as $element) {
212:             if (isset($element['ATTRIBUTES'][$value])) {
213:                 $list[$element['MAILBOX']] = $element['ATTRIBUTES'][$value];
214:             }
215:         }
216:         return $this->decodeListKeys($list);
217:     }
218: 
219:     /**
220:      * Fetches the annotation from a folder.
221:      *
222:      * @param string $folder    The name of the folder.
223:      * @param string $annotation The annotation to get.
224:      *
225:      * @return string The annotation value.
226:      */
227:     public function getAnnotation($folder, $annotation)
228:     {
229:         list($entry, $type) = $this->_getAnnotateMoreEntry($annotation);
230:         $result = Horde_Kolab_Storage_Exception_Pear::catchError(
231:             $this->getBackend()->getAnnotation(
232:                 $entry, $type, $this->encodePath($folder)
233:             )
234:         );var_dump($result);
235:         foreach ($result as $element) {
236:             if (isset($element['ATTRIBUTES'][$type])) {
237:                 return $element['ATTRIBUTES'][$type];
238:             }
239:         }
240:         return '';
241:     }
242: 
243:     /**
244:      * Sets the annotation on a folder.
245:      *
246:      * @param string $folder    The name of the folder.
247:      * @param string $annotation The annotation to set.
248:      * @param array  $value      The values to set
249:      *
250:      * @return NULL
251:      */
252:     public function setAnnotation($folder, $annotation, $value)
253:     {
254:         list($entry, $type) = $this->_getAnnotateMoreEntry($annotation);
255:         Horde_Kolab_Storage_Exception_Pear::catchError(
256:             $this->getBackend()->setAnnotation(
257:                 $entry, array($type => $value), $this->encodePath($folder)
258:             )
259:         );
260:     }
261: 
262:     /**
263:      * Retrieve the namespace information for this connection.
264:      *
265:      * @return Horde_Kolab_Storage_Driver_Namespace The initialized namespace handler.
266:      */
267:     public function getNamespace()
268:     {
269:         if ($this->getBackend()->hasCapability('NAMESPACE') === true) {
270:             $namespaces = array();
271:             foreach ($this->getBackend()->getNamespace() as $type => $elements) {
272:                 foreach ($elements as $namespace) {
273:                     switch ($type) {
274:                     case 'others':
275:                         $namespace['type'] = 'other';
276:                         break;
277:                     default:
278:                         $namespace['type'] = $type;
279:                         break;
280:                     }
281:                     $namespace['delimiter'] = $namespace['delimter'];
282:                     $namespaces[] = $namespace;
283:                 }
284:             }
285:             return new Horde_Kolab_Storage_Folder_Namespace_Imap(
286:                 $this->getAuth(),
287:                 $namespaces,
288:                 $this->getParam('namespaces', array())
289:             );
290:         }
291:         return parent::getNamespace();
292:     }
293: 
294:     /**
295:      * Opens the given folder.
296:      *
297:      * @param string $folder  The folder to open
298:      *
299:      * @return NULL
300:      */
301:     public function select($folder)
302:     {
303:         Horde_Kolab_Storage_Exception_Pear::catchError(
304:             $this->getBackend()->selectMailbox($this->encodePath($folder))
305:         );
306:     }
307: 
308:     /**
309:      * Returns the status of the current folder.
310:      *
311:      * @param string $folder Check the status of this folder.
312:      *
313:      * @return array  An array that contains 'uidvalidity' and 'uidnext'.
314:      */
315:     public function status($folder)
316:     {
317:         $result = Horde_Kolab_Storage_Exception_Pear::catchError(
318:             $this->getBackend()->getStatus($this->encodePath($folder))
319:         );
320:         return array(
321:             'uidvalidity' => $result['UIDVALIDITY'],
322:             'uidnext' => $result['UIDNEXT']
323:         );
324:     }
325: 
326:     /**
327:      * Returns the message ids of the messages in this folder.
328:      *
329:      * @param string $folder Check the status of this folder.
330:      *
331:      * @return array  The message ids.
332:      */
333:     public function getUids($folder)
334:     {
335:         $this->select($folder);
336:         $uids = Horde_Kolab_Storage_Exception_Pear::catchError(
337:             $this->getBackend()->search('UNDELETED', true)
338:         );
339:         if (!is_array($uids)) {
340:             $uids = array();
341:         }
342:         return $uids;
343:     }
344: 
345:     /**
346:      * Retrieves a complete message.
347:      *
348:      * @param string $folder The folder to fetch the messages from.
349:      * @param array  $uid    The message UID.
350:      *
351:      * @return array The message encapsuled as an array that contains a
352:      *               Horde_Mime_Headers and a Horde_Mime_Part object.
353:      */
354:     public function fetchComplete($folder, $uid)
355:     {
356:         $this->select($folder);
357:         return array(
358:             Horde_Mime_Headers::parseHeaders(
359:                 Horde_Kolab_Storage_Exception_Pear::catchError(
360:                     $this->getBackend()->getRawHeaders($uid, '', true)
361:                 )
362:             ),
363:             Horde_Mime_Part::parseMessage(
364:                 Horde_Kolab_Storage_Exception_Pear::catchError(
365:                     $this->getBackend()->getBody($uid, true)
366:                 )
367:             )
368:         );
369:     }
370: 
371:     /**
372:      * Retrieves the messages for the given message ids.
373:      *
374:      * @param string $folder The folder to fetch the messages from.
375:      * @param array  $uids                The message UIDs.
376:      *
377:      * @return array An array of message structures parsed into Horde_Mime_Part
378:      *               instances.
379:      */
380:     public function fetchStructure($folder, $uids)
381:     {
382:         $result = array();
383: 
384:         $this->select($folder);
385:         foreach ($uids as $uid) {
386:             $structure = Horde_Kolab_Storage_Exception_Pear::catchError(
387:                 $this->getBackend()->getStructure($uid, true)
388:             );
389:             $ob = $this->_parseStructure($structure);
390:             $ob->buildMimeIds();
391:             $result[$uid]['structure'] = $ob;
392:         }
393:         return $result;
394:     }
395: 
396:     /**
397:      * Retrieves a bodypart for the given message ID and mime part ID.
398:      *
399:      * @param string $folder The folder to fetch the messages from.
400:      * @param array  $uid                 The message UID.
401:      * @param array  $id                  The mime part ID.
402:      *
403:      * @return resource|string The body part, as a stream resource or string.
404:      */
405:     public function fetchBodypart($folder, $uid, $id)
406:     {
407:         $this->select($folder);
408:         return Horde_Kolab_Storage_Exception_Pear::catchError(
409:             $this->getBackend()->getBodyPart($uid, $id, true)
410:         );
411:     }
412: 
413:     /**
414:      * Appends a message to the given folder.
415:      *
416:      * @param string   $folder  The folder to append the message(s) to.
417:      * @param resource $msg     The message to append.
418:      *
419:      * @return mixed True or the UID of the new message in case the backend
420:      *               supports UIDPLUS.
421:      */
422:     public function appendMessage($folder, $msg)
423:     {
424:         rewind($msg);
425:         $this->select($folder);
426:         return Horde_Kolab_Storage_Exception_Pear::catchError(
427:             $this->getBackend()->appendMessage(stream_get_contents($msg))
428:         );
429:     }
430: 
431:     /**
432:      * Deletes messages from the specified folder.
433:      *
434:      * @param string  $folder  The folder to delete messages from.
435:      * @param integer $uids    IMAP message ids.
436:      *
437:      * @return NULL
438:      */
439:     public function deleteMessages($folder, $uids)
440:     {
441:         $this->select($folder);
442:         return Horde_Kolab_Storage_Exception_Pear::catchError(
443:             $this->getBackend()->deleteMessages($uids, true)
444:         );
445:     }
446: 
447:     /**
448:      * Moves a message to a new folder.
449:      *
450:      * @param integer $uid         IMAP message id.
451:      * @param string  $old_folder  Source folder.
452:      * @param string  $new_folder  Target folder.
453:      *
454:      * @return NULL
455:      */
456:     public function moveMessage($uid, $old_folder, $new_folder)
457:     {
458:         $this->select($old_folder);
459:         Horde_Kolab_Storage_Exception_Pear::catchError(
460:             $this->getBackend()->copyMessage($uid, $new_folder)
461:         );
462:         $this->deleteMessages($old_folder, array($uid));
463:         $this->expunge($old_folder);
464:     }
465: 
466:     /**
467:      * Expunges messages in the current folder.
468:      *
469:      * @return mixed  True or a PEAR error in case of an error.
470:      */
471:     public function expunge($folder)
472:     {
473:         $this->select($folder);
474:         return Horde_Kolab_Storage_Exception_Pear::catchError(
475:             $this->getBackend()->expunge()
476:         );
477:     }
478: 
479:     /**
480:      * Parse the output from imap_fetchstructure() into a MIME Part object.
481:      *
482:      * @param object $data  Data from imap_fetchstructure().
483:      *
484:      * @return Horde_Mime_Part  A MIME Part object.
485:      */
486:     protected function _parseStructure($data)
487:     {
488:         $ob = new Horde_Mime_Part();
489: 
490:         $ob->setType(strtolower($data->type) . '/' . strtolower($data->subType));
491: 
492:         // Optional for multipart-parts, required for all others
493:         if (isset($data->parameters)) {
494:             $params = array();
495:             foreach ($data->parameters as $key => $value) {
496:                 $params[strtolower($key)] = $value;
497:             }
498: 
499:             $params = Horde_Mime::decodeParam('content-type', $params, 'UTF-8');
500:             foreach ($params['params'] as $key => $value) {
501:                 $ob->setContentTypeParameter($key, $value);
502:             }
503:         }
504: 
505:         // Optional entries. 'location' and 'language' not supported
506:         if (isset($data->disposition)) {
507:             $ob->setDisposition($data->disposition);
508:             if (isset($data->dparameters)) {
509:                 $dparams = array();
510:                 foreach ($data->dparameters as $key => $value) {
511:                     $dparams[strtolower($key)] = $value;
512:                 }
513: 
514:                 $dparams = Horde_Mime::decodeParam('content-disposition', $dparams, 'UTF-8');
515:                 foreach ($dparams['params'] as $key => $value) {
516:                     $ob->setDispositionParameter($key, $value);
517:                 }
518:             }
519:         }
520: 
521:         if ($ob->getPrimaryType() == 'multipart') {
522:             // multipart/* specific entries
523:             foreach ($data->subParts as $val) {
524:                 $ob->addPart($this->_parseStructure($val));
525:             }
526:         } else {
527:             // Required options
528:             if (isset($data->partID)) {
529:                 $ob->setContentId($data->partID);
530:             }
531: 
532:             $ob->setTransferEncoding(strtolower($data->encoding));
533:             $ob->setBytes($data->bytes);
534: 
535:             if ($ob->getType() == 'message/rfc822') {
536:                 $ob->addPart($this->_parseStructure(reset($data->subParts)));
537:             }
538:         }
539: 
540:         return $ob;
541:     }
542: }
543: 
API documentation generated by ApiGen