From 41371a2a2760aa0d684dfeb4f7764293fd947388 Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Fri, 21 Jan 2011 21:03:01 -0500 Subject: [PATCH] Move hierarchical functionality into The Sql and Sqlng share drivers. Ansel is refactored to use the Sql driver for now. More refactoring is needed before it can be switched back and forth between any drivers. (Need to compose Horde_Share_Object with Ansel_Gallery instead of Ansel_Gallery extending the share object). Squashed commit of the following: commit ed76634819d4e6c1737366d5ffafbfcc0630d12c Author: Michael J. Rubinsky Date: Fri Jan 21 20:59:26 2011 -0500 Need to check against share ids in Ansel, not share_names commit eb742b3414c3f27978beaa3c933f65f0e243efb2 Author: Michael J. Rubinsky Date: Fri Jan 21 20:38:09 2011 -0500 Cleanup/small refactoring for merged hierarchical driver commit b3e50233d7288f3007ddea45cb35e0724c664aed Author: Michael J. Rubinsky Date: Fri Jan 21 20:28:16 2011 -0500 extend Horde_Share_Object_Sql for now. Need to refactor so Ansel_Gallery is composed with Horde_Share_Object instead of extending it. commit bb79f1f43aa7374cee325a70fd6849f52086ec75 Author: Michael J. Rubinsky Date: Fri Jan 21 20:23:56 2011 -0500 Simplify commit 76ae1f5d2bb28a9267e336d912f4bd2cc49a4894 Author: Michael J. Rubinsky Date: Fri Jan 21 16:37:14 2011 -0500 Merge hierarchical functionality into base sql and sqlng drivers. --- ansel/lib/Ansel.php | 31 +- ansel/lib/Gallery.php | 12 +- ansel/lib/Injector/Factory/Storage.php | 2 +- ansel/lib/Storage.php | 13 +- ansel/lib/View/Gallery.php | 24 +- ansel/lib/View/GalleryProperties.php | 1 + ansel/lib/View/GalleryRenderer/Base.php | 16 +- ansel/lib/View/GalleryRenderer/Gallery.php | 51 +- .../migration/8_ansel_upgrade_sqlhierarchical.php | 47 ++ framework/Share/lib/Horde/Share/Base.php | 30 +- framework/Share/lib/Horde/Share/Kolab.php | 17 + framework/Share/lib/Horde/Share/Object/Sql.php | 119 +++- .../lib/Horde/Share/Object/Sql/Hierarchical.php | 270 ++++---- framework/Share/lib/Horde/Share/Sql.php | 282 ++++++-- .../Share/lib/Horde/Share/Sql/Hierarchical.php | 708 ++++++++++----------- framework/Share/lib/Horde/Share/Sqlng.php | 87 ++- framework/Share/test/Horde/Share/Base.php | 95 ++- framework/Share/test/Horde/Share/Sql/Base.php | 9 + .../Share/test/Horde/Share/Sql/Pdo/MysqlTest.php | 6 +- .../Share/test/Horde/Share/Sql/Pdo/PgsqlTest.php | 6 +- .../Share/test/Horde/Share/Sql/Pdo/SqliteTest.php | 6 +- .../test/Horde/Share/SqlHierarchical/Base.php | 7 +- .../Horde/Share/SqlHierarchical/Pdo/MysqlTest.php | 6 +- .../Horde/Share/SqlHierarchical/Pdo/PgsqlTest.php | 6 +- .../Horde/Share/SqlHierarchical/Pdo/SqliteTest.php | 6 +- framework/Share/test/Horde/Share/Sqlng/Base.php | 9 + framework/Share/test/Horde/Share/migration/sql.php | 1 + .../Share/test/Horde/Share/migration/sqlng.php | 1 + 28 files changed, 1157 insertions(+), 711 deletions(-) create mode 100644 ansel/migration/8_ansel_upgrade_sqlhierarchical.php diff --git a/ansel/lib/Ansel.php b/ansel/lib/Ansel.php index 89a5d6e50..1fff82b46 100644 --- a/ansel/lib/Ansel.php +++ b/ansel/lib/Ansel.php @@ -64,7 +64,6 @@ class Ansel * the filters. Can be an array of attribute/values * pairs or a gallery owner username. * (boolean)all_levels - * (integer)parent The parent share to start listing at. * (integer)from The gallery to start listing at. * (integer)count The number of galleries to return. * (integer)ignore An Ansel_Gallery id to ignore when building the tree. @@ -79,38 +78,28 @@ class Ansel ->listGalleries($params); $params = new Horde_Support_Array($params); - $tree = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Tree')->create('gallery_tree', 'Select'); - /* Remove the ignored gallery, make sure it's also not the selected - * gallery */ + $tree = $GLOBALS['injector'] + ->getInstance('Horde_Core_Factory_Tree') + ->create('gallery_tree', 'Select'); + + // Remove the ignored gallery, make sure it's also not the selected if ($params->ignore) { if ($params->selected == $params->ignore) { $params->selected = null; } } - foreach ($galleries as $gallery_id => $gallery) { - // We don't use $gallery->getParents() on purpose since we - // only need the count of parents. This potentially saves a number - // of DB queries. - $parents = $gallery->get('parents'); - $indents = empty($parents) ? 0 : substr_count($parents, ':') + 1; + foreach ($galleries as $gallery) { + $gallery_id = $gallery->getId(); $gallery_name = $gallery->get('name'); + $label = Horde_String::abbreviate($gallery_name); $len = Horde_String::length($gallery_name); - if ($len > 30) { - $label = Horde_String::substr($gallery_name, 0, 30) . '...'; - } else { - $label = $gallery_name; - } $treeparams = array(); $treeparams['selected'] = $gallery_id == $params->selected; $parent = $gallery->getParent(); - $parent = (empty($params['parent'])) ? null : $params['parent']->id; - if ((!empty($params['parent']) && !empty($galleries[$params['parent']])) || - (empty($params['parent']))) { - - $tree->addNode($gallery->id, $parent, $label, $indents, true, $treeparams); - } + $parent = empty($parent) ? null : $parent->getId(); + $tree->addNode($gallery->id, $parent, $label, null, true, $treeparams); } return $tree->getTree(); diff --git a/ansel/lib/Gallery.php b/ansel/lib/Gallery.php index b9fea4582..79fdda2a3 100644 --- a/ansel/lib/Gallery.php +++ b/ansel/lib/Gallery.php @@ -11,7 +11,7 @@ * @author Michael J. Rubinsky * @package Ansel */ -class Ansel_Gallery extends Horde_Share_Object_Sql_Hierarchical implements Serializable +class Ansel_Gallery extends Horde_Share_Object_Sql implements Serializable { /** * The gallery mode helper @@ -27,10 +27,13 @@ class Ansel_Gallery extends Horde_Share_Object_Sql_Hierarchical implements Seria */ public function __construct($attributes = array()) { - /* Pass on up the chain */ parent::__construct($attributes); - $GLOBALS['injector']->getInstance('Ansel_Storage')->shares->initShareObject($this); - $this->_setModeHelper(isset($attributes['attribute_view_mode']) ? $attributes['attribute_view_mode'] : 'Normal'); + $GLOBALS['injector']->getInstance('Ansel_Storage') + ->shares->initShareObject($this); + + $this->_setModeHelper(isset($attributes['attribute_view_mode']) ? + $attributes['attribute_view_mode'] : + 'Normal'); } /** @@ -77,6 +80,7 @@ class Ansel_Gallery extends Horde_Share_Object_Sql_Hierarchical implements Seria /** * Simple factory to set the proper mode object. * + * @TODO: Use DI * @param string $type The mode to use * * @return Ansel_Gallery_Mode object diff --git a/ansel/lib/Injector/Factory/Storage.php b/ansel/lib/Injector/Factory/Storage.php index f964e93df..c22cfb3b7 100644 --- a/ansel/lib/Injector/Factory/Storage.php +++ b/ansel/lib/Injector/Factory/Storage.php @@ -44,7 +44,7 @@ class Ansel_Injector_Factory_Storage { $scope = $this->_injector->getInstance('Ansel_Config')->get('scope'); if (empty($this->_instances[$scope])) { - $this->_instances[$scope] = new Ansel_Storage($this->_injector->getInstance('Horde_Core_Factory_Share')->create($scope, 'Sql_Hierarchical')); + $this->_instances[$scope] = new Ansel_Storage($this->_injector->getInstance('Horde_Core_Factory_Share')->create($scope, 'Sql')); } return $this->_instances[$scope]; diff --git a/ansel/lib/Storage.php b/ansel/lib/Storage.php index dee5fdd57..574fde1c6 100644 --- a/ansel/lib/Storage.php +++ b/ansel/lib/Storage.php @@ -121,7 +121,7 @@ class Ansel_Storage /* Create the gallery */ try { - $gallery = $this->_shares->newShare($GLOBALS['registry']->getAuth(), ''); + $gallery = $this->_shares->newShare($GLOBALS['registry']->getAuth(), strval(new Horde_Support_Randomid())); } catch (Horde_Share_Exception $e) { Horde::logMessage($e->getMessage, 'ERR'); throw new Ansel_Exception($e); @@ -722,7 +722,7 @@ class Ansel_Storage public function galleryExists($gallery_id = null, $slug = null) { if (empty($slug)) { - $results = $this->_shares->exists($gallery_id); + $results = $this->_shares->idExists($gallery_id); } else { $results = $this->_shares->countShares($GLOBALS['registry']->getAuth(), Horde_Perms::READ, array('slug' => $slug)); } @@ -745,11 +745,11 @@ class Ansel_Storage * @param boolean $allLevels Return all levels, or just the direct * children of $parent? Defaults to all levels. * - * @return int The count + * @return integer The count * @throws Ansel_Exception */ - public function countGalleries($userid, $perm = Horde_Perms::SHOW, $attributes = null, - $parent = null, $allLevels = true) + public function countGalleries($userid, $perm = Horde_Perms::SHOW, + $attributes = null, $parent = null, $allLevels = true) { static $counts; @@ -757,6 +757,9 @@ class Ansel_Storage $parent_id = $parent->getId(); } else { $parent_id = $parent; + if (!is_null($parent)) { + $parent = $this->_shares->getShare($parent); + } } $key = "$userid,$perm,$parent_id,$allLevels" . serialize($attributes); diff --git a/ansel/lib/View/Gallery.php b/ansel/lib/View/Gallery.php index 9384761fa..3f1679e6a 100644 --- a/ansel/lib/View/Gallery.php +++ b/ansel/lib/View/Gallery.php @@ -46,13 +46,13 @@ class Ansel_View_Gallery extends Ansel_View_Base 'month' => isset($this->_params['month']) ? $this->_params['month'] : 0, 'day' => isset($this->_params['day']) ? $this->_params['day'] : 0)); - $galleryurl = Ansel::getUrlFor('view', array_merge( - array('gallery' => $this->gallery->id, - 'slug' => empty($params['slug']) ? '' : $params['slug'], - 'page' => empty($params['page']) ? 0 : $params['page'], - 'view' => 'Gallery'), - $date), - true); + $galleryurl = Ansel::getUrlFor('view', array_merge( + array('gallery' => $this->gallery->id, + 'slug' => empty($params['slug']) ? '' : $params['slug'], + 'page' => empty($params['page']) ? 0 : $params['page'], + 'view' => 'Gallery'), + $date), + true); $params = array('gallery' => $this->gallery->id, 'url' => $galleryurl); Horde::url('disclamer.php')->add($params)->setRaw(true)->redirect(); @@ -61,7 +61,7 @@ class Ansel_View_Gallery extends Ansel_View_Base if ($this->gallery->hasPasswd()) { if (!empty($params['api'])) { - return PEAR::raiseError(_("Locked galleries are not viewable via the api.")); + throw new Ansel_Exception(_("Locked galleries are not viewable via the api.")); } $date = Ansel::getDateParameter( array('year' => isset($this->_params['year']) ? $this->_params['year'] : 0, @@ -85,12 +85,10 @@ class Ansel_View_Gallery extends Ansel_View_Base throw new Horde_Exception('Access denied viewing this gallery.'); } - // Since this is a gallery view, the resource is just a reference to the - // gallery. We keep both instance variables becuase both gallery and - // image views are assumed to have a gallery object. + // Since this is a gallery view, the resource is the gallery. $this->resource = $this->gallery; - /* Do we have an explicit style set? If not, use the gallery's */ + // Do we have an explicit style set? If not, use the gallery's if (!empty($this->_params['style'])) { $style = Ansel::getStyleDefinition($this->_params['style']); } else { @@ -103,7 +101,7 @@ class Ansel_View_Gallery extends Ansel_View_Base $renderer = (!empty($style->gallery_view)) ? $style->gallery_view : 'Gallery'; } - /* Load the helper */ + // Load the helper $classname = 'Ansel_View_GalleryRenderer_' . basename($renderer); $this->_renderer = new $classname($this); $this->_renderer->init(); diff --git a/ansel/lib/View/GalleryProperties.php b/ansel/lib/View/GalleryProperties.php index 6711659a4..f5a8b0660 100644 --- a/ansel/lib/View/GalleryProperties.php +++ b/ansel/lib/View/GalleryProperties.php @@ -254,6 +254,7 @@ class Ansel_View_GalleryProperties if (empty($gallery_parent)) { $gallery_parent = null; } + if ($galleryId && ($exists = ($GLOBALS['injector']->getInstance('Ansel_Storage')->galleryExists($galleryId)) === true)) { diff --git a/ansel/lib/View/GalleryRenderer/Base.php b/ansel/lib/View/GalleryRenderer/Base.php index 9b710a200..e5eb482ae 100644 --- a/ansel/lib/View/GalleryRenderer/Base.php +++ b/ansel/lib/View/GalleryRenderer/Base.php @@ -131,34 +131,31 @@ abstract class Ansel_View_GalleryRenderer_Base $this->gallerySlug = $this->view->gallery->get('slug'); $this->page = $this->view->page; - /* Number perpage from prefs or config */ + // Number perpage from prefs or config if ($this->view->tilesperpage) { $this->perpage = $this->view->tilesperpage; } else { $this->perpage = min($prefs->getValue('tilesperpage'), $conf['thumbnail']['perpage']); } - - /* Calculate the starting and ending images on this page */ $this->pagestart = ($this->page * $this->perpage) + 1; - /* Fetch the children */ + // Fetch the children $this->fetchChildren($this->view->force_grouping); // Do we have an explicit style set from the API? - // If not, use the gallery's + // If not, use the gallery's if (!empty($this->view->style)) { $this->style = Ansel::getStyleDefinition($this->view->style); } else { $this->style = $this->view->gallery->getStyle(); } - /* Include any widgets */ + // Include any widgets if (!empty($this->style->widgets) && !$this->view->api) { - - /* Special case widgets - these are built in */ + // Special case widgets - these are built in if (array_key_exists('Actions', $this->style->widgets)) { - /* Don't show action widget if no actions */ + // Don't show action widget if no actions if ($GLOBALS['registry']->getAuth() || !empty($conf['report_content']['driver']) && (($conf['report_content']['allow'] == 'authenticated' && @@ -184,7 +181,6 @@ abstract class Ansel_View_GalleryRenderer_Base /** * Default implementation for fetching children/images for this view. * Other view classes can override this if they need anything special. - * */ public function fetchChildren($noauto) { diff --git a/ansel/lib/View/GalleryRenderer/Gallery.php b/ansel/lib/View/GalleryRenderer/Gallery.php index 5736e0280..20cc8c995 100644 --- a/ansel/lib/View/GalleryRenderer/Gallery.php +++ b/ansel/lib/View/GalleryRenderer/Gallery.php @@ -32,7 +32,6 @@ class Ansel_View_GalleryRenderer_Gallery extends Ansel_View_GalleryRenderer_Base * Return the HTML representing this view. * * @return string The HTML. - * */ public function html() { @@ -45,20 +44,28 @@ class Ansel_View_GalleryRenderer_Gallery extends Ansel_View_GalleryRenderer_Base $owner = $galleryOwner; } - /* Only need these if not being called via the api */ if (empty($this->view->api)) { - $option_edit = $this->view->gallery->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT); - $option_select = $option_delete = $this->view->gallery->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE); - $option_move = ($option_delete && $GLOBALS['injector']->getInstance('Ansel_Storage')->countGalleries(Horde_Perms::EDIT)); - $option_copy = ($option_edit && $GLOBALS['injector']->getInstance('Ansel_Storage')->countGalleries(Horde_Perms::EDIT)); + $option_edit = $this->view->gallery->hasPermission( + $GLOBALS['registry']->getAuth(), Horde_Perms::EDIT); + + $option_select = $option_delete = $this->view->gallery->hasPermission( + $GLOBALS['registry']->getAuth(), Horde_Perms::DELETE); + + $option_move = ($option_delete && $GLOBALS['injector'] + ->getInstance('Ansel_Storage') + ->countGalleries(Horde_Perms::EDIT)); + + $option_copy = ($option_edit && $GLOBALS['injector'] + ->getInstance('Ansel_Storage') + ->countGalleries(Horde_Perms::EDIT)); - /* See if we requested a show_actions change */ + // See if we requested a show_actions change if (Horde_Util::getFormData('actionID', '') == 'show_actions') { $prefs->setValue('show_actions', (int)!$prefs->getValue('show_actions')); } } - /* Set up the pager */ + // Set up the pager $date_params = Ansel::getDateParameter( array('year' => !empty($this->view->year) ? $this->view->year : 0, 'month' => !empty($this->view->month) ? $this->view->month : 0, @@ -72,11 +79,9 @@ class Ansel_View_GalleryRenderer_Gallery extends Ansel_View_GalleryRenderer_Base $pagerurl = new Horde_Url(str_replace(array('%g', '%s'), array($this->galleryId, $this->gallerySlug), urldecode($this->view->gallery_view_url))); $pagerurl->add($date_params); } else { - /* - * Build the pager url. Add the needed variables directly to the - * url instead of passing it as a preserved variable to the pager - * since the logic to build the URL is already in getUrlFor() - */ + // Build the pager url. Add the needed variables directly to the + // url instead of passing it as a preserved variable to the pager + // since the logic to build the URL is already in getUrlFor() $pager_params = array_merge( array('gallery' => $this->galleryId, 'view' => 'Gallery', @@ -85,17 +90,13 @@ class Ansel_View_GalleryRenderer_Gallery extends Ansel_View_GalleryRenderer_Base $pagerurl = Ansel::getUrlfor('view', $pager_params, true); } - /* See what callback to use to tweak the pager urls */ - if (!empty($this->view->urlCallback)) { - $callback = $this->view->urlCallback; - } else { - $callback = null; - } - $params = array('num' => $this->numTiles, - 'url' => $pagerurl, - 'perpage' => $this->perpage, - 'url_callback' => $callback); - + // See what callback to use to tweak the pager urls + $params = array( + 'num' => $this->numTiles, + 'url' => $pagerurl, + 'perpage' => $this->perpage, + 'url_callback' => empty($this->view->urlCallback) ? null : $this->view->urlCallback, + ); $pager = new Horde_Core_Ui_Pager('page', $vars, $params); Horde::startBuffer(); @@ -105,7 +106,7 @@ class Ansel_View_GalleryRenderer_Gallery extends Ansel_View_GalleryRenderer_Base $includes->includeFiles(); } - /* Needed in the template files */ + // Needed in the template files $tilesperrow = $prefs->getValue('tilesperrow'); $cellwidth = round(100 / $tilesperrow); $count = 0; diff --git a/ansel/migration/8_ansel_upgrade_sqlhierarchical.php b/ansel/migration/8_ansel_upgrade_sqlhierarchical.php new file mode 100644 index 000000000..64a8cf50e --- /dev/null +++ b/ansel/migration/8_ansel_upgrade_sqlhierarchical.php @@ -0,0 +1,47 @@ + + * @category Horde + * @license http://www.fsf.org/copyleft/gpl.html GPL + * @package Ansel + */ +class AnselUpgradeSqlHierarchical extends Horde_Db_Migration_Base +{ + /** + * Upgrade. + */ + public function up() + { + $this->removeIndex('ansel_shares', 'share_parents'); + $this->addColumn('ansel_shares', 'share_name', 'string', array('limit' => 255, 'null' => false)); + $this->changeColumn('ansel_shares', 'share_parents', 'text'); + + // Add sharenames + $sql = 'SELECT share_id FROM ansel_shares;'; + $ids = $this->_connection->selectValues($sql); + $sql = 'UPDATE ansel_shares SET share_name = ? WHERE share_id = ?'; + foreach ($ids as $id) { + $params = array(strval(new Horde_Support_Randomid()), $id); + $this->_connection->update($sql, $params); + } + } + + /** + * Downgrade + * + */ + public function down() + { + $this->removeColumn('ansel_shares', 'share_name'); + $this->changeColumn('ansel_shares', 'share_parents', 'string', array('limit' => 255)); + $this->addIndex('ansel_shares', array('share_parents')); + } + +} diff --git a/framework/Share/lib/Horde/Share/Base.php b/framework/Share/lib/Horde/Share/Base.php index 343126acd..1eae0936e 100644 --- a/framework/Share/lib/Horde/Share/Base.php +++ b/framework/Share/lib/Horde/Share/Base.php @@ -494,9 +494,9 @@ abstract class Horde_Share_Base abstract protected function _removeShare(Horde_Share_Object $share); /** - * Checks if a share exists in the system. + * Checks if a share name exists in the system. * - * @param string $share The share to check. + * @param string $share The share name to check. * * @return boolean True if the share exists. */ @@ -510,6 +510,23 @@ abstract class Horde_Share_Base } /** + * Check that a share id exists in the system. + * + * @param integer $id The share id + * + * @return boolean True if the share exists. + */ + public function idExists($id) + { + if (isset($this->_shareMap[$id])) { + return true; + } + + return $this->_idExists($id); + } + + + /** * Checks if a share exists in the system. * * @param string $share The share to check. @@ -520,6 +537,15 @@ abstract class Horde_Share_Base abstract protected function _exists($share); /** + * Check that a share id exists in the system. + * + * @param integer $id The share id + * + * @return boolean True if the share exists. + */ + abstract protected function _idExists($id); + + /** * Finds out what rights the given user has to this object. * * @see Horde_Perms::getPermissions diff --git a/framework/Share/lib/Horde/Share/Kolab.php b/framework/Share/lib/Horde/Share/Kolab.php index c509a9a06..cac026674 100644 --- a/framework/Share/lib/Horde/Share/Kolab.php +++ b/framework/Share/lib/Horde/Share/Kolab.php @@ -204,6 +204,23 @@ class Horde_Share_Kolab extends Horde_Share_Base } /** + * Check that a share id exists in the system. + * + * @param integer $id The share id + * + * @return boolean True if the share exists. + */ + protected function _idExists($id) + { + try { + $share = $this->_getShare($id); + return true; + } catch (Horde_Exception_NotFound $e) { + return false; + } + } + + /** * Returns an array of all shares that $userid has access to. * * @param string $userid The userid of the user to check access for. diff --git a/framework/Share/lib/Horde/Share/Object/Sql.php b/framework/Share/lib/Horde/Share/Object/Sql.php index a8f8656ed..95ad99d8c 100644 --- a/framework/Share/lib/Horde/Share/Object/Sql.php +++ b/framework/Share/lib/Horde/Share/Object/Sql.php @@ -29,6 +29,9 @@ class Horde_Share_Object_Sql extends Horde_Share_Object implements Serializable */ public function __construct($data) { + if (!isset($data['share_parents'])) { + $data['share_parents'] = null; + } if (!isset($data['perm']) || !is_array($data['perm'])) { $this->data['perm'] = array( 'users' => array(), @@ -107,10 +110,12 @@ class Horde_Share_Object_Sql extends Horde_Share_Object implements Serializable */ public function get($attribute) { - if ($attribute == 'owner') { - return $this->data['share_owner']; + if ($attribute == 'owner' || $attribute == 'parents') { + return $this->data['share_' . $attribute]; } elseif (isset($this->data['attribute_' . $attribute])) { return $this->data['attribute_' . $attribute]; + } else { + return null; } } @@ -135,6 +140,116 @@ class Horde_Share_Object_Sql extends Horde_Share_Object implements Serializable } /** + * Return a count of the number of children this share has + * + * @param string $user The user to use for checking perms + * @param integer $perm A Horde_Perms::* constant + * @param boolean $allLevels Count grandchildren or just children + * + * @return integer The number of child shares + */ + public function countChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true) + { + return $this->getShareOb()->countShares($user, $perm, null, $this, $allLevels); + } + + /** + * Get all children of this share. + * + * @param string $user The user to use for checking perms + * @param integer $perm Horde_Perms::* constant. If NULL will return + * all shares regardless of permissions. + * @param boolean $allLevels Return all levels. + * + * @return array An array of Horde_Share_Object objects + */ + public function getChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true) + { + return $this->getShareOb()->listShares( + $user, array('perm' => $perm, + 'direction' => 1, + 'parent' => $this, + 'all_levels' => $allLevels)); + } + + /** + * Returns a child's direct parent + * + * @return Horde_Share_Object The direct parent Horde_Share_Object + */ + public function getParent() + { + return $this->getShareOb()->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 ($share instanceof 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 boolean + */ + public function setParent($parent) + { + if (!is_null($parent) && !is_a($parent, 'Horde_Share_Object')) { + $parent = $this->getShareOb()->getShareById($parent); + } + + /* If we are an existing share, check for any children */ + if ($this->getId()) { + $children = $this->getShareOb()->listShares(null, + array('perm' => null, + 'parent' => $this, + 'all_levels' => true)); + } 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; + $sql = 'UPDATE ' . $this->getShareOb()->getTable() . ' SET share_parents = ? WHERE share_id = ?'; + try { + $this->getShareOb()->getStorage()->update($sql, array($this->data['share_parents'], $this->getId())); + } catch (Horde_Db_Exception $e) { + throw new Horde_Share_Exception($e->getMessage()); + } + + /* Now we can reset the children's parent */ + foreach ($children as $child) { + $child->setParent($this); + } + + $this->_shareOb->expireListCache(); + return true; + } + + /** * Saves the current attribute values. */ protected function _save() diff --git a/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php b/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php index 73d6bc8bf..d33d0e01b 100644 --- a/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php +++ b/framework/Share/lib/Horde/Share/Object/Sql/Hierarchical.php @@ -10,146 +10,146 @@ */ class Horde_Share_Object_Sql_Hierarchical extends Horde_Share_Object_Sql { - /** - * Constructor. - * - * @param array $data - * - * @return Horde_Share_Object_sql_hierarchical - */ - public function __construct($data) - { - if (!isset($data['share_parents'])) { - $data['share_parents'] = null; - } - parent::__construct($data); - } +// /** +// * Constructor. +// * +// * @param array $data +// * +// * @return Horde_Share_Object_sql_hierarchical +// */ +// public function __construct($data) +// { +// if (!isset($data['share_parents'])) { +// $data['share_parents'] = null; +// } +// parent::__construct($data); +// } - /** - * Return a count of the number of children this share has - * - * @param string $user The user to use for checking perms - * @param integer $perm A Horde_Perms::* constant - * @param boolean $allLevels Count grandchildren or just children - * - * @return integer The number of child shares - */ - public function countChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true) - { - return $this->getShareOb()->countShares($user, $perm, null, $this, $allLevels); - } +// /** +// * Return a count of the number of children this share has +// * +// * @param string $user The user to use for checking perms +// * @param integer $perm A Horde_Perms::* constant +// * @param boolean $allLevels Count grandchildren or just children +// * +// * @return integer The number of child shares +// */ +// public function countChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true) +// { +// return $this->getShareOb()->countShares($user, $perm, null, $this, $allLevels); +// } - /** - * Get all children of this share. - * - * @param string $user The user to use for checking perms - * @param integer $perm Horde_Perms::* constant. If NULL will return - * all shares regardless of permissions. - * @param boolean $allLevels Return all levels. - * - * @return array An array of Horde_Share_Object objects - */ - public function getChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true) - { - return $this->getShareOb()->listShares( - $user, array('perm' => $perm, - 'direction' => 1, - 'parent' => $this, - 'all_levels' => $allLevels)); - } +// /** +// * Get all children of this share. +// * +// * @param string $user The user to use for checking perms +// * @param integer $perm Horde_Perms::* constant. If NULL will return +// * all shares regardless of permissions. +// * @param boolean $allLevels Return all levels. +// * +// * @return array An array of Horde_Share_Object objects +// */ +// public function getChildren($user, $perm = Horde_Perms::SHOW, $allLevels = true) +// { +// return $this->getShareOb()->listShares( +// $user, array('perm' => $perm, +// 'direction' => 1, +// 'parent' => $this, +// 'all_levels' => $allLevels)); +// } - /** - * Returns a child's direct parent - * - * @return Horde_Share_Object The direct parent Horde_Share_Object - */ - public function getParent() - { - return $this->getShareOb()->getParent($this); - } +// /** +// * Returns a child's direct parent +// * +// * @return Horde_Share_Object The direct parent Horde_Share_Object +// */ +// public function getParent() +// { +// return $this->getShareOb()->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 ($share instanceof Horde_Share_Object) { +// $parents[] = $share; +// $share = $share->getParent(); +// } +// +// return array_reverse($parents); +// } - /** - * Get all of this share's parents. - * - * @return array() An array of Horde_Share_Objects - */ - public function getParents() - { - $parents = array(); - $share = $this->getParent(); - while ($share instanceof Horde_Share_Object) { - $parents[] = $share; - $share = $share->getParent(); - } +// /** +// * Set the parent object for this share. +// * +// * @param mixed $parent A Horde_Share object or share id for the parent. +// * +// * @return boolean +// */ +// public function setParent($parent) +// { +// if (!is_null($parent) && !is_a($parent, 'Horde_Share_Object')) { +// $parent = $this->getShareOb()->getShareById($parent); +// } +// +// /* If we are an existing share, check for any children */ +// if ($this->getId()) { +// $children = $this->getShareOb()->listShares(null, +// array('perm' => null, +// 'parent' => $this, +// 'all_levels' => true)); +// } 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; +// $sql = 'UPDATE ' . $this->getShareOb()->getTable() . ' SET share_parents = ? WHERE share_id = ?'; +// try { +// $this->getShareOb()->getStorage()->update($sql, array($this->data['share_parents'], $this->getId())); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e->getMessage()); +// } +// +// /* Now we can reset the children's parent */ +// foreach ($children as $child) { +// $child->setParent($this); +// } +// +// $this->_shareOb->expireListCache(); +// return true; +// } - 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 boolean - */ - public function setParent($parent) - { - if (!is_null($parent) && !is_a($parent, 'Horde_Share_Object')) { - $parent = $this->getShareOb()->getShareById($parent); - } - - /* If we are an existing share, check for any children */ - if ($this->getId()) { - $children = $this->getShareOb()->listShares(null, - array('perm' => null, - 'parent' => $this, - 'all_levels' => true)); - } 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; - $sql = 'UPDATE ' . $this->getShareOb()->getTable() . ' SET share_parents = ? WHERE share_id = ?'; - try { - $this->getShareOb()->getStorage()->update($sql, array($this->data['share_parents'], $this->getId())); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e->getMessage()); - } - - /* Now we can reset the children's parent */ - foreach ($children as $child) { - $child->setParent($this); - } - - $this->_shareOb->expireListCache(); - 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 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 diff --git a/framework/Share/lib/Horde/Share/Sql.php b/framework/Share/lib/Horde/Share/Sql.php index 96c5064f3..3d1284676 100644 --- a/framework/Share/lib/Horde/Share/Sql.php +++ b/framework/Share/lib/Horde/Share/Sql.php @@ -241,7 +241,7 @@ class Horde_Share_Sql extends Horde_Share_Base } /** - * Returns an array of Horde_Share_Object_sql objects corresponding + * Returns an array of Horde_Share_Object objects corresponding * to the given set of unique IDs, with the details retrieved * appropriately. * @@ -251,7 +251,7 @@ class Horde_Share_Sql extends Horde_Share_Base * @return array The requested shares. * @throws Horde_Share_Exception */ - protected function _getShares(array $ids, $key = 'share_name') + protected function _getShares(array $ids) { try { $rows = $this->_db->selectAll('SELECT * FROM ' . $this->_table . ' WHERE share_id IN (' . str_repeat('?, ', count($ids) - 1) . '?)', $ids); @@ -262,7 +262,7 @@ class Horde_Share_Sql extends Horde_Share_Base $sharelist = array(); foreach ($rows as $share) { $this->_loadPermissions($share); - $sharelist[$share[$key]] = $this->_createObject($share); + $sharelist[$share['share_name']] = $this->_createObject($share); } return $sharelist; @@ -336,24 +336,31 @@ class Horde_Share_Sql extends Horde_Share_Base * * @param string $userid The userid of the user to check access for. * @param array $params Additional parameters for the search. - * - 'perm': Require this level of permissions. Horde_Perms constant. - * - 'attributes': Restrict shares to these attributes. A hash or username. - * - 'from': Offset. Start at this share - * - 'count': Limit. Only return this many. - * - 'sort_by': Sort by attribute. - * - 'direction': Sort by direction. + *
+     *  'perm'          Require this level of permissions. Horde_Perms constant.
+     *  'attribtues'    Restrict shares to these attributes. A hash or username.
+     *  'from'          Offset. Start at this share
+     *  'count'         Limit.  Only return this many.
+     *  'sort_by'       Sort by attribute.
+     *  'direction'     Sort by direction.
+     *  'parent'        Start at this share in the hierarchy. Either share_id or
+     *                  Horde_Share_Object
+     *  'all_levels'    List all levels or just the direct children of parent?
+     *
* * @return array The shares the user has access to. * @throws Horde_Share_Exception */ public function listShares($userid, array $params = array()) { - $params = array_merge(array('perm' => Horde_Perms::SHOW, + $params = array_merge(array('perm' => Horde_Perms::SHOW, 'attributes' => null, 'from' => 0, 'count' => 0, 'sort_by' => null, - 'direction' => 0), + 'direction' => 0, + 'parent' => null, + 'all_levels' => true), $params); $key = md5(serialize(array($userid, $params))); if (!empty($this->_listcache[$key])) { @@ -361,7 +368,7 @@ class Horde_Share_Sql extends Horde_Share_Base } $shares = array(); if (is_null($params['sort_by'])) { - $sortfield = 's.share_name'; + $sortfield = 's.share_id'; } elseif ($params['sort_by'] == 'owner' || $params['sort_by'] == 'id') { $sortfield = 's.share_' . $params['sort_by']; } else { @@ -369,7 +376,7 @@ class Horde_Share_Sql extends Horde_Share_Base } $query = 'SELECT DISTINCT s.* ' - . $this->getShareCriteria($userid, $params['perm'], $params['attributes']) + . $this->getShareCriteria($userid, $params['perm'], $params['attributes'], $params['parent'], $params['all_levels']) . ' ORDER BY ' . $sortfield . (($params['direction'] == 0) ? ' ASC' : ' DESC'); @@ -379,6 +386,7 @@ class Horde_Share_Sql extends Horde_Share_Base } catch (Horde_Db_Exception $e) { throw new Horde_Share_Exception($e->getMessage()); } + $users = array(); $groups = array(); foreach ($rows as $share) { @@ -393,38 +401,37 @@ class Horde_Share_Sql extends Horde_Share_Base // Get users permissions if (!empty($users)) { - $query = 'SELECT * FROM ' . $this->_table - . '_users WHERE share_id IN (' . implode(', ', $users) - . ')'; + $query = 'SELECT share_id, user_uid, perm FROM ' . $this->_table + . '_users WHERE share_id IN (' . str_repeat('?,', count($users) - 1) . '?)'; + try { - $rows = $this->_db->selectAll($query); + $rows = $this->_db->selectAll($query, $users); } catch (Horde_Db_Exception $e) { throw new Horde_Share_Exception($e->getMessage()); } - foreach ($rows as $row) { - $shares[$row['share_id']]['perm']['users'] = $this->_buildPermsFromRow($row, 'user_uid'); + foreach ($rows as $share) { + $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; } } // Get groups permissions if (!empty($groups)) { - $query = 'SELECT * FROM ' . $this->_table - . '_groups WHERE share_id IN (' . implode(', ', $groups) - . ')'; + $query = 'SELECT share_id, group_uid, perm FROM ' . $this->_table + . '_groups WHERE share_id IN (' . str_repeat('?,', count($groups) - 1) . '?)'; try { - $rows = $this->_db->selectAll($query); + $rows = $this->_db->selectAll($query, $groups); } catch (Horde_Db_Exception $e) { throw new Horde_Share_Exception($e->getMessage()); } - foreach ($rows as $row) { - $shares[$row['share_id']]['perm']['groups'] = $this->_buildPermsFromRow($row, 'group_uid'); + foreach ($rows as $share) { + $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; } } $sharelist = array(); - foreach ($shares as $data) { + foreach ($shares as $id => $data) { $this->_getSharePerms($data); - $sharelist[$data['share_name']] = $this->_createObject($data); + $sharelist[$id] = $this->_createObject($data); } unset($shares); @@ -432,9 +439,98 @@ class Horde_Share_Sql extends Horde_Share_Base if (!empty($this->_callbacks['list'])) { $sharelist = $this->runCallback('list', array($userid, $sharelist, $params)); } + $this->_listcache[$key] = $sharelist; - return $this->_listcache[$key]; + return $sharelist; + } + + /** + * Return a list of users who have shares with the given permissions + * for the current user. + * + * @param integer $perm The level of permissions required. + * @param mixed $parent The parent share to start looking in. + * (Horde_Share_Object, share_id, or null) + * @param boolean $allLevels Return all levels, or just the direct + * children of $parent? Defaults to all levels. + * @param integer $from The user to start listing at. + * @param integer $count The number of users to return. + * + * @return array List of users. + * @throws Horde_Share_Exception + */ + public function listOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true, + $from = 0, $count = 0) + { + $sql = 'SELECT DISTINCT(s.share_owner) ' + . $this->getShareCriteria($this->_user, $perm, null, $parent, $allLevels); + + if ($count) { + $sql = $this->_db->addLimitOffset($sql, array('limit' => $count, 'offset' => $from)); + } + + try { + $allowners = $this->_db->selectValues($sql); + } catch (Horde_Db_Exception $e) { + throw new Horde_Share_Exception($e); + } + + $owners = array(); + foreach ($allowners as $owner) { + if ($this->countShares($this->_user, $perm, $owner, $parent, $allLevels)) { + $owners[] = $owner; + } + } + + return $owners; + } + + /** + * Count the number of users who have shares with the given permissions + * for the current user. + * + * @param integer $perm The level of permissions required. + * @param mixed $parent The parent share to start looking in. + * (Horde_Share_Object, share_id, or null). + * @param boolean $allLevels Return all levels, or just the direct + * children of $parent? + * + * @return integer Number of users. + * @throws Horde_Share_Exception + */ + public function countOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true) + { + $sql = 'SELECT COUNT(DISTINCT(s.share_owner)) ' + . $this->getShareCriteria($this->_user, $perm, null, $parent, $allLevels); + + try { + $results = $this->_db->selectValue($sql); + } catch (Horde_Db_Exception $e) { + throw new Horde_Share_Exception($e); + } + + return $results; + } + + /** + * Returns a share's direct parent object. + * + * @param Horde_Share_Object $child The share to get parent for. + * + * @return Horde_Share_Object The parent share, if it exists. + */ + public function getParent(Horde_Share_Object $child) + { + $parents = $child->get('parents'); + + // No parents, this is at the root. + if (empty($parents)) { + return null; + } + $parents = explode(':', $parents); + + return $this->getShareById(array_pop($parents)); } /** @@ -477,31 +573,35 @@ class Horde_Share_Sql extends Horde_Share_Base } /** - * 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. + * Returns the count of all shares that $userid has access to. * - * @return integer The number of shares + * @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. + * @param mixed $parent The share to start searching from + * (Horde_Share_Object, share_id, or null) + * @param boolean $allLevels Return all levels, or just the direct + * children of $parent? + * + * @return integer Number of shares the user has access to. * @throws Horde_Share_Exception */ public function countShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null) + $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); try { - $results = $this->_db->selectValue($query); + $this->_db->selectValue($query); } catch (Horde_Db_Exception $e) { throw new Horde_Share_Exception($e); } - return $results; + return $this->_db->selectValue($query); } /** @@ -540,6 +640,34 @@ class Horde_Share_Sql extends Horde_Share_Base * * @param Horde_Share_Object $share The share to remove. * + * @throws Horde_Share_Exception + */ + public function removeShare(Horde_Share_Object $share) + { + // First Remove Children + foreach ($share->getChildren(null, null, true) as $child) { + $this->removeShare($child); + } + + // Run the results through the callback, if configured. + $this->runCallback('remove', array($share)); + + /* Remove share from the caches. */ + $id = $share->getId(); + unset($this->_shareMap[$id]); + unset($this->_cache[$share->getName()]); + + /* Reset caches that depend on unknown criteria. */ + $this->expireListCache(); + + $this->_removeShare($share); + } + + /** + * Removes a share from the shares system permanently. + * + * @param Horde_Share_Object $share The share to remove. + * * @return boolean * @throws Horde_Share_Exception */ @@ -575,20 +703,39 @@ class Horde_Share_Sql extends Horde_Share_Base } } + protected function _idExists($id) + { + try { + return (boolean)$this->_db->selectOne('SELECT 1 FROM ' . $this->_table . ' WHERE share_id = ?', array($id)); + } catch (Horde_Db_Exception $e) { + throw new Horde_Share_Exception($e); + } + } + /** - * Returns a criteria statement for querying shares. - * - * @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 returned to those who - * have these attribute values. + * Returns an array of criteria for querying shares. + * + * @param string $userid The userid of the user to check access for. + * @param integer $perm The level of permissions required. Set to null + * to skip permission filtering. + * @param mixed $attributes Restrict the shares returned to those who + * have these attribute values. + * @param mixed $parent The share to start searching in. + * (A Horde_Share_Object, share_id or null) + * @param boolean $allLevels Return all levels, or just the direct + * children of $parent? Defaults to all levels. * * @return string The criteria string for fetching this user's shares. + * @throws Horde_Share_Exception */ public function getShareCriteria($userid, $perm = Horde_Perms::SHOW, - $attributes = null) + $attributes = null, $parent = null, + $allLevels = true) { - list($query, $where) = $this->_getUserAndGroupCriteria($userid, $perm); + $query = $where = ''; + if (!is_null($perm)) { + list($query, $where) = $this->_getUserAndGroupCriteria($userid, $perm); + } $query = ' FROM ' . $this->_table . ' s ' . $query; /* Convert to driver's keys */ @@ -599,7 +746,9 @@ class Horde_Share_Sql extends Horde_Share_Base if (is_array($attributes)) { // Build attribute/key filter. - $where = ' (' . $where . ') '; + if (!empty($where)) { + $where = ' (' . $where . ') '; + } foreach ($attributes as $key => $value) { if (is_array($value)) { $value = array_map(array($this->_db, 'quote'), $value); @@ -609,9 +758,36 @@ class Horde_Share_Sql extends Horde_Share_Base } } } elseif (!empty($attributes)) { - // Restrict to shares owned by the user specified in the - // $attributes string. - $where = ' (' . $where . ') AND s.share_owner = ' . $this->_db->quote($attributes); + // Restrict to shares owned by the user specified + $where = (!empty($where) ? ' (' . $where . ') AND ' : ' ') . 's.share_owner = ' . $this->_db->quote($attributes); + } + + // See if we need to filter by parent or get the parent object + if ($parent != null) { + if (!($parent instanceof Horde_Share_Object)) { + $parent = $this->getShareById($parent); + } + + // Need to append the parent's share id to the list of parents in + // order to search the share_parents field. + $parents = $parent->get('parents') . ':' . $parent->getId(); + if ($allLevels) { + $where_parent = '(share_parents = ' . $this->_db->quote($parents) + . ' OR share_parents LIKE ' . $this->_db->quote($parents . ':%') . ')'; + } else { + $where_parent = 's.share_parents = ' . $this->_db->quote($parents); + } + } elseif (!$allLevels) { + // No parents, and we only want the root. + $where_parent = "(s.share_parents = '' OR s.share_parents IS NULL)"; + } + + if (!empty($where_parent)) { + if (empty($where)) { + $where = $where_parent; + } else { + $where = '(' . $where . ') AND ' . $where_parent; + } } return $query . ' WHERE ' . $where; diff --git a/framework/Share/lib/Horde/Share/Sql/Hierarchical.php b/framework/Share/lib/Horde/Share/Sql/Hierarchical.php index 3cbcca93c..6fed7e9e4 100644 --- a/framework/Share/lib/Horde/Share/Sql/Hierarchical.php +++ b/framework/Share/lib/Horde/Share/Sql/Hierarchical.php @@ -9,25 +9,25 @@ */ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql { - /** - * The Horde_Share_Object subclass to instantiate objects as - * - * @var string - */ - protected $_shareObject = 'Horde_Share_Object_Sql_Hierarchical'; - - /** - * Returns a new share object. - * - * @param string $owner The share owner name. - * @param string $name The share's name. - * - * @return Horde_Share_Object_Sql_Hierarchical A new share object. - */ - protected function _newShare($owner, $name = '') - { - return $this->_createObject(); - } +// /** +// * The Horde_Share_Object subclass to instantiate objects as +// * +// * @var string +// */ +// protected $_shareObject = 'Horde_Share_Object_Sql_Hierarchical'; +// +// /** +// * Returns a new share object. +// * +// * @param string $owner The share owner name. +// * @param string $name The share's name. +// * +// * @return Horde_Share_Object_Sql_Hierarchical A new share object. +// */ +// protected function _newShare($owner, $name = '') +// { +// return $this->_createObject(); +// } /** * Returns an array of all shares that $userid has access to. @@ -51,287 +51,287 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql */ public function listShares($userid, array $params = array()) { - $params = array_merge(array('perm' => Horde_Perms::SHOW, - 'attributes' => null, - 'from' => 0, - 'count' => 0, - 'sort_by' => null, - 'direction' => 0, - 'parent' => null, - 'all_levels' => true), - $params); - $key = md5(serialize(array($userid, $params))); - if (!empty($this->_listcache[$key])) { - return $this->_listcache[$key]; - } - $shares = array(); - if (is_null($params['sort_by'])) { - $sortfield = 's.share_id'; - } elseif ($params['sort_by'] == 'owner' || $params['sort_by'] == 'id') { - $sortfield = 's.share_' . $params['sort_by']; - } else { - $sortfield = 's.attribute_' . $params['sort_by']; - } - - $query = 'SELECT DISTINCT s.* ' - . $this->getShareCriteria($userid, $params['perm'], $params['attributes'], $params['parent'], $params['all_levels']) - . ' ORDER BY ' . $sortfield - . (($params['direction'] == 0) ? ' ASC' : ' DESC'); - - $query = $this->_db->addLimitOffset($query, array('limit' => $params['count'], 'offset' => $params['from'])); - try { - $rows = $this->_db->selectAll($query); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e->getMessage()); - } - - $users = array(); - $groups = array(); - foreach ($rows as $share) { - $shares[(int)$share['share_id']] = $this->_fromDriverCharset($share); - if ($this->_hasUsers($share)) { - $users[] = (int)$share['share_id']; - } - if ($this->_hasGroups($share)) { - $groups[] = (int)$share['share_id']; - } - } - - // Get users permissions - if (!empty($users)) { - $query = 'SELECT share_id, user_uid, perm FROM ' . $this->_table - . '_users WHERE share_id IN (' . str_repeat('?,', count($users) - 1) . '?)'; - - try { - $rows = $this->_db->selectAll($query, $users); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e->getMessage()); - } - foreach ($rows as $share) { - $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; - } - } - - // Get groups permissions - if (!empty($groups)) { - $query = 'SELECT share_id, group_uid, perm FROM ' . $this->_table - . '_groups WHERE share_id IN (' . str_repeat('?,', count($groups) - 1) . '?)'; - try { - $rows = $this->_db->selectAll($query, $groups); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e->getMessage()); - } - foreach ($rows as $share) { - $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; - } - } - - $sharelist = array(); - foreach ($shares as $id => $data) { - $this->_getSharePerms($data); - $sharelist[$id] = $this->_createObject($data); - } - unset($shares); - - // Run the results through the callback, if configured. - if (!empty($this->_callbacks['list'])) { - $sharelist = $this->runCallback('list', array($userid, $sharelist, $params)); - } - - $this->_listcache[$key] = $sharelist; - - return $sharelist; - } - - /** - * Returns an array of criteria for querying shares. - * - * @TODO: - * remove ignorePerms param, simply set perm to null for this - * - * @param string $userid The userid of the user to check access for. - * @param integer $perm The level of permissions required. Set to null - * to skip permission filtering. - * @param mixed $attributes Restrict the shares returned to those who - * have these attribute values. - * @param mixed $parent The share to start searching in. - * (A Horde_Share_Object, share_id or null) - * @param boolean $allLevels Return all levels, or just the direct - * children of $parent? Defaults to all levels. - * - * @return string The criteria string for fetching this user's shares. - * @throws Horde_Share_Exception - */ - public function getShareCriteria($userid, $perm = Horde_Perms::SHOW, - $attributes = null, $parent = null, - $allLevels = true) - { - $query = $where = ''; - if (!is_null($perm)) { - list($query, $where) = $this->_getUserAndGroupCriteria($userid, $perm); - } - $query = ' FROM ' . $this->_table . ' s ' . $query; - - /* Convert to driver's keys */ - $attributes = $this->_toDriverKeys($attributes); - - /* ...and to driver charset */ - $attributes = $this->toDriverCharset($attributes); - - if (is_array($attributes)) { - // Build attribute/key filter. - if (!empty($where)) { - $where = ' (' . $where . ') '; - } - foreach ($attributes as $key => $value) { - if (is_array($value)) { - $value = array_map(array($this->_db, 'quote'), $value); - $where .= ' AND ' . $key . ' IN (' . implode(', ', $value) . ')'; - } else { - $where .= ' AND ' . $key . ' = ' . $this->_db->quote($value); - } - } - } elseif (!empty($attributes)) { - // Restrict to shares owned by the user specified - $where = (!empty($where) ? ' (' . $where . ') AND ' : ' ') . 's.share_owner = ' . $this->_db->quote($attributes); - } - - // See if we need to filter by parent or get the parent object - if ($parent != null) { - if (!($parent instanceof Horde_Share_Object)) { - $parent = $this->getShareById($parent); - } - - // Need to append the parent's share id to the list of parents in - // order to search the share_parents field. - $parents = $parent->get('parents') . ':' . $parent->getId(); - if ($allLevels) { - $where_parent = '(share_parents = ' . $this->_db->quote($parents) - . ' OR share_parents LIKE ' . $this->_db->quote($parents . ':%') . ')'; - } else { - $where_parent = 's.share_parents = ' . $this->_db->quote($parents); - } - } elseif (!$allLevels) { - // No parents, and we only want the root. - $where_parent = "(s.share_parents = '' OR s.share_parents IS NULL)"; - } - - if (!empty($where_parent)) { - if (empty($where)) { - $where = $where_parent; - } else { - $where = '(' . $where . ') AND ' . $where_parent; - } - } - - return $query . ' WHERE ' . $where; - } - - /** - * Return a list of users who have shares with the given permissions - * for the current user. - * - * @param integer $perm The level of permissions required. - * @param mixed $parent The parent share to start looking in. - * (Horde_Share_Object, share_id, or null) - * @param boolean $allLevels Return all levels, or just the direct - * children of $parent? Defaults to all levels. - * @param integer $from The user to start listing at. - * @param integer $count The number of users to return. - * - * @return array List of users. - * @throws Horde_Share_Exception - */ - public function listOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true, - $from = 0, $count = 0) - { - $sql = 'SELECT DISTINCT(s.share_owner) ' - . $this->getShareCriteria($this->_user, $perm, null, $parent, $allLevels); - - if ($count) { - $sql = $this->_db->addLimitOffset($sql, array('limit' => $count, 'offset' => $from)); - } - - try { - $allowners = $this->_db->selectValues($sql); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e); - } - - $owners = array(); - foreach ($allowners as $owner) { - if ($this->countShares($this->_user, $perm, $owner, $parent, $allLevels)) { - $owners[] = $owner; - } - } - - return $owners; - } - - /** - * Count the number of users who have shares with the given permissions - * for the current user. - * - * @param integer $perm The level of permissions required. - * @param mixed $parent The parent share to start looking in. - * (Horde_Share_Object, share_id, or null). - * @param boolean $allLevels Return all levels, or just the direct - * children of $parent? - * - * @return integer Number of users. - * @throws Horde_Share_Exception - */ - public function countOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true) - { - $sql = 'SELECT COUNT(DISTINCT(s.share_owner)) ' - . $this->getShareCriteria($this->_user, $perm, null, $parent, $allLevels); - - try { - $results = $this->_db->selectValue($sql); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e); - } - - return $results; +// $params = array_merge(array('perm' => Horde_Perms::SHOW, +// 'attributes' => null, +// 'from' => 0, +// 'count' => 0, +// 'sort_by' => null, +// 'direction' => 0, +// 'parent' => null, +// 'all_levels' => true), +// $params); +// $key = md5(serialize(array($userid, $params))); +// if (!empty($this->_listcache[$key])) { +// return $this->_listcache[$key]; +// } +// $shares = array(); +// if (is_null($params['sort_by'])) { +// $sortfield = 's.share_id'; +// } elseif ($params['sort_by'] == 'owner' || $params['sort_by'] == 'id') { +// $sortfield = 's.share_' . $params['sort_by']; +// } else { +// $sortfield = 's.attribute_' . $params['sort_by']; +// } +// +// $query = 'SELECT DISTINCT s.* ' +// . $this->getShareCriteria($userid, $params['perm'], $params['attributes'], $params['parent'], $params['all_levels']) +// . ' ORDER BY ' . $sortfield +// . (($params['direction'] == 0) ? ' ASC' : ' DESC'); +// +// $query = $this->_db->addLimitOffset($query, array('limit' => $params['count'], 'offset' => $params['from'])); +// try { +// $rows = $this->_db->selectAll($query); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e->getMessage()); +// } +// +// $users = array(); +// $groups = array(); +// foreach ($rows as $share) { +// $shares[(int)$share['share_id']] = $this->_fromDriverCharset($share); +// if ($this->_hasUsers($share)) { +// $users[] = (int)$share['share_id']; +// } +// if ($this->_hasGroups($share)) { +// $groups[] = (int)$share['share_id']; +// } +// } +// +// // Get users permissions +// if (!empty($users)) { +// $query = 'SELECT share_id, user_uid, perm FROM ' . $this->_table +// . '_users WHERE share_id IN (' . str_repeat('?,', count($users) - 1) . '?)'; +// +// try { +// $rows = $this->_db->selectAll($query, $users); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e->getMessage()); +// } +// foreach ($rows as $share) { +// $shares[$share['share_id']]['perm']['users'][$share['user_uid']] = (int)$share['perm']; +// } +// } +// +// // Get groups permissions +// if (!empty($groups)) { +// $query = 'SELECT share_id, group_uid, perm FROM ' . $this->_table +// . '_groups WHERE share_id IN (' . str_repeat('?,', count($groups) - 1) . '?)'; +// try { +// $rows = $this->_db->selectAll($query, $groups); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e->getMessage()); +// } +// foreach ($rows as $share) { +// $shares[$share['share_id']]['perm']['groups'][$share['group_uid']] = (int)$share['perm']; +// } +// } +// +// $sharelist = array(); +// foreach ($shares as $id => $data) { +// $this->_getSharePerms($data); +// $sharelist[$id] = $this->_createObject($data); +// } +// unset($shares); +// +// // Run the results through the callback, if configured. +// if (!empty($this->_callbacks['list'])) { +// $sharelist = $this->runCallback('list', array($userid, $sharelist, $params)); +// } +// +// $this->_listcache[$key] = $sharelist; +// +// return $sharelist; } - /** - * Returns a share's direct parent object. - * - * @param Horde_Share_Object $child The share to get parent for. - * - * @return Horde_Share_Object The parent share, if it exists. - */ - public function getParent(Horde_Share_Object $child) - { - $parents = $child->get('parents'); - - // No parents, this is at the root. - if (empty($parents)) { - return null; - } - $parents = explode(':', $parents); - - return $this->getShareById(array_pop($parents)); - } - - /** - * Returns a Horde_Share_Object object corresponding to the given unique - * ID, with the details retrieved appropriately. - * - * @param string $cid The id of the share to retrieve. - * - * @return Horde_Share_Object The requested share. - */ - public function getShareById($cid) - { - if (!isset($this->_cache[$cid])) { - $share = $this->_getShareById($cid); - $this->_cache[$cid] = $share; - } - - return $this->_cache[$cid]; - } +// /** +// * Returns an array of criteria for querying shares. +// * +// * @TODO: +// * remove ignorePerms param, simply set perm to null for this +// * +// * @param string $userid The userid of the user to check access for. +// * @param integer $perm The level of permissions required. Set to null +// * to skip permission filtering. +// * @param mixed $attributes Restrict the shares returned to those who +// * have these attribute values. +// * @param mixed $parent The share to start searching in. +// * (A Horde_Share_Object, share_id or null) +// * @param boolean $allLevels Return all levels, or just the direct +// * children of $parent? Defaults to all levels. +// * +// * @return string The criteria string for fetching this user's shares. +// * @throws Horde_Share_Exception +// */ +// public function getShareCriteria($userid, $perm = Horde_Perms::SHOW, +// $attributes = null, $parent = null, +// $allLevels = true) +// { +// $query = $where = ''; +// if (!is_null($perm)) { +// list($query, $where) = $this->_getUserAndGroupCriteria($userid, $perm); +// } +// $query = ' FROM ' . $this->_table . ' s ' . $query; +// +// /* Convert to driver's keys */ +// $attributes = $this->_toDriverKeys($attributes); +// +// /* ...and to driver charset */ +// $attributes = $this->toDriverCharset($attributes); +// +// if (is_array($attributes)) { +// // Build attribute/key filter. +// if (!empty($where)) { +// $where = ' (' . $where . ') '; +// } +// foreach ($attributes as $key => $value) { +// if (is_array($value)) { +// $value = array_map(array($this->_db, 'quote'), $value); +// $where .= ' AND ' . $key . ' IN (' . implode(', ', $value) . ')'; +// } else { +// $where .= ' AND ' . $key . ' = ' . $this->_db->quote($value); +// } +// } +// } elseif (!empty($attributes)) { +// // Restrict to shares owned by the user specified +// $where = (!empty($where) ? ' (' . $where . ') AND ' : ' ') . 's.share_owner = ' . $this->_db->quote($attributes); +// } +// +// // See if we need to filter by parent or get the parent object +// if ($parent != null) { +// if (!($parent instanceof Horde_Share_Object)) { +// $parent = $this->getShareById($parent); +// } +// +// // Need to append the parent's share id to the list of parents in +// // order to search the share_parents field. +// $parents = $parent->get('parents') . ':' . $parent->getId(); +// if ($allLevels) { +// $where_parent = '(share_parents = ' . $this->_db->quote($parents) +// . ' OR share_parents LIKE ' . $this->_db->quote($parents . ':%') . ')'; +// } else { +// $where_parent = 's.share_parents = ' . $this->_db->quote($parents); +// } +// } elseif (!$allLevels) { +// // No parents, and we only want the root. +// $where_parent = "(s.share_parents = '' OR s.share_parents IS NULL)"; +// } +// +// if (!empty($where_parent)) { +// if (empty($where)) { +// $where = $where_parent; +// } else { +// $where = '(' . $where . ') AND ' . $where_parent; +// } +// } +// +// return $query . ' WHERE ' . $where; +// } + +// /** +// * Return a list of users who have shares with the given permissions +// * for the current user. +// * +// * @param integer $perm The level of permissions required. +// * @param mixed $parent The parent share to start looking in. +// * (Horde_Share_Object, share_id, or null) +// * @param boolean $allLevels Return all levels, or just the direct +// * children of $parent? Defaults to all levels. +// * @param integer $from The user to start listing at. +// * @param integer $count The number of users to return. +// * +// * @return array List of users. +// * @throws Horde_Share_Exception +// */ +// public function listOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true, +// $from = 0, $count = 0) +// { +// $sql = 'SELECT DISTINCT(s.share_owner) ' +// . $this->getShareCriteria($this->_user, $perm, null, $parent, $allLevels); +// +// if ($count) { +// $sql = $this->_db->addLimitOffset($sql, array('limit' => $count, 'offset' => $from)); +// } +// +// try { +// $allowners = $this->_db->selectValues($sql); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e); +// } +// +// $owners = array(); +// foreach ($allowners as $owner) { +// if ($this->countShares($this->_user, $perm, $owner, $parent, $allLevels)) { +// $owners[] = $owner; +// } +// } +// +// return $owners; +// } + +// /** +// * Count the number of users who have shares with the given permissions +// * for the current user. +// * +// * @param integer $perm The level of permissions required. +// * @param mixed $parent The parent share to start looking in. +// * (Horde_Share_Object, share_id, or null). +// * @param boolean $allLevels Return all levels, or just the direct +// * children of $parent? +// * +// * @return integer Number of users. +// * @throws Horde_Share_Exception +// */ +// public function countOwners($perm = Horde_Perms::SHOW, $parent = null, $allLevels = true) +// { +// $sql = 'SELECT COUNT(DISTINCT(s.share_owner)) ' +// . $this->getShareCriteria($this->_user, $perm, null, $parent, $allLevels); +// +// try { +// $results = $this->_db->selectValue($sql); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e); +// } +// +// return $results; +// } + +// /** +// * Returns a share's direct parent object. +// * +// * @param Horde_Share_Object $child The share to get parent for. +// * +// * @return Horde_Share_Object The parent share, if it exists. +// */ +// public function getParent(Horde_Share_Object $child) +// { +// $parents = $child->get('parents'); +// +// // No parents, this is at the root. +// if (empty($parents)) { +// return null; +// } +// $parents = explode(':', $parents); +// +// return $this->getShareById(array_pop($parents)); +// } +// +// /** +// * Returns a Horde_Share_Object object corresponding to the given unique +// * ID, with the details retrieved appropriately. +// * +// * @param string $cid The id of the share to retrieve. +// * +// * @return Horde_Share_Object The requested share. +// */ +// public function getShareById($cid) +// { +// if (!isset($this->_cache[$cid])) { +// $share = $this->_getShareById($cid); +// $this->_cache[$cid] = $share; +// } +// +// return $this->_cache[$cid]; +// } /** * Returns an array of Horde_Share_Object objects corresponding to the @@ -387,62 +387,62 @@ class Horde_Share_Sql_Hierarchical extends Horde_Share_Sql $this->_removeShare($share); } - /** - * Returns an array of Horde_Share_Object objects corresponding - * to the given set of unique IDs, with the details retrieved - * appropriately. - * - * @param array $ids The array of ids to retrieve. - * - * @return array The requested shares keyed be share_id. - * @throws Horde_Share_Exception - */ - protected function _getShares(array $ids) - { - return parent::_getShares($ids, 'share_id'); - } - - /** - * Override the Horde_Share base class to avoid any confusion - * - * @throws Horde_Share_Exception - */ - public function getShare($name) - { - throw new Horde_Share_Exception(Horde_Share_Translation::t("Share names are not supported in this driver")); - } - - /** - * Returns the count 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. - * @param mixed $parent The share to start searching from - * (Horde_Share_Object, share_id, or null) - * @param boolean $allLevels Return all levels, or just the direct - * children of $parent? - * - * @return integer Number of shares the user has access to. - * @throws Horde_Share_Exception - */ - 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, $parent, $allLevels); - - try { - $this->_db->selectValue($query); - } catch (Horde_Db_Exception $e) { - throw new Horde_Share_Exception($e); - } - - return $this->_db->selectValue($query); - } +// /** +// * Returns an array of Horde_Share_Object objects corresponding +// * to the given set of unique IDs, with the details retrieved +// * appropriately. +// * +// * @param array $ids The array of ids to retrieve. +// * +// * @return array The requested shares keyed be share_id. +// * @throws Horde_Share_Exception +// */ +// protected function _getShares(array $ids) +// { +// return parent::_getShares($ids, 'share_id'); +// } + +// /** +// * Override the Horde_Share base class to avoid any confusion +// * +// * @throws Horde_Share_Exception +// */ +// public function getShare($name) +// { +// throw new Horde_Share_Exception(Horde_Share_Translation::t("Share names are not supported in this driver")); +// } + +// /** +// * Returns the count 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. +// * @param mixed $parent The share to start searching from +// * (Horde_Share_Object, share_id, or null) +// * @param boolean $allLevels Return all levels, or just the direct +// * children of $parent? +// * +// * @return integer Number of shares the user has access to. +// * @throws Horde_Share_Exception +// */ +// 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, $parent, $allLevels); +// +// try { +// $this->_db->selectValue($query); +// } catch (Horde_Db_Exception $e) { +// throw new Horde_Share_Exception($e); +// } +// +// return $this->_db->selectValue($query); +// } /** * Checks if a share exists in the system. diff --git a/framework/Share/lib/Horde/Share/Sqlng.php b/framework/Share/lib/Horde/Share/Sqlng.php index 544bb1579..7ba35d2a4 100644 --- a/framework/Share/lib/Horde/Share/Sqlng.php +++ b/framework/Share/lib/Horde/Share/Sqlng.php @@ -63,12 +63,17 @@ class Horde_Share_Sqlng extends Horde_Share_Sql * * @param string $userid The userid of the user to check access for. * @param array $params Additional parameters for the search. - * - 'perm': Require this level of permissions. Horde_Perms constant. - * - 'attributes': Restrict shares to these attributes. A hash or username. - * - 'from': Offset. Start at this share - * - 'count': Limit. Only return this many. - * - 'sort_by': Sort by attribute. - * - 'direction': Sort by direction. + *
+     *  'perm'          Require this level of permissions. Horde_Perms constant.
+     *  'attribtues'    Restrict shares to these attributes. A hash or username.
+     *  'from'          Offset. Start at this share
+     *  'count'         Limit.  Only return this many.
+     *  'sort_by'       Sort by attribute.
+     *  'direction'     Sort by direction.
+     *  'parent'        Start at this share in the hierarchy. Either share_id or
+     *                  Horde_Share_Object
+     *  'all_levels'    List all levels or just the direct children of parent?
+     *
* * @return array The shares the user has access to. * @throws Horde_Share_Exception @@ -80,7 +85,9 @@ class Horde_Share_Sqlng extends Horde_Share_Sql 'from' => 0, 'count' => 0, 'sort_by' => null, - 'direction' => 0), + 'direction' => 0, + 'parent' => null, + 'all_levels' => true), $params); $key = md5(serialize(array($userid, $params))); @@ -102,13 +109,14 @@ class Horde_Share_Sqlng extends Horde_Share_Sql } else { $sortfield = 'attribute_' . $params['sort_by']; } - - $query = 'SELECT * FROM ' . $this->_table . ' WHERE ' - . $this->_getShareCriteria($userid, $perms, $params['attributes'], $shareids) + $where = $this->_getShareCriteria($userid, $perms, $params['attributes'], $shareids, $params['parent'], $params['all_levels']); + $query = 'SELECT DISTINCT * FROM ' . $this->_table . ' s ' . + (!empty($where) ? ' WHERE ' . $where : '') . ' ORDER BY ' . $sortfield . (($params['direction'] == 0) ? ' ASC' : ' DESC'); $query = $this->_db->addLimitOffset($query, array('limit' => $params['count'], 'offset' => $params['from'])); + try { $rows = $this->_db->selectAll($query); } catch (Horde_Db_Exception $e) { @@ -148,20 +156,24 @@ class Horde_Share_Sqlng extends Horde_Share_Sql } /** - * Returns the number of shares that $userid has access to. + * Returns the count 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. + * @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. + * @param mixed $parent The share to start searching from + * (Horde_Share_Object, share_id, or null) + * @param boolean $allLevels Return all levels, or just the direct + * children of $parent? * - * @return integer The number of shares + * @return integer Number of shares the user has access to. * @throws Horde_Share_Exception */ public function countShares($userid, $perm = Horde_Perms::SHOW, - $attributes = null) + $attributes = null, $parent = null, $allLevels = true) { $perms = $this->convertBitmaskToArray($perm); $shareids = null; @@ -169,10 +181,9 @@ class Horde_Share_Sqlng extends Horde_Share_Sql list(, , $shareids) = $this->_getUserAndGroupShares($userid, $perms); } - $query = 'SELECT COUNT(share_id) FROM ' - . $this->_table . ' WHERE ' - . $this->_getShareCriteria($userid, $perms, $attributes, $shareids); - + $query = 'SELECT COUNT(DISTINCT share_id) FROM ' + . $this->_table . ' s WHERE ' + . $this->_getShareCriteria($userid, $perms, $attributes, $shareids, $parent, $allLevels); try { return $this->_db->selectValue($query); } catch (Horde_Db_Exception $e) { @@ -319,7 +330,8 @@ class Horde_Share_Sqlng extends Horde_Share_Sql * @return string The criteria string for fetching this user's shares. */ protected function _getShareCriteria($userid, array $perms, $attributes, - $shareids = null) + $shareids = null, $parent = null, + $allLevels = true) { /* Convert to driver's keys */ $attributes = $this->_toDriverKeys($attributes); @@ -362,6 +374,33 @@ class Horde_Share_Sqlng extends Horde_Share_Sql $where = '(' . $where . ') AND share_owner = ' . $this->_db->quote($attributes); } + // See if we need to filter by parent or get the parent object + if ($parent != null) { + if (!($parent instanceof Horde_Share_Object)) { + $parent = $this->getShareById($parent); + } + + // Need to append the parent's share id to the list of parents in + // order to search the share_parents field. + $parents = $parent->get('parents') . ':' . $parent->getId(); + if ($allLevels) { + $where_parent = '(share_parents = ' . $this->_db->quote($parents) + . ' OR share_parents LIKE ' . $this->_db->quote($parents . ':%') . ')'; + } else { + $where_parent = 's.share_parents = ' . $this->_db->quote($parents); + } + } elseif (!$allLevels) { + // No parents, and we only want the root. + $where_parent = "(s.share_parents = '' OR s.share_parents IS NULL)"; + } + if (!empty($where_parent)) { + if (empty($where)) { + $where = $where_parent; + } else { + $where = '(' . $where . ') AND ' . $where_parent; + } + } + return $where; } diff --git a/framework/Share/test/Horde/Share/Base.php b/framework/Share/test/Horde/Share/Base.php index 535e66057..1e184710b 100644 --- a/framework/Share/test/Horde/Share/Base.php +++ b/framework/Share/test/Horde/Share/Base.php @@ -28,6 +28,15 @@ class Horde_Share_Test_Base extends Horde_Test_Case $share->set('desc', '行事曆'); $this->assertInstanceOf('Horde_Share_Object', $share); self::$share->addShare($share); + + // Add a child to the share to test hierarchical functions + $child = self::$share->newShare('john', 'mychildshare'); + $child->set('name', 'My Child Share'); + $child->set('desc', 'description'); + $this->assertInstanceOf('Horde_Share_Object', $child); + $child->setParent($share); + $child->save(); + return $share; } @@ -47,6 +56,9 @@ class Horde_Share_Test_Base extends Horde_Test_Case $this->assertFalse($share->hasPermission('john', Horde_Perms::EDIT)); $this->assertFalse($share->hasPermission('john', Horde_Perms::DELETE)); + // Child share + $childshare = self::$share->getShare('mychildshare'); + // Foreign share with user permissions. $janeshare = self::$share->newShare('jane', 'janeshare'); $janeshare->set('name', 'Jane\'s Share'); @@ -68,10 +80,10 @@ class Horde_Share_Test_Base extends Horde_Test_Case $this->assertTrue($groupshare->hasPermission('john', Horde_Perms::DELETE)); // Foreign share without permissions. - $share = self::$share->newShare('jane', 'noshare'); - $share->save(); + $fshare = self::$share->newShare('jane', 'noshare'); + $fshare->save(); - return array($myshareid, $janeshare->getId(), $groupshare->getId()); + return array($myshareid, $janeshare->getId(), $groupshare->getId(), $childshare->getid(), $share->getId()); } public function exists() @@ -89,15 +101,18 @@ class Horde_Share_Test_Base extends Horde_Test_Case public function countShares() { // Getting shares from cache. - $this->assertEquals(4, self::$share->countShares('john')); - $this->assertEquals(2, self::$share->countShares('john', Horde_Perms::EDIT)); + $this->assertEquals(5, self::$share->countShares('john')); + // Top level only. + $this->assertEquals(2, self::$share->countShares('john', Horde_Perms::EDIT, null, null, false)); + $this->assertEquals(3, self::$share->countShares('john', Horde_Perms::EDIT)); // Reset cache. self::$share->resetCache(); // Getting shares from backend. - $this->assertEquals(4, self::$share->countShares('john')); - $this->assertEquals(2, self::$share->countShares('john', Horde_Perms::EDIT)); + $this->assertEquals(5, self::$share->countShares('john')); + $this->assertEquals(2, self::$share->countShares('john', Horde_Perms::EDIT, null, null, false)); + $this->assertEquals(3, self::$share->countShares('john', Horde_Perms::EDIT)); } public function getShare() @@ -208,7 +223,7 @@ class Horde_Share_Test_Base extends Horde_Test_Case { $shares = self::$share->listAllShares(); $this->assertInternalType('array', $shares); - $this->assertEquals(5, count($shares)); + $this->assertEquals(6, count($shares)); $this->assertArrayHasKey('myshare', $shares); $this->assertArrayHasKey('systemshare', $shares); $this->assertArrayHasKey('janeshare', $shares); @@ -233,13 +248,13 @@ class Horde_Share_Test_Base extends Horde_Test_Case // Default listing. $shares = self::$share->listShares('john'); $this->assertInternalType('array', $shares); - $this->assertEquals(4, count($shares)); + $this->assertEquals(5, count($shares)); // Test arguments for default listing. $this->assertEquals($shares, self::$share->listShares('john', array('perm' => Horde_Perms::SHOW, 'attributes' => null, 'from' => 0, 'count' => 0, 'sort_by' => null, 'direction' => 0))); // Getting back the correct shares? - $shares = array_values(self::$share->listShares('john', array('sort_by' => 'id'))); + $shares = array_values(self::$share->listShares('john', array('all_levels' => false, 'sort_by' => 'id'))); $this->assertEquals($shareids[0], $shares[0]->getId()); $this->assertEquals($shareids[1], $shares[2]->getId()); $this->assertEquals($shareids[2], $shares[3]->getId()); @@ -259,37 +274,59 @@ class Horde_Share_Test_Base extends Horde_Test_Case $this->assertEquals('System Share', $shares[0]->get('name')); // Shares with certain permissions. - $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(5, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::EDIT, 'sort_by' => 'id'))); $this->assertInternalType('array', $shares); + $this->assertEquals(3, count($shares)); + $this->assertEquals($shareids[0], $shares[0]->getId()); + $this->assertEquals($shareids[1], $shares[2]->getId()); + + // Again with only toplevel + $shares = array_values(self::$share->listShares('john', array('all_levels' => false, 'perm' => Horde_Perms::EDIT, 'sort_by' => 'id'))); + $this->assertInternalType('array', $shares); $this->assertEquals(2, count($shares)); $this->assertEquals($shareids[0], $shares[0]->getId()); $this->assertEquals($shareids[1], $shares[1]->getId()); + $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::DELETE, 'sort_by' => 'id'))); $this->assertInternalType('array', $shares); - $this->assertEquals(2, count($shares)); + $this->assertEquals(3, count($shares)); $this->assertEquals($shareids[0], $shares[0]->getId()); - $this->assertEquals($shareids[2], $shares[1]->getId()); + $this->assertEquals($shareids[3], $shares[1]->getId()); + $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::EDIT | Horde_Perms::DELETE))); $this->assertInternalType('array', $shares); - $this->assertEquals(3, count($shares)); + $this->assertEquals(4, count($shares)); $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::ALL))); $this->assertInternalType('array', $shares); - $this->assertEquals(4, count($shares)); + $this->assertEquals(5, count($shares)); // Paging. $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::ALL, 'sort_by' => 'id', 'from' => 2, 'count' => 2))); $this->assertInternalType('array', $shares); $this->assertEquals(2, count($shares)); + $this->assertEquals($shareids[4], $shares[0]->getId()); + $this->assertEquals($shareids[1], $shares[1]->getId()); + + // Paging with top level only + $shares = array_values(self::$share->listShares('john', array('all_levels' => false, 'perm' => Horde_Perms::ALL, 'sort_by' => 'id', 'from' => 2, 'count' => 2))); + $this->assertInternalType('array', $shares); + $this->assertEquals(2, count($shares)); $this->assertEquals($shareids[1], $shares[0]->getId()); $this->assertEquals($shareids[2], $shares[1]->getId()); + // Restrict to children of a share only + $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::ALL, 'parent' => $shareids[0]))); + $this->assertInternalType('array', $shares); + $this->assertEquals(1, count($shares)); + $this->assertEquals($shareids[3], $shares[0]->getId()); + // Sort order and direction. $shares = array_values(self::$share->listShares('john', array('perm' => Horde_Perms::ALL, 'sort_by' => 'id', 'direction' => 1))); $this->assertInternalType('array', $shares); - $this->assertEquals(4, count($shares)); + $this->assertEquals(5, count($shares)); $this->assertEquals($shareids[2], $shares[0]->getId()); - $this->assertEquals($shareids[0], $shares[3]->getId()); + $this->assertEquals($shareids[0], $shares[4]->getId()); // Attribute searching. $shares = array_values(self::$share->listShares('john', array('attributes' => array('name' => 'Jane\'s Share')))); @@ -329,27 +366,27 @@ class Horde_Share_Test_Base extends Horde_Test_Case $janeshare->save(); // Getting shares from cache. - $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); - $this->assertEquals(1, count(self::$share->listShares('john', array('perm' => Horde_Perms::EDIT)))); + $this->assertEquals(5, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(2, count(self::$share->listShares('john', array('perm' => Horde_Perms::EDIT)))); // Reset cache. self::$share->resetCache(); // Getting shares from backend. - $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); - $this->assertEquals(1, count(self::$share->listShares('john', array('perm' => Horde_Perms::EDIT)))); + $this->assertEquals(5, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(2, count(self::$share->listShares('john', array('perm' => Horde_Perms::EDIT)))); $janeshare->removeUser('john'); $janeshare->save(); // Getting shares from cache. - $this->assertEquals(3, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); // Reset cache. self::$share->resetCache(); // Getting shares from backend. - $this->assertEquals(3, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); return $shareids; } @@ -361,27 +398,27 @@ class Horde_Share_Test_Base extends Horde_Test_Case $groupshare->save(); // Getting shares from cache. - $this->assertEquals(3, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); - $this->assertEquals(1, count(self::$share->listShares('john', array('perm' => Horde_Perms::DELETE)))); + $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(2, count(self::$share->listShares('john', array('perm' => Horde_Perms::DELETE)))); // Reset cache. self::$share->resetCache(); // Getting shares from backend. - $this->assertEquals(3, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); - $this->assertEquals(1, count(self::$share->listShares('john', array('perm' => Horde_Perms::DELETE)))); + $this->assertEquals(4, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(2, count(self::$share->listShares('john', array('perm' => Horde_Perms::DELETE)))); $groupshare->removeGroup('mygroup'); $groupshare->save(); // Getting shares from cache. - $this->assertEquals(2, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(3, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); // Reset cache. self::$share->resetCache(); // Getting shares from backend. - $this->assertEquals(2, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); + $this->assertEquals(3, count(self::$share->listShares('john', array('perm' => Horde_Perms::READ)))); } public function removeShare(array $share) diff --git a/framework/Share/test/Horde/Share/Sql/Base.php b/framework/Share/test/Horde/Share/Sql/Base.php index 88add07c0..f56a27597 100644 --- a/framework/Share/test/Horde/Share/Sql/Base.php +++ b/framework/Share/test/Horde/Share/Sql/Base.php @@ -79,6 +79,15 @@ class Horde_Share_Test_Sql_Base extends Horde_Share_Test_Base } /** + */ + public function testGetParent() + { + $share = self::$share->getShare('myshare'); + $child = self::$share->getShare('mychildshare'); + $this->assertEquals($share->getId(), $child->getParent()->getId()); + } + + /** * @depends testGetShare */ public function testGetShareById(array $shares) diff --git a/framework/Share/test/Horde/Share/Sql/Pdo/MysqlTest.php b/framework/Share/test/Horde/Share/Sql/Pdo/MysqlTest.php index e9ad76338..06684b765 100644 --- a/framework/Share/test/Horde/Share/Sql/Pdo/MysqlTest.php +++ b/framework/Share/test/Horde/Share/Sql/Pdo/MysqlTest.php @@ -22,11 +22,7 @@ class Horde_Share_Sql_Pdo_MysqlTest extends Horde_Share_Test_Sql_Base } $config = self::getConfig('SHARE_SQL_PDO_MYSQL_TEST_CONFIG'); if ($config && !empty($config['share']['sql']['pdo_mysql'])) { - try { - self::$db = new Horde_Db_Adapter_Pdo_Mysql($config['share']['sql']['pdo_mysql']); - } catch (Horde_Db_Exception $e) { - return; - } + self::$db = new Horde_Db_Adapter_Pdo_Mysql($config['share']['sql']['pdo_mysql']); parent::setUpBeforeClass(); } } diff --git a/framework/Share/test/Horde/Share/Sql/Pdo/PgsqlTest.php b/framework/Share/test/Horde/Share/Sql/Pdo/PgsqlTest.php index e13693933..a3b21dbad 100644 --- a/framework/Share/test/Horde/Share/Sql/Pdo/PgsqlTest.php +++ b/framework/Share/test/Horde/Share/Sql/Pdo/PgsqlTest.php @@ -22,11 +22,7 @@ class Horde_Share_Sql_Pdo_PgsqlTest extends Horde_Share_Test_Sql_Base } $config = self::getConfig('SHARE_SQL_PDO_PGSQL_TEST_CONFIG'); if ($config && !empty($config['share']['sql']['pdo_pgsql'])) { - try { - self::$db = new Horde_Db_Adapter_Pdo_Pgsql($config['share']['sql']['pdo_pgsql']); - } catch (Horde_Db_Exception $e) { - return; - } + self::$db = new Horde_Db_Adapter_Pdo_Pgsql($config['share']['sql']['pdo_pgsql']); parent::setUpBeforeClass(); } } diff --git a/framework/Share/test/Horde/Share/Sql/Pdo/SqliteTest.php b/framework/Share/test/Horde/Share/Sql/Pdo/SqliteTest.php index 2df5dd529..005b6f7a1 100644 --- a/framework/Share/test/Horde/Share/Sql/Pdo/SqliteTest.php +++ b/framework/Share/test/Horde/Share/Sql/Pdo/SqliteTest.php @@ -20,11 +20,7 @@ class Horde_Share_Sql_Pdo_SqliteTest extends Horde_Share_Test_Sql_Base !in_array('sqlite', PDO::getAvailableDrivers())) { return; } - try { - self::$db = new Horde_Db_Adapter_Pdo_Sqlite(array('dbname' => ':memory:', 'charset' => 'utf-8')); - } catch (Horde_Db_Exception $e) { - return; - } + self::$db = new Horde_Db_Adapter_Pdo_Sqlite(array('dbname' => ':memory:', 'charset' => 'utf-8')); parent::setUpBeforeClass(); } } diff --git a/framework/Share/test/Horde/Share/SqlHierarchical/Base.php b/framework/Share/test/Horde/Share/SqlHierarchical/Base.php index bc3427f67..b348f92e7 100644 --- a/framework/Share/test/Horde/Share/SqlHierarchical/Base.php +++ b/framework/Share/test/Horde/Share/SqlHierarchical/Base.php @@ -37,9 +37,10 @@ class Horde_Share_Test_SqlHierarchical_Base extends Horde_Share_Test_Base public function testAddShare() { - $share = parent::addShare(); - $this->assertInstanceOf('Horde_Share_Object_Sql_Hierarchical', $share); - return $share->getId(); + $this->markTestSkipped('Hierarchical driver tests are deprecated.'); +// $share = parent::addShare(); +// $this->assertInstanceOf('Horde_Share_Object_Sql_Hierarchical', $share); +// return $share->getId(); } /** diff --git a/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/MysqlTest.php b/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/MysqlTest.php index 7afcbaaa0..f1f31f9bb 100644 --- a/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/MysqlTest.php +++ b/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/MysqlTest.php @@ -22,11 +22,7 @@ class Horde_Share_SqlHierarchical_Pdo_MysqlTest extends Horde_Share_Test_SqlHier } $config = self::getConfig('SHARE_SQL_PDO_MYSQL_TEST_CONFIG'); if ($config && !empty($config['share']['sql']['pdo_mysql'])) { - try { - self::$db = new Horde_Db_Adapter_Pdo_Mysql($config['share']['sql']['pdo_mysql']); - } catch (Horde_Db_Exception $e) { - return; - } + self::$db = new Horde_Db_Adapter_Pdo_Mysql($config['share']['sql']['pdo_mysql']); parent::setUpBeforeClass(); } } diff --git a/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/PgsqlTest.php b/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/PgsqlTest.php index 1644894cd..bbfa37e0d 100644 --- a/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/PgsqlTest.php +++ b/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/PgsqlTest.php @@ -22,11 +22,7 @@ class Horde_Share_SqlHierarchical_Pdo_PgsqlTest extends Horde_Share_Test_SqlHier } $config = self::getConfig('SHARE_SQL_PDO_PGSQL_TEST_CONFIG'); if ($config && !empty($config['share']['sql']['pdo_pgsql'])) { - try { - self::$db = new Horde_Db_Adapter_Pdo_Pgsql($config['share']['sql']['pdo_pgsql']); - } catch (Horde_Db_Exception $e) { - return; - } + self::$db = new Horde_Db_Adapter_Pdo_Pgsql($config['share']['sql']['pdo_pgsql']); parent::setUpBeforeClass(); } } diff --git a/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/SqliteTest.php b/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/SqliteTest.php index 3b81f5e57..2ae72fdcc 100644 --- a/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/SqliteTest.php +++ b/framework/Share/test/Horde/Share/SqlHierarchical/Pdo/SqliteTest.php @@ -20,11 +20,7 @@ class Horde_Share_SqlHierarchical_Pdo_SqliteTest extends Horde_Share_Test_SqlHie !in_array('sqlite', PDO::getAvailableDrivers())) { return; } - try { - self::$db = new Horde_Db_Adapter_Pdo_Sqlite(array('dbname' => ':memory:', 'charset' => 'utf-8')); - } catch (Horde_Db_Exception $e) { - return; - } + self::$db = new Horde_Db_Adapter_Pdo_Sqlite(array('dbname' => ':memory:', 'charset' => 'utf-8')); parent::setUpBeforeClass(); } } diff --git a/framework/Share/test/Horde/Share/Sqlng/Base.php b/framework/Share/test/Horde/Share/Sqlng/Base.php index ace6e2219..ca98ebc95 100644 --- a/framework/Share/test/Horde/Share/Sqlng/Base.php +++ b/framework/Share/test/Horde/Share/Sqlng/Base.php @@ -95,6 +95,15 @@ class Horde_Share_Test_Sqlng_Base extends Horde_Share_Test_Base } /** + */ + public function testGetParent() + { + $share = self::$share->getShare('myshare'); + $child = self::$share->getShare('mychildshare'); + $this->assertEquals($share->getId(), $child->getParent()->getId()); + } + + /** * @depends testPermissions */ public function testListAllShares() diff --git a/framework/Share/test/Horde/Share/migration/sql.php b/framework/Share/test/Horde/Share/migration/sql.php index 1a9895692..113885a03 100644 --- a/framework/Share/test/Horde/Share/migration/sql.php +++ b/framework/Share/test/Horde/Share/migration/sql.php @@ -15,6 +15,7 @@ function migrate_sql($db) $t = $migration->createTable('test_shares', array('primaryKey' => 'share_id')); $t->column('share_name', 'string', array('limit' => 255, 'null' => false)); $t->column('share_owner', 'string', array('limit' => 255)); + $t->column('share_parents', 'text', array()); $t->column('share_flags', 'integer', array('default' => 0, 'null' => false)); $t->column('perm_creator', 'integer', array('default' => 0, 'null' => false)); $t->column('perm_default', 'integer', array('default' => 0, 'null' => false)); diff --git a/framework/Share/test/Horde/Share/migration/sqlng.php b/framework/Share/test/Horde/Share/migration/sqlng.php index 9bd2f027f..73a6bd8da 100644 --- a/framework/Share/test/Horde/Share/migration/sqlng.php +++ b/framework/Share/test/Horde/Share/migration/sqlng.php @@ -15,6 +15,7 @@ function migrate_sqlng($db) $t = $migration->createTable('test_shares', array('primaryKey' => 'share_id')); $t->column('share_name', 'string', array('limit' => 255, 'null' => false)); $t->column('share_owner', 'string', array('limit' => 255)); + $t->column('share_parents', 'text'); $t->column('share_flags', 'integer', array('default' => 0, 'null' => false)); $t->column('perm_creator_' . Horde_Perms::SHOW, 'boolean', array('default' => false, 'null' => false)); $t->column('perm_creator_' . Horde_Perms::READ, 'boolean', array('default' => false, 'null' => false)); -- 2.11.0