summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Files/Cache/Scanner.php49
-rw-r--r--lib/private/Files/Storage/Wrapper/Encoding.php533
-rw-r--r--lib/private/Share20/DefaultShareProvider.php2
-rw-r--r--lib/private/Share20/Manager.php15
-rw-r--r--lib/private/Share20/ProviderFactory.php3
-rw-r--r--lib/private/Share20/Share.php17
-rw-r--r--lib/private/URLGenerator.php23
-rw-r--r--lib/private/legacy/util.php7
-rw-r--r--lib/public/Comments/CommentsEntityEvent.php76
9 files changed, 683 insertions, 42 deletions
diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php
index 03aca1924b0..fd309a4ac45 100644
--- a/lib/private/Files/Cache/Scanner.php
+++ b/lib/private/Files/Cache/Scanner.php
@@ -341,7 +341,7 @@ class Scanner extends BasicEmitter implements IScanner {
if (is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if (!Filesystem::isIgnoredDir($file)) {
- $children[] = $file;
+ $children[] = trim(\OC\Files\Filesystem::normalizePath($file), '/');
}
}
}
@@ -355,29 +355,45 @@ class Scanner extends BasicEmitter implements IScanner {
* @param string $path
* @param bool $recursive
* @param int $reuse
- * @param array $folderData existing cache data for the folder to be scanned
+ * @param int $folderId id for the folder to be scanned
* @param bool $lock set to false to disable getting an additional read lock during scanning
* @return int the size of the scanned folder or -1 if the size is unknown at this stage
*/
- protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null, $lock = true) {
+ protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderId = null, $lock = true) {
if ($reuse === -1) {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
$this->emit('\OC\Files\Cache\Scanner', 'scanFolder', array($path, $this->storageId));
$size = 0;
- $childQueue = array();
- if (is_array($folderData) and isset($folderData['fileid'])) {
- $folderId = $folderData['fileid'];
- } else {
+ if (!is_null($folderId)) {
$folderId = $this->cache->getId($path);
}
+ $childQueue = $this->handleChildren($path, $recursive, $reuse, $folderId, $lock, $size);
+
+ foreach ($childQueue as $child => $childId) {
+ $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childId, $lock);
+ if ($childSize === -1) {
+ $size = -1;
+ } else if ($size !== -1) {
+ $size += $childSize;
+ }
+ }
+ $this->updateCache($path, array('size' => $size), $folderId);
+ $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId));
+ return $size;
+ }
+
+ private function handleChildren($path, $recursive, $reuse, $folderId, $lock, &$size) {
+ // we put this in it's own function so it cleans up the memory before we start recursing
$existingChildren = $this->getExistingChildren($folderId);
$newChildren = $this->getNewChildren($path);
if ($this->useTransactions) {
\OC::$server->getDatabaseConnection()->beginTransaction();
}
+
$exceptionOccurred = false;
+ $childQueue = [];
foreach ($newChildren as $file) {
$child = ($path) ? $path . '/' . $file : $file;
try {
@@ -385,7 +401,7 @@ class Scanner extends BasicEmitter implements IScanner {
$data = $this->scanFile($child, $reuse, $folderId, $existingData, $lock);
if ($data) {
if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) {
- $childQueue[$child] = $data;
+ $childQueue[$child] = $data['fileid'];
} else if ($data['size'] === -1) {
$size = -1;
} else if ($size !== -1) {
@@ -420,20 +436,7 @@ class Scanner extends BasicEmitter implements IScanner {
// we reload them here
\OC::$server->getMimeTypeLoader()->reset();
}
-
- foreach ($childQueue as $child => $childData) {
- $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childData, $lock);
- if ($childSize === -1) {
- $size = -1;
- } else if ($size !== -1) {
- $size += $childSize;
- }
- }
- if (!is_array($folderData) or !isset($folderData['size']) or $folderData['size'] !== $size) {
- $this->updateCache($path, array('size' => $size), $folderId);
- }
- $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId));
- return $size;
+ return $childQueue;
}
/**
@@ -466,7 +469,7 @@ class Scanner extends BasicEmitter implements IScanner {
} else {
$lastPath = null;
while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) {
- $this->runBackgroundScanJob(function() use ($path) {
+ $this->runBackgroundScanJob(function () use ($path) {
$this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG);
}, $path);
// FIXME: this won't proceed with the next item, needs revamping of getIncomplete()
diff --git a/lib/private/Files/Storage/Wrapper/Encoding.php b/lib/private/Files/Storage/Wrapper/Encoding.php
new file mode 100644
index 00000000000..0171dfe19b7
--- /dev/null
+++ b/lib/private/Files/Storage/Wrapper/Encoding.php
@@ -0,0 +1,533 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Storage\Wrapper;
+
+use OCP\ICache;
+use OC\Cache\CappedMemoryCache;
+
+/**
+ * Encoding wrapper that deals with file names that use unsupported encodings like NFD.
+ *
+ * When applied and a UTF-8 path name was given, the wrapper will first attempt to access
+ * the actual given name and then try its NFD form.
+ */
+class Encoding extends Wrapper {
+
+ /**
+ * @var ICache
+ */
+ private $namesCache;
+
+ /**
+ * @param array $parameters
+ */
+ public function __construct($parameters) {
+ $this->storage = $parameters['storage'];
+ $this->namesCache = new CappedMemoryCache();
+ }
+
+ /**
+ * Returns whether the given string is only made of ASCII characters
+ *
+ * @param string $str string
+ *
+ * @return bool true if the string is all ASCII, false otherwise
+ */
+ private function isAscii($str) {
+ return (bool) !preg_match('/[\\x80-\\xff]+/', $str);
+ }
+
+ /**
+ * Checks whether the given path exists in NFC or NFD form after checking
+ * each form for each path section and returns the correct form.
+ * If no existing path found, returns the path as it was given.
+ *
+ * @param string $fullPath path to check
+ *
+ * @return string original or converted path
+ */
+ private function findPathToUse($fullPath) {
+ $cachedPath = $this->namesCache[$fullPath];
+ if ($cachedPath !== null) {
+ return $cachedPath;
+ }
+
+ $sections = explode('/', $fullPath);
+ $path = '';
+ foreach ($sections as $section) {
+ $convertedPath = $this->findPathToUseLastSection($path, $section);
+ if ($convertedPath === null) {
+ // no point in continuing if the section was not found, use original path
+ return $fullPath;
+ }
+ $path = $convertedPath . '/';
+ }
+ $path = rtrim($path, '/');
+ return $path;
+ }
+
+ /**
+ * Checks whether the last path section of the given path exists in NFC or NFD form
+ * and returns the correct form. If no existing path found, returns null.
+ *
+ * @param string $basePath base path to check
+ * @param string $lastSection last section of the path to check for NFD/NFC variations
+ *
+ * @return string|null original or converted path, or null if none of the forms was found
+ */
+ private function findPathToUseLastSection($basePath, $lastSection) {
+ $fullPath = $basePath . $lastSection;
+ if ($lastSection === '' || $this->isAscii($lastSection) || $this->storage->file_exists($fullPath)) {
+ $this->namesCache[$fullPath] = $fullPath;
+ return $fullPath;
+ }
+
+ // swap encoding
+ if (\Normalizer::isNormalized($lastSection, \Normalizer::FORM_C)) {
+ $otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_D);
+ } else {
+ $otherFormPath = \Normalizer::normalize($lastSection, \Normalizer::FORM_C);
+ }
+ $otherFullPath = $basePath . $otherFormPath;
+ if ($this->storage->file_exists($otherFullPath)) {
+ $this->namesCache[$fullPath] = $otherFullPath;
+ return $otherFullPath;
+ }
+
+ // return original path, file did not exist at all
+ $this->namesCache[$fullPath] = $fullPath;
+ return null;
+ }
+
+ /**
+ * see http://php.net/manual/en/function.mkdir.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function mkdir($path) {
+ // note: no conversion here, method should not be called with non-NFC names!
+ $result = $this->storage->mkdir($path);
+ if ($result) {
+ $this->namesCache[$path] = $path;
+ }
+ return $result;
+ }
+
+ /**
+ * see http://php.net/manual/en/function.rmdir.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function rmdir($path) {
+ $result = $this->storage->rmdir($this->findPathToUse($path));
+ if ($result) {
+ unset($this->namesCache[$path]);
+ }
+ return $result;
+ }
+
+ /**
+ * see http://php.net/manual/en/function.opendir.php
+ *
+ * @param string $path
+ * @return resource
+ */
+ public function opendir($path) {
+ return $this->storage->opendir($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.is_dir.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function is_dir($path) {
+ return $this->storage->is_dir($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.is_file.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function is_file($path) {
+ return $this->storage->is_file($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.stat.php
+ * only the following keys are required in the result: size and mtime
+ *
+ * @param string $path
+ * @return array
+ */
+ public function stat($path) {
+ return $this->storage->stat($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.filetype.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function filetype($path) {
+ return $this->storage->filetype($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.filesize.php
+ * The result for filesize when called on a folder is required to be 0
+ *
+ * @param string $path
+ * @return int
+ */
+ public function filesize($path) {
+ return $this->storage->filesize($this->findPathToUse($path));
+ }
+
+ /**
+ * check if a file can be created in $path
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isCreatable($path) {
+ return $this->storage->isCreatable($this->findPathToUse($path));
+ }
+
+ /**
+ * check if a file can be read
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isReadable($path) {
+ return $this->storage->isReadable($this->findPathToUse($path));
+ }
+
+ /**
+ * check if a file can be written to
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isUpdatable($path) {
+ return $this->storage->isUpdatable($this->findPathToUse($path));
+ }
+
+ /**
+ * check if a file can be deleted
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isDeletable($path) {
+ return $this->storage->isDeletable($this->findPathToUse($path));
+ }
+
+ /**
+ * check if a file can be shared
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isSharable($path) {
+ return $this->storage->isSharable($this->findPathToUse($path));
+ }
+
+ /**
+ * get the full permissions of a path.
+ * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
+ *
+ * @param string $path
+ * @return int
+ */
+ public function getPermissions($path) {
+ return $this->storage->getPermissions($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.file_exists.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function file_exists($path) {
+ return $this->storage->file_exists($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.filemtime.php
+ *
+ * @param string $path
+ * @return int
+ */
+ public function filemtime($path) {
+ return $this->storage->filemtime($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.file_get_contents.php
+ *
+ * @param string $path
+ * @return string
+ */
+ public function file_get_contents($path) {
+ return $this->storage->file_get_contents($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.file_put_contents.php
+ *
+ * @param string $path
+ * @param string $data
+ * @return bool
+ */
+ public function file_put_contents($path, $data) {
+ return $this->storage->file_put_contents($this->findPathToUse($path), $data);
+ }
+
+ /**
+ * see http://php.net/manual/en/function.unlink.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function unlink($path) {
+ $result = $this->storage->unlink($this->findPathToUse($path));
+ if ($result) {
+ unset($this->namesCache[$path]);
+ }
+ return $result;
+ }
+
+ /**
+ * see http://php.net/manual/en/function.rename.php
+ *
+ * @param string $path1
+ * @param string $path2
+ * @return bool
+ */
+ public function rename($path1, $path2) {
+ // second name always NFC
+ return $this->storage->rename($this->findPathToUse($path1), $this->findPathToUse($path2));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.copy.php
+ *
+ * @param string $path1
+ * @param string $path2
+ * @return bool
+ */
+ public function copy($path1, $path2) {
+ return $this->storage->copy($this->findPathToUse($path1), $this->findPathToUse($path2));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.fopen.php
+ *
+ * @param string $path
+ * @param string $mode
+ * @return resource
+ */
+ public function fopen($path, $mode) {
+ $result = $this->storage->fopen($this->findPathToUse($path), $mode);
+ if ($result && $mode !== 'r' && $mode !== 'rb') {
+ unset($this->namesCache[$path]);
+ }
+ return $result;
+ }
+
+ /**
+ * get the mimetype for a file or folder
+ * The mimetype for a folder is required to be "httpd/unix-directory"
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getMimeType($path) {
+ return $this->storage->getMimeType($this->findPathToUse($path));
+ }
+
+ /**
+ * see http://php.net/manual/en/function.hash.php
+ *
+ * @param string $type
+ * @param string $path
+ * @param bool $raw
+ * @return string
+ */
+ public function hash($type, $path, $raw = false) {
+ return $this->storage->hash($type, $this->findPathToUse($path), $raw);
+ }
+
+ /**
+ * see http://php.net/manual/en/function.free_space.php
+ *
+ * @param string $path
+ * @return int
+ */
+ public function free_space($path) {
+ return $this->storage->free_space($this->findPathToUse($path));
+ }
+
+ /**
+ * search for occurrences of $query in file names
+ *
+ * @param string $query
+ * @return array
+ */
+ public function search($query) {
+ return $this->storage->search($query);
+ }
+
+ /**
+ * see http://php.net/manual/en/function.touch.php
+ * If the backend does not support the operation, false should be returned
+ *
+ * @param string $path
+ * @param int $mtime
+ * @return bool
+ */
+ public function touch($path, $mtime = null) {
+ return $this->storage->touch($this->findPathToUse($path), $mtime);
+ }
+
+ /**
+ * get the path to a local version of the file.
+ * The local version of the file can be temporary and doesn't have to be persistent across requests
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getLocalFile($path) {
+ return $this->storage->getLocalFile($this->findPathToUse($path));
+ }
+
+ /**
+ * check if a file or folder has been updated since $time
+ *
+ * @param string $path
+ * @param int $time
+ * @return bool
+ *
+ * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
+ * returning true for other changes in the folder is optional
+ */
+ public function hasUpdated($path, $time) {
+ return $this->storage->hasUpdated($this->findPathToUse($path), $time);
+ }
+
+ /**
+ * get a cache instance for the storage
+ *
+ * @param string $path
+ * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
+ * @return \OC\Files\Cache\Cache
+ */
+ public function getCache($path = '', $storage = null) {
+ if (!$storage) {
+ $storage = $this;
+ }
+ return $this->storage->getCache($this->findPathToUse($path), $storage);
+ }
+
+ /**
+ * get a scanner instance for the storage
+ *
+ * @param string $path
+ * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
+ * @return \OC\Files\Cache\Scanner
+ */
+ public function getScanner($path = '', $storage = null) {
+ if (!$storage) {
+ $storage = $this;
+ }
+ return $this->storage->getScanner($this->findPathToUse($path), $storage);
+ }
+
+ /**
+ * get the ETag for a file or folder
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getETag($path) {
+ return $this->storage->getETag($this->findPathToUse($path));
+ }
+
+ /**
+ * @param \OCP\Files\Storage $sourceStorage
+ * @param string $sourceInternalPath
+ * @param string $targetInternalPath
+ * @return bool
+ */
+ public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+ if ($sourceStorage === $this) {
+ return $this->copy($sourceInternalPath, $this->findPathToUse($targetInternalPath));
+ }
+
+ $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $this->findPathToUse($targetInternalPath));
+ if ($result) {
+ unset($this->namesCache[$targetInternalPath]);
+ }
+ return $result;
+ }
+
+ /**
+ * @param \OCP\Files\Storage $sourceStorage
+ * @param string $sourceInternalPath
+ * @param string $targetInternalPath
+ * @return bool
+ */
+ public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
+ if ($sourceStorage === $this) {
+ $result = $this->rename($sourceInternalPath, $this->findPathToUse($targetInternalPath));
+ if ($result) {
+ unset($this->namesCache[$sourceInternalPath]);
+ unset($this->namesCache[$targetInternalPath]);
+ }
+ return $result;
+ }
+
+ $result = $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $this->findPathToUse($targetInternalPath));
+ if ($result) {
+ unset($this->namesCache[$sourceInternalPath]);
+ unset($this->namesCache[$targetInternalPath]);
+ }
+ return $result;
+ }
+
+ /**
+ * @param string $path
+ * @return array
+ */
+ public function getMetaData($path) {
+ return $this->storage->getMetaData($this->findPathToUse($path));
+ }
+}
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index f0de39fdad3..8a39c18a495 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -733,7 +733,7 @@ class DefaultShareProvider implements IShareProvider {
* @throws InvalidShare
*/
private function createShare($data) {
- $share = new Share($this->rootFolder);
+ $share = new Share($this->rootFolder, $this->userManager);
$share->setId((int)$data['id'])
->setShareType((int)$data['share_type'])
->setPermissions((int)$data['permissions'])
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index dee9e0cdd21..3568995472a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -201,7 +201,12 @@ class Manager implements IManager {
}
// And you can't share your rootfolder
- if ($this->rootFolder->getUserFolder($share->getSharedBy())->getPath() === $share->getNode()->getPath()) {
+ if ($this->userManager->userExists($share->getSharedBy())) {
+ $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
+ } else {
+ $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
+ }
+ if ($sharedPath === $share->getNode()->getPath()) {
throw new \InvalidArgumentException('You can\'t share your root folder');
}
@@ -713,7 +718,11 @@ class Manager implements IManager {
}
if ($share->getPermissions() !== $originalShare->getPermissions()) {
- $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
+ if ($this->userManager->userExists($share->getShareOwner())) {
+ $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
+ } else {
+ $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
+ }
\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
'itemSource' => $share->getNode()->getId(),
@@ -1107,7 +1116,7 @@ class Manager implements IManager {
* @return \OCP\Share\IShare;
*/
public function newShare() {
- return new \OC\Share20\Share($this->rootFolder);
+ return new \OC\Share20\Share($this->rootFolder, $this->userManager);
}
/**
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 0bedfb84fc7..b436a7bc5f3 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -115,7 +115,8 @@ class ProviderFactory implements IProviderFactory {
$l,
$this->serverContainer->getLogger(),
$this->serverContainer->getLazyRootFolder(),
- $this->serverContainer->getConfig()
+ $this->serverContainer->getConfig(),
+ $this->serverContainer->getUserManager()
);
}
diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php
index c361f01216f..f56fd94b409 100644
--- a/lib/private/Share20/Share.php
+++ b/lib/private/Share20/Share.php
@@ -24,8 +24,7 @@ use OCP\Files\File;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
-use OCP\IUser;
-use OCP\IGroup;
+use OCP\IUserManager;
use OCP\Share\Exceptions\IllegalIDChangeException;
class Share implements \OCP\Share\IShare {
@@ -68,8 +67,12 @@ class Share implements \OCP\Share\IShare {
/** @var IRootFolder */
private $rootFolder;
- public function __construct(IRootFolder $rootFolder) {
+ /** @var IUserManager */
+ private $userManager;
+
+ public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
$this->rootFolder = $rootFolder;
+ $this->userManager = $userManager;
}
/**
@@ -145,7 +148,13 @@ class Share implements \OCP\Share\IShare {
throw new NotFoundException();
}
- $userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
+ // for federated shares the owner can be a remote user, in this
+ // case we use the initiator
+ if($this->userManager->userExists($this->shareOwner)) {
+ $userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
+ } else {
+ $userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
+ }
$nodes = $userFolder->getById($this->fileId);
if (empty($nodes)) {
diff --git a/lib/private/URLGenerator.php b/lib/private/URLGenerator.php
index 327c0c32dfe..9c4b0ff0864 100644
--- a/lib/private/URLGenerator.php
+++ b/lib/private/URLGenerator.php
@@ -159,28 +159,31 @@ class URLGenerator implements IURLGenerator {
} elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.svg")
&& file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.png")) {
$path = \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$basename.png";
- } elseif ($appPath && file_exists($appPath . "/img/$image")) {
- $path = \OC_App::getAppWebPath($app) . "/img/$image";
- } elseif ($appPath && !file_exists($appPath . "/img/$basename.svg")
- && file_exists($appPath . "/img/$basename.png")) {
- $path = \OC_App::getAppWebPath($app) . "/img/$basename.png";
} elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) {
$path = \OC::$WEBROOT . "/themes/$theme/$app/img/$image";
} elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.svg")
&& file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.png"))) {
$path = \OC::$WEBROOT . "/themes/$theme/$app/img/$basename.png";
- } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) {
- $path = \OC::$WEBROOT . "/$app/img/$image";
- } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/$app/img/$basename.svg")
- && file_exists(\OC::$SERVERROOT . "/$app/img/$basename.png"))) {
- $path = \OC::$WEBROOT . "/$app/img/$basename.png";
} elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$image")) {
$path = \OC::$WEBROOT . "/themes/$theme/core/img/$image";
} elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.svg")
&& file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.png")) {
$path = \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png";
+ } elseif ($appPath && file_exists($appPath . "/img/$image")) {
+ $path = \OC_App::getAppWebPath($app) . "/img/$image";
+ } elseif ($appPath && !file_exists($appPath . "/img/$basename.svg")
+ && file_exists($appPath . "/img/$basename.png")) {
+ $path = \OC_App::getAppWebPath($app) . "/img/$basename.png";
+ } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) {
+ $path = \OC::$WEBROOT . "/$app/img/$image";
+ } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/$app/img/$basename.svg")
+ && file_exists(\OC::$SERVERROOT . "/$app/img/$basename.png"))) {
+ $path = \OC::$WEBROOT . "/$app/img/$basename.png";
} elseif (file_exists(\OC::$SERVERROOT . "/core/img/$image")) {
$path = \OC::$WEBROOT . "/core/img/$image";
+ } elseif (!file_exists(\OC::$SERVERROOT . "/core/img/$basename.svg")
+ && file_exists(\OC::$SERVERROOT . "/core/img/$basename.png")) {
+ $path = \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png";
}
if($path !== '') {
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index 4f7a8668dfc..de97a762246 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -172,6 +172,13 @@ class OC_Util {
return $storage;
});
+ \OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
+ if ($mount->getOption('encoding_compatibility', true) && !$storage->instanceOfStorage('\OC\Files\Storage\Shared') && !$storage->isLocal()) {
+ return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]);
+ }
+ return $storage;
+ });
+
\OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) {
// set up quota for home storages, even for other users
// which can happen when using sharing
diff --git a/lib/public/Comments/CommentsEntityEvent.php b/lib/public/Comments/CommentsEntityEvent.php
new file mode 100644
index 00000000000..5f012a79885
--- /dev/null
+++ b/lib/public/Comments/CommentsEntityEvent.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Comments;
+
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Class CommentsEntityEvent
+ *
+ * @package OCP\Comments
+ * @since 9.1.0
+ */
+class CommentsEntityEvent extends Event {
+
+ const EVENT_ENTITY = 'OCP\Comments\ICommentsManager::registerEntity';
+
+ /** @var string */
+ protected $event;
+ /** @var \Closure[] */
+ protected $collections;
+
+ /**
+ * DispatcherEvent constructor.
+ *
+ * @param string $event
+ * @since 9.1.0
+ */
+ public function __construct($event) {
+ $this->event = $event;
+ $this->collections = [];
+ }
+
+ /**
+ * @param string $name
+ * @param \Closure $entityExistsFunction The closure should take one
+ * argument, which is the id of the entity, that comments
+ * should be handled for. The return should then be bool,
+ * depending on whether comments are allowed (true) or not.
+ * @throws \OutOfBoundsException when the entity name is already taken
+ * @since 9.1.0
+ */
+ public function addEntityCollection($name, \Closure $entityExistsFunction) {
+ if (isset($this->collections[$name])) {
+ throw new \OutOfBoundsException('Duplicate entity name "' . $name . '"');
+ }
+
+ $this->collections[$name] = $entityExistsFunction;
+ }
+
+ /**
+ * @return \Closure[]
+ * @since 9.1.0
+ */
+ public function getEntityCollections() {
+ return $this->collections;
+ }
+}