diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index a08544909b..7495a5bbe6 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -1,7 +1,8 @@ . +*/ + +class OC_Share_Backend_File extends OCP\Share_Backend { + + const FORMAT_SOURCE_PATH = 0; + const FORMAT_FILE_APP = 1; + const FORMAT_FILE_APP_ROOT = 2; + const FORMAT_OPENDIR = 3; + + public function getSource($item, $uid) { + if (OC_Filesystem::file_exists($item)) { + return array('item' => null, 'file' => $item); + } + return false; + } + + public function generateTarget($item, $uid, $exclude = null) { + // TODO Make sure target path doesn't exist already + return '/Shared'.$item; + } + + public function formatItems($items, $format, $parameters = null) { + if ($format == self::FORMAT_OPENDIR) { + $files = array(); + foreach ($items as $file) { + $files[] = basename($file['file_target']); + } + return $files; + } else { + $shares = array(); + $ids = array(); + foreach ($items as $item) { + $shares[$item['file_source']] = $item; + $ids[] = $item['file_source']; + } + $ids = "'".implode("','", $ids)."'"; + if ($format == self::FORMAT_SOURCE_PATH) { + $query = OCP\DB::prepare('SELECT path FROM *PREFIX*fscache WHERE id IN ('.$ids.')'); + $result = $query->execute()->fetchAll(); + if (isset($result[0]['path'])) { + return $result[0]['path']; + } + return false; + } else if ($format == self::FORMAT_FILE_APP) { + $query = OCP\DB::prepare('SELECT id, path, name, ctime, mtime, mimetype, size, encrypted, versioned, writable FROM *PREFIX*fscache WHERE id IN ('.$ids.')'); + $result = $query->execute(); + $files = array(); + while ($file = $result->fetchRow()) { + // Set target path + $file['path'] = $shares[$file['id']]['file_target']; + $file['name'] = basename($file['path']); + // TODO Set permissions: $file['writable'] + $files[] = $file; + } + return $files; + } else if ($format == self::FORMAT_FILE_APP_ROOT) { + $query = OCP\DB::prepare('SELECT id, path, name, ctime, mtime, mimetype, size, encrypted, versioned, writable FROM *PREFIX*fscache WHERE id IN ('.$ids.')'); + $result = $query->execute(); + $mtime = 0; + $size = 0; + while ($file = $result->fetchRow()) { + if ($file['mtime'] > $mtime) { + $mtime = $file['mtime']; + } + $size += $file['size']; + } + return array(0 => array('name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size, 'writable' => false)); + } + } + return array(); + } + +} + +?> \ No newline at end of file diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php new file mode 100644 index 0000000000..033e2ba966 --- /dev/null +++ b/apps/files_sharing/lib/share/folder.php @@ -0,0 +1,64 @@ +. +*/ + +class OC_Share_Backend_Folder extends OC_Share_Backend_File { + + public function inCollection($collections, $item) { + // TODO + } + + public function getChildrenSources($item) { + return OC_FileCache::getFolderContent($item); + } + + public function formatItems($items, $format, $parameters = null) { + if ($format == self::FORMAT_FILE_APP && isset($parameters['folder'])) { + $folder = $items[key($items)]; + $query = OCP\DB::prepare('SELECT path FROM *PREFIX*fscache WHERE id = ?'); + $result = $query->execute(array($folder['file_source']))->fetchRow(); + if (isset($result['path'])) { + if (isset($parameters['mimetype_filter'])) { + $mimetype_filter = $parameters['mimetype_filter']; + } else { + $mimetype_filter = ''; + } + $pos = strpos($result['path'], $folder['item']); + $path = substr($result['path'], $pos).substr($parameters['folder'], strlen($folder['file_target'])); + $root = substr($result['path'], 0, $pos); + return OC_FileCache::getFolderContent($path, $root, $mimetype_filter); + } + }/* else if ($format == self::FORMAT_OPENDIR_ROOT) { + $query = OCP\DB::prepare('SELECT name FROM *PREFIX*fscache WHERE id IN ('.$ids.')'); + $result = $query->execute(); + $files = array(); + while ($file = $result->fetchRow()) { + // Set target path + $files[] = basename($shares[$file['id']]['item_target']); + } + return $files; + }*/ + return array(); + } + +} + + +?> \ No newline at end of file diff --git a/apps/files_sharing/sharedstorage.php b/apps/files_sharing/sharedstorage.php index 11a5d39f01..1dfdf13379 100644 --- a/apps/files_sharing/sharedstorage.php +++ b/apps/files_sharing/sharedstorage.php @@ -32,30 +32,25 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $this->sharedFolder = $arguments['sharedFolder']; } - public function getSourcePath($target) { - $target = $this->sharedFolder.$target; + private function getSourcePath($target) { + $target = $this->sharedFolder.'/'.$target; + $target = rtrim($target, '/'); if (isset($this->sourcePaths[$target])) { return $this->sourcePaths[$target]; } else { - if (dirname($target) != $this->sharedFolder) { - $len = strlen($this->sharedFolder); - $pos = strpos($target, '/', $len); - // Get shared folder name - $itemTarget = substr($target, $len, $pos); - $insideFolder = true; + $pos = strpos($target, '/', 8); + // Get shared folder name + if ($pos !== false) { + $itemTarget = substr($target, 0, $pos); } else { $itemTarget = $target; - $insideFolder = false; } $sourcePath = OCP\Share::getItemSharedWith('file', $itemTarget, OC_Share_Backend_File::FORMAT_SOURCE_PATH); if ($sourcePath) { - if ($insideFolder) { - $this->sourcePaths[$target] = $sourcePath.substr($target, $pos); - } else { - $this->sourcePaths[$target] = $sourcePath; - } + $this->sourcePaths[$target] = $sourcePath.substr($target, strlen($itemTarget)); return $this->sourcePaths[$target]; } + OCP\Util::writeLog('files_sharing', 'File source path not found for: '.$target, OCP\Util::ERROR); return false; } } @@ -70,8 +65,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == "" || $path == "/" || !$this->is_writable($path)) { return false; } else { - $source = $this->getSourcePath($path); - if ($source) { + if ($source = $this->getSourcePath($path)) { $storage = OC_Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); } @@ -80,116 +74,54 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function rmdir($path) { // The folder will be removed from the database, but won't be deleted from the owner's filesystem - OC_Share::unshareFromMySelf($this->datadir.$path); - $this->clearFolderSizeCache($path); + // TODO } public function opendir($path) { - if ($path == "" || $path == "/") { - $path = $this->datadir.$path; - // TODO - $sharedItems = OC_Share::getItemsInFolder($path); - $files = array(); - foreach ($sharedItems as $item) { - // If item is in the root of the shared storage provider and the item exists add it to the fakedirs - if (dirname($item['target'])."/" == $path && $this->file_exists(basename($item['target']))) { - $files[] = basename($item['target']); - } - } - OC_FakeDirStream::$dirs['shared']=$files; + if ($path == '' || $path == '/') { + $files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_Folder::FORMAT_OPENDIR); + OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else { - $source = $this->getSourcePath($path); - if ($source) { + if ($source = $this->getSourcePath($path)) { $storage = OC_Filesystem::getStorage($source); - $dh = $storage->opendir($this->getInternalPath($source)); - $modifiedItems = OC_Share::getItemsInFolder($source); - if ($modifiedItems && $dh) { - $sources = array(); - $targets = array(); - // Remove any duplicate or trailing '/' - $path = preg_replace('{(/)\1+}', "/", $path); - $targetFolder = rtrim($this->datadir.$path, "/"); - foreach ($modifiedItems as $item) { - // If the item is in the current directory and the item exists add it to the arrays - if (dirname($item['target']) == $targetFolder && $this->file_exists($path."/".basename($item['target']))) { - // If the item was unshared from self, add it it to the arrays - if ($item['permissions'] == OC_Share::UNSHARED) { - $sources[] = basename($item['source']); - $targets[] = ""; - } else { - $sources[] = basename($item['source']); - $targets[] = basename($item['target']); - } - } - } - // Don't waste time if there aren't any modified items in the current directory - if (empty($sources)) { - return $dh; - } else { - global $FAKEDIRS; - $files = array(); - while (($filename = readdir($dh)) !== false) { - if ($filename != "." && $filename != "..") { - // If the file isn't in the sources array it isn't modified and can be added as is - if (!in_array($filename, $sources)) { - $files[] = $filename; - // The file has a different name than the source and is added to the fakedirs - } else { - $target = $targets[array_search($filename, $sources)]; - // Don't add the file if it was unshared from self by the user - if ($target != "") { - $files[] = $target; - } - } - } - } - $FAKEDIRS['shared'] = $files; - return opendir('fakedir://shared'); - } - } else { - return $dh; - } + return $storage->opendir($this->getInternalPath($source)); } } } - + public function is_dir($path) { - if ($path == "" || $path == "/") { + if ($path == '' || $path == '/') { return true; } else { - $source = $this->getSourcePath($path); - if ($source) { + if ($source = $this->getSourcePath($path)) { $storage = OC_Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); } } } - + public function is_file($path) { - $source = $this->getSourcePath($path); - if ($source) { + if ($source = $this->getSourcePath($path)) { $storage = OC_Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); } } - - // TODO fill in other components of array + public function stat($path) { - if ($path == "" || $path == "/") { - $stat["size"] = $this->filesize($path); - $stat["mtime"] = $this->filemtime($path); - $stat["ctime"] = $this->filectime($path); + if ($path == '' || $path == '/') { + $stat['size'] = $this->filesize($path); + $stat['mtime'] = $this->filemtime($path); + $stat['ctime'] = $this->filectime($path); return $stat; } else { - $source = $this->getSourcePath($path); - if ($source) { + if ($source = $this->getSourcePath($path)) { $storage = OC_Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); } } } - + public function filetype($path) { if ($path == "" || $path == "/") { return "dir"; @@ -202,7 +134,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } } - + public function filesize($path) { if ($path == "" || $path == "/" || $this->is_dir($path)) { return $this->getFolderSize($path); @@ -215,55 +147,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } } - public function getFolderSize($path) { - return 0; //depricated - } - - private function calculateFolderSize($path) { - if ($this->is_file($path)) { - $path = dirname($path); - } - $size = 0; - if ($dh = $this->opendir($path)) { - while (($filename = readdir($dh)) !== false) { - if ($filename != "." && $filename != "..") { - $subFile = $path."/".$filename; - if ($this->is_file($subFile)) { - $size += $this->filesize($subFile); - } else { - $size += $this->getFolderSize($subFile); - } - } - } - if ($size > 0) { - $dbpath = rtrim($this->datadir.$path, "/"); -// $query = OCP\DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)"); -// $result = $query->execute(array($dbpath, $size)); - } - } - return $size; - } - - private function clearFolderSizeCache($path) { - $path = rtrim($path, "/"); - $path = preg_replace('{(/)\1+}', "/", $path); - if ($this->is_file($path)) { - $path = dirname($path); - } - $dbpath = rtrim($this->datadir.$path, "/"); -// $query = OCP\DB::prepare("DELETE FROM *PREFIX*/*foldersize*/ WHERE path = ?"); -// $result = $query->execute(array($dbpath)); - if ($path != "/" && $path != "") { - $parts = explode("/", $path); - $part = array_pop($parts); - if (empty($part)) { - array_pop($parts); - } - $parent = implode("/", $parts); - $this->clearFolderSizeCache($parent); - } - } - public function is_readable($path) { return true; } @@ -271,7 +154,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function is_writable($path) { if($path == "" || $path == "/"){ return false; - }elseif (OC_Share::getPermissions($this->datadir.$path) & OC_Share::WRITE) { + }elseif (OC_Share::getPermissions($this->sharedFolder.$path) & OC_Share::WRITE) { return true; } else { return false; @@ -336,7 +219,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $source = $this->getSourcePath($path); if ($source) { $info = array( - 'target' => $this->datadir.$path, + 'target' => $this->sharedFolder.$path, 'source' => $source, ); OCP\Util::emitHook('OC_Filestorage_Shared', 'file_get_contents', $info); @@ -350,7 +233,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $source = $this->getSourcePath($path); if ($source) { $info = array( - 'target' => $this->datadir.$path, + 'target' => $this->sharedFolder.$path, 'source' => $source, ); OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info); @@ -366,7 +249,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function unlink($path) { // The item will be removed from the database, but won't be touched on the owner's filesystem - $target = $this->datadir.$path; + $target = $this->sharedFolder.$path; // Check if the item is inside a shared folder if (OC_Share::getParentFolders($target)) { // If entry for item already exists @@ -385,8 +268,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function rename($path1, $path2) { - $oldTarget = $this->datadir.$path1; - $newTarget = $this->datadir.$path2; + $oldTarget = $this->sharedFolder.$path1; + $newTarget = $this->sharedFolder.$path2; // Check if the item is inside a shared folder if ($folders = OC_Share::getParentFolders($oldTarget)) { $root1 = substr($path1, 0, strpos($path1, "/")); @@ -442,7 +325,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $source = $this->getSourcePath($path); if ($source) { $info = array( - 'target' => $this->datadir.$path, + 'target' => $this->sharedFolder.$path, 'source' => $source, 'mode' => $mode, ); @@ -541,7 +424,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public static function setup($options) { $user_dir = $options['user_dir']; - OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => $user_dir.'/Shared'), $user_dir.'/Shared/'); + OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } /** @@ -551,6 +434,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { */ public function hasUpdated($path,$time){ //TODO - return $this->filemtime($path)>$time; + return false; } } diff --git a/core/js/share.js b/core/js/share.js index 755e71e996..3c7d2619eb 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -84,10 +84,8 @@ OC.Share={ $(html).appendTo(appendTo); var data = OC.Share.loadItem(itemType, item); if (data) { - $.each(data, function(index, shares) { - $.each(shares, function(id, share) { - OC.Share.addShareWith(share.share_with, share.permissions); - }); + $.each(data, function(index, share) { + OC.Share.addShareWith(share.share_with, share.permissions); }); } $('#dropdown').show('blind'); @@ -160,6 +158,7 @@ $(document).ready(function() { }); if (typeof FileActions !== 'undefined') { + OC.Share.loadIcons('file'); FileActions.register('all', 'Share', function(filename) { // Return the correct sharing icon @@ -187,19 +186,24 @@ $(document).ready(function() { } }, function(filename) { var item = $('#dir').val() + '/' + filename; - var appendTo = $('tr').filterAttr('data-file',filename).find('td.filename'); + if ($('tr').filterAttr('data-file', filename).data('type') == 'dir') { + var itemType = 'folder'; + } else { + var itemType = 'file'; + } + var appendTo = $('tr').filterAttr('data-file', filename).find('td.filename'); // Check if drop down is already visible for a different file if (($('#dropdown').length > 0)) { if (item != $('#dropdown').data('item')) { OC.Share.hideDropDown(function () { $('tr').removeClass('mouseOver'); $('tr').filterAttr('data-file', filename).addClass('mouseOver'); - OC.Share.showDropDown('file', item, appendTo, true); + OC.Share.showDropDown(itemType, item, appendTo, true); }); } } else { $('tr').filterAttr('data-file',filename).addClass('mouseOver'); - OC.Share.showDropDown('file', item, appendTo, true); + OC.Share.showDropDown(itemType, item, appendTo, true); } }); } diff --git a/lib/filecache.php b/lib/filecache.php index d956f34dc4..b6f4d23986 100644 --- a/lib/filecache.php +++ b/lib/filecache.php @@ -324,6 +324,10 @@ class OC_FileCache{ $eventSource->send('scanning',array('file'=>$path,'count'=>$count)); } $lastSend=$count; + // NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache) + if (substr($path, 0, 7) == '/Shared') { + return; + } if($root===false){ $view=OC_Filesystem::getView(); }else{ @@ -361,6 +365,10 @@ class OC_FileCache{ * @return int size of the scanned file */ public static function scanFile($path,$root=false){ + // NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache) + if (substr($path, 0, 7) == '/Shared') { + return; + } if($root===false){ $view=OC_Filesystem::getView(); }else{ diff --git a/lib/files.php b/lib/files.php index 2feae20afe..4f58ff6782 100644 --- a/lib/files.php +++ b/lib/files.php @@ -33,15 +33,30 @@ class OC_Files { * @param dir $directory path under datadirectory */ public static function getDirectoryContent($directory, $mimetype_filter = ''){ - $files=OC_FileCache::getFolderContent($directory, false, $mimetype_filter); - if ($directory == '') { - $files = array_merge($files, array()); - } else if (substr($directory, 7) == '/Shared') { - $files = array_merge($files, OCP\Share::getItemsSharedWith('file', $directory, OC_Share_Backend_File::FORMAT_FILE_APP)); + $files = array(); + if (substr($directory, 0, 7) == '/Shared') { + if ($directory == '/Shared') { + $files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP, array('mimetype_filter' => $mimetype_filter)); + } else { + $pos = strpos($directory, '/', 8); + // Get shared folder name + if ($pos !== false) { + $itemTarget = substr($directory, 0, $pos); + } else { + $itemTarget = $directory; + } + $files = OCP\Share::getItemSharedWith('folder', $itemTarget, OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); + } + } else { + $files = OC_FileCache::getFolderContent($directory, false, $mimetype_filter); + if ($directory == '') { + // Add 'Shared' folder + $files = array_merge($files, OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT)); + } } - foreach($files as &$file){ - $file['directory']=$directory; - $file['type']=($file['mimetype']=='httpd/unix-directory')?'dir':'file'; + foreach ($files as &$file) { + $file['directory'] = $directory; + $file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; } usort($files, "fileCmp");//TODO: remove this once ajax is merged return $files; @@ -109,8 +124,7 @@ class OC_Files { header('Content-Type: application/zip'); header('Content-Length: ' . filesize($filename)); }else{ - $fileData=OC_FileCache::get($filename); - header('Content-Type: ' . $fileData['mimetype']); + header('Content-Type: '.OC_Filesystem::getMimeType($filename)); } }elseif($zip or !OC_Filesystem::file_exists($filename)){ header("HTTP/1.0 404 Not Found"); diff --git a/lib/public/share.php b/lib/public/share.php index 641d164001..8c7f5a7ad8 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -53,9 +53,9 @@ class Share { * @param array (optional) List of supported file extensions if this item type depends on files * @return Returns true if backend is registered or false if error */ - public static function registerBackend($itemType, $class, $dependsOn = null, $supportedFileExtensions = null) { + public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) { if (!isset(self::$backendTypes[$itemType])) { - self::$backendTypes[$itemType] = array('class' => $class, 'dependsOn' => $dependsOn, 'supportedFileExtensions' => $supportedFileExtensions); + self::$backendTypes[$itemType] = array('class' => $class, 'collectionOf' => $collectionOf, 'supportedFileExtensions' => $supportedFileExtensions); return true; } \OC_Log::write('OCP\Share', 'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class'].' is already registered for '.$itemType, \OC_Log::WARN); @@ -69,8 +69,8 @@ class Share { * @param int Number of items to return (optional) Returns all by default * @return Return depends on format */ - public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, $limit = -1) { - return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $limit); + public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, $parameters = null, $limit = -1) { + return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, $limit); } /** @@ -80,8 +80,8 @@ class Share { * @param int Format (optional) Format type must be defined by the backend * @return Return depends on format */ - public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE) { - return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, 1); + public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE, $parameters = null) { + return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, 1); } /** @@ -91,8 +91,8 @@ class Share { * @param int Format (optional) Format type must be defined by the backend * @return Return depends on format */ - public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE) { - return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, 1, true); + public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE, $parameters = null) { + return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, 1, true); } /** @@ -102,8 +102,8 @@ class Share { * @param int Number of items to return (optional) Returns all by default * @return Return depends on format */ - public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $limit = -1) { - return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format, $limit); + public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null, $limit = -1) { + return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format, $parameters, $limit); } /** @@ -113,8 +113,8 @@ class Share { * @param int Format (optional) Format type must be defined by the backend * @return Return depends on format */ - public static function getItemShared($itemType, $item, $format = self::FORMAT_NONE) { - return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format); + public static function getItemShared($itemType, $item, $format = self::FORMAT_NONE, $parameters = null) { + return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, $parameters); } /** @@ -124,8 +124,8 @@ class Share { * @param int Format (optional) Format type must be defined by the backend * @return Return depends on format */ - public static function getItemSharedBySource($itemType, $item, $format = self::FORMAT_NONE) { - return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, -1, true); + public static function getItemSharedBySource($itemType, $item, $format = self::FORMAT_NONE, $parameters = null) { + return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, $parameters, -1, true); } /** @@ -195,7 +195,7 @@ class Share { if ($parentFolder && $files = \OC_Files::getDirectoryContent($item)) { for ($i = 0; $i < count($files); $i++) { $name = substr($files[$i]['name'], strpos($files[$i]['name'], $item) - strlen($item)); - if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = OC_Files::getDirectoryContent($name, '/')) { + if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC_Files::getDirectoryContent($name, '/')) { // Continue scanning into child folders array_push($files, $children); } else { @@ -370,19 +370,19 @@ class Share { } /** - * @brief Get a list of parent item types for the specified item type + * @brief Get a list of collection item types for the specified item type * @param string Item type * @return array */ - private static function getParentItemTypes($itemType) { - $parents = array($itemType); - foreach (self::$backends as $type => $backend) { - if (in_array($backend->dependsOn, $parents)) { - $parents[] = $type; + private static function getCollectionItemTypes($itemType) { + $collections = array($itemType); + foreach (self::$backendTypes as $type => $backend) { + if (in_array($backend['collectionOf'], $collections)) { + $collections[] = $type; } } - if (!empty($parents)) { - return $parents; + if (count($collections) > 1) { + return $collections; } return false; } @@ -400,19 +400,13 @@ class Share { * See public functions getItem(s)... for parameter usage * */ - private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $limit = -1, $isSource = false) { + private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $isSource = false) { if ($backend = self::getBackend($itemType)) { // Check if there are any parent types that include this type of items, e.g. a music album contains songs - if (isset($itemType)) { - if ($parents = self::getParentItemTypes($itemType)) { - $where = "WHERE item_type IN ('".implode("','", $parents)."')"; - } else { - $where = "WHERE item_type = '".$itemType."'"; - } - // TODO exclude items that are inside of folders and got converted i.e. songs, pictures - if ($itemType == 'files') { - - } + if ($parents = self::getCollectionItemTypes($itemType)) { + $where = "WHERE item_type IN ('".implode("','", $parents)."')"; + } else { + $where = "WHERE item_type = '".$itemType."'"; } if (isset($shareType) && isset($shareWith)) { // Include all user and group items @@ -450,20 +444,21 @@ class Share { } } else { if ($isSource) { - if ($itemType == 'file') { + if ($itemType == 'file' || $itemType == 'folder') { $where .= " AND file_source = '".$item."'"; } else { $where .= " AND item_source = '".$item."'"; } } else { - if ($itemType == 'file' && substr($item, -1) == '/') { - // Special case to select only the shared files inside the folder - $where .= " AND file_target LIKE '".$item."%/'"; + if ($itemType == 'file' || $itemType == 'folder') { + $where .= " AND file_target = '".$item."'"; } else { $where .= " AND item_target = '".$item."'"; } } } + } else if ($itemType == 'file') { + // TODO Exclude converted items inside shared folders } if ($limit != -1) { if ($limit == 1 && $shareType == self::$shareTypeUserAndGroups) { @@ -486,16 +481,12 @@ class Share { $result = $query->execute(); $items = array(); while ($item = $result->fetchRow()) { - if ($limit == 1) { - // Return just the item instead of 3-dimensional array - return $item; - } // Filter out duplicate group shares for users with unique targets if ($item['share_type'] == self::$shareTypeGroupUserUnique) { // Remove the parent group share - unset($items[$item['item_source']][$item['parent']]); + unset($items[$item['parent']]); } - $items[$item['item_source']][$item['id']] = $item; + $items[$item['id']] = $item; // TODO Add in parent item types children? if ($parents && in_array($item['item_type'], $parents)) { $children[] = $item; @@ -506,20 +497,17 @@ class Share { return $items; } else if ($format == self::FORMAT_STATUSES) { $statuses = array(); - foreach ($items as $shares) { - foreach ($shares as $info) { - if ($info['share_type'] == self::SHARE_TYPE_PRIVATE_LINK) { - $statuses[$info['item']] = true; - break; - } else if (!isset($statuses[$info['item']])) { - $statuses[$info['item']] = false; - } + foreach ($items as $item) { + if ($item['share_type'] == self::SHARE_TYPE_PRIVATE_LINK) { + $statuses[$item['item']] = true; + break; + } else if (!isset($statuses[$item['item']])) { + $statuses[$item['item']] = false; } - } return $statuses; } else { - return $backend->formatItems($items, $format); + return $backend->formatItems($items, $format, $parameters); } } else if ($limit == 1 || (isset($uidOwner) && isset($item))) { return false; @@ -764,12 +752,14 @@ abstract class Share_Backend { * This function allows the backend to control the output of shared items with custom formats. * It is only called through calls to the public getItem(s)Shared(With) functions. */ - public abstract function formatItems($items, $format); + public abstract function formatItems($items, $format, $parameters = null); } -abstract class Share_Backend_Parent extends Share_Backend { +abstract class Share_Backend_Collection extends Share_Backend { + + public abstract function inCollection($collections, $item); public abstract function getChildren($item);