Overview

Packages

  • None
  • Share

Classes

  • Horde_Share_Base
  • Horde_Share_Datatree
  • Horde_Share_Kolab
  • Horde_Share_Object
  • Horde_Share_Object_Datatree
  • Horde_Share_Object_DataTree_Share
  • Horde_Share_Object_Kolab
  • Horde_Share_Object_Sql
  • Horde_Share_Object_Sqlng
  • Horde_Share_Sql
  • Horde_Share_Sqlng
  • Horde_Share_Translation
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Base class for all Horde_Share drivers.
  4:  *
  5:  * Copyright 2002-2012 Horde LLC (http://www.horde.org/)
  6:  * Copyright 2002-2007 Infoteck Internet <webmaster@infoteck.qc.ca>
  7:  *
  8:  * See the enclosed file COPYING for license information (LGPL). If you
  9:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 10:  *
 11:  * @author  Joel Vandal <joel@scopserv.com>
 12:  * @author  Mike Cochrame <mike@graftonhall.co.nz>
 13:  * @author  Chuck Hagenbuch <chuck@horde.org>
 14:  * @author  Jan Schneider <jan@horde.org>
 15:  * @author  Gunnar Wrobel <wrobel@pardus.de>
 16:  * @author  Michael J. Rubinsky <mrubinsk@horde.org>
 17:  * @package Share
 18:  */
 19: abstract class Horde_Share_Base
 20: {
 21:     /**
 22:      * The application we're managing shares for.
 23:      *
 24:      * @var string
 25:      */
 26:     protected $_app;
 27: 
 28:     /**
 29:      * The root of the Share tree.
 30:      *
 31:      * @var mixed
 32:      */
 33:     protected $_root = null;
 34: 
 35:     /**
 36:      * A cache of all shares that have been retrieved, so we don't hit the
 37:      * backend again and again for them.
 38:      *
 39:      * @var array
 40:      */
 41:     protected $_cache = array();
 42: 
 43:     /**
 44:      * Id-name-map of already cached share objects.
 45:      *
 46:      * @var array
 47:      */
 48:     protected $_shareMap = array();
 49: 
 50:     /**
 51:      * Cache used for listShares().
 52:      *
 53:      * @var array
 54:      */
 55:     protected $_listcache = array();
 56: 
 57:     /**
 58:      * A list of objects that we're currently sorting, for reference during the
 59:      * sorting algorithm.
 60:      *
 61:      * @var array
 62:      */
 63:     protected $_sortList;
 64: 
 65:     /**
 66:      * The Horde_Share_Object subclass to instantiate objects as
 67:      *
 68:      * @var string
 69:      */
 70:     protected $_shareObject;
 71: 
 72:     /**
 73:      * The Horde_Perms object
 74:      *
 75:      * @var Horde_Perms_Base
 76:      */
 77:     protected $_permsObject;
 78: 
 79:     /**
 80:      * The current user
 81:      *
 82:      * @var string
 83:      */
 84:     protected $_user;
 85: 
 86:     /**
 87:      * The Horde_Group driver
 88:      *
 89:      * @var Horde_Group_Base
 90:      */
 91:     protected $_groups;
 92: 
 93:     /**
 94:      * A callback that is passed to the share objects for setting the objects'
 95:      * Horde_Share object.
 96:      *
 97:      * @var callback
 98:      */
 99:     protected $_shareCallback;
100: 
101:     /**
102:      * Logger
103:      *
104:      * @var Horde_Log_Logger
105:      */
106:     protected $_logger;
107: 
108:     /**
109:      * Configured callbacks. We currently support:
110:      *<pre>
111:      * add      - Called immediately before a new share is added. Receives the
112:      *            share object as a parameter.
113:      * modify   - Called immediately before a share object's changes are saved
114:      *            to storage. Receives the share object as a parameter.
115:      * remove   - Called immediately before a share is removed from storage.
116:      *            Receives the share object as a parameter.
117:      * list     - Called immediately after a list of shares is received from
118:      *            storage. Passed the userid, share list, and any parameters
119:      *            passed to the listShare call. Should return the (possibly
120:      *            modified) share list. @see listShares() for more
121:      *            info.
122:      *</pre>
123:      *
124:      * @var array
125:      */
126:     protected $_callbacks;
127: 
128:     /**
129:      * Constructor.
130:      *
131:      * @param string $app               The application that the shares belong
132:      *                                  to.
133:      * @param string $user              The current user.
134:      * @param Horde_Perms_Base $perms   The permissions object.
135:      * @param Horde_Group_Base $groups  The Horde_Group driver.
136:      *
137:      */
138:     public function __construct($app, $user, Horde_Perms_Base $perms,
139:                                 Horde_Group_Base $groups)
140:     {
141:         $this->_app = $app;
142:         $this->_user = $user;
143:         $this->_permsObject = $perms;
144:         $this->_groups = $groups;
145:         $this->_logger = new Horde_Support_Stub();
146:     }
147: 
148:     /**
149:      * Set a logger object.
150:      *
151:      * @inject
152:      *
153:      * @var Horde_Log_Logger $logger  The logger object.
154:      */
155:     public function setLogger(Horde_Log_Logger $logger)
156:     {
157:         $this->_logger = $logger;
158:     }
159: 
160:     /**
161:      * (Re)connects the share object to this share driver.
162:      *
163:      * @param Horde_Share_Object $object
164:      */
165:     public function initShareObject(Horde_Share_Object $object)
166:     {
167:         $object->setShareOb(empty($this->_shareCallback) ? $this : $this->_shareCallback);
168:     }
169: 
170:     public function setShareCallback($callback)
171:     {
172:         $this->_shareCallback = $callback;
173:     }
174: 
175:     /**
176:      * Returns the application we're managing shares for.
177:      *
178:      * @return string  The application this share belongs to.
179:      */
180:     public function getApp()
181:     {
182:         return $this->_app;
183:     }
184: 
185:     /**
186:      * Returns a Horde_Share_Object object corresponding to the given share
187:      * name, with the details retrieved appropriately.
188:      *
189:      * @param string $name  The name of the share to retrieve.
190:      *
191:      * @return Horde_Share_Object  The requested share.
192:      */
193:     public function getShare($name)
194:     {
195:         if (isset($this->_cache[$name])) {
196:             return $this->_cache[$name];
197:         }
198: 
199:         $share = $this->_getShare($name);
200:         $this->_shareMap[$share->getId()] = $name;
201:         $this->_cache[$name] = $share;
202: 
203:         return $share;
204:     }
205: 
206:     /**
207:      * Returns a Horde_Share_Object object corresponding to the given
208:      * share name, with the details retrieved appropriately.
209:      *
210:      * @param string $name  The name of the share to retrieve.
211:      *
212:      * @return Horde_Share_Object  The requested share.
213:      * @throws Horde_Exception_NotFound
214:      * @throws Horde_Share_Exception
215:      */
216:     abstract protected function _getShare($name);
217: 
218:     /**
219:      * Returns a Horde_Share_Object object corresponding to the given unique
220:      * ID, with the details retrieved appropriately.
221:      *
222:      * @param string $cid  The id of the share to retrieve.
223:      *
224:      * @return Horde_Share_Object  The requested share.
225:      */
226:     public function getShareById($cid)
227:     {
228:         if (!isset($this->_shareMap[$cid])) {
229:             $share = $this->_getShareById($cid);
230:             $name = $share->getName();
231:             $this->_cache[$name] = $share;
232:             $this->_shareMap[$cid] = $name;
233:         }
234: 
235:         return $this->_cache[$this->_shareMap[$cid]];
236:     }
237: 
238:     /**
239:      * Returns a Horde_Share_Object object corresponding to the given
240:      * unique ID, with the details retrieved appropriately.
241:      *
242:      * @param integer $id  The id of the share to retrieve.
243:      *
244:      * @return Horde_Share_Object_sql  The requested share.
245:      * @throws Horde_Share_Exception, Horde_Exception_NotFound
246:      */
247:     abstract protected function _getShareById($id);
248: 
249:     /**
250:      * Returns an array of Horde_Share_Object objects corresponding to the
251:      * given set of unique IDs, with the details retrieved appropriately.
252:      *
253:      * @param array $cids  The array of ids to retrieve.
254:      *
255:      * @return array  The requested shares.
256:      */
257:     public function getShares(array $cids)
258:     {
259:         $all_shares = $missing_ids = array();
260:         foreach ($cids as $cid) {
261:             if (!isset($this->_shareMap[$cid])) {
262:                 $missing_ids[] = $cid;
263:             }
264:         }
265: 
266:         if (count($missing_ids)) {
267:             $shares = $this->_getShares($missing_ids);
268:             foreach (array_keys($shares) as $key) {
269:                 $this->_cache[$key] = $shares[$key];
270:                 $this->_shareMap[$shares[$key]->getId()] = $key;
271:             }
272:         }
273: 
274:         foreach ($cids as $cid) {
275:             $all_shares[$this->_shareMap[$cid]] = $this->_cache[$this->_shareMap[$cid]];
276:         }
277: 
278:         return $all_shares;
279:     }
280: 
281:     /**
282:      * Returns an array of Horde_Share_Object objects corresponding
283:      * to the given set of unique IDs, with the details retrieved
284:      * appropriately.
285:      *
286:      * @param array $ids  The array of ids to retrieve.
287:      *
288:      * @return array  The requested shares.
289:      * @throws Horde_Share_Exception
290:      */
291:     abstract protected function _getShares(array $ids);
292: 
293:     /**
294:      * Lists *all* shares for the current app/share, regardless of
295:      * permissions.
296:      *
297:      * This is for admin functionality and scripting tools, and shouldn't be
298:      * called from user-level code!
299:      *
300:      * @return array  All shares for the current app/share.
301:      */
302:     public function listAllShares()
303:     {
304:         $shares = $this->_listAllShares();
305:         $this->_sortList = $shares;
306:         uasort($shares, array($this, '_sortShares'));
307:         $this->_sortList = null;
308: 
309:         return $shares;
310:     }
311: 
312:     /**
313:      * Lists *all* shares for the current app/share, regardless of permissions.
314:      *
315:      * @return array  All shares for the current app/share.
316:      * @throws Horde_Share_Exception
317:      */
318:     abstract protected function _listAllShares();
319: 
320:     /**
321:      * Returns an array of all shares that $userid has access to.
322:      *
323:      * @param string $userid  The userid of the user to check access for. An
324:      *                        empty value for the userid will only return shares
325:      *                        with guest access.
326:      * @param array $params   Additional parameters for the search.
327:      *<pre>
328:      *  'perm'        Require this level of permissions. Horde_Perms constant.
329:      *  'attributes'  Restrict shares to these attributes. A hash or username.
330:      *  'from'        Offset. Start at this share
331:      *  'count'       Limit.  Only return this many.
332:      *  'sort_by'     Sort by attribute.
333:      *  'direction'   Sort by direction.
334:      *</pre>
335:      *
336:      * @return array  The shares the user has access to.
337:      */
338:     public function listShares($userid, array $params = array())
339:     {
340:         $params = array_merge(array('perm' => Horde_Perms::SHOW,
341:                                     'attributes' => null,
342:                                     'from' => 0,
343:                                     'count' => 0,
344:                                     'sort_by' => null,
345:                                     'direction' => 0),
346:                               $params);
347: 
348:         $shares = $this->_listShares($userid, $params);
349:         if (!count($shares)) {
350:             return $shares;
351:         }
352: 
353:         $shares = $this->getShares($shares);
354:         if (is_null($params['sort_by'])) {
355:             $this->_sortList = $shares;
356:             uasort($shares, array($this, '_sortShares'));
357:             $this->_sortList = null;
358:         }
359: 
360:         // Run the results through the callback, if configured.
361:         if (!empty($this->_callbacks['list'])) {
362:             return $this->runCallback('list', array($userid, $shares, $params));
363:         }
364: 
365:         return $shares;
366:     }
367: 
368:     /**
369:      * Returns an array of all shares that $userid has access to.
370:      *
371:      * @param string $userid     The userid of the user to check access for.
372:      * @param array  $params     See listShares().
373:      *
374:      * @return array  The shares the user has access to.
375:      */
376:     abstract protected function _listShares($userid, array $params = array());
377: 
378:     /**
379:      * Returns an array of all system shares.
380:      *
381:      * @return array  All system shares.
382:      */
383:     public function listSystemShares()
384:     {
385:         return array();
386:     }
387: 
388:     /**
389:      * Returns the number of shares that $userid has access to.
390:      *
391:      * @param string $userid     The userid of the user to check access for.
392:      * @param integer $perm      The level of permissions required.
393:      * @param mixed $attributes  Restrict the shares counted to those
394:      *                           matching $attributes. An array of
395:      *                           attribute/values pairs or a share owner
396:      *                           username.
397:      *
398:      * @return integer  The number of shares
399:      */
400:     public function countShares($userid, $perm = Horde_Perms::SHOW,
401:                                 $attributes = null)
402:     {
403:         return count($this->_listShares($userid, array('perm' => $perm, 'attributes' => $attributes)));
404:     }
405: 
406:     /**
407:      * Returns a new share object.
408:      *
409:      * @param string $owner           The share owner name.
410:      * @param string $share_name      The share's name.
411:      * @param string $name_attribute  The name displayed to the user.
412:      *
413:      * @return Horde_Share_Object  A new share object.
414:      * @throws Horde_Share_Exception
415:      */
416:     public function newShare($owner, $share_name = '', $name_attribute = '')
417:     {
418:         $share = $this->_newShare($share_name);
419:         $share->set('owner', $owner);
420:         $share->set('name', $name_attribute);
421:         return $share;
422:     }
423: 
424:     /**
425:      * Returns a new share object.
426:      *
427:      * @param string $name   The share's name.
428:      *
429:      * @return Horde_Share_Object  A new share object
430:      * @throws InvalidArgumentException
431:      */
432:     abstract protected function _newShare($name);
433: 
434:     /**
435:      * Adds a share to the shares system.
436:      *
437:      * The share must first be created with newShare(), and have any initial
438:      * details added to it, before this function is called.
439:      *
440:      * @param Horde_Share_Object $share  The new share object.
441:      *
442:      * @throws Horde_Share_Exception
443:      */
444:     public function addShare(Horde_Share_Object $share)
445:     {
446:         // Run the results through the callback, if configured.
447:         $this->runCallback('add', array($share));
448:         $this->_addShare($share);
449: 
450:         /* Store new share in the caches. */
451:         $id = $share->getId();
452:         $name = $share->getName();
453:         $this->_cache[$name] = $share;
454:         $this->_shareMap[$id] = $name;
455: 
456:         /* Reset caches that depend on unknown criteria. */
457:         $this->expireListCache();
458:     }
459: 
460:     /**
461:      * Adds a share to the shares system.
462:      *
463:      * The share must first be created with
464:      * Horde_Share_sql::_newShare(), and have any initial details added
465:      * to it, before this function is called.
466:      *
467:      * @param Horde_Share_Object $share  The new share object.
468:      */
469:     abstract protected function _addShare(Horde_Share_Object $share);
470: 
471:     /**
472:      * Renames a share in the shares system.
473:      *
474:      * @param Horde_Share_Object $share  The share to rename.
475:      * @param string $name               The share's new name.
476:      *
477:      * @throws Horde_Share_Exception
478:      */
479:     public function renameShare(Horde_Share_Object $share, $name)
480:     {
481:         /* Move share in the caches. */
482:         unset($this->_cache[$share->getName()]);
483:         $this->_cache[$name] = $share;
484: 
485:         /* Reset caches that depend on unknown criteria. */
486:         $this->expireListCache();
487: 
488:         $this->_renameShare($share, $name);
489:     }
490: 
491:     /**
492:      * Renames a share in the shares system.
493:      *
494:      * @param Horde_Share_Object $share  The share to rename.
495:      * @param string $name               The share's new name.
496:      *
497:      * @throws Horde_Share_Exception
498:      */
499:     abstract protected function _renameShare(Horde_Share_Object $share, $name);
500: 
501:     /**
502:      * Removes a share from the shares system permanently.
503:      *
504:      * @param Horde_Share_Object $share  The share to remove.
505:      *
506:      * @throws Horde_Share_Exception
507:      */
508:     public function removeShare(Horde_Share_Object $share)
509:     {
510:         // Run the results through the callback, if configured.
511:         $this->runCallback('remove', array($share));
512: 
513:         /* Remove share from the caches. */
514:         $id = $share->getId();
515:         unset($this->_shareMap[$id]);
516:         unset($this->_cache[$share->getName()]);
517: 
518:         /* Reset caches that depend on unknown criteria. */
519:         $this->expireListCache();
520: 
521:         $this->_removeShare($share);
522:     }
523: 
524:     /**
525:      * Removes a share from the shares system permanently.
526:      *
527:      * @param Horde_Share_Object $share  The share to remove.
528:      *
529:      * @throws Horde_Share_Exception
530:      */
531:     abstract protected function _removeShare(Horde_Share_Object $share);
532: 
533:     /**
534:      * Checks if a share name exists in the system.
535:      *
536:      * @param string $share  The share name to check.
537:      *
538:      * @return boolean  True if the share exists.
539:      */
540:     public function exists($share)
541:     {
542:         if (isset($this->_cache[$share])) {
543:             return true;
544:         }
545: 
546:         return $this->_exists($share);
547:     }
548: 
549:     /**
550:      * Check that a share id exists in the system.
551:      *
552:      * @param integer $id  The share id
553:      *
554:      * @return boolean True if the share exists.
555:      */
556:     public function idExists($id)
557:     {
558:         if (isset($this->_shareMap[$id])) {
559:             return true;
560:         }
561: 
562:         return $this->_idExists($id);
563:     }
564: 
565: 
566:     /**
567:      * Checks if a share exists in the system.
568:      *
569:      * @param string $share  The share to check.
570:      *
571:      * @return boolean  True if the share exists.
572:      * @throws Horde_Share_Exception
573:      */
574:     abstract protected function _exists($share);
575: 
576:     /**
577:      * Check that a share id exists in the system.
578:      *
579:      * @param integer $id  The share id
580:      *
581:      * @return boolean True if the share exists.
582:      */
583:     abstract protected function _idExists($id);
584: 
585:     /**
586:      * Finds out what rights the given user has to this object.
587:      *
588:      * @see Horde_Perms::getPermissions
589:      *
590:      * @param mixed $share  The share that should be checked for the users
591:      *                      permissions.
592:      * @param string $user  The user to check for.
593:      *
594:      * @return mixed  A bitmask of permissions, a permission value, or an array
595:      *                of permission values the user has, depending on the
596:      *                permission type and whether the permission value is
597:      *                ambiguous. False if there is no such permsission.
598:      */
599:     public function getPermissions($share, $user = null)
600:     {
601:         if (!($share instanceof Horde_Share_Object)) {
602:             $share = $this->getShare($share);
603:         }
604: 
605:         return $this->_permsObject->getPermissions($share->getPermission(), $user);
606:     }
607: 
608:     /**
609:      * Set the class type to use for creating share objects.
610:      *
611:      * @var string $classname  The classname to use.
612:      */
613:     public function setShareClass($classname)
614:     {
615:         $this->_shareObject = $classname;
616:     }
617: 
618:     /**
619:      * Getter for Horde_Perms object
620:      *
621:      * @return Horde_Perms_Base
622:      */
623:     public function getPermsObject()
624:     {
625:         return $this->_permsObject;
626:     }
627: 
628:     /**
629:      * Convert TO the storage driver's charset. Individual share objects should
630:      * implement this method if needed.
631:      *
632:      * @param array $data  Data to be converted.
633:      */
634:     public function toDriverCharset($data)
635:     {
636:         return $data;
637:     }
638: 
639:     /**
640:      * Add a callback to the collection
641:      *
642:      * @param string $type
643:      * @param array $callback
644:      */
645:     public function addCallback($type, $callback)
646:     {
647:         $this->_callbacks[$type] = $callback;
648:     }
649: 
650:     /**
651:      * Returns the share's list cache.
652:      *
653:      * @return array
654:      */
655:     public function getListCache()
656:     {
657:         return $this->_listcache;
658:     }
659: 
660:     /**
661:      * Set the list cache.
662:      *
663:      * @param array $cache
664:      */
665:     public function setListCache($cache)
666:     {
667:         $this->_listcache = $cache;
668:     }
669: 
670:     /**
671:      * Resets the internal caches.
672:      */
673:     public function resetCache()
674:     {
675:         $this->_cache = $this->_shareMap = array();
676:         $this->expireListCache();
677:     }
678: 
679:     /**
680:      * Give public access to call the share callbacks. Needed to run the
681:      * callbacks from the Horde_Share_Object objects.
682:      *
683:      * @param string $type   The callback to run
684:      * @param array $params  The parameters to pass to the callback.
685:      *
686:      * @return mixed
687:      */
688:     public function runCallback($type, $params)
689:     {
690:         if (!empty($this->_callbacks[$type])) {
691:             return call_user_func_array($this->_callbacks[$type], $params);
692:         }
693:     }
694: 
695:     /**
696:      * Expire the current list cache. This would be needed anytime a share is
697:      * either added, deleted, had a change in owner, parent, or perms.
698:      */
699:     public function expireListCache()
700:     {
701:         $this->_listcache = array();
702:     }
703: 
704:     /**
705:      * Utility function to be used with uasort() for sorting arrays of
706:      * Horde_Share objects.
707:      *
708:      * Example:
709:      * <code>
710:      * uasort($list, array('Horde_Share', '_sortShares'));
711:      * </code>
712:      */
713:     protected function _sortShares($a, $b)
714:     {
715:         $aParts = explode(':', $a->getName());
716:         $bParts = explode(':', $b->getName());
717: 
718:         $min = min(count($aParts), count($bParts));
719:         $idA = '';
720:         $idB = '';
721:         for ($i = 0; $i < $min; $i++) {
722:             if ($idA) {
723:                 $idA .= ':';
724:                 $idB .= ':';
725:             }
726:             $idA .= $aParts[$i];
727:             $idB .= $bParts[$i];
728: 
729:             if ($idA != $idB) {
730:                 $curA = isset($this->_sortList[$idA]) ? $this->_sortList[$idA]->get('name') : '';
731:                 $curB = isset($this->_sortList[$idB]) ? $this->_sortList[$idB]->get('name') : '';
732:                 return strnatcasecmp($curA, $curB);
733:             }
734:         }
735: 
736:         return count($aParts) > count($bParts);
737:     }
738: }
739: 
API documentation generated by ApiGen