From 8d899d2a9375471e7ef8620515281ebb673f0f1e Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Wed, 19 May 2010 10:45:39 -0400 Subject: [PATCH] First round of H4-ifying Horde_Share. Mostly PHP5 stuff and restructuring of package layout. Still coming: Finish auditing apps for pear error checks from share package, and the addition of a binder for Horde_Share --- ansel/lib/Ansel.php | 7 - ansel/lib/Faces/Base.php | 4 +- ansel/lib/Gallery.php | 2 +- ansel/lib/Storage.php | 8 +- framework/Share/Share/kolab.php | 716 --------------------- framework/Share/{ => lib/Horde}/Share.php | 483 ++------------ .../datatree.php => lib/Horde/Share/Datatree.php} | 318 ++------- framework/Share/lib/Horde/Share/Exception.php | 9 + framework/Share/lib/Horde/Share/Kolab.php | 334 ++++++++++ framework/Share/lib/Horde/Share/Object.php | 367 +++++++++++ .../Share/lib/Horde/Share/Object/Datatree.php | 138 ++++ .../lib/Horde/Share/Object/Datatree/Share.php | 99 +++ framework/Share/lib/Horde/Share/Object/Kolab.php | 360 +++++++++++ framework/Share/lib/Horde/Share/Object/Sql.php | 283 ++++++++ .../lib/Horde/Share/Object/Sql/Hierarchical.php | 186 ++++++ .../{Share/sql.php => lib/Horde/Share/Sql.php} | 516 ++++----------- .../Horde/Share/Sql/Hierarchical.php} | 300 ++------- framework/Share/package.xml | 142 +++- horde/services/shares/edit.php | 31 +- kronolith/edit.php | 3 +- kronolith/lib/Api.php | 3 - kronolith/lib/Driver/Sql.php | 23 +- kronolith/lib/FreeBusy.php | 8 +- kronolith/perms.php | 29 +- whups/lib/Query.php | 3 - 25 files changed, 2243 insertions(+), 2129 deletions(-) delete mode 100644 framework/Share/Share/kolab.php rename framework/Share/{ => lib/Horde}/Share.php (51%) rename framework/Share/{Share/datatree.php => lib/Horde/Share/Datatree.php} (55%) create mode 100644 framework/Share/lib/Horde/Share/Exception.php create mode 100644 framework/Share/lib/Horde/Share/Kolab.php create mode 100644 framework/Share/lib/Horde/Share/Object.php create mode 100644 framework/Share/lib/Horde/Share/Object/Datatree.php create mode 100644 framework/Share/lib/Horde/Share/Object/Datatree/Share.php create mode 100644 framework/Share/lib/Horde/Share/Object/Kolab.php create mode 100644 framework/Share/lib/Horde/Share/Object/Sql.php create mode 100644 framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php rename framework/Share/{Share/sql.php => lib/Horde/Share/Sql.php} (67%) rename framework/Share/{Share/sql_hierarchical.php => lib/Horde/Share/Sql/Hierarchical.php} (69%) diff --git a/ansel/lib/Ansel.php b/ansel/lib/Ansel.php index e73cd7c49..c745826bf 100644 --- a/ansel/lib/Ansel.php +++ b/ansel/lib/Ansel.php @@ -11,13 +11,6 @@ * @author Michael J. Rubinsky * @package Ansel */ - -/** Horde_Share */ -require_once 'Horde/Share.php'; - -/** Need to bring this in explicitly since we extend the object class */ -require_once 'Horde/Share/sql_hierarchical.php'; - class Ansel { /** diff --git a/ansel/lib/Faces/Base.php b/ansel/lib/Faces/Base.php index a1201d5ed..52943554f 100644 --- a/ansel/lib/Faces/Base.php +++ b/ansel/lib/Faces/Base.php @@ -164,7 +164,7 @@ class Ansel_Faces_Base // should be encapsulated by the shares driver and not parsed from // an internally generated query string fragment. Will need to split // this out into two seperate operations somehow. - $share = substr($GLOBALS['ansel_storage']->shares->_getShareCriteria( + $share = substr($GLOBALS['ansel_storage']->shares->getShareCriteria( Horde_Auth::getAuth(), Horde_Perms::READ), 5); $sql = 'SELECT f.face_id, f.gallery_id, f.image_id, f.face_name FROM ansel_faces f, ' @@ -201,7 +201,7 @@ class Ansel_Faces_Base { // add gallery permission // FIXME: Ditto on the REALLY ugly hack comment from above! - $share = substr($GLOBALS['ansel_storage']->shares->_getShareCriteria( + $share = substr($GLOBALS['ansel_storage']->shares->getShareCriteria( Horde_Auth::getAuth(), Horde_Perms::READ), 5); $sql = 'SELECT COUNT(*) FROM ansel_faces f, ' diff --git a/ansel/lib/Gallery.php b/ansel/lib/Gallery.php index 8685adcd8..b3a782330 100644 --- a/ansel/lib/Gallery.php +++ b/ansel/lib/Gallery.php @@ -28,7 +28,7 @@ class Ansel_Gallery extends Horde_Share_Object_sql_hierarchical public function __construct($attributes = array()) { /* Pass on up the chain */ - parent::Horde_Share_Object_sql_hierarchical($attributes); + parent::__construct($attributes); $this->setShareOb($GLOBALS['ansel_storage']->shares); $mode = isset($attributes['attribute_view_mode']) ? $attributes['attribute_view_mode'] : 'Normal'; $this->_setModeHelper($mode); diff --git a/ansel/lib/Storage.php b/ansel/lib/Storage.php index 522a124d8..5afd1d7e4 100644 --- a/ansel/lib/Storage.php +++ b/ansel/lib/Storage.php @@ -66,7 +66,7 @@ class Ansel_Storage 'sql_hierarchical'); /* Ansel_Gallery is just a subclass of Horde_Share_Object */ - $this->_shares->_shareObject = 'Ansel_Gallery'; + $this->_shares->setShareClass('Ansel_Gallery'); /* Database handle */ $this->_db = $GLOBALS['ansel_db']; @@ -721,7 +721,7 @@ class Ansel_Storage if (!count($galleries) && !count($slugs)) { $sql = 'SELECT DISTINCT ' . $this->_getImageFields('i') . ' FROM ansel_images i, ' - . str_replace('WHERE' , ' WHERE i.gallery_id = s.share_id AND (', substr($this->_shares->_getShareCriteria(Horde_Auth::getAuth()), 5)) . ')'; + . str_replace('WHERE' , ' WHERE i.gallery_id = s.share_id AND (', substr($this->_shares->getShareCriteria(Horde_Auth::getAuth()), 5)) . ')'; } elseif (!count($slugs) && count($galleries)) { // Searching by gallery_id $sql = 'SELECT ' . $this->_getImageFields() . ' FROM ansel_images ' @@ -810,8 +810,8 @@ class Ansel_Storage public function listCategories($perm = Horde_Perms::SHOW, $from = 0, $count = 0) { $sql = 'SELECT DISTINCT attribute_category FROM ' - . $this->_shares->_table; - $results = $this->_shares->_db->query($sql); + . $this->_shares->getTable(); + $results = $this->_shares->getReadDb()->query($sql); if ($results instanceof PEAR_Error) { throw new Horde_Exception($results->getMessage()); } diff --git a/framework/Share/Share/kolab.php b/framework/Share/Share/kolab.php deleted file mode 100644 index af6cd4940..000000000 --- a/framework/Share/Share/kolab.php +++ /dev/null @@ -1,716 +0,0 @@ - - * @author Gunnar Wrobel - * @package Horde_Share - */ -class Horde_Share_kolab extends Horde_Share { - - /** - * Our Kolab folder list handler - * - * @var Kolab_List - */ - var $_list; - - /** - * The share type - * - * @var string - */ - var $_type; - - /** - * A marker for the validity of the list cache - * - * @var int - */ - var $_listCacheValidity; - - /** - * The session handler. - * - * @var Horde_Kolab_Session - */ - private $_session; - - /** - * Initializes the object. - * - * @throws Horde_Exception - */ - function __wakeup() - { - if (empty($GLOBALS['conf']['kolab']['enabled'])) { - throw new Horde_Exception('You must enable the kolab settings to use the Kolab Share driver.'); - } - - $this->_type = $this->_getFolderType($this->_app); - if (is_a($this->_type, 'PEAR_Error')) { - return $this->_type; - } - - $this->_list = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage'); - - parent::__wakeup(); - } - - private function _getFolderType($app) - { - switch ($app) { - case 'mnemo': - return 'note'; - case 'kronolith': - return 'event'; - case 'turba': - return 'contact'; - case 'nag': - return 'task'; - default: - return PEAR::raiseError(sprintf(_("The Horde/Kolab integration engine does not support \"%s\""), $app)); - } - } - - /** - * Returns the properties that need to be serialized. - * - * @return array List of serializable properties. - */ - function __sleep() - { - $properties = get_object_vars($this); - unset($properties['_sortList'], $properties['_list']); - $properties = array_keys($properties); - return $properties; - } - - /** - * Returns a Horde_Share_Object_kolab object of the request folder. - * - * @param string $object The share to fetch. - * - * @return Horde_Share_Object_kolab The share object. - */ - function &_getShare($object) - { - if (empty($object)) { - $error = PEAR::raiseError('No object requested.'); - return $error; - } - - /** Get the corresponding folder for this share ID */ - $folder = $this->_list->getByShare($object, $this->_type); - if (is_a($folder, 'PEAR_Error')) { - return $folder; - } - - /** Does the folder exist? */ - if (!$folder->exists()) { - return PEAR::raiseError(sprintf(_("Share \"%s\" does not exist."), $object)); - } - - /** Create the object from the folder */ - $share = new Horde_Share_Object_kolab($object, $this->_type); - $result = $share->setFolder($folder); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - return $share; - } - - /** - * Returns a Horde_Share_Object_kolab object of the requested folder. - * - * @param string $id The id of the share to fetch. - * - * @return Horde_Share_Object_kolab The share object. - */ - function &_getShareById($id) - { - return $this->_getShare($id); - } - - /** - * Returns an array of Horde_Share_Object_kolab objects corresponding to - * the requested folders. - * - * @param string $ids The ids of the shares to fetch. - * - * @return array An array of Horde_Share_Object_kolab objects. - */ - function &_getShares($ids) - { - $objects = array(); - foreach ($ids as $id) { - $result = &$this->_getShare($id); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - $objects[$id] = &$result; - } - return $objects; - } - - /** - * Lists *all* shares for the current app/share, regardless of - * permissions. - * - * Currently not implemented in this class. - * - * @return array All shares for the current app/share. - */ - function &_listAllShares() - { - $shares = array(); - return $shares; - } - - /** - * Returns an array of all shares that $userid has access to. - * - * @param string $userid The userid of the user to check access for. - * @param integer $perm The level of permissions required. - * @param mixed $attributes Restrict the shares counted to those - * matching $attributes. An array of - * attribute/values pairs or a share owner - * username. - * - * @return array The shares the user has access to. - */ - function &_listShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null, $from = 0, $count = 0, - $sort_by = null, $direction = 0) - { - $key = serialize(array($this->_type, $userid, $perm, $attributes)); - if ($this->_list === false) { - $this->_listCache[$key] = array(); - } else if (empty($this->_listCache[$key]) - || $this->_list->validity != $this->_listCacheValidity) { - $sharelist = $this->_list->getByType($this->_type); - if (is_a($sharelist, 'PEAR_Error')) { - return $sharelist; - } - - $shares = array(); - foreach ($sharelist as $folder) { - $id = $folder->getShareId(); - $share = &$this->getShare($id); - if (is_a($share, 'PEAR_Error')) { - return $share; - } - - $keep = true; - if (!$share->hasPermission($userid, $perm)) { - $keep = false; - } - if (isset($attributes) && $keep) { - if (is_array($attributes)) { - foreach ($attributes as $key => $value) { - if (!$share->get($key) == $value) { - $keep = false; - break; - } - } - } elseif (!$share->get('owner') == $attributes) { - $keep = false; - } - } - if ($keep) { - $shares[] = $id; - } - } - $this->_listCache[$key] = $shares; - $this->_listCacheValidity = $this->_list->validity; - } - - return $this->_listCache[$key]; - } - - /** - * Returns the number of shares that $userid has access to. - * - * @param string $userid The userid of the user to check access for. - * @param integer $perm The level of permissions required. - * @param mixed $attributes Restrict the shares counted to those - * matching $attributes. An array of - * attribute/values pairs or a share owner - * username. - * - * @return integer The number of shares - */ - function _countShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null) - { - $shares = $this->_listShares($userid, $perm, $attributes); - if (is_a($share, 'PEAR_Error')) { - return $share; - } - - return count($shares); - } - - /** - * Returns a new share object. - * - * @param string $name The share's name. - * - * @return Horde_Share_Object_kolab A new share object. - */ - function &_newShare($name) - { - $storageObject = new Horde_Share_Object_kolab($name, $this->_type); - return $storageObject; - } - - /** - * Adds a share to the shares system. - * - * The share must first be created with Horde_Share_kolab::_newShare(), - * and have any initial details added to it, before this function is - * called. - * - * @param Horde_Share_Object_kolab $share The new share object. - */ - function _addShare(&$share) - { - return $share->save(); - } - - /** - * Removes a share from the shares system permanently. - * - * @param Horde_Share_Object_kolab $share The share to remove. - */ - function _removeShare(&$share) - { - $share_id = $share->getName(); - - $result = $share->delete(); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - } - - /** - * Checks if a share exists in the system. - * - * @param string $share The share to check. - * - * @return boolean True if the share exists. - */ - function _exists($object) - { - if (empty($object)) { - return false; - } - - /** Get the corresponding folder for this share ID */ - $folder = $this->_list->getByShare($object, $this->_type); - if (is_a($folder, 'PEAR_Error')) { - return $folder; - } - - return $folder->exists(); - } - - /** - * Create a default share for the current app - * - * @return string The share ID of the new default share. - */ - function getDefaultShare() - { - $default = $this->_list->getDefault($this->_type); - if (is_a($default, 'PEAR_Error')) { - return $default; - } - if ($default !== false) { - return $this->getShare($default->getShareId()); - } - - /** Okay, no default folder yet */ - $share = $this->newShare(Horde_Auth::getAuth()); - if (is_a($share, 'PEAR_Error')) { - return $share; - } - /** The value does not matter here as the share will rewrite it */ - $share->set('name', ''); - $result = $this->addShare($share); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - return $share; - } -} - -/** - * Extension of the Horde_Share_Object class for handling Kolab share - * information. - * - * @author Stuart Binge - * @author Gunnar Wrobel - * @package Horde_Share - */ -class Horde_Share_Object_kolab extends Horde_Share_Object { - - /** - * The Kolab folder this share is based on. - * - * @var Kolab_Folder - */ - var $_folder; - - /** - * The Kolab folder name. - * - * @var string - */ - var $_folder_name; - - /** - * A cache for the share attributes. - * - * @var array - */ - var $_data; - - /** - * Our Kolab folder list handler - * - * @var Kolab_List - */ - var $_list; - - /** - * The session handler. - * - * @var Horde_Kolab_Session - */ - private $_session; - - /** - * Constructor. - * - * Sets the folder name. - * - * @param string $id The share id. - */ - function Horde_Share_Object_kolab($id, $type) - { - // We actually ignore the random id string that all horde apps provide - // as initial name and wait for a set('name', 'xyz') call. But we want - // to know if we should create a default share. - if ($id == Horde_Auth::getAuth()) { - $this->_data['default'] = true; - } else { - $this->_data['default'] = false; - } - $this->_type = $type; - $this->__wakeup(); - } - - /** - * Associates a Share object with this share. - * - * @param Horde_Share $shareOb The Share object. - */ - function setShareOb(&$shareOb) - { - /** Ignore the parent as we don't need it */ - } - - /** - * Initializes the object. - */ - function __wakeup() - { - $this->_list = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage'); - if (isset($this->_folder_name)) { - $this->_folder = $this->_list->getFolder($this->_folder_name); - } - } - - /** - * Returns the properties that need to be serialized. - * - * @return array List of serializable properties. - */ - function __sleep() - { - $properties = get_object_vars($this); - unset($properties['_shareOb'], $properties['_list'], - $properties['_folder']); - $properties = array_keys($properties); - return $properties; - } - - /** - * Returns the default share name for the current application. - * - * @return string The default share name. - */ - function getDefaultShareName() - { - switch ($this->_type) { - case 'contact': - return _("Contacts"); - case 'note': - return _("Notes"); - case 'event': - return _("Calendar"); - case 'task': - return _("Tasks"); - case 'filter': - return _("Filters"); - case 'h-prefs': - return _("Preferences"); - } - } - - /** - * Sets the folder for this storage object. - * - * @param string $folder Name of the Kolab folder. - * @param array $perms The permissions of the folder if they are known. - */ - function setFolder(&$folder) - { - if (!isset($this->_folder)) { - $this->_folder = &$folder; - $this->_folder_name = $folder->name; - } else { - return PEAR::raiseError(_("The share has already been initialized!")); - } - } - - /** - * Returns the ID of this share. - * - * @return string The share's ID. - */ - function _getId() - { - return $this->_folder->getShareId(); - } - - /** - * Returns the name of this share. - * - * @return string The share's name. - */ - function _getName() - { - return $this->_folder->getShareId(); - } - - /** - * Returns an attribute value from this object. - * - * @param string $attribute The attribute to return. - * - * @return mixed The value for $attribute. - */ - function _get($attribute) - { - if (isset($this->_data[$attribute])) { - return $this->_data[$attribute]; - } - - if (!isset($this->_folder)) { - return $this->_folderError(); - } - - switch ($attribute) { - case 'owner': - $this->_data['owner'] = $this->_folder->getOwner(); - break; - - case 'name': - $this->_data['name'] = $this->_folder->getTitle(); - break; - - case 'type': - $this->_data['type'] = $this->_folder->getType(); - break; - - case 'params': - $params = @unserialize($this->_folder->getAttribute('params')); - $default = array('source' => 'kolab', - 'default' => $this->get('default'), - 'name' => $this->get('name')); - $type = $this->get('type'); - if (!is_a($type, 'PEAR_Error') && $type == 'event') { - $default = array_merge($default, array( - 'fbrelevance' => $this->_folder->getFbrelevance(), - 'xfbaccess' => $this->_folder->getXfbaccess() - )); - } - if (is_a($params, 'PEAR_Error') || $params == '') { - $params = $default; - } - $this->_data['params'] = serialize(array_merge($default, $params)); - break; - - case 'default': - $this->_data['default'] = $this->_folder->isDefault(); - break; - - default: - $annotation = $this->_folder->getAttribute($attribute); - if (is_a($annotation, 'PEAR_Error') || empty($annotation)) { - $annotation = ''; - } - $this->_data[$attribute] = $annotation; - break; - } - - return $this->_data[$attribute]; - } - - /** - * Sets an attribute value in this object. - * - * @param string $attribute The attribute to set. - * @param mixed $value The value for $attribute. - * - * @return mixed True if setting the attribute did succeed, a PEAR_Error - * otherwise. - */ - function _set($attribute, $value) - { - switch ($attribute) { - case 'name': - /* On folder creation of default shares we wish to ignore - * the names provided by the Horde applications. We use - * the Kolab default names. */ - if (!isset($this->_folder)) { - if ($this->get('default')) { - $value = $this->getDefaultShareName(); - } - $this->setFolder($this->_list->getNewFolder()); - } - $this->_folder->setName($value); - $this->_data['name'] = $this->_folder->getTitle(); - break; - - case 'params': - $value = unserialize($value); - if (isset($value['default'])) { - $this->_data['default'] = $value['default']; - unset($value['default']); - } - $value = serialize($value); - - default: - $this->_data[$attribute] = $value; - } - } - - /** - * Saves the current attribute values. - */ - function _save() - { - if (!isset($this->_folder)) { - return $this->_folderError(); - } - - $data = $this->_data; - /** The name is handled immediately when set */ - unset($data['name']); - $data['type'] = $this->_type; - - $result = $this->_folder->save($data); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - /** The name may have changed */ - $this->_data['name'] = $this->_folder->getTitle(); - $this->_folder_name = $this->_folder->name; - return true; - } - - /** - * Delete this share. - * - * @return boolean|PEAR_Error True on success. - */ - function delete() - { - if (!isset($this->_folder)) { - return $this->_folderError(); - } - return $this->_folder->delete(); - } - - /** - * Checks to see if a user has a given permission. - * - * @param string $userid The userid of the user. - * @param integer $permission A Horde_Perms::* constant to test for. - * @param string $creator The creator of the shared object. - * - * @return boolean|PEAR_Error Whether or not $userid has $permission. - */ - function hasPermission($userid, $permission, $creator = null) - { - if (!isset($this->_folder)) { - return $this->_folderError(); - } - return $this->_folder->hasPermission($userid, $permission, $creator); - } - - /** - * Returns the permissions from this storage object. - * - * @return Horde_Perms_Permission_Kolab|PEAR_Error The permissions on the share. - */ - function &getPermission() - { - if (!isset($this->_folder)) { - return $this->_folderError(); - } - return $this->_folder->getPermission(); - } - - /** - * Sets the permissions on the share. - * - * @param Horde_Perms_Permission_Kolab $perms Permission object to folder on the - * object. - * @param boolean $update Save the updated information? - * - * @return boolean|PEAR_Error True on success. - */ - function setPermission(&$perms, $update = true) - { - if (!isset($this->_folder)) { - return $this->_folderError(); - } - return $this->_folder->setPermission($perms, $update); - } - - /** - * Return a standard error in case the share has not been - * correctly initialized. - * - * @return PEAR_Error The PEAR_Error to return. - */ - function _folderError() - { - return PEAR::raiseError(_("The Kolab share object has not been initialized yet!")); - } -} diff --git a/framework/Share/Share.php b/framework/Share/lib/Horde/Share.php similarity index 51% rename from framework/Share/Share.php rename to framework/Share/lib/Horde/Share.php index d30cb903c..d838fb5ce 100644 --- a/framework/Share/Share.php +++ b/framework/Share/lib/Horde/Share.php @@ -17,21 +17,21 @@ * @author Gunnar Wrobel * @package Horde_Share */ -class Horde_Share { - +class Horde_Share +{ /** * The application we're managing shares for. * * @var string */ - var $_app; + protected $_app; /** * The root of the Share tree. * * @var mixed */ - var $_root = null; + protected $_root = null; /** * A cache of all shares that have been retrieved, so we don't hit the @@ -39,21 +39,21 @@ class Horde_Share { * * @var array */ - var $_cache = array(); + protected $_cache = array(); /** * Id-name-map of already cached share objects. * * @var array */ - var $_shareMap = array(); + protected $_shareMap = array(); /** * Cache used for listShares(). * * @var array */ - var $_listcache = array(); + protected $_listcache = array(); /** * A list of objects that we're currently sorting, for reference during the @@ -61,7 +61,15 @@ class Horde_Share { * * @var array */ - var $_sortList; + protected $_sortList; + + /** + * The Horde_Share_Object subclass to instantiate objects as + * + * @var string + */ + protected $_shareObject; + /** * Attempts to return a reference to a concrete Horde_Share instance. @@ -124,7 +132,7 @@ class Horde_Share { * * @param string $app The application that the shares belong to. */ - function Horde_Share($app) + public function __construct($app) { $this->_app = $app; $this->__wakeup(); @@ -135,7 +143,7 @@ class Horde_Share { * * @throws Horde_Exception */ - function __wakeup() + public function __wakeup() { try { Horde::callHook('share_init', array($this, $this->_app)); @@ -147,7 +155,7 @@ class Horde_Share { * * @return array List of serializable properties. */ - function __sleep() + public function __sleep() { $properties = get_object_vars($this); unset($properties['_sortList']); @@ -158,7 +166,7 @@ class Horde_Share { /** * Stores the object in the session cache. */ - function shutdown() + public function shutdown() { $driver = str_replace('horde_share_', '', Horde_String::lower(get_class($this))); $session = new Horde_SessionObjects(); @@ -170,7 +178,7 @@ class Horde_Share { * * @return string The application this share belongs to. */ - function getApp() + public function getApp() { return $this->_app; } @@ -183,16 +191,13 @@ class Horde_Share { * * @return Horde_Share_Object The requested share. */ - function getShare($name) + public function getShare($name) { if (isset($this->_cache[$name])) { return $this->_cache[$name]; } $share = $this->_getShare($name); - if (is_a($share, 'PEAR_Error')) { - return $share; - } $share->setShareOb($this); $this->_shareMap[$share->getId()] = $name; $this->_cache[$name] = $share; @@ -208,13 +213,10 @@ class Horde_Share { * * @return Horde_Share_Object The requested share. */ - function getShareById($cid) + public function getShareById($cid) { if (!isset($this->_shareMap[$cid])) { $share = $this->_getShareById($cid); - if (is_a($share, 'PEAR_Error')) { - return $share; - } $share->setShareOb($this); $name = $share->getName(); $this->_cache[$name] = $share; @@ -232,7 +234,7 @@ class Horde_Share { * * @return array The requested shares. */ - function getShares($cids) + public function getShares($cids) { $all_shares = array(); $missing_ids = array(); @@ -246,10 +248,6 @@ class Horde_Share { if (count($missing_ids)) { $shares = $this->_getShares($missing_ids); - if (is_a($shares, 'PEAR_Error')) { - return $shares; - } - foreach (array_keys($shares) as $key) { $this->_cache[$key] = $shares[$key]; $this->_cache[$key]->setShareOb($this); @@ -270,13 +268,9 @@ class Horde_Share { * * @return array All shares for the current app/share. */ - function listAllShares() + public function listAllShares() { $shares = $this->_listAllShares(); - if (is_a($shares, 'PEAR_Error') || !count($shares)) { - return $shares; - } - $this->_sortList = $shares; uasort($shares, array($this, '_sortShares')); $this->_sortList = null; @@ -296,7 +290,7 @@ class Horde_Share { * * @return array The shares the user has access to. */ - function listShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, + public function listShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, $from = 0, $count = 0, $sort_by = null, $direction = 0) { $shares = $this->_listShares($userid, $perm, $attributes, $from, @@ -304,16 +298,8 @@ class Horde_Share { if (!count($shares)) { return $shares; } - if (is_a($shares, 'PEAR_Error')) { - return $shares; - } - /* Make sure getShares() didn't return an error. */ $shares = $this->getShares($shares); - if (is_a($shares, 'PEAR_Error')) { - return $shares; - } - if (is_null($sort_by)) { $this->_sortList = $shares; uasort($shares, array($this, '_sortShares')); @@ -332,7 +318,7 @@ class Horde_Share { * * @return array All system shares. */ - function listSystemShares() + public function listSystemShares() { return array(); } @@ -349,7 +335,7 @@ class Horde_Share { * * @return integer The number of shares */ - function countShares($userid, $perm = Horde_Perms::SHOW, $attributes = null) + public function countShares($userid, $perm = Horde_Perms::SHOW, $attributes = null) { return $this->_countShares($userid, $perm, $attributes); } @@ -360,11 +346,12 @@ class Horde_Share { * @param string $name The share's name. * * @return Horde_Share_Object A new share object. + * @throws Horde_Share_Exception */ - function newShare($name) + public function newShare($name) { if (empty($name)) { - return PEAR::raiseError('Share names must be non-empty'); + throw new Horde_Share_Exception('Share names must be non-empty'); } $share = $this->_newShare($name); $share->setShareOb($this); @@ -380,12 +367,14 @@ class Horde_Share { * any initial details added to it, before this function is called. * * @param Horde_Share_Object $share The new share object. - * @throws Horde_Exception + * + * @return boolean + * @throws Horde_Share_Exception */ - function addShare($share) + public function addShare($share) { if (!is_a($share, 'Horde_Share_Object')) { - return PEAR::raiseError('Shares must be Horde_Share_Object objects or extend that class.'); + throw new Horde_Share_Exception('Shares must be Horde_Share_Object objects or extend that class.'); } try { @@ -393,9 +382,6 @@ class Horde_Share { } catch (Horde_Exception_HookNotSet $e) {} $result = $this->_addShare($share); - if (is_a($result, 'PEAR_Error')) { - return $result; - } /* Store new share in the caches. */ $id = $share->getId(); @@ -414,12 +400,12 @@ class Horde_Share { * * @param Horde_Share_Object $share The share to remove. * - * @throws Horde_Exception + * @throws Horde_Share_Exception */ - function removeShare($share) + public function removeShare($share) { if (!is_a($share, 'Horde_Share_Object')) { - return PEAR::raiseError('Shares must be Horde_Share_Object objects or extend that class.'); + throw new Horde_Share_Exception('Shares must be Horde_Share_Object objects or extend that class.'); } try { @@ -444,7 +430,7 @@ class Horde_Share { * * @return boolean True if the share exists. */ - function exists($share) + public function exists($share) { if (isset($this->_cache[$share])) { return true; @@ -467,19 +453,10 @@ class Horde_Share { * permission type and whether the permission value is * ambiguous. False if there is no such permsission. */ - function getPermissions($share, $user = null) + public function getPermissions($share, $user = null) { - if (is_a($share, 'PEAR_Error')) { - Horde::logMessage($share, 'ERR'); - return false; - } - if (!is_a($share, 'Horde_Share_Object')) { $share = $this->getShare($share); - if (is_a($share, 'PEAR_Error')) { - Horde::logMessage($share, 'ERR'); - return false; - } } $perm = $share->getPermission(); @@ -496,19 +473,27 @@ class Horde_Share { * * @return Identity An Identity instance. */ - function getIdentityByShare($share) + public function getIdentityByShare($share) { if (!is_a($share, 'Horde_Share_Object')) { $share = $this->getShare($share); - if (is_a($share, 'PEAR_Error')) { - return null; - } } + // TODO: Need to inject this into this method instead of using injector return $GLOBALS['injector']->getInstance('Horde_Prefs_Identity')->getIdentity($share->get('owner')); } /** + * Set the class type to use for creating share objects. + * + * @var string $classname The classname to use. + */ + public function setShareClass($classname) + { + $this->_shareObject = $classname; + } + + /** * Utility function to be used with uasort() for sorting arrays of * Horde_Share objects. * @@ -519,7 +504,7 @@ class Horde_Share { * * @access protected */ - function _sortShares($a, $b) + protected function _sortShares($a, $b) { $aParts = explode(':', $a->getName()); $bParts = explode(':', $b->getName()); @@ -546,363 +531,3 @@ class Horde_Share { } } - -/** - * Abstract class for storing Share information. - * - * This class should be extended for the more specific drivers. - * - * @author Mike Cochrane - * @author Jan Schneider - * @author Gunnar Wrobel - * @package Horde_Share - */ -class Horde_Share_Object { - - /** - * The Horde_Share object which this share came from - needed for updating - * data in the backend to make changes stick, etc. - * - * @var Horde_Share - */ - var $_shareOb; - - /** - * Returns the properties that need to be serialized. - * - * @return array List of serializable properties. - */ - function __sleep() - { - $properties = get_object_vars($this); - unset($properties['_shareOb']); - $properties = array_keys($properties); - return $properties; - } - - /** - * Associates a Share object with this share. - * - * @param Horde_Share $shareOb The Share object. - */ - function setShareOb($shareOb) - { - if (!is_a($shareOb, 'Horde_Share')) { - return PEAR::raiseError('This object needs a Horde_Share instance as storage handler!'); - } - $this->_shareOb = $shareOb; - } - - /** - * Sets an attribute value in this object. - * - * @param string $attribute The attribute to set. - * @param mixed $value The value for $attribute. - * - * @return mixed True if setting the attribute did succeed, a PEAR_Error - * otherwise. - */ - function set($attribute, $value) - { - return $this->_set($attribute, $value); - } - - /** - * Returns an attribute value from this object. - * - * @param string $attribute The attribute to return. - * - * @return mixed The value for $attribute. - */ - function get($attribute) - { - return $this->_get($attribute); - } - - /** - * Returns the ID of this share. - * - * @return string The share's ID. - */ - function getId() - { - return $this->_getId(); - } - - /** - * Returns the name of this share. - * - * @return string The share's name. - */ - function getName() - { - return $this->_getName(); - } - - /** - * Saves the current attribute values. - * - * @throws Horde_Exception - */ - function save() - { - try { - Horde::callHook('share_modify', array($this)); - } catch (Horde_Exception_HookNotSet $e) {} - - return $this->_save(); - } - - /** - * Gives a user a certain privilege for this share. - * - * @param string $userid The userid of the user. - * @param integer $permission A Horde_Perms::* constant. - */ - function addUserPermission($userid, $permission) - { - $perm = $this->getPermission(); - $perm->addUserPermission($userid, $permission, false); - $this->setPermission($perm); - } - - /** - * Removes a certain privilege for a user from this share. - * - * @param string $userid The userid of the user. - * @param integer $permission A Horde_Perms::* constant. - */ - function removeUserPermission($userid, $permission) - { - $perm = $this->getPermission(); - $perm->removeUserPermission($userid, $permission, false); - $this->setPermission($perm); - } - - /** - * Gives a group certain privileges for this share. - * - * @param string $group The group to add permissions for. - * @param integer $permission A Horde_Perms::* constant. - */ - function addGroupPermission($group, $permission) - { - $perm = $this->getPermission(); - $perm->addGroupPermission($group, $permission, false); - $this->setPermission($perm); - } - - /** - * Removes a certain privilege from a group. - * - * @param string $group The group to remove permissions from. - * @param constant $permission A Horde_Perms::* constant. - */ - function removeGroupPermission($group, $permission) - { - $perm = $this->getPermission(); - $perm->removeGroupPermission($group, $permission, false); - $this->setPermission($perm); - } - - /** - * Removes a user from this share. - * - * @param string $userid The userid of the user to remove. - */ - function removeUser($userid) - { - /* Remove all $userid's permissions. */ - $perm = $this->getPermission(); - $perm->removeUserPermission($userid, Horde_Perms::SHOW, false); - $perm->removeUserPermission($userid, Horde_Perms::READ, false); - $perm->removeUserPermission($userid, Horde_Perms::EDIT, false); - $perm->removeUserPermission($userid, Horde_Perms::DELETE, false); - return $this->setPermission($perm); - } - - /** - * Removes a group from this share. - * - * @param integer $groupId The group to remove. - */ - function removeGroup($groupId) - { - /* Remove all $groupId's permissions. */ - $perm = $this->getPermission(); - $perm->removeGroupPermission($groupId, Horde_Perms::SHOW, false); - $perm->removeGroupPermission($groupId, Horde_Perms::READ, false); - $perm->removeGroupPermission($groupId, Horde_Perms::EDIT, false); - $perm->removeGroupPermission($groupId, Horde_Perms::DELETE, false); - return $this->setPermission($perm); - } - - /** - * Returns an array containing all the userids of the users with access to - * this share. - * - * @param integer $perm_level List only users with this permission level. - * Defaults to all users. - * - * @return array The users with access to this share. - */ - function listUsers($perm_level = null) - { - $perm = $this->getPermission(); - $results = array_keys($perm->getUserPermissions($perm_level)); - // Always return the share's owner. - if ($this->get('owner')) { - array_push($results, $this->get('owner')); - } - return $results; - } - - /** - * Returns an array containing all the groupids of the groups with access - * to this share. - * - * @param integer $perm_level List only users with this permission level. - * Defaults to all users. - * - * @return array The IDs of the groups with access to this share. - */ - function listGroups($perm_level = null) - { - $perm = $this->getPermission(); - return array_keys($perm->getGroupPermissions($perm_level)); - } - - /** - * Locks an item from this share, or the entire share if no item defined. - * - * @param string $item_uid A uid of an item from this share. - * - * @return mixed A lock ID on success, PEAR_Error on failure, false if: - * - The share is already locked - * - The item is already locked - * - A share lock was requested and an item is already - * locked in the share - */ - function lock($item_uid = null) - { - try { - $locks = $GLOBALS['injector']->getInstance('Horde_Lock'); - } catch (Horde_Lock_Exception $e) { - Horde::logMessage($e, 'ERR'); - return PEAR::raiseError($e->getMessage()); - } - - $shareid = $this->getId(); - - // Default parameters. - $locktype = Horde_Lock::TYPE_EXCLUSIVE; - $timeout = 600; - $itemscope = $this->_shareOb->getApp() . ':' . $shareid; - - if (!empty($item_uid)) { - // Check if the share is locked. Share locks are placed at app - // scope. - try { - - $result = $locks->getLocks($this->_shareOb->getApp(), $shareid, $locktype); - } catch (Horde_Lock_Exception $e) { - return PEAR::raiseError($e->getMessage); - } - if (!empty($result)) { - // Lock found. - return false; - } - // Try to place the item lock at app:shareid scope. - return $locks->setLock(Horde_Auth::getAuth(), $itemscope, $item_uid, - $timeout, $locktype); - } else { - // Share lock requested. Check for locked items. - try { - $result = $locks->getLocks($itemscope, null, $locktype); - } catch (Horde_Lock_Exception $e) { - return PEAR::raiseError($e->getException); - } - if (!empty($result)) { - // Lock found. - return false; - } - // Try to place the share lock - return $locks->setLock(Horde_Auth::getAuth(), $this->_shareOb->getApp(), - $shareid, $timeout, $locktype); - } - } - - /** - * Removes the lock for a lock ID. - * - * @param string $lockid The lock ID as generated by a previous call - * to lock(). - * - * @return mixed True on success, PEAR_Error on failure. - */ - function unlock($lockid) - { - try { - $locks = $GLOBALS['injector']->getInstance('Horde_Lock'); - } catch (Horde_Lock_Exception $e) { - Horde::logMessage($e, 'ERR'); - return PEAR::raiseError($e->getMessage()); - } - - return $locks->clearLock($lockid); - } - - /** - * Checks for existing locks. - * - * First this checks for share locks and if none exists, checks for item - * locks (if item_uid defined). It will return the first lock found. - * - * @param string $item_uid A uid of an item from this share. - * - * @return mixed Hash with the found lock information in 'lock' and the - * lock type ('share' or 'item') in 'type', or an empty - * array if there are no locks, or a PEAR_Error on failure. - */ - function checkLocks($item_uid = null) - { - try { - $locks = $GLOBALS['injector']->getInstance('Horde_Lock'); - } catch (Horde_Lock_Exception $e) { - Horde::logMessage($e, 'ERR'); - return PEAR::raiseError($e->getMessage()); - } - - $shareid = $this->getId(); - $locktype = Horde_Lock::TYPE_EXCLUSIVE; - - // Check for share locks - try { - $result = $locks->getLocks($this->_shareOb->getApp(), $shareid, $locktype); - } catch (Horde_Lock_Exception $e) { - Horde::logMessage($e, 'ERR'); - return PEAR::raiseError($e->getMessage()); - } - - if (empty($result) && !empty($item_uid)) { - // Check for item locks - $locktargettype = 'item'; - try { - $result = $locks->getLocks($this->_shareOb->getApp() . ':' . $shareid, $item_uid, $locktype); - } catch (Horde_Lock_Exception $e) { - Horde::logMessage($e, 'ERR'); - return PEAR::raiseError($e->getMessage()); - } - } else { - $locktargettype = 'share'; - } - - if (empty($result)) { - return array(); - } - - return array('type' => $locktargettype, - 'lock' => reset($result)); - } - -} diff --git a/framework/Share/Share/datatree.php b/framework/Share/lib/Horde/Share/Datatree.php similarity index 55% rename from framework/Share/Share/datatree.php rename to framework/Share/lib/Horde/Share/Datatree.php index 282366d9e..ccebe21da 100644 --- a/framework/Share/Share/datatree.php +++ b/framework/Share/lib/Horde/Share/Datatree.php @@ -19,29 +19,30 @@ require_once 'Horde/DataTree.php'; * @author Gunnar Wrobel * @package Horde_Share */ -class Horde_Share_datatree extends Horde_Share { - +class Horde_Share_Datatree extends Horde_Share +{ /** * The Horde_Share_Object subclass to instantiate objects as * * @var string */ - var $_shareObject = 'Horde_Share_Object_datatree'; + protected $_shareObject = 'Horde_Share_Object_Datatree'; /** * Pointer to a DataTree instance to manage/store shares * * @var DataTree */ - var $_datatree; + protected $_datatree; /** * Initializes the object. * * @throws Horde_Exception */ - function __wakeup() + public function __wakeup() { + // TODO: Remove GLOBAL config access if (empty($GLOBALS['conf']['datatree']['driver'])) { throw new Horde_Exception('You must configure a DataTree backend to use Shares.'); } @@ -70,14 +71,16 @@ class Horde_Share_datatree extends Horde_Share { * @param string $name The name of the share to retrieve. * * @return Horde_Share_Object_datatree The requested share. + * @throws Horde_Share_Exception */ - function &_getShare($name) + public function _getShare($name) { $datatreeObject = $this->_datatree->getObject($name, 'DataTreeObject_Share'); - if (is_a($datatreeObject, 'PEAR_Error')) { - return $datatreeObject; + if ($datatreeObject instanceof PEAR_Error) { + throw new Horde_Share_Exception($datatreeObject->getMessage()); } $share = new $this->_shareObject($datatreeObject); + return $share; } @@ -88,14 +91,16 @@ class Horde_Share_datatree extends Horde_Share { * @param string $cid The id of the share to retrieve. * * @return Horde_Share_Object_datatree The requested share. + * @throws Horde_Share_Exception */ - function &_getShareById($id) + protected function _getShareById($id) { $datatreeObject = $this->_datatree->getObjectById($id, 'DataTreeObject_Share'); if (is_a($datatreeObject, 'PEAR_Error')) { - return $datatreeObject; + throw new Horde_Share_Exception($datatreeObject->getMessage()); } $share = new $this->_shareObject($datatreeObject); + return $share; } @@ -107,13 +112,14 @@ class Horde_Share_datatree extends Horde_Share { * @param array $cids The array of ids to retrieve. * * @return array The requested shares. + * @throws Horde_Share_Exception */ - function &_getShares($ids) + protected function _getShares($ids) { $shares = array(); $objects = &$this->_datatree->getObjects($ids, 'DataTreeObject_Share'); if (is_a($objects, 'PEAR_Error')) { - return $objects; + throw new Horde_Share_Exception($objects->getMessage()); } foreach (array_keys($objects) as $key) { if (is_a($objects[$key], 'PEAR_Error')) { @@ -129,13 +135,15 @@ class Horde_Share_datatree extends Horde_Share { * permissions. * * @return array All shares for the current app/share. + * @throws Horde_Share_Exception */ - function &_listAllShares() + function _listAllShares() { - $sharelist = $this->_datatree->get(DATATREE_FORMAT_FLAT, DATATREE_ROOT, - true); - if (is_a($sharelist, 'PEAR_Error') || !count($sharelist)) { - // If we got back an error or an empty array, just return it. + $sharelist = $this->_datatree->get(DATATREE_FORMAT_FLAT, DATATREE_ROOT, true); + if ($sharelist instanceof PEAR_Error) { + throw new Horde_Share_Exception($sharelist->getMessage()); + } + if (!count($sharelist)) { return $sharelist; } unset($sharelist[DATATREE_ROOT]); @@ -154,21 +162,22 @@ class Horde_Share_datatree extends Horde_Share { * username. * * @return array The shares the user has access to. + * @throws Horde_Share_Exception */ - function &_listShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null, $from = 0, $count = 0, - $sort_by = null, $direction = 0) + function _listShares($userid, $perm = Horde_Perms::SHOW, + $attributes = null, $from = 0, $count = 0, + $sort_by = null, $direction = 0) { $key = serialize(array($userid, $perm, $attributes)); if (empty($this->_listCache[$key])) { - $criteria = $this->_getShareCriteria($userid, $perm, $attributes); + $criteria = $this->getShareCriteria($userid, $perm, $attributes); $sharelist = $this->_datatree->getByAttributes($criteria, DATATREE_ROOT, true, 'id', $from, $count, $sort_by, null, $direction); - if (is_a($sharelist, 'PEAR_Error')) { - return $sharelist; + if ($sharelist instanceof PEAR_Error) { + throw new Horde_Share_Exception($sharelist->getMessage()); } $this->_listCache[$key] = array_keys($sharelist); } @@ -188,10 +197,10 @@ class Horde_Share_datatree extends Horde_Share { * * @return integer The number of shares */ - function _countShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null) + protected function _countShares($userid, $perm = Horde_Perms::SHOW, + $attributes = null) { - $criteria = $this->_getShareCriteria($userid, $perm, $attributes); + $criteria = $this->getShareCriteria($userid, $perm, $attributes); return $this->_datatree->countByAttributes($criteria, DATATREE_ROOT, true, 'id'); } @@ -202,11 +211,12 @@ class Horde_Share_datatree extends Horde_Share { * * @return Horde_Share_Object_datatree A new share object. */ - function &_newShare($name) + protected function &_newShare($name) { - $datatreeObject = new DataTreeObject_Share($name); + $datatreeObject = new Horde_Share_Object_DataTree_Share($name); $datatreeObject->setDataTree($this->_datatree); $share = new $this->_shareObject($datatreeObject); + return $share; } @@ -219,7 +229,7 @@ class Horde_Share_datatree extends Horde_Share { * * @param Horde_Share_Object_datatree $share The new share object. */ - function _addShare(&$share) + protected function _addShare(&$share) { return $this->_datatree->add($share->datatreeObject); } @@ -229,7 +239,7 @@ class Horde_Share_datatree extends Horde_Share { * * @param Horde_Share_Object_datatree $share The share to remove. */ - function _removeShare(&$share) + protected function _removeShare(&$share) { return $this->_datatree->remove($share->datatreeObject); } @@ -241,7 +251,7 @@ class Horde_Share_datatree extends Horde_Share { * * @return boolean True if the share exists. */ - function _exists($share) + protected function _exists($share) { return $this->_datatree->exists($share); } @@ -257,8 +267,8 @@ class Horde_Share_datatree extends Horde_Share { * * @return array The criteria tree for fetching this user's shares. */ - function _getShareCriteria($userid, $perm = Horde_Perms::SHOW, - $attributes = null) + public function getShareCriteria($userid, $perm = Horde_Perms::SHOW, + $attributes = null) { if (!empty($userid)) { $criteria = array( @@ -289,10 +299,11 @@ class Horde_Share_datatree extends Horde_Share { array('field' => 'value', 'op' => '&', 'test' => $perm))))); // If the user has any group memberships, check for those also. + // @TODO: inject require_once 'Horde/Group.php'; $group = &Group::singleton(); $groups = $group->getGroupMemberships($userid, true); - if (!is_a($groups, 'PEAR_Error') && $groups) { + if (!($groups instanceof PEAR_Error) && $groups) { // (name == perm_groups and key in ($groups) and val & $perm) $criteria['OR'][] = array( 'AND' => array( @@ -335,242 +346,3 @@ class Horde_Share_datatree extends Horde_Share { } } - -/** - * Extension of the Horde_Share_Object class for storing share information in - * the DataTree driver. - * - * @author Mike Cochrane - * @author Jan Schneider - * @author Gunnar Wrobel - * @package Horde_Share - */ -class Horde_Share_Object_datatree extends Horde_Share_Object { - - /** - * The actual storage object that holds the data. - * - * @var mixed - */ - var $datatreeObject; - - /** - * Constructor. - * - * @param DataTreeObject_Share $datatreeObject A DataTreeObject_Share - * instance. - */ - function Horde_Share_Object_datatree($datatreeObject) - { - if (is_a($datatreeObject, 'PEAR_Error')) { - debug_context(); - } - $this->datatreeObject = $datatreeObject; - } - - /** - * Sets an attribute value in this object. - * - * @param string $attribute The attribute to set. - * @param mixed $value The value for $attribute. - * - * @return mixed True if setting the attribute did succeed, a PEAR_Error - * otherwise. - */ - function _set($attribute, $value) - { - return $this->datatreeObject->set($attribute, $value); - } - - /** - * Returns one of the attributes of the object, or null if it isn't - * defined. - * - * @param string $attribute The attribute to retrieve. - * - * @return mixed The value of the attribute, or an empty string. - */ - function _get($attribute) - { - return $this->datatreeObject->get($attribute); - } - - /** - * Returns the ID of this share. - * - * @return string The share's ID. - */ - function _getId() - { - return $this->datatreeObject->getId(); - } - - /** - * Returns the name of this share. - * - * @return string The share's name. - */ - function _getName() - { - return $this->datatreeObject->getName(); - } - - /** - * Saves the current attribute values. - */ - function _save() - { - return $this->datatreeObject->save(); - } - - /** - * Checks to see if a user has a given permission. - * - * @param string $userid The userid of the user. - * @param integer $permission A Horde_Perms::* constant to test for. - * @param string $creator The creator of the event. - * - * @return boolean Whether or not $userid has $permission. - */ - function hasPermission($userid, $permission, $creator = null) - { - if ($userid && $userid == $this->datatreeObject->get('owner')) { - return true; - } - - return $GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission($this->getPermission(), $userid, $permission, $creator); - } - - /** - * Sets the permission of this share. - * - * @param Horde_Perms_Permission $perm Permission object. - * @param boolean $update Should the share be saved - * after this operation? - * - * @return boolean True if no error occured, PEAR_Error otherwise - */ - function setPermission(&$perm, $update = true) - { - $this->datatreeObject->data['perm'] = $perm->getData(); - if ($update) { - return $this->datatreeObject->save(); - } - return true; - } - - /** - * Returns the permission of this share. - * - * @return Horde_Persm_Permission Permission object that represents the - * permissions on this share - */ - function &getPermission() - { - $perm = new Horde_Perms_Permission($this->datatreeObject->getName()); - $perm->data = isset($this->datatreeObject->data['perm']) - ? $this->datatreeObject->data['perm'] - : array(); - - return $perm; - } - -} - -/** - * Extension of the DataTreeObject class for storing Share information in the - * DataTree driver. If you want to store specialized Share information, you - * should extend this class instead of extending DataTreeObject directly. - * - * @author Mike Cochrane - * @author Jan Schneider - * @package Horde_Share - */ -class DataTreeObject_Share extends DataTreeObject { - - /** - * Returns the properties that need to be serialized. - * - * @return array List of serializable properties. - */ - function __sleep() - { - $properties = get_object_vars($this); - unset($properties['datatree']); - $properties = array_keys($properties); - return $properties; - } - - /** - * Maps this object's attributes from the data array into a format that we - * can store in the attributes storage backend. - * - * @access protected - * - * @param boolean $permsonly Only process permissions? Lets subclasses - * override part of this method while handling - * their additional attributes seperately. - * - * @return array The attributes array. - */ - function _toAttributes($permsonly = false) - { - // Default to no attributes. - $attributes = array(); - - foreach ($this->data as $key => $value) { - if ($key == 'perm') { - foreach ($value as $type => $perms) { - if (is_array($perms)) { - foreach ($perms as $member => $perm) { - $attributes[] = array('name' => 'perm_' . $type, - 'key' => $member, - 'value' => $perm); - } - } else { - $attributes[] = array('name' => 'perm_' . $type, - 'key' => '', - 'value' => $perms); - } - } - } elseif (!$permsonly) { - $attributes[] = array('name' => $key, - 'key' => '', - 'value' => $value); - } - } - - return $attributes; - } - - /** - * Takes in a list of attributes from the backend and maps it to our - * internal data array. - * - * @access protected - * - * @param array $attributes The list of attributes from the backend - * (attribute name, key, and value). - * @param boolean $permsonly Only process permissions? Lets subclasses - * override part of this method while handling - * their additional attributes seperately. - */ - function _fromAttributes($attributes, $permsonly = false) - { - // Initialize data array. - $this->data['perm'] = array(); - - foreach ($attributes as $attr) { - if (substr($attr['name'], 0, 4) == 'perm') { - if (!empty($attr['key'])) { - $this->data['perm'][substr($attr['name'], 5)][$attr['key']] = $attr['value']; - } else { - $this->data['perm'][substr($attr['name'], 5)] = $attr['value']; - } - } elseif (!$permsonly) { - $this->data[$attr['name']] = $attr['value']; - } - } - } - -} diff --git a/framework/Share/lib/Horde/Share/Exception.php b/framework/Share/lib/Horde/Share/Exception.php new file mode 100644 index 000000000..88d2525a1 --- /dev/null +++ b/framework/Share/lib/Horde/Share/Exception.php @@ -0,0 +1,9 @@ + + * @author Gunnar Wrobel + * @package Horde_Share + */ +class Horde_Share_kolab extends Horde_Share +{ + /** + * Our Kolab folder list handler + * + * @var Kolab_List + */ + protected $_list; + + /** + * The share type + * + * @var string + */ + protected $_type; + + /** + * A marker for the validity of the list cache + * + * @var int + */ + protected $_listCacheValidity; + + /** + * The session handler. + * + * @var Horde_Kolab_Session + */ + protected $_session; + + /** + * Initializes the object. + * + * @throws Horde_Exception + */ + public function __wakeup() + { + if (empty($GLOBALS['conf']['kolab']['enabled'])) { + throw new Horde_Exception('You must enable the kolab settings to use the Kolab Share driver.'); + } + + $this->_type = $this->_getFolderType($this->_app); + if ($this->_type instanceof PEAR_Error) { + return $this->_type; + } + + $this->_list = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage'); + + parent::__wakeup(); + } + + private function _getFolderType($app) + { + switch ($app) { + case 'mnemo': + return 'note'; + case 'kronolith': + return 'event'; + case 'turba': + return 'contact'; + case 'nag': + return 'task'; + default: + throw new Horde_Share_Exception(sprintf(_("The Horde/Kolab integration engine does not support \"%s\""), $app)); + } + } + + /** + * Returns the properties that need to be serialized. + * + * @return array List of serializable properties. + */ + public function __sleep() + { + $properties = get_object_vars($this); + unset($properties['_sortList'], $properties['_list']); + $properties = array_keys($properties); + return $properties; + } + + /** + * Returns a Horde_Share_Object_kolab object of the request folder. + * + * @param string $object The share to fetch. + * + * @return Horde_Share_Object_kolab The share object. + * @throws Horde_Share_Exception + */ + protected function _getShare($object) + { + if (empty($object)) { + throw new Horde_Share_Exception('No object requested.'); + } + + /** Get the corresponding folder for this share ID */ + $folder = $this->_list->getByShare($object, $this->_type); + + /** Does the folder exist? */ + if (!$folder->exists()) { + throw new Horde_Share_Exception(sprintf(_("Share \"%s\" does not exist."), $object)); + } + + /** Create the object from the folder */ + $share = new Horde_Share_Object_Kolab($object, $this->_type); + $share->setFolder($folder); + + return $share; + } + + /** + * Returns a Horde_Share_Object_kolab object of the requested folder. + * + * @param string $id The id of the share to fetch. + * + * @return Horde_Share_Object_kolab The share object. + */ + protected function &_getShareById($id) + { + return $this->_getShare($id); + } + + /** + * Returns an array of Horde_Share_Object_kolab objects corresponding to + * the requested folders. + * + * @param string $ids The ids of the shares to fetch. + * + * @return array An array of Horde_Share_Object_kolab objects. + */ + protected function &_getShares($ids) + { + $objects = array(); + foreach ($ids as $id) { + $result = &$this->_getShare($id); + if ($result instanceof PEAR_Error) { + return $result; + } + $objects[$id] = &$result; + } + return $objects; + } + + /** + * Lists *all* shares for the current app/share, regardless of + * permissions. + * + * Currently not implemented in this class. + * + * @return array All shares for the current app/share. + */ + protected function &_listAllShares() + { + $shares = array(); + return $shares; + } + + /** + * Returns an array of all shares that $userid has access to. + * + * @param string $userid The userid of the user to check access for. + * @param integer $perm The level of permissions required. + * @param mixed $attributes Restrict the shares counted to those + * matching $attributes. An array of + * attribute/values pairs or a share owner + * username. + * + * @return array The shares the user has access to. + */ + protected function _listShares($userid, $perm = Horde_Perms::SHOW, + $attributes = null, $from = 0, $count = 0, + $sort_by = null, $direction = 0) + { + $key = serialize(array($this->_type, $userid, $perm, $attributes)); + if ($this->_list === false) { + $this->_listCache[$key] = array(); + } else if (empty($this->_listCache[$key]) + || $this->_list->validity != $this->_listCacheValidity) { + $sharelist = $this->_list->getByType($this->_type); + if ($sharelist instanceof PEAR_Error) { + throw new Horde_Share_Exception($sharelist->getMessage()); + } + + $shares = array(); + foreach ($sharelist as $folder) { + $id = $folder->getShareId(); + $share = &$this->getShare($id); + $keep = true; + if (!$share->hasPermission($userid, $perm)) { + $keep = false; + } + if (isset($attributes) && $keep) { + if (is_array($attributes)) { + foreach ($attributes as $key => $value) { + if (!$share->get($key) == $value) { + $keep = false; + break; + } + } + } elseif (!$share->get('owner') == $attributes) { + $keep = false; + } + } + if ($keep) { + $shares[] = $id; + } + } + $this->_listCache[$key] = $shares; + $this->_listCacheValidity = $this->_list->validity; + } + + return $this->_listCache[$key]; + } + + /** + * Returns the number of shares that $userid has access to. + * + * @param string $userid The userid of the user to check access for. + * @param integer $perm The level of permissions required. + * @param mixed $attributes Restrict the shares counted to those + * matching $attributes. An array of + * attribute/values pairs or a share owner + * username. + * + * @return integer The number of shares + */ + protected function _countShares($userid, $perm = Horde_Perms::SHOW, + $attributes = null) + { + $shares = $this->_listShares($userid, $perm, $attributes); + return count($shares); + } + + /** + * Returns a new share object. + * + * @param string $name The share's name. + * + * @return Horde_Share_Object_kolab A new share object. + */ + protected function &_newShare($name) + { + $storageObject = new Horde_Share_Object_Kolab($name, $this->_type); + return $storageObject; + } + + /** + * Adds a share to the shares system. + * + * The share must first be created with Horde_Share_kolab::_newShare(), + * and have any initial details added to it, before this function is + * called. + * + * @param Horde_Share_Object_kolab $share The new share object. + */ + protected function _addShare(&$share) + { + return $share->save(); + } + + /** + * Removes a share from the shares system permanently. + * + * @param Horde_Share_Object_Kolab $share The share to remove. + */ + protected function _removeShare(Horde_Share_Object $share) + { + $share_id = $share->getName(); + $result = $share->delete(); + } + + /** + * Checks if a share exists in the system. + * + * @param string $share The share to check. + * + * @return boolean True if the share exists. + */ + protected function _exists($object) + { + if (empty($object)) { + return false; + } + + /** Get the corresponding folder for this share ID */ + $folder = $this->_list->getByShare($object, $this->_type); + if ($folder instanceof PEAR_Error) { + throw new Horde_Share_Exception($folder->getMessage()); + } + + return $folder->exists(); + } + + /** + * Create a default share for the current app + * + * @return string The share ID of the new default share. + */ + public function getDefaultShare() + { + $default = $this->_list->getDefault($this->_type); + if ($default instanceof PEAR_Error) { + throw new Horde_Share_Exception($default->getMessage()); + } + if ($default !== false) { + return $this->getShare($default->getShareId()); + } + + /** Okay, no default folder yet */ + $share = $this->newShare(Horde_Auth::getAuth()); + + /** The value does not matter here as the share will rewrite it */ + $share->set('name', ''); + $result = $this->addShare($share); + + return $share; + } +} diff --git a/framework/Share/lib/Horde/Share/Object.php b/framework/Share/lib/Horde/Share/Object.php new file mode 100644 index 000000000..d9e94fe00 --- /dev/null +++ b/framework/Share/lib/Horde/Share/Object.php @@ -0,0 +1,367 @@ + + * @author Jan Schneider + * @author Gunnar Wrobel + * @package Horde_Share + */ +class Horde_Share_Object +{ + /** + * The Horde_Share object which this share came from - needed for updating + * data in the backend to make changes stick, etc. + * + * @var Horde_Share + */ + protected $_shareOb; + + /** + * Returns the properties that need to be serialized. + * + * @return array List of serializable properties. + */ + public function __sleep() + { + $properties = get_object_vars($this); + unset($properties['_shareOb']); + $properties = array_keys($properties); + return $properties; + } + + /** + * Associates a Share object with this share. + * + * @param Horde_Share $shareOb The Share object. + */ + public function setShareOb($shareOb) + { + if (!($shareOb instanceof Horde_Share)) { + throw new Horde_Share_Exception('This object needs a Horde_Share instance as storage handler!'); + } + $this->_shareOb = $shareOb; + } + + /** + * Sets an attribute value in this object. + * + * @param string $attribute The attribute to set. + * @param mixed $value The value for $attribute. + * + * @return mixed True if setting the attribute did succeed, a PEAR_Error + * otherwise. + */ + public function set($attribute, $value) + { + return $this->_set($attribute, $value); + } + + /** + * Returns an attribute value from this object. + * + * @param string $attribute The attribute to return. + * + * @return mixed The value for $attribute. + */ + public function get($attribute) + { + return $this->_get($attribute); + } + + /** + * Returns the ID of this share. + * + * @return string The share's ID. + */ + public function getId() + { + return $this->_getId(); + } + + /** + * Returns the name of this share. + * + * @return string The share's name. + */ + public function getName() + { + return $this->_getName(); + } + + /** + * Saves the current attribute values. + * + * @return boolean + * @throws Horde_Exception + */ + public function save() + { + try { + Horde::callHook('share_modify', array($this)); + } catch (Horde_Exception_HookNotSet $e) {} + + return $this->_save(); + } + + /** + * Gives a user a certain privilege for this share. + * + * @param string $userid The userid of the user. + * @param integer $permission A Horde_Perms::* constant. + */ + public function addUserPermission($userid, $permission) + { + $perm = $this->getPermission(); + $perm->addUserPermission($userid, $permission, false); + $this->setPermission($perm); + } + + /** + * Removes a certain privilege for a user from this share. + * + * @param string $userid The userid of the user. + * @param integer $permission A Horde_Perms::* constant. + */ + public function removeUserPermission($userid, $permission) + { + $perm = $this->getPermission(); + $perm->removeUserPermission($userid, $permission, false); + $this->setPermission($perm); + } + + /** + * Gives a group certain privileges for this share. + * + * @param string $group The group to add permissions for. + * @param integer $permission A Horde_Perms::* constant. + */ + public function addGroupPermission($group, $permission) + { + $perm = $this->getPermission(); + $perm->addGroupPermission($group, $permission, false); + $this->setPermission($perm); + } + + /** + * Removes a certain privilege from a group. + * + * @param string $group The group to remove permissions from. + * @param constant $permission A Horde_Perms::* constant. + */ + public function removeGroupPermission($group, $permission) + { + $perm = $this->getPermission(); + $perm->removeGroupPermission($group, $permission, false); + $this->setPermission($perm); + } + + /** + * Removes a user from this share. + * + * @param string $userid The userid of the user to remove. + */ + public function removeUser($userid) + { + /* Remove all $userid's permissions. */ + $perm = $this->getPermission(); + $perm->removeUserPermission($userid, Horde_Perms::SHOW, false); + $perm->removeUserPermission($userid, Horde_Perms::READ, false); + $perm->removeUserPermission($userid, Horde_Perms::EDIT, false); + $perm->removeUserPermission($userid, Horde_Perms::DELETE, false); + + return $this->setPermission($perm); + } + + /** + * Removes a group from this share. + * + * @param integer $groupId The group to remove. + */ + public function removeGroup($groupId) + { + /* Remove all $groupId's permissions. */ + $perm = $this->getPermission(); + $perm->removeGroupPermission($groupId, Horde_Perms::SHOW, false); + $perm->removeGroupPermission($groupId, Horde_Perms::READ, false); + $perm->removeGroupPermission($groupId, Horde_Perms::EDIT, false); + $perm->removeGroupPermission($groupId, Horde_Perms::DELETE, false); + + return $this->setPermission($perm); + } + + /** + * Returns an array containing all the userids of the users with access to + * this share. + * + * @param integer $perm_level List only users with this permission level. + * Defaults to all users. + * + * @return array The users with access to this share. + */ + public function listUsers($perm_level = null) + { + $perm = $this->getPermission(); + $results = array_keys($perm->getUserPermissions($perm_level)); + // Always return the share's owner. + if ($this->get('owner')) { + array_push($results, $this->get('owner')); + } + return $results; + } + + /** + * Returns an array containing all the groupids of the groups with access + * to this share. + * + * @param integer $perm_level List only users with this permission level. + * Defaults to all users. + * + * @return array The IDs of the groups with access to this share. + */ + public function listGroups($perm_level = null) + { + $perm = $this->getPermission(); + return array_keys($perm->getGroupPermissions($perm_level)); + } + + /** + * Locks an item from this share, or the entire share if no item defined. + * + * @param string $item_uid A uid of an item from this share. + * + * @return mixed A lock ID on success, PEAR_Error on failure, false if: + * - The share is already locked + * - The item is already locked + * - A share lock was requested and an item is already + * locked in the share + * @throws Horde_Share_Exception + */ + public function lock($item_uid = null) + { + try { + // TODO: Pass this in as a parameter, don't use the injector directly in + // a library + $locks = $GLOBALS['injector']->getInstance('Horde_Lock'); + } catch (Horde_Lock_Exception $e) { + Horde::logMessage($e, 'ERR'); + throw new Horde_Share_Exception($e); + } + + $shareid = $this->getId(); + + // Default parameters. + $locktype = Horde_Lock::TYPE_EXCLUSIVE; + $timeout = 600; + $itemscope = $this->_shareOb->getApp() . ':' . $shareid; + + if (!empty($item_uid)) { + // Check if the share is locked. Share locks are placed at app + // scope. + try { + $result = $locks->getLocks($this->_shareOb->getApp(), $shareid, $locktype); + } catch (Horde_Lock_Exception $e) { + throw new Horde_Share_Exception($e); + } + if (!empty($result)) { + // Lock found. + return false; + } + // Try to place the item lock at app:shareid scope. + return $locks->setLock(Horde_Auth::getAuth(), $itemscope, $item_uid, + $timeout, $locktype); + } else { + // Share lock requested. Check for locked items. + try { + $result = $locks->getLocks($itemscope, null, $locktype); + } catch (Horde_Lock_Exception $e) { + throw new Horde_Share_Exception($e); + } + if (!empty($result)) { + // Lock found. + return false; + } + // Try to place the share lock + return $locks->setLock(Horde_Auth::getAuth(), $this->_shareOb->getApp(), + $shareid, $timeout, $locktype); + } + } + + /** + * Removes the lock for a lock ID. + * + * @param string $lockid The lock ID as generated by a previous call + * to lock(). + * + * @return mixed True on success, PEAR_Error on failure. + */ + public function unlock($lockid) + { + try { + // TODO: pass in method, do not use injector in library + $locks = $GLOBALS['injector']->getInstance('Horde_Lock'); + } catch (Horde_Lock_Exception $e) { + Horde::logMessage($e, 'ERR'); + throw new Horde_Share_Exception($e); + } + + return $locks->clearLock($lockid); + } + + /** + * Checks for existing locks. + * + * First this checks for share locks and if none exists, checks for item + * locks (if item_uid defined). It will return the first lock found. + * + * @param string $item_uid A uid of an item from this share. + * + * @return mixed Hash with the found lock information in 'lock' and the + * lock type ('share' or 'item') in 'type', or an empty + * array if there are no locks, or a PEAR_Error on failure. + */ + public function checkLocks($item_uid = null) + { + // TODO: Inject lock object, do not use injector in library + try { + $locks = $GLOBALS['injector']->getInstance('Horde_Lock'); + } catch (Horde_Lock_Exception $e) { + Horde::logMessage($e, 'ERR'); + throw new Horde_Share_Exception($e); + } + + $shareid = $this->getId(); + $locktype = Horde_Lock::TYPE_EXCLUSIVE; + + // Check for share locks + try { + $result = $locks->getLocks($this->_shareOb->getApp(), $shareid, $locktype); + } catch (Horde_Lock_Exception $e) { + Horde::logMessage($e, 'ERR'); + throw new Horde_Share_Exception($e); + } + + if (empty($result) && !empty($item_uid)) { + // Check for item locks + $locktargettype = 'item'; + try { + $result = $locks->getLocks($this->_shareOb->getApp() . ':' . $shareid, $item_uid, $locktype); + } catch (Horde_Lock_Exception $e) { + Horde::logMessage($e, 'ERR'); + throw new Horde_Share_Exception($e->getMessage()); + } + } else { + $locktargettype = 'share'; + } + + if (empty($result)) { + return array(); + } + + return array('type' => $locktargettype, + 'lock' => reset($result)); + } + +} diff --git a/framework/Share/lib/Horde/Share/Object/Datatree.php b/framework/Share/lib/Horde/Share/Object/Datatree.php new file mode 100644 index 000000000..6b21f2732 --- /dev/null +++ b/framework/Share/lib/Horde/Share/Object/Datatree.php @@ -0,0 +1,138 @@ + + * @author Jan Schneider + * @author Gunnar Wrobel + * @package Horde_Share + */ +class Horde_Share_Object_Datatree extends Horde_Share_Object +{ + /** + * The actual storage object that holds the data. + * + * @var mixed + */ + public $datatreeObject; + + /** + * Constructor. + * + * @param DataTreeObject_Share $datatreeObject A DataTreeObject_Share + * instance. + */ + public function __construct(Horde_Share_Object_Datatree_Share $datatreeObject) + { + $this->datatreeObject = $datatreeObject; + } + + /** + * Sets an attribute value in this object. + * + * @param string $attribute The attribute to set. + * @param mixed $value The value for $attribute. + * + * @return mixed True if setting the attribute did succeed, a PEAR_Error + * otherwise. + */ + public function _set($attribute, $value) + { + return $this->datatreeObject->set($attribute, $value); + } + + /** + * Returns one of the attributes of the object, or null if it isn't + * defined. + * + * @param string $attribute The attribute to retrieve. + * + * @return mixed The value of the attribute, or an empty string. + */ + public function _get($attribute) + { + return $this->datatreeObject->get($attribute); + } + + /** + * Returns the ID of this share. + * + * @return string The share's ID. + */ + protected function _getId() + { + return $this->datatreeObject->getId(); + } + + /** + * Returns the name of this share. + * + * @return string The share's name. + */ + protected function _getName() + { + return $this->datatreeObject->getName(); + } + + /** + * Saves the current attribute values. + */ + protected function _save() + { + return $this->datatreeObject->save(); + } + + /** + * Checks to see if a user has a given permission. + * + * @param string $userid The userid of the user. + * @param integer $permission A Horde_Perms::* constant to test for. + * @param string $creator The creator of the event. + * + * @return boolean Whether or not $userid has $permission. + */ + public function hasPermission($userid, $permission, $creator = null) + { + if ($userid && $userid == $this->datatreeObject->get('owner')) { + return true; + } + // TODO: inject + return $GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission($this->getPermission(), $userid, $permission, $creator); + } + + /** + * Sets the permission of this share. + * + * @param Horde_Perms_Permission $perm Permission object. + * @param boolean $update Should the share be saved + * after this operation? + * + * @return boolean True if no error occured, PEAR_Error otherwise + */ + public function setPermission(&$perm, $update = true) + { + $this->datatreeObject->data['perm'] = $perm->getData(); + if ($update) { + return $this->datatreeObject->save(); + } + return true; + } + + /** + * Returns the permission of this share. + * + * @return Horde_Perms_Permission Permission object that represents the + * permissions on this share + */ + function getPermission() + { + $perm = new Horde_Perms_Permission($this->datatreeObject->getName()); + $perm->data = isset($this->datatreeObject->data['perm']) + ? $this->datatreeObject->data['perm'] + : array(); + + return $perm; + } + +} diff --git a/framework/Share/lib/Horde/Share/Object/Datatree/Share.php b/framework/Share/lib/Horde/Share/Object/Datatree/Share.php new file mode 100644 index 000000000..83f62997f --- /dev/null +++ b/framework/Share/lib/Horde/Share/Object/Datatree/Share.php @@ -0,0 +1,99 @@ + + * @author Jan Schneider + * @package Horde_Share + */ +class Horde_Share_Object_DataTree_Share extends DataTreeObject +{ + /** + * Returns the properties that need to be serialized. + * + * @return array List of serializable properties. + */ + public function __sleep() + { + $properties = get_object_vars($this); + unset($properties['datatree']); + $properties = array_keys($properties); + return $properties; + } + + /** + * Maps this object's attributes from the data array into a format that we + * can store in the attributes storage backend. + * + * @access protected + * + * @param boolean $permsonly Only process permissions? Lets subclasses + * override part of this method while handling + * their additional attributes seperately. + * + * @return array The attributes array. + */ + protected function _toAttributes($permsonly = false) + { + // Default to no attributes. + $attributes = array(); + + foreach ($this->data as $key => $value) { + if ($key == 'perm') { + foreach ($value as $type => $perms) { + if (is_array($perms)) { + foreach ($perms as $member => $perm) { + $attributes[] = array('name' => 'perm_' . $type, + 'key' => $member, + 'value' => $perm); + } + } else { + $attributes[] = array('name' => 'perm_' . $type, + 'key' => '', + 'value' => $perms); + } + } + } elseif (!$permsonly) { + $attributes[] = array('name' => $key, + 'key' => '', + 'value' => $value); + } + } + + return $attributes; + } + + /** + * Takes in a list of attributes from the backend and maps it to our + * internal data array. + * + * @access protected + * + * @param array $attributes The list of attributes from the backend + * (attribute name, key, and value). + * @param boolean $permsonly Only process permissions? Lets subclasses + * override part of this method while handling + * their additional attributes seperately. + */ + protected function _fromAttributes($attributes, $permsonly = false) + { + // Initialize data array. + $this->data['perm'] = array(); + + foreach ($attributes as $attr) { + if (substr($attr['name'], 0, 4) == 'perm') { + if (!empty($attr['key'])) { + $this->data['perm'][substr($attr['name'], 5)][$attr['key']] = $attr['value']; + } else { + $this->data['perm'][substr($attr['name'], 5)] = $attr['value']; + } + } elseif (!$permsonly) { + $this->data[$attr['name']] = $attr['value']; + } + } + } + +} diff --git a/framework/Share/lib/Horde/Share/Object/Kolab.php b/framework/Share/lib/Horde/Share/Object/Kolab.php new file mode 100644 index 000000000..eb4490fb8 --- /dev/null +++ b/framework/Share/lib/Horde/Share/Object/Kolab.php @@ -0,0 +1,360 @@ + + * @author Gunnar Wrobel + * @package Horde_Share + */ +class Horde_Share_Object_Kolab extends Horde_Share_Object +{ + /** + * The Kolab folder this share is based on. + * + * @var Kolab_Folder + */ + protected $_folder; + + /** + * The Kolab folder name. + * + * @var string + */ + protected $_folder_name; + + /** + * A cache for the share attributes. + * + * @var array + */ + protected $_data; + + /** + * Our Kolab folder list handler + * + * @var Kolab_List + */ + protected $_list; + + /** + * The session handler. + * + * @var Horde_Kolab_Session + */ + private $_session; + + /** + * Constructor. + * + * Sets the folder name. + * + * @param string $id The share id. + */ + public function __construct($id, $type) + { + // We actually ignore the random id string that all horde apps provide + // as initial name and wait for a set('name', 'xyz') call. But we want + // to know if we should create a default share. + if ($id == Horde_Auth::getAuth()) { + $this->_data['default'] = true; + } else { + $this->_data['default'] = false; + } + $this->_type = $type; + $this->__wakeup(); + } + + /** + * Associates a Share object with this share. + * + * @param Horde_Share $shareOb The Share object. + */ + public function setShareOb($shareOb) + { + /** Ignore the parent as we don't need it */ + } + + /** + * Initializes the object. + */ + public function __wakeup() + { + $this->_list = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage'); + if (isset($this->_folder_name)) { + $this->_folder = $this->_list->getFolder($this->_folder_name); + } + } + + /** + * Returns the properties that need to be serialized. + * + * @return array List of serializable properties. + */ + public function __sleep() + { + $properties = get_object_vars($this); + unset($properties['_shareOb'], $properties['_list'], + $properties['_folder']); + $properties = array_keys($properties); + return $properties; + } + + /** + * Returns the default share name for the current application. + * + * @return string The default share name. + */ + public function getDefaultShareName() + { + switch ($this->_type) { + case 'contact': + return _("Contacts"); + case 'note': + return _("Notes"); + case 'event': + return _("Calendar"); + case 'task': + return _("Tasks"); + case 'filter': + return _("Filters"); + case 'h-prefs': + return _("Preferences"); + } + } + + /** + * Sets the folder for this storage object. + * + * @param string $folder Name of the Kolab folder. + * @param array $perms The permissions of the folder if they are known. + */ + public function setFolder(&$folder) + { + if (!isset($this->_folder)) { + $this->_folder = &$folder; + $this->_folder_name = $folder->name; + } else { + throw new Horde_Share_Exception(_("The share has already been initialized!")); + } + } + + /** + * Returns the ID of this share. + * + * @return string The share's ID. + */ + protected function _getId() + { + return $this->_folder->getShareId(); + } + + /** + * Returns the name of this share. + * + * @return string The share's name. + */ + protected function _getName() + { + return $this->_folder->getShareId(); + } + + /** + * Returns an attribute value from this object. + * + * @param string $attribute The attribute to return. + * + * @return mixed The value for $attribute. + */ + protected function _get($attribute) + { + if (isset($this->_data[$attribute])) { + return $this->_data[$attribute]; + } + + if (!isset($this->_folder)) { + return $this->_folderError(); + } + + switch ($attribute) { + case 'owner': + $this->_data['owner'] = $this->_folder->getOwner(); + break; + + case 'name': + $this->_data['name'] = $this->_folder->getTitle(); + break; + + case 'type': + $this->_data['type'] = $this->_folder->getType(); + break; + + case 'params': + $params = @unserialize($this->_folder->getAttribute('params')); + $default = array('source' => 'kolab', + 'default' => $this->get('default'), + 'name' => $this->get('name')); + $type = $this->get('type'); + if (!($type instanceof PEAR_Error) && $type == 'event') { + $default = array_merge($default, array( + 'fbrelevance' => $this->_folder->getFbrelevance(), + 'xfbaccess' => $this->_folder->getXfbaccess() + )); + } + if ($params instanceof PEAR_Error || $params == '') { + $params = $default; + } + $this->_data['params'] = serialize(array_merge($default, $params)); + break; + + case 'default': + $this->_data['default'] = $this->_folder->isDefault(); + break; + + default: + $annotation = $this->_folder->getAttribute($attribute); + if ($annotation instanceof PEAR_Error || empty($annotation)) { + $annotation = ''; + } + $this->_data[$attribute] = $annotation; + break; + } + + return $this->_data[$attribute]; + } + + /** + * Sets an attribute value in this object. + * + * @param string $attribute The attribute to set. + * @param mixed $value The value for $attribute. + * + * @return mixed True if setting the attribute did succeed, a PEAR_Error + * otherwise. + */ + protected function _set($attribute, $value) + { + switch ($attribute) { + case 'name': + /* On folder creation of default shares we wish to ignore + * the names provided by the Horde applications. We use + * the Kolab default names. */ + if (!isset($this->_folder)) { + if ($this->get('default')) { + $value = $this->getDefaultShareName(); + } + $this->setFolder($this->_list->getNewFolder()); + } + $this->_folder->setName($value); + $this->_data['name'] = $this->_folder->getTitle(); + break; + + case 'params': + $value = unserialize($value); + if (isset($value['default'])) { + $this->_data['default'] = $value['default']; + unset($value['default']); + } + $value = serialize($value); + + default: + $this->_data[$attribute] = $value; + } + } + + /** + * Saves the current attribute values. + */ + protected function _save() + { + if (!isset($this->_folder)) { + return $this->_folderError(); + } + + $data = $this->_data; + /** The name is handled immediately when set */ + unset($data['name']); + $data['type'] = $this->_type; + + $result = $this->_folder->save($data); + if ($result instanceof PEAR_Error) { + return $result; + } + + /** The name may have changed */ + $this->_data['name'] = $this->_folder->getTitle(); + $this->_folder_name = $this->_folder->name; + return true; + } + + /** + * Delete this share. + * + * @return boolean|PEAR_Error True on success. + */ + public function delete() + { + if (!isset($this->_folder)) { + return $this->_folderError(); + } + return $this->_folder->delete(); + } + + /** + * Checks to see if a user has a given permission. + * + * @param string $userid The userid of the user. + * @param integer $permission A Horde_Perms::* constant to test for. + * @param string $creator The creator of the shared object. + * + * @return boolean|PEAR_Error Whether or not $userid has $permission. + */ + public function hasPermission($userid, $permission, $creator = null) + { + if (!isset($this->_folder)) { + return $this->_folderError(); + } + return $this->_folder->hasPermission($userid, $permission, $creator); + } + + /** + * Returns the permissions from this storage object. + * + * @return Horde_Perms_Permission_Kolab|PEAR_Error The permissions on the share. + */ + public function getPermission() + { + if (!isset($this->_folder)) { + return $this->_folderError(); + } + return $this->_folder->getPermission(); + } + + /** + * Sets the permissions on the share. + * + * @param Horde_Perms_Permission_Kolab $perms Permission object to folder on the + * object. + * @param boolean $update Save the updated information? + * + * @return boolean|PEAR_Error True on success. + */ + public function setPermission($perms, $update = true) + { + if (!isset($this->_folder)) { + return $this->_folderError(); + } + return $this->_folder->setPermission($perms, $update); + } + + /** + * Return a standard error in case the share has not been + * correctly initialized. + * + * @throws Horde_Share_Exception + */ + protected function _folderError() + { + throw new Horde_Share_Exception(_("The Kolab share object has not been initialized yet!")); + } +} diff --git a/framework/Share/lib/Horde/Share/Object/Sql.php b/framework/Share/lib/Horde/Share/Object/Sql.php new file mode 100644 index 000000000..2553e3e6b --- /dev/null +++ b/framework/Share/lib/Horde/Share/Object/Sql.php @@ -0,0 +1,283 @@ + + * @package Horde_Share + */ +class Horde_Share_Object_Sql extends Horde_Share_Object +{ + /** + * The actual storage object that holds the data. + * + * @TODO: Check visibility - should be protected/private + * @var mixed + */ + public $data = array(); + + /** + * Constructor. + * + * @param array $data Share data array. + */ + public function __construct($data) + { + if (!isset($data['perm']) || !is_array($data['perm'])) { + $this->data['perm'] = array( + 'users' => array(), + 'type' => 'matrix', + 'default' => isset($data['perm_default']) + ? (int)$data['perm_default'] : 0, + 'guest' => isset($data['perm_guest']) + ? (int)$data['perm_guest'] : 0, + 'creator' => isset($data['perm_creator']) + ? (int)$data['perm_creator'] : 0, + 'groups' => array()); + + unset($data['perm_creator'], $data['perm_guest'], + $data['perm_default']); + } + $this->data = array_merge($data, $this->data); + } + + /** + * Sets an attribute value in this object. + * + * @param string $attribute The attribute to set. + * @param mixed $value The value for $attribute. + * + * @return mixed True if setting the attribute did succeed, a PEAR_Error + * otherwise. + */ + public function _set($attribute, $value) + { + if ($attribute == 'owner') { + return $this->data['share_owner'] = $value; + } else { + return $this->data['attribute_' . $attribute] = $value; + } + } + + /** + * Returns one of the attributes of the object, or null if it isn't + * defined. + * + * @param string $attribute The attribute to retrieve. + * + * @return mixed The value of the attribute, or an empty string. + */ + protected function _get($attribute) + { + if ($attribute == 'owner') { + return $this->data['share_owner']; + } elseif (isset($this->data['attribute_' . $attribute])) { + return $this->data['attribute_' . $attribute]; + } + } + + /** + * Returns the ID of this share. + * + * @return string The share's ID. + */ + protected function _getId() + { + return isset($this->data['share_id']) ? $this->data['share_id'] : null; + } + + /** + * Returns the name of this share. + * + * @return string The share's name. + */ + protected function _getName() + { + return $this->data['share_name']; + } + + /** + * Saves the current attribute values. + */ + protected function _save() + { + $db = $this->_shareOb->getWriteDb(); + $table = $this->_shareOb->getTable(); + + $fields = array(); + $params = array(); + + foreach ($this->_shareOb->_toDriverCharset($this->data) as $key => $value) { + if ($key != 'share_id' && $key != 'perm' && $key != 'share_flags') { + $fields[] = $key; + $params[] = $value; + } + } + + $fields[] = 'perm_creator'; + $params[] = isset($this->data['perm']['creator']) ? (int)$this->data['perm']['creator'] : 0; + + $fields[] = 'perm_default'; + $params[] = isset($this->data['perm']['default']) ? (int)$this->data['perm']['default'] : 0; + + $fields[] = 'perm_guest'; + $params[] = isset($this->data['perm']['guest']) ? (int)$this->data['perm']['guest'] : 0; + + $fields[] = 'share_flags'; + $flags = 0; + if (!empty($this->data['perm']['users'])) { + $flags |= Horde_Share_Sql::SQL_FLAG_USERS; + } + if (!empty($this->data['perm']['groups'])) { + $flags |= Horde_Share_Sql::SQL_FLAG_GROUPS; + } + $params[] = $flags; + + if (empty($this->data['share_id'])) { + $share_id = $db->nextId($table); + if ($share_id instanceof PEAR_Error) { + Horde::logMessage($share_id, 'ERR'); + throw new Horde_Share_Exception($share_id->getMessage()); + } + + $this->data['share_id'] = $share_id; + $fields[] = 'share_id'; + $params[] = $this->data['share_id']; + + $query = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (?' . str_repeat(', ?', count($fields) - 1) . ')'; + } else { + $query = 'UPDATE ' . $table . ' SET ' . implode(' = ?, ', $fields) . ' = ? WHERE share_id = ?'; + $params[] = $this->data['share_id']; + } + $stmt = $db->prepare($query, null, MDB2_PREPARE_MANIP); + if ($stmt instanceof PEAR_Error) { + Horde::logMessage($stmt, 'ERR'); + throw new Horde_Share_Exception($stmt->getMessage()); + } + $result = $stmt->execute($params); + if ($result instanceof PEAR_Error) { + Horde::logMessage($result, 'ERR'); + throw new Horde_Share_Exception($result->getMessage()); + } + $stmt->free(); + + // Update the share's user permissions + $stmt = $db->prepare('DELETE FROM ' . $table . '_users WHERE share_id = ?', null, MDB2_PREPARE_MANIP); + if ($stmt instanceof PEAR_Error) { + Horde::logMessage($stmt, 'ERR'); + throw new Horde_Share_Exception($stmt->getMessage()); + } + $result = $stmt->execute(array($this->data['share_id'])); + if ($result instanceof PEAR_Error) { + Horde::logMessage($result, 'ERR'); + throw new Horde_Share_Exception($result->getMessage()); + } + $stmt->free(); + + if (!empty($this->data['perm']['users'])) { + $data = array(); + foreach ($this->data['perm']['users'] as $user => $perm) { + $stmt = $db->prepare('INSERT INTO ' . $table . '_users (share_id, user_uid, perm) VALUES (?, ?, ?)', null, MDB2_PREPARE_MANIP); + if ($stmt instanceof PEAR_Error) { + Horde::logMessage($stmt, 'ERR'); + throw new Horde_Share_Exception($stmt->getMessage()); + } + $result = $stmt->execute(array($this->data['share_id'], $user, $perm)); + if ($result instanceof PEAR_Error) { + Horde::logMessage($result, 'ERR'); + throw new Horde_Share_Exception($result->getMessage()); + } + $stmt->free(); + } + } + + // Update the share's group permissions + $stmt = $db->prepare('DELETE FROM ' . $table . '_groups WHERE share_id = ?', null, MDB2_PREPARE_MANIP); + if ($stmt instanceof PEAR_Error) { + Horde::logMessage($stmt, 'ERR'); + throw new Horde_Share_Exception($stmt->getMessage()); + } + $result = $stmt->execute(array($this->data['share_id'])); + if ($result instanceof PEAR_Error) { + Horde::logMessage($result, 'ERR'); + throw new Horde_Share_Exception($result->getMessage()); + } + $stmt->free(); + + if (!empty($this->data['perm']['groups'])) { + $data = array(); + foreach ($this->data['perm']['groups'] as $group => $perm) { + $stmt = $db->prepare('INSERT INTO ' . $table . '_groups (share_id, group_uid, perm) VALUES (?, ?, ?)', null, MDB2_PREPARE_MANIP); + if ($stmt instanceof PEAR_Error) { + Horde::logMessage($stmt, 'ERR'); + throw new Horde_Share_Exception($stmt->getMessage()); + } + $result = $stmt->execute(array($this->data['share_id'], $group, $perm)); + if ($result instanceof PEAR_Error) { + Horde::logMessage($result, 'ERR'); + throw new Horde_Share_Exception($result->getMessage()); + } + $stmt->free(); + } + } + + return true; + } + + /** + * Checks to see if a user has a given permission. + * + * @param string $userid The userid of the user. + * @param integer $permission A Horde_Perms::* constant to test for. + * @param string $creator The creator of the event. + * + * @return boolean Whether or not $userid has $permission. + */ + public function hasPermission($userid, $permission, $creator = null) + { + if ($userid == $this->data['share_owner']) { + return true; + } + // @TODO: inject perms, don't use the injector here + return $GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission($this->getPermission(), $userid, $permission, $creator); + } + + /** + * Sets the permission of this share. + * + * @param Horde_Perms_Permission $perm Permission object. + * @param boolean $update Should the share be saved + * after this operation? + * + * @TODO: Look at storing the Perm object itself, instead of the data + * (Make it easier to inject the perm object instead of instantiating + * it in the library). + * + * @return boolean True if no error occured, PEAR_Error otherwise + */ + public function setPermission($perm, $update = true) + { + $this->data['perm'] = $perm->getData(); + if ($update) { + return $this->save(); + } + return true; + } + + /** + * Returns the permission of this share. + * + * @return Horde_Perms_Permission Permission object that represents the + * permissions on this share. + */ + public function getPermission() + { + $perm = new Horde_Perms_Permission($this->getName()); + $perm->data = isset($this->data['perm']) + ? $this->data['perm'] + : array(); + + return $perm; + } + +} diff --git a/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php b/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php new file mode 100644 index 000000000..4fb21f09f --- /dev/null +++ b/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php @@ -0,0 +1,186 @@ + + * @author Michael J. Rubinsky + * + * @package Horde_Share + */ +class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql +{ + /** + * Constructor. This is here primarily to make calling the parent + * constructor(s) from any subclasses cleaner. + * + * @param unknown_type $data + * @return Horde_Share_Object_sql_hierarchical + */ + public function __construct($data) + { + if (!isset($data['share_parents'])) { + $data['share_parents'] = null; + } + parent::__construct($data); + } + + public function inheritPermissions() + { + throw new Horde_Share_Exception('Not implemented.'); + } + + /** + * Return a count of the number of children this share has + * + * @param integer $perm A Horde_Perms::* constant + * @param boolean $allLevels Count grandchildren or just children + * + * @return mixed The number of child shares || PEAR_Error + */ + public function countChildren($perm = Horde_Perms::SHOW, $allLevels = true) + { + return $this->_shareOb->countShares(Horde_Auth::getAuth(), $perm, null, $this, $allLevels); + } + + /** + * Get all children of this share. + * + * @param int $perm Horde_Perms::* constant. If NULL will return + * all shares regardless of permissions. + * @param boolean $allLevels Return all levels. + * + * @return mixed An array of Horde_Share_Object objects || PEAR_Error + */ + public function getChildren($perm = Horde_Perms::SHOW, $allLevels = true) + { + return $this->_shareOb->listShares(Horde_Auth::getAuth(), $perm, null, 0, 0, + null, 1, $this, $allLevels, is_null($perm)); + + } + + /** + * Returns a child's direct parent + * + * @return mixed The direct parent Horde_Share_Object or PEAR_Error + */ + public function getParent() + { + return $this->_shareOb->getParent($this); + } + + /** + * Get all of this share's parents. + * + * @return array() An array of Horde_Share_Objects + */ + public function getParents() + { + $parents = array(); + $share = $this->getParent(); + while (is_a($share, 'Horde_Share_Object')) { + $parents[] = $share; + $share = $share->getParent(); + } + return array_reverse($parents); + } + + /** + * Set the parent object for this share. + * + * @param mixed $parent A Horde_Share object or share id for the parent. + * + * @return mixed true || PEAR_Error + */ + public function setParent($parent) + { + if (!is_null($parent) && !is_a($parent, 'Horde_Share_Object')) { + $parent = $this->_shareOb->getShareById($parent); + if ($parent instanceof PEAR_Error) { + Horde::logMessage($parent, 'ERR'); + throw new Horde_Share_Exception($parent->getMessage()); + } + } + + /* If we are an existing share, check for any children */ + if ($this->getId()) { + $children = $this->_shareOb->listShares( + Horde_Auth::getAuth(), Horde_Perms::EDIT, null, 0, 0, null, 0, + $this->getId()); + } else { + $children = array(); + } + + /* Can't set a child share as a parent */ + if (!empty($parent) && in_array($parent->getId(), array_keys($children))) { + throw new Horde_Share_Exception('Cannot set an existing child as the parent'); + } + + if (!is_null($parent)) { + $parent_string = $parent->get('parents') . ':' . $parent->getId(); + } else { + $parent_string = null; + } + $this->data['share_parents'] = $parent_string; + $query = $this->_shareOb->_write_db->prepare('UPDATE ' . $this->_shareOb->_table . ' SET share_parents = ? WHERE share_id = ?', null, MDB2_PREPARE_MANIP); + $result = $query->execute(array($this->data['share_parents'], $this->getId())); + $query->free(); + if ($result instanceof PEAR_Error) { + throw new Horde_Share_Exception($result->getMessage()); + } + + /* Now we can reset the children's parent */ + foreach($children as $child) { + $child->setParent($this); + } + + return true; + } + + /** + * Returns the permission of this share. + * + * @return Horde_Perms_Permission Permission object that represents the + * permissions on this share. + */ + public function getPermission() + { + $perm = new Horde_Perms_Permission(''); + $perm->data = isset($this->data['perm']) + ? $this->data['perm'] + : array(); + + return $perm; + } + + /** + * Returns one of the attributes of the object, or null if it isn't + * defined. + * + * @param string $attribute The attribute to retrieve. + * + * @return mixed The value of the attribute, or an empty string. + */ + protected function _get($attribute) + { + if ($attribute == 'owner' || $attribute == 'parents') { + return $this->data['share_' . $attribute]; + } elseif (isset($this->data['attribute_' . $attribute])) { + return $this->data['attribute_' . $attribute]; + } else { + return null; + } + } + + /** + * Hierarchical shares do not have share names. + * + * @return unknown + */ + protected function _getName() + { + return ''; + } + +} + diff --git a/framework/Share/Share/sql.php b/framework/Share/lib/Horde/Share/Sql.php similarity index 67% rename from framework/Share/Share/sql.php rename to framework/Share/lib/Horde/Share/Sql.php index 50dc29664..95df8d1e7 100644 --- a/framework/Share/Share/sql.php +++ b/framework/Share/lib/Horde/Share/Sql.php @@ -12,55 +12,56 @@ * @package Horde_Share */ -/** The share has user permissions */ -define('HORDE_SHARE_SQL_FLAG_USERS', 1); - -/** The share has group permissions */ -define('HORDE_SHARE_SQL_FLAG_GROUPS', 2); - /** * @package Horde_Share */ -class Horde_Share_sql extends Horde_Share { +class Horde_Share_Sql extends Horde_Share +{ + /* Share has user perms */ + const SQL_FLAG_USERS = 1; + + /* Share has group perms */ + const SQL_FLAG_GROUPS = 2; /** * Handle for the current database connection. + * @TODO: port to Horde_Db * - * @var DB + * @var MDB2 */ - var $_db; + protected $_db; /** * Handle for the current database connection, used for writing. Defaults * to the same handle as $db if a separate write database is not required. * - * @var DB + * @var MDB2 */ - var $_write_db; + protected $_write_db; /** * SQL connection parameters */ - var $_params = array(); + protected $_params = array(); /** * Main share table for the current scope. * * @var string */ - var $_table; + protected $_table; /** * The Horde_Share_Object subclass to instantiate objects as * * @var string */ - var $_shareObject = 'Horde_Share_Object_sql'; + protected $_shareObject = 'Horde_Share_Object_Sql'; /** * Initializes the object. */ - function __wakeup() + public function __wakeup() { $this->_table = $this->_app . '_shares'; $this->_connect(); @@ -77,7 +78,7 @@ class Horde_Share_sql extends Horde_Share { * * @return array List of serializable properties. */ - function __sleep() + public function __sleep() { $properties = get_object_vars($this); unset($properties['_sortList'], @@ -89,7 +90,7 @@ class Horde_Share_sql extends Horde_Share { /** * Get storage table */ - function getTable() + public function getTable() { return $this->_table; } @@ -97,44 +98,51 @@ class Horde_Share_sql extends Horde_Share { /** * Refetence to write db */ - function getWriteDb() + public function getWriteDb() { return $this->_write_db; } + public function getReadDb() + { + return $this->_db; + } + /** * Finds out if the share has user set */ - function _hasUsers($share) + public function _hasUsers($share) { - return $share['share_flags'] & HORDE_SHARE_SQL_FLAG_USERS; + return $share['share_flags'] & self::SQL_FLAG_USERS; } /** * Finds out if the share has user set */ - function _hasGroups($share) + public function _hasGroups($share) { - return $share['share_flags'] & HORDE_SHARE_SQL_FLAG_GROUPS; + return $share['share_flags'] & self::SQL_FLAG_GROUPS; } /** * Get users permissions * * @param array $share Share data array + * + * @throws Horde_Share_Exception */ - function _getShareUsers(&$share) + protected function _getShareUsers(&$share) { if ($this->_hasUsers($share)) { $stmt = $this->_db->prepare('SELECT user_uid, perm FROM ' . $this->_table . '_users WHERE share_id = ?'); - if (is_a($stmt, 'PEAR_Error')) { + if ($stmt instanceof PEAR_Error) { Horde::logMessage($stmt, 'ERR'); - return $stmt; + throw new Horde_Share_Exception($stmt->getMessage()); } $result = $stmt->execute(array($share['share_id'])); - if (is_a($result, 'PEAR_Error')) { + if ( $result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $share['perm']['users'][$row['user_uid']] = (int)$row['perm']; @@ -149,20 +157,21 @@ class Horde_Share_sql extends Horde_Share { * Get groups permissions * * @param array $share Share data array + * @throws Horde_Share_Exception */ - function _getShareGroups(&$share) + protected function _getShareGroups(&$share) { if ($this->_hasGroups($share)) { // Get groups permissions $stmt = $this->_db->prepare('SELECT group_uid, perm FROM ' . $this->_table . '_groups WHERE share_id = ?'); - if (is_a($stmt, 'PEAR_Error')) { + if ($stmt instanceof PEAR_Error) { Horde::logMessage($stmt, 'ERR'); - return $stmt; + throw new Horde_Share_Exception($stmt->getMessage()); } $result = $stmt->execute(array($share['share_id'])); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $share['perm']['groups'][$row['group_uid']] = (int)$row['perm']; @@ -181,24 +190,24 @@ class Horde_Share_sql extends Horde_Share { * * @return Horde_Share_Object_sql The requested share. */ - function _getShare($name) + protected function _getShare($name) { $stmt = $this->_db->prepare('SELECT * FROM ' . $this->_table . ' WHERE share_name = ?'); - if (is_a($stmt, 'PEAR_Error')) { + if ($stmt instanceof PEAR_Error) { Horde::logMessage($stmt, 'ERR'); - return $stmt; + throw new Horde_Share_Exception($stmt->getMessage()); } $results = $stmt->execute(array($name)); - if (is_a($results, 'PEAR_Error')) { + if ($results instanceof PEAR_Error) { Horde::logMessage($results, 'ERR'); - return $results; + throw new Horde_Share_Exception($results->getMessage()); } $data = $results->fetchRow(MDB2_FETCHMODE_ASSOC); - if (is_a($data, 'PEAR_Error')) { + if ($data instanceof PEAR_Error) { Horde::logMessage($data, 'ERR'); - return $data; + throw new Horde_Share_Exception($data->getMessage()); } elseif (empty($data)) { - return PEAR::RaiseError(sprintf(_("Share \"%s\" does not exist."), $name)); + throw new Horde_Share_Exception(sprintf(_("Share \"%s\" does not exist."), $name)); } $stmt->free(); $results->free(); @@ -217,14 +226,14 @@ class Horde_Share_sql extends Horde_Share { * * @param array $data Array of share attributes */ - function _loadPermissions(&$data) + protected function _loadPermissions(&$data) { $this->_getShareUsers($data); $this->_getShareGroups($data); $this->_getSharePerms($data); } - function _getSharePerms(&$data) + protected function _getSharePerms(&$data) { $data['perm']['type'] = 'matrix'; $data['perm']['default'] = isset($data['perm_default']) ? (int)$data['perm_default'] : 0; @@ -240,26 +249,27 @@ class Horde_Share_sql extends Horde_Share { * @param integer $cid The id of the share to retrieve. * * @return Horde_Share_Object_sql The requested share. + * @throws Horde_Share_Exception */ - function _getShareById($id) + protected function _getShareById($id) { $params = array($id); $stmt = $this->_db->prepare('SELECT * FROM ' . $this->_table . ' WHERE share_id = ?'); - if (is_a($stmt, 'PEAR_Error')) { + if ($stmt instanceof PEAR_Error) { Horde::logMessage($stmt, 'ERR'); - return $stmt; + throw new Horde_Share_Exception($stmt->getMessage()); } $results = $stmt->execute($params); - if (is_a($results, 'PEAR_Error')) { + if ($results instanceof PEAR_Error) { Horde::logMessage($results, 'ERR'); - return $results; + throw new Horde_Share_Exception($results->getMessage()); } $data = $results->fetchRow(MDB2_FETCHMODE_ASSOC); - if (is_a($data, 'PEAR_Error')) { + if ($data instanceof PEAR_Error) { Horde::logMessage($data, 'ERR'); - return $data; + throw new Horde_Share_Exception($data->getMessage()); } elseif (empty($data)) { - return PEAR::RaiseError(sprintf(_("Share ID %d does not exist."), $id)); + throw new Horde_Share_Exception(sprintf(_("Share ID %d does not exist."), $id)); } $stmt->free(); @@ -283,14 +293,14 @@ class Horde_Share_sql extends Horde_Share { * * @return array The requested shares. */ - function _getShares($ids) + protected function _getShares($ids) { $shares = array(); $query = 'SELECT * FROM ' . $this->_table . ' WHERE share_id IN (' . implode(', ', $ids) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (empty($result)) { return array(); } @@ -313,9 +323,9 @@ class Horde_Share_sql extends Horde_Share { $query = 'SELECT share_id, user_uid, perm FROM ' . $this->_table . '_users ' . ' WHERE share_id IN (' . implode(', ', $users) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; @@ -329,9 +339,9 @@ class Horde_Share_sql extends Horde_Share { $query = 'SELECT share_id, group_uid, perm FROM ' . $this->_table . '_groups' . ' WHERE share_id IN (' . implode(', ', $groups) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; @@ -357,8 +367,9 @@ class Horde_Share_sql extends Horde_Share { * called from user-level code! * * @return array All shares for the current app/share. + * @throws Horde_Share_Exception */ - function listAllShares() + public function listAllShares() { return $this->_listAllShares(); } @@ -369,14 +380,14 @@ class Horde_Share_sql extends Horde_Share { * * @return array All shares for the current app/share. */ - function _listAllShares() + protected function _listAllShares() { $shares = array(); $query = 'SELECT * FROM ' . $this->_table . ' ORDER BY share_name ASC'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (empty($result)) { return array(); } @@ -389,7 +400,7 @@ class Horde_Share_sql extends Horde_Share { // Get users permissions $query = 'SELECT share_id, user_uid, perm FROM ' . $this->_table . '_users'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); return $result; } elseif (!empty($result)) { @@ -402,9 +413,9 @@ class Horde_Share_sql extends Horde_Share { // Get groups permissions $query = 'SELECT share_id, group_uid, perm FROM ' . $this->_table . '_groups'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; @@ -433,9 +444,9 @@ class Horde_Share_sql extends Horde_Share { * username. * * @return array The shares the user has access to. - * @throws Horde_Exception + * @throws Horde_Share_Exception */ - function listShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, + public function listShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, $from = 0, $count = 0, $sort_by = null, $direction = 0) { $shares = array(); @@ -448,7 +459,7 @@ class Horde_Share_sql extends Horde_Share { } $query = 'SELECT DISTINCT s.* ' - . $this->_getShareCriteria($userid, $perm, $attributes) + . $this->getShareCriteria($userid, $perm, $attributes) . ' ORDER BY ' . $sortfield . (($direction == 0) ? ' ASC' : ' DESC'); if ($from > 0 || $count > 0) { @@ -465,9 +476,9 @@ class Horde_Share_sql extends Horde_Share { Horde::logMessage(sprintf("SQL Query by Horde_Share_sql::listShares: %s", $query), 'DEBUG'); $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (empty($result)) { return array(); } @@ -491,9 +502,9 @@ class Horde_Share_sql extends Horde_Share { . '_users WHERE share_id IN (' . implode(', ', $users) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; @@ -508,9 +519,9 @@ class Horde_Share_sql extends Horde_Share { . '_groups WHERE share_id IN (' . implode(', ', $groups) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; @@ -538,8 +549,9 @@ class Horde_Share_sql extends Horde_Share { * Returns an array of all system shares. * * @return array All system shares. + * @throws Horde_Share_Exception */ - function listSystemShares() + public function listSystemShares() { // Fix field names for sqlite. MDB2 tries to handle this with // MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES, but it doesn't stick. @@ -552,9 +564,9 @@ class Horde_Share_sql extends Horde_Share { $query = 'SELECT * FROM ' . $this->_table . ' WHERE share_owner IS NULL'; Horde::logMessage('SQL Query by Horde_Share_sql::listSystemShares: ' . $query, 'DEBUG'); $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage());; } elseif (empty($result)) { return array(); } @@ -583,10 +595,10 @@ class Horde_Share_sql extends Horde_Share { * * @return integer The number of shares */ - function _countShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null) + protected function _countShares($userid, $perm = Horde_Perms::SHOW, + $attributes = null) { - $query = $this->_getShareCriteria($userid, $perm, $attributes); + $query = $this->getShareCriteria($userid, $perm, $attributes); $query = 'SELECT COUNT(DISTINCT s.share_id) ' . $query; Horde::logMessage(sprintf("SQL Query by Horde_Share_sql::_countShares: %s", $query), 'DEBUG'); return $this->_db->queryOne($query); @@ -599,7 +611,7 @@ class Horde_Share_sql extends Horde_Share { * * @return Horde_Share_Object_sql A new share object. */ - function _newShare($name) + protected function _newShare($name) { return new $this->_shareObject(array('share_name' => $name)); } @@ -613,7 +625,7 @@ class Horde_Share_sql extends Horde_Share { * * @param Horde_Share_Object_sql $share The new share object. */ - function _addShare($share) + protected function _addShare($share) { return $share->save(); } @@ -622,8 +634,11 @@ class Horde_Share_sql extends Horde_Share { * Removes a share from the shares system permanently. * * @param Horde_Share_Object_sql $share The share to remove. + * + * @return boolean + * @throws Horde_Share_Exception */ - function _removeShare($share) + protected function _removeShare($share) { $params = array($share->getId()); $tables = array($this->_table, @@ -633,14 +648,14 @@ class Horde_Share_sql extends Horde_Share { /* Remove the share entry */ $stmt = $this->_write_db->prepare('DELETE FROM ' . $table . ' WHERE share_id = ?', null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { + if ($stmt instanceof PEAR_Error) { Horde::logMessage($stmt, 'ERR'); - return $stmt; + throw new Horde_Share_Exception($stmt->getMessage()); } $result = $stmt->execute($params); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } $stmt->free(); } @@ -654,20 +669,21 @@ class Horde_Share_sql extends Horde_Share { * @param string $share The share to check. * * @return boolean True if the share exists. + * @throws Horde_Share_Exception */ - function _exists($share) + protected function _exists($share) { $stmt = $this->_db->prepare('SELECT 1 FROM ' . $this->_table . ' WHERE share_name = ?'); - if (is_a($stmt, 'PEAR_Error')) { + if ($stmt instanceof PEAR_Error) { Horde::logMessage($stmt, 'ERR'); - return $stmt; + throw new Horde_Share_Exception($stmt->getMessage()); } $result = $stmt->execute(array($share)); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } $exists = (bool)$result->fetchOne(); @@ -688,7 +704,7 @@ class Horde_Share_sql extends Horde_Share { * * @return string The criteria string for fetching this user's shares. */ - function _getShareCriteria($userid, $perm = Horde_Perms::SHOW, + public function getShareCriteria($userid, $perm = Horde_Perms::SHOW, $attributes = null) { $query = ' FROM ' . $this->_table . ' s '; @@ -710,6 +726,7 @@ class Horde_Share_sql extends Horde_Share { . ' AND (' . Horde_SQL::buildClause($this->_db, 'u.perm', '&', $perm) . '))'; // If the user has any group memberships, check for those also. + // @TODO: Inject the group driver require_once 'Horde/Group.php'; $group = Group::singleton(); $groups = $group->getGroupMemberships($userid, true); @@ -723,7 +740,7 @@ class Horde_Share_sql extends Horde_Share { $query .= ' LEFT JOIN ' . $this->_table . '_groups g ON g.share_id = s.share_id'; $where .= ' OR (g.group_uid IN (' . implode(',', $group_ids) . ')' . ' AND (' . Horde_SQL::buildClause($this->_db, 'g.perm', '&', $perm) . '))'; - } elseif (is_a($groups, 'PEAR_Error')) { + } elseif ($groups instanceof PEAR_Error) { Horde::logMessage($groups, 'ERR'); } } else { @@ -751,8 +768,11 @@ class Horde_Share_sql extends Horde_Share { /** * Resets the current database name so that MDB2 is always selecting the * database before sending a query. + * + * @TODO: This needs to be public since it's used as a callback in MDB2. + * Remove when refactored to use Horde_Db */ - function _selectDB($db, $scope, $message, $is_manip = null) + public function _selectDB($db, $scope, $message, $is_manip = null) { if ($scope == 'query') { $db->connected_database_name = ''; @@ -760,12 +780,21 @@ class Horde_Share_sql extends Horde_Share { } /** + * Set the SQL table name to use for the current scope's share storage. + * + * @var string $table The table name + */ + public function setShareTable($table) { + $this->_table = $table; + } + + /** * Attempts to open a connection to the sql server. * * @return boolean True on success. - * @throws Horde_Exception + * @throws Horde_Share_Exception */ - function _connect() + protected function _connect() { $this->_params = $GLOBALS['conf']['sql']; if (!isset($this->_params['database'])) { @@ -782,8 +811,8 @@ class Horde_Share_sql extends Horde_Share { $params = $this->_params; unset($params['charset']); $this->_write_db = MDB2::factory($params); - if (is_a($this->_write_db, 'PEAR_Error')) { - throw new Horde_Exception_Prior($this->_write_db); + if ($this->_write_db instanceof PEAR_Error) { + throw new Horde_Share_Excetion($this->_write_db->getMessage()); } /* Attach debug handler. */ @@ -816,8 +845,8 @@ class Horde_Share_sql extends Horde_Share { $params = array_merge($params, $this->_params['read']); unset($params['charset']); $this->_db = MDB2::singleton($params); - if (is_a($this->_db, 'PEAR_Error')) { - throw new Horde_Exception_Prior($this->_db); + if ($this->_db instanceof PEAR_Error) { + throw new Horde_Share_Exception($this->_db); } $this->_db->setOption('seqcol_name', 'id'); @@ -851,7 +880,7 @@ class Horde_Share_sql extends Horde_Share { /** * Utility function to convert from the SQL server's charset. */ - function _fromDriverCharset($data) + protected function _fromDriverCharset($data) { foreach ($data as $key => $value) { if (substr($key, 0, 9) == 'attribute') { @@ -865,8 +894,11 @@ class Horde_Share_sql extends Horde_Share { /** * Utility function to convert TO the SQL server's charset. + * + * @TODO: This needs to be public since it's called by the share object. + * Look at making this outright public or maybe moving it to the object. */ - function _toDriverCharset($data) + public function _toDriverCharset($data) { if (!is_array($data)) { return $data; @@ -890,7 +922,7 @@ class Horde_Share_sql extends Horde_Share { * * @return array The driver keyed array. */ - function _toDriverKeys($data) + protected function _toDriverKeys($data) { if (!is_array($data)) { return $data; @@ -909,281 +941,3 @@ class Horde_Share_sql extends Horde_Share { } } - -/** - * Extension of the Horde_Share_Object class for storing share information in - * the sql driver. - * - * @author Duck - * @package Horde_Share - */ -class Horde_Share_Object_sql extends Horde_Share_Object { - - /** - * The actual storage object that holds the data. - * - * @var mixed - */ - var $data = array(); - - /** - * Constructor. - * - * @param array $data Share data array. - */ - function Horde_Share_Object_sql($data) - { - if (!isset($data['perm']) || !is_array($data['perm'])) { - $this->data['perm'] = array( - 'users' => array(), - 'type' => 'matrix', - 'default' => isset($data['perm_default']) - ? (int)$data['perm_default'] : 0, - 'guest' => isset($data['perm_guest']) - ? (int)$data['perm_guest'] : 0, - 'creator' => isset($data['perm_creator']) - ? (int)$data['perm_creator'] : 0, - 'groups' => array()); - - unset($data['perm_creator'], $data['perm_guest'], - $data['perm_default']); - } - $this->data = array_merge($data, $this->data); - } - - /** - * Sets an attribute value in this object. - * - * @param string $attribute The attribute to set. - * @param mixed $value The value for $attribute. - * - * @return mixed True if setting the attribute did succeed, a PEAR_Error - * otherwise. - */ - function _set($attribute, $value) - { - if ($attribute == 'owner') { - return $this->data['share_owner'] = $value; - } else { - return $this->data['attribute_' . $attribute] = $value; - } - } - - /** - * Returns one of the attributes of the object, or null if it isn't - * defined. - * - * @param string $attribute The attribute to retrieve. - * - * @return mixed The value of the attribute, or an empty string. - */ - function _get($attribute) - { - if ($attribute == 'owner') { - return $this->data['share_owner']; - } elseif (isset($this->data['attribute_' . $attribute])) { - return $this->data['attribute_' . $attribute]; - } - } - - /** - * Returns the ID of this share. - * - * @return string The share's ID. - */ - function _getId() - { - return isset($this->data['share_id']) ? $this->data['share_id'] : null; - } - - /** - * Returns the name of this share. - * - * @return string The share's name. - */ - function _getName() - { - return $this->data['share_name']; - } - - /** - * Saves the current attribute values. - */ - function _save() - { - $db = $this->_shareOb->getWriteDb(); - $table = $this->_shareOb->getTable(); - - $fields = array(); - $params = array(); - - foreach ($this->_shareOb->_toDriverCharset($this->data) as $key => $value) { - if ($key != 'share_id' && $key != 'perm' && $key != 'share_flags') { - $fields[] = $key; - $params[] = $value; - } - } - - $fields[] = 'perm_creator'; - $params[] = isset($this->data['perm']['creator']) ? (int)$this->data['perm']['creator'] : 0; - - $fields[] = 'perm_default'; - $params[] = isset($this->data['perm']['default']) ? (int)$this->data['perm']['default'] : 0; - - $fields[] = 'perm_guest'; - $params[] = isset($this->data['perm']['guest']) ? (int)$this->data['perm']['guest'] : 0; - - $fields[] = 'share_flags'; - $flags = 0; - if (!empty($this->data['perm']['users'])) { - $flags |= HORDE_SHARE_SQL_FLAG_USERS; - } - if (!empty($this->data['perm']['groups'])) { - $flags |= HORDE_SHARE_SQL_FLAG_GROUPS; - } - $params[] = $flags; - - if (empty($this->data['share_id'])) { - $share_id = $db->nextId($table); - if (is_a($share_id, 'PEAR_Error')) { - Horde::logMessage($share_id, 'ERR'); - return $share_id; - } - - $this->data['share_id'] = $share_id; - $fields[] = 'share_id'; - $params[] = $this->data['share_id']; - - $query = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (?' . str_repeat(', ?', count($fields) - 1) . ')'; - } else { - $query = 'UPDATE ' . $table . ' SET ' . implode(' = ?, ', $fields) . ' = ? WHERE share_id = ?'; - $params[] = $this->data['share_id']; - } - $stmt = $db->prepare($query, null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute($params); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - - // Update the share's user permissions - $stmt = $db->prepare('DELETE FROM ' . $table . '_users WHERE share_id = ?', null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute(array($this->data['share_id'])); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - - if (!empty($this->data['perm']['users'])) { - $data = array(); - foreach ($this->data['perm']['users'] as $user => $perm) { - $stmt = $db->prepare('INSERT INTO ' . $table . '_users (share_id, user_uid, perm) VALUES (?, ?, ?)', null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute(array($this->data['share_id'], $user, $perm)); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - } - } - - // Update the share's group permissions - $stmt = $db->prepare('DELETE FROM ' . $table . '_groups WHERE share_id = ?', null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute(array($this->data['share_id'])); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - - if (!empty($this->data['perm']['groups'])) { - $data = array(); - foreach ($this->data['perm']['groups'] as $group => $perm) { - $stmt = $db->prepare('INSERT INTO ' . $table . '_groups (share_id, group_uid, perm) VALUES (?, ?, ?)', null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute(array($this->data['share_id'], $group, $perm)); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - } - } - - return true; - } - - /** - * Checks to see if a user has a given permission. - * - * @param string $userid The userid of the user. - * @param integer $permission A Horde_Perms::* constant to test for. - * @param string $creator The creator of the event. - * - * @return boolean Whether or not $userid has $permission. - */ - function hasPermission($userid, $permission, $creator = null) - { - if ($userid == $this->data['share_owner']) { - return true; - } - - return $GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission($this->getPermission(), $userid, $permission, $creator); - } - - /** - * Sets the permission of this share. - * - * @param Horde_Perms_Permission $perm Permission object. - * @param boolean $update Should the share be saved - * after this operation? - * - * @return boolean True if no error occured, PEAR_Error otherwise - */ - function setPermission($perm, $update = true) - { - $this->data['perm'] = $perm->getData(); - if ($update) { - return $this->save(); - } - return true; - } - - /** - * Returns the permission of this share. - * - * @return Horde_Perms_Permission Permission object that represents the - * permissions on this share. - */ - function getPermission() - { - $perm = new Horde_Perms_Permission($this->getName()); - $perm->data = isset($this->data['perm']) - ? $this->data['perm'] - : array(); - - return $perm; - } - -} diff --git a/framework/Share/Share/sql_hierarchical.php b/framework/Share/lib/Horde/Share/Sql/Hierarchical.php similarity index 69% rename from framework/Share/Share/sql_hierarchical.php rename to framework/Share/lib/Horde/Share/Sql/Hierarchical.php index 937ea0e79..007af4b90 100644 --- a/framework/Share/Share/sql_hierarchical.php +++ b/framework/Share/lib/Horde/Share/Sql/Hierarchical.php @@ -7,25 +7,27 @@ * @author Michael J. Rubinsky * @package Horde_Share */ -class Horde_Share_sql_hierarchical extends Horde_Share_sql { - +class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql +{ /** * The Horde_Share_Object subclass to instantiate objects as * * @var string */ - var $_shareObject = 'Horde_Share_Object_sql_hierarchical'; + protected $_shareObject = 'Horde_Share_Object_Sql_Hierarchical'; /** * Override new share creation so we can allow for shares with empty * share_names. * */ - function &newShare($name = '') + public function newShare($name = '') { - $share = &$this->_newShare(); + $share = $this->_newShare(); $share->setShareOb($this); + //@TODO: inject the Auth object $share->set('owner', Horde_Auth::getAuth()); + return $share; } @@ -36,7 +38,7 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return Horde_Share_Object_sql A new share object. */ - function &_newShare() + protected function _newShare() { $share = new $this->_shareObject(); return $share; @@ -59,12 +61,13 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * @param boolean $alllevels List all levels or just the direct children * of $parent? * - * @return mixed The shares the user has access to || PEAR_Error + * @return mixed The shares the user has access to + * @throws Horde_Share_Exception */ - function &listShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, - $from = 0, $count = 0, $sort_by = null, - $direction = 0, $parent = null, - $allLevels = true, $ignorePerms = false) + public function &listShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, + $from = 0, $count = 0, $sort_by = null, + $direction = 0, $parent = null, + $allLevels = true, $ignorePerms = false) { $shares = array(); if (is_null($sort_by)) { @@ -76,7 +79,7 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { } $query = 'SELECT DISTINCT s.* ' - . $this->_getShareCriteria($userid, $perm, $attributes, + . $this->getShareCriteria($userid, $perm, $attributes, $parent, $allLevels, $ignorePerms) . ' ORDER BY ' . $sortfield . (($direction == 0) ? ' ASC' : ' DESC'); @@ -86,9 +89,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { Horde::logMessage('Query By Horde_Share_sql_hierarchical: ' . $query, 'DEBUG'); $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (empty($result)) { return array(); } @@ -112,9 +115,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { . '_users WHERE share_id IN (' . implode(', ', $users) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; @@ -129,9 +132,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { . '_groups WHERE share_id IN (' . implode(', ', $groups) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; @@ -169,14 +172,15 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * children of $parent? Defaults to all levels. * * @return string The criteria string for fetching this user's shares. + * @throws Horde_Share_Exception */ - function _getShareCriteria($userid, $perm = Horde_Perms::SHOW, $attributes = null, - $parent = null, $allLevels = true, - $ignorePerms = false) + public function getShareCriteria($userid, $perm = Horde_Perms::SHOW, $attributes = null, + $parent = null, $allLevels = true, + $ignorePerms = false) { static $criteria; - if (is_a($parent, 'Horde_Share_Object')) { + if ($parent instanceof Horde_Share_Object) { $parent_id = $parent->getId(); } else { $parent_id = $parent; @@ -209,10 +213,11 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { . ' AND (' . Horde_SQL::buildClause($this->_db, 'u.perm', '&', $perm) . '))'; // If the user has any group memberships, check for those also. + // @TODO: Inject the group driver require_once 'Horde/Group.php'; $group = &Group::singleton(); $groups = $group->getGroupMemberships($userid, true); - if (!is_a($groups, 'PEAR_Error') && $groups) { + if (!($groups instanceof PEAR_Error) && $groups) { // (name == perm_groups and key in ($groups) and val & $perm) $ids = array_keys($groups); $group_ids = array(); @@ -252,10 +257,10 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { // See if we need to filter by parent or get the parent object if ($parent != null) { - if (!is_a($parent, 'Horde_Share_Object')) { + if (!($parent instanceof Horde_Share_Object)) { $parent = $this->getShareById($parent); - if (is_a($parent, 'PEAR_Error')) { - return $parent; + if ($parent instanceof PEAR_Error) { + throw new Horde_Share_Exception($parent->getMessage()); } } @@ -300,11 +305,11 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return array List of users. */ - function listOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true, - $from = 0, $count = 0) + public function listOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true, + $from = 0, $count = 0) { $sql = 'SELECT DISTINCT(s.share_owner) ' - . $this->_getShareCriteria(Horde_Auth::getAuth(), $perm, null, + . $this->getShareCriteria(Horde_Auth::getAuth(), $perm, null, $parent, $allLevels); if ($count) { @@ -312,9 +317,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { } $allowners = $this->_db->queryCol($sql); - if (is_a($allowners, 'PEAR_Error')) { + if ($allowners instanceof PEAR_Error) { Horde::logMessage($allowners, 'ERR'); - return $allowners; + throw new Horde_Share_Exception($allowners->getMessage()); } $owners = array(); @@ -341,10 +346,10 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return integer Number of users. */ - function countOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true) + public function countOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true) { $sql = 'SELECT COUNT(DISTINCT(s.share_owner)) ' - . $this->_getShareCriteria(Horde_Auth::getAuth(), $perm, null, $parent, + . $this->getShareCriteria(Horde_Auth::getAuth(), $perm, null, $parent, $allLevels); return $this->_db->queryOne($sql); @@ -357,7 +362,7 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return Horde_Share_Object The parent share, if it exists. */ - function getParent($child) + public function getParent($child) { $parents = $child->get('parents'); @@ -377,12 +382,12 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return Horde_Share_Object The requested share. */ - function &getShareById($cid) + public function getShareById($cid) { if (!isset($this->_cache[$cid])) { $share = &$this->_getShareById($cid); - if (is_a($share, 'PEAR_Error')) { - return $share; + if ($share instanceof PEAR_Error) { + throw new Horde_Share_Exception($share->getMessage()); } $share->setShareOb($this); $this->_cache[$cid] = &$share; @@ -398,8 +403,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * @param array $cids The array of ids to retrieve. * * @return array The requested shares keyed by share_id. + * @throws Horde_Share_Exception */ - function &getShares($cids) + public function getShares($cids) { $all_shares = array(); $missing_ids = array(); @@ -413,8 +419,8 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { if (count($missing_ids)) { $shares = &$this->_getShares($missing_ids); - if (is_a($shares, 'PEAR_Error')) { - return $shares; + if ($shares instanceof PEAR_Error) { + throw new Horde_Share_Exception($shares->getMessage()); } foreach (array_keys($shares) as $key) { @@ -434,15 +440,11 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * @param Horde_Share_Object $share The share to remove. * @throws Horde_Exception */ - function removeShare(&$share) + public function removeShare(Horde_Share_Object $share) { - if (!is_a($share, 'Horde_Share_Object')) { - return PEAR::raiseError('Shares must be Horde_Share_Object objects or extend that class.'); - } - try { Horde::callHook('share_remove', array($share)); - } catch (Horde_Exception_HookNotSet $e) {} + } catch (Horde_Share_Exception_HookNotSet $e) {} /* Get the list of all $share's children */ $children = $share->getChildren(null, true); @@ -454,8 +456,8 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { foreach ($children as $child) { $result = $this->_removeShare($child); - if (is_a($result, 'PEAR_Error')) { - return $result; + if ($result instanceof PEAR_Error) { + throw new Horde_Share_Exception($result->getMessage()); } } @@ -471,14 +473,14 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return array The requested shares keyed by share_id. */ - function &_getShares($ids) + protected function _getShares($ids) { $shares = array(); $query = 'SELECT * FROM ' . $this->_table . ' WHERE share_id IN (' . implode(', ', $ids) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (empty($result)) { return array(); } @@ -501,9 +503,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { $query = 'SELECT share_id, user_uid, perm FROM ' . $this->_table . '_users ' . ' WHERE share_id IN (' . implode(', ', $users) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; @@ -517,9 +519,9 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { $query = 'SELECT share_id, group_uid, perm FROM ' . $this->_table . '_groups' . ' WHERE share_id IN (' . implode(', ', $groups) . ')'; $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { + if ($result instanceof PEAR_Error) { Horde::logMessage($result, 'ERR'); - return $result; + throw new Horde_Share_Exception($result->getMessage()); } elseif (!empty($result)) { while ($share = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; @@ -539,10 +541,11 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { /** * Override the Horde_Share base class to avoid any confusion * + * @throws Horde_Share_Exception */ - function getShare($name) + public function getShare($name) { - return PEAR::raiseError(_("Share names are not supported in this driver")); + throw new Horde_Share_Exception(_("Share names are not supported in this driver")); } /** @@ -561,193 +564,14 @@ class Horde_Share_sql_hierarchical extends Horde_Share_sql { * * @return integer Number of shares the user has access to. */ - function countShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, + public function countShares($userid, $perm = Horde_Perms::SHOW, $attributes = null, $parent = null, $allLevels = true) { $query = 'SELECT COUNT(DISTINCT s.share_id) ' - . $this->_getShareCriteria($userid, $perm, $attributes, + . $this->getShareCriteria($userid, $perm, $attributes, $parent, $allLevels); return $this->_db->queryOne($query); } } - -/** - * Class for storing Share information. - */ -class Horde_Share_Object_sql_hierarchical extends Horde_Share_Object_sql { - - /** - * Constructor. This is here primarily to make calling the parent - * constructor(s) from any subclasses cleaner. - * - * @param unknown_type $data - * @return Horde_Share_Object_sql_hierarchical - */ - function Horde_Share_Object_sql_hierarchical($data) - { - if (!isset($data['share_parents'])) { - $data['share_parents'] = null; - } - parent::Horde_Share_Object_sql($data); - } - - function inheritPermissions() - { - //FIXME: Not called from anywhere yet anyway. - } - - /** - * Return a count of the number of children this share has - * - * @param integer $perm A Horde_Perms::* constant - * @param boolean $allLevels Count grandchildren or just children - * - * @return mixed The number of child shares || PEAR_Error - */ - function countChildren($perm = Horde_Perms::SHOW, $allLevels = true) - { - return $this->_shareOb->countShares(Horde_Auth::getAuth(), $perm, null, $this, $allLevels); - } - - /** - * Get all children of this share. - * - * @param int $perm Horde_Perms::* constant. If NULL will return - * all shares regardless of permissions. - * @param boolean $allLevels Return all levels. - * - * @return mixed An array of Horde_Share_Object objects || PEAR_Error - */ - function getChildren($perm = Horde_Perms::SHOW, $allLevels = true) - { - return $this->_shareOb->listShares(Horde_Auth::getAuth(), $perm, null, 0, 0, - null, 1, $this, $allLevels, is_null($perm)); - - } - - /** - * Returns a child's direct parent - * - * @return mixed The direct parent Horde_Share_Object or PEAR_Error - */ - function getParent() - { - return $this->_shareOb->getParent($this); - } - - /** - * Get all of this share's parents. - * - * @return array() An array of Horde_Share_Objects - */ - function getParents() - { - $parents = array(); - $share = $this->getParent(); - while (is_a($share, 'Horde_Share_Object')) { - $parents[] = $share; - $share = $share->getParent(); - } - return array_reverse($parents); - } - - /** - * Set the parent object for this share. - * - * @param mixed $parent A Horde_Share object or share id for the parent. - * - * @return mixed true || PEAR_Error - */ - function setParent($parent) - { - if (!is_null($parent) && !is_a($parent, 'Horde_Share_Object')) { - $parent = $this->_shareOb->getShareById($parent); - if (is_a($parent, 'PEAR_Error')) { - Horde::logMessage($parent, 'ERR'); - return $parent; - } - } - - /* If we are an existing share, check for any children */ - if ($this->getId()) { - $children = $this->_shareOb->listShares( - Horde_Auth::getAuth(), Horde_Perms::EDIT, null, 0, 0, null, 0, - $this->getId()); - } else { - $children = array(); - } - - /* Can't set a child share as a parent */ - if (!empty($parent) && in_array($parent->getId(), array_keys($children))) { - return PEAR::raiseError('Cannot set an existing child as the parent'); - } - - if (!is_null($parent)) { - $parent_string = $parent->get('parents') . ':' . $parent->getId(); - } else { - $parent_string = null; - } - $this->data['share_parents'] = $parent_string; - $query = $this->_shareOb->_write_db->prepare('UPDATE ' . $this->_shareOb->_table . ' SET share_parents = ? WHERE share_id = ?', null, MDB2_PREPARE_MANIP); - $result = $query->execute(array($this->data['share_parents'], $this->getId())); - $query->free(); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - /* Now we can reset the children's parent */ - foreach($children as $child) { - $child->setParent($this); - } - - return true; - } - - /** - * Returns the permission of this share. - * - * @return Horde_Perms_Permission Permission object that represents the - * permissions on this share. - */ - function &getPermission() - { - $perm = new Horde_Perms_Permission(''); - $perm->data = isset($this->data['perm']) - ? $this->data['perm'] - : array(); - - return $perm; - } - - /** - * Returns one of the attributes of the object, or null if it isn't - * defined. - * - * @param string $attribute The attribute to retrieve. - * - * @return mixed The value of the attribute, or an empty string. - */ - function _get($attribute) - { - if ($attribute == 'owner' || $attribute == 'parents') { - return $this->data['share_' . $attribute]; - } elseif (isset($this->data['attribute_' . $attribute])) { - return $this->data['attribute_' . $attribute]; - } else { - return null; - } - } - - /** - * Hierarchical shares do not have share names. - * - * @return unknown - */ - function _getName() - { - return ''; - } - -} diff --git a/framework/Share/package.xml b/framework/Share/package.xml index 6c081763b..e9d891fec 100644 --- a/framework/Share/package.xml +++ b/framework/Share/package.xml @@ -1,56 +1,78 @@ - + Horde_Share pear.horde.org Horde Shared Permissions System Horde_Share:: This class provides an interface to all shared -resources a user owns or has access to. - +resources a user owns or has access to. Chuck Hagenbuch chuck chuck@horde.org yes - 2006-05-08 - + 2010-05-17 + - 0.0.3 - 0.0.3 + 0.0.4 + 0.0.4 beta beta LGPL - * Converted to package.xml 2.0 for pear.horde.org. -* Split into a driver pattern. -* Simplified the API greatly, removing unused functions. -* Add a method for counting the number of shares at a certain access level. -* Add native SQL driver (duck@obala.net, Request #6109). -* Implemented extended free/busy access concept in the Kolab driver. + +* Converted to Horde 4 coding standards - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - 4.0.0 + 5.2.0 - 1.4.0b1 + 1.5.0 Perms @@ -62,10 +84,40 @@ resources a user owns or has access to. - + + + + + + + + + + + + + + + + + 0.0.1 + 0.0.1 + + + alpha + alpha + + 2003-07-05 + LGPL + +Initial release as a PEAR package + + + + 0.0.2 0.0.2 @@ -75,7 +127,8 @@ resources a user owns or has access to. 2004-10-29 LGPL - - Added countShares(). + +- Added countShares(). - listShares() and countShares() now treat the $owner argument as an optional username restricting the returned shares, not a modifier to the initial $userid. Now $userid is the user @@ -86,16 +139,37 @@ resources a user owns or has access to. - 0.0.1 - 0.0.1 + 0.0.3 + 0.0.3 - alpha - alpha + beta + beta - 2003-07-05 + 2006-05-08 + LGPL + +* Converted to package.xml 2.0 for pear.horde.org. + * Split into a driver pattern. + * Simplified the API greatly, removing unused functions. + * Add a method for counting the number of shares at a certain access level. + * Add native SQL driver (duck@obala.net, Request #6109). + * Implemented extended free/busy access concept in the Kolab driver. + + + + + 0.0.4 + 0.0.4 + + + beta + beta + + 2010-05-17 LGPL - Initial release as a PEAR package + +* Converted to Horde 4 coding standards diff --git a/horde/services/shares/edit.php b/horde/services/shares/edit.php index 33ee6c177..903463e91 100644 --- a/horde/services/shares/edit.php +++ b/horde/services/shares/edit.php @@ -40,21 +40,23 @@ $reload = false; $actionID = Horde_Util::getFormData('actionID', 'edit'); switch ($actionID) { case 'edit': - $share = &$shares->getShareById(Horde_Util::getFormData('cid')); - if (!$share instanceof PEAR_Error) { + try { + $share = &$shares->getShareById(Horde_Util::getFormData('cid')); $form = 'edit.inc'; $perm = &$share->getPermission(); - } elseif (($category = Horde_Util::getFormData('share')) !== null) { - $share = &$shares->getShare($category); - if (!$share instanceof PEAR_Error) { - $form = 'edit.inc'; - $perm = &$share->getPermission(); + } catch (Horde_Share_Exception $e) { + if (($category = Horde_Util::getFormData('share')) !== null) { + try { + $share = $shares->getShare($category); + $form = 'edit.inc'; + $perm = &$share->getPermission(); + } catch (Horde_Share_Exception $e) { + $notification->push($e->getMessage(), 'horde.error'); + } } } - if ($share instanceof PEAR_Error) { - $notification->push($share, 'horde.error'); - } elseif (!Horde_Auth::getAuth() || + if (!Horde_Auth::getAuth() || (isset($share) && !Horde_Auth::isAdmin() && Horde_Auth::getAuth() != $share->get('owner'))) { @@ -63,10 +65,13 @@ case 'edit': break; case 'editform': - $share = &$shares->getShareById(Horde_Util::getFormData('cid')); - if ($share instanceof PEAR_Error) { + try { + $share = &$shares->getShareById(Horde_Util::getFormData('cid')); + } catch (Horde_Share_Exception $e) { $notification->push(_("Attempt to edit a non-existent share."), 'horde.error'); - } else { + } + + if (!empty($share)) { if (!Horde_Auth::getAuth() || (!Horde_Auth::isAdmin() && Horde_Auth::getAuth() != $share->get('owner'))) { diff --git a/kronolith/edit.php b/kronolith/edit.php index d161cffee..6f65299c2 100644 --- a/kronolith/edit.php +++ b/kronolith/edit.php @@ -139,8 +139,7 @@ if ($exception = Horde_Util::getFormData('del_exception')) { // has permissions to do so. try { $sourceShare = Kronolith::getInternalCalendar($source); - if (!($share instanceof PEAR_Error) && - $sourceShare->hasPermission(Horde_Auth::getAuth(), Horde_Perms::DELETE) && + if ($sourceShare->hasPermission(Horde_Auth::getAuth(), Horde_Perms::DELETE) && (($user == Horde_Auth::getAuth() && $share->hasPermission(Horde_Auth::getAuth(), Horde_Perms::EDIT)) || ($user != Horde_Auth::getAuth() && diff --git a/kronolith/lib/Api.php b/kronolith/lib/Api.php index c02f70781..b39deec41 100644 --- a/kronolith/lib/Api.php +++ b/kronolith/lib/Api.php @@ -412,9 +412,6 @@ class Kronolith_Api extends Horde_Registry_Api // Remove share and all groups/permissions. $share = $GLOBALS['kronolith_shares']->getShare($calendarId); $result = $GLOBALS['kronolith_shares']->removeShare($share); - if ($result instanceof PEAR_Error) { - throw new Kronolith_Exception($result); - } } catch (Exception $e) { throw new Kronolith_Exception(sprintf(_("Unable to delete calendar \"%s\": %s"), $calendarId, $e->getMessage())); } diff --git a/kronolith/lib/Driver/Sql.php b/kronolith/lib/Driver/Sql.php index 1b282aa0e..0490f102b 100644 --- a/kronolith/lib/Driver/Sql.php +++ b/kronolith/lib/Driver/Sql.php @@ -588,9 +588,10 @@ class Kronolith_Driver_Sql extends Kronolith_Driver $tagger->replaceTags($event->uid, $event->tags, $event->creator, 'event'); /* Add tags again, but as the share owner (replaceTags removes ALL tags). */ - $cal = $GLOBALS['kronolith_shares']->getShare($event->calendar); - if ($cal instanceof PEAR_Error) { - throw new Kronolith_Exception($cal); + try { + $cal = $GLOBALS['kronolith_shares']->getShare($event->calendar); + } catch (Horde_Share_Exception $e) { + throw new Kronolith_Exception($e); } $tagger->tag($event->uid, $event->tags, $cal->get('owner'), 'event'); @@ -656,8 +657,12 @@ class Kronolith_Driver_Sql extends Kronolith_Driver /* Add tags again, but as the share owner (replaceTags removes ALL * tags). */ - $cal = $GLOBALS['kronolith_shares']->getShare($event->calendar); - $this->handleError($cal); + try { + $cal = $GLOBALS['kronolith_shares']->getShare($event->calendar); + } catch (Horde_Share_Exception $e) { + Horde::logMessage($e->getMessage(), 'ERR'); + throw new Kronolith_Exception($e); + } $tagger->tag($event->uid, $event->tags, $cal->get('owner'), 'event'); /* Update Geolocation */ @@ -970,8 +975,12 @@ class Kronolith_Driver_Sql extends Kronolith_Driver throw new Horde_Exception_PermissionDenied(); } - $shares = $GLOBALS['kronolith_shares']->listShares($user, Horde_Perms::EDIT); - $this->handleError($shares); + try { + $shares = $GLOBALS['kronolith_shares']->listShares($user, Horde_Perms::EDIT); + } catch (Horde_Share_Exception $e) { + Horde::logMessage($shares, 'ERR'); + throw new Kronolith_Exception($shares); + } foreach (array_keys($shares) as $calendar) { $ids = Kronolith::listEventIds(null, null, $calendar); diff --git a/kronolith/lib/FreeBusy.php b/kronolith/lib/FreeBusy.php index 3425f0daf..8f0f4c1d8 100644 --- a/kronolith/lib/FreeBusy.php +++ b/kronolith/lib/FreeBusy.php @@ -32,8 +32,10 @@ class Kronolith_FreeBusy } /* Fetch the appropriate share and check permissions. */ - $share = $kronolith_shares->getShare($calendar[0]); - if ($share instanceof PEAR_Error) { + try { + $share = $kronolith_shares->getShare($calendar[0]); + $owner = $share->get('owner'); + } catch (Horde_Share_Exception $e) { // Might be a Kronolith_Resource try { $resource = Kronolith_Resource::isResourceCalendar($calendar[0]); @@ -41,8 +43,6 @@ class Kronolith_FreeBusy } catch (Horde_Exception $e) { return $returnObj ? $share : ''; } - } else { - $owner = $share->get('owner'); } /* Default the start date to today. */ diff --git a/kronolith/perms.php b/kronolith/perms.php index 3a3289b54..62d994bde 100644 --- a/kronolith/perms.php +++ b/kronolith/perms.php @@ -27,17 +27,21 @@ $reload = false; $actionID = Horde_Util::getFormData('actionID', 'edit'); switch ($actionID) { case 'edit': - $share = $shares->getShareById(Horde_Util::getFormData('cid')); - if (!($share instanceof PEAR_Error)) { + try { + $share = $shares->getShareById(Horde_Util::getFormData('cid')); $perm = $share->getPermission(); - } elseif (($category = Horde_Util::getFormData('share')) !== null) { - try { - $share = $shares->getShare($category); + } catch (Horde_Share_Exception $e) { + if (($category = Horde_Util::getFormData('share')) !== null) { + try { + $share = $shares->getShare($category); + $perm = $share->getPermission(); + } catch (Exception $e) { + $notification->push($e, 'horde.error'); + } $perm = $share->getPermission(); - } catch (Exception $e) { - $notification->push($e, 'horde.error'); } } + if (!Horde_Auth::getAuth() || (isset($share) && !Horde_Auth::isAdmin() && @@ -47,10 +51,8 @@ case 'edit': break; case 'editform': - $share = $shares->getShareById(Horde_Util::getFormData('cid')); - if ($share instanceof PEAR_Error) { - $notification->push(_("Attempt to edit a non-existent share."), 'horde.error'); - } else { + try { + $share = $shares->getShareById(Horde_Util::getFormData('cid')); if (!Horde_Auth::getAuth() || (!Horde_Auth::isAdmin() && Horde_Auth::getAuth() != $share->get('owner'))) { @@ -71,11 +73,14 @@ case 'editform': $notification->push($e, 'horde.error'); } $perm = $share->getPermission(); + } catch (Horde_Share_Exception $e) { + $notification->push(_("Attempt to edit a non-existent share."), 'horde.error'); } + break; } -if ($share instanceof PEAR_Error) { +if (empty($share)) { $title = _("Edit Permissions"); } else { $title = sprintf(_("Edit Permissions for %s"), $share->get('name')); diff --git a/whups/lib/Query.php b/whups/lib/Query.php index b17dc9ef2..07c503a0b 100644 --- a/whups/lib/Query.php +++ b/whups/lib/Query.php @@ -11,9 +11,6 @@ * @package Whups */ -/** Horde_Share */ -require_once 'Horde/Share.php'; - /** Horde_Form_Action */ require_once 'Horde/Form/Action.php'; -- 2.11.0