aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.drone.yml18
-rw-r--r--README.md2
-rw-r--r--apps/comments/appinfo/app.php1
-rw-r--r--apps/comments/css/comments.css14
-rw-r--r--apps/comments/js/activitytabviewplugin.js59
-rw-r--r--apps/comments/lib/Activity/Extension.php19
-rw-r--r--apps/dav/lib/Connector/Sabre/FilesPlugin.php3
-rw-r--r--apps/dav/lib/Files/FilesHome.php55
-rw-r--r--apps/dav/lib/Files/RootCollection.php13
-rw-r--r--apps/dav/lib/Upload/UploadHome.php2
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php52
-rw-r--r--apps/files/lib/Activity.php29
-rw-r--r--apps/files_sharing/lib/Activity.php1
-rw-r--r--apps/files_sharing/tests/EtagPropagationTest.php2
-rw-r--r--apps/files_sharing/tests/GroupEtagPropagationTest.php2
-rw-r--r--apps/files_sharing/tests/SharedMountTest.php2
-rw-r--r--apps/systemtags/lib/Activity/Extension.php2
-rwxr-xr-xautotest.sh7
-rw-r--r--core/css/icons.css7
-rw-r--r--core/img/actions/star-dark.svg1
-rw-r--r--core/img/places/files-dark.svg1
-rw-r--r--lib/composer/composer/autoload_classmap.php10
-rw-r--r--lib/composer/composer/autoload_static.php10
-rw-r--r--lib/private/AppFramework/DependencyInjection/DIContainer.php5
-rw-r--r--lib/private/Avatar.php23
-rw-r--r--lib/private/AvatarManager.php29
-rw-r--r--lib/private/Files/AppData/AppData.php131
-rw-r--r--lib/private/Files/AppData/Factory.php50
-rw-r--r--lib/private/Files/SimpleFS/SimpleFile.php115
-rw-r--r--lib/private/Files/SimpleFS/SimpleFolder.php87
-rw-r--r--lib/private/Repair.php5
-rw-r--r--lib/private/Repair/NC11/MoveAvatarBackgroundJob.php104
-rw-r--r--lib/private/Repair/NC11/MoveAvatars.php64
-rw-r--r--lib/private/Server.php18
-rw-r--r--lib/private/legacy/app.php74
-rw-r--r--lib/private/legacy/util.php12
-rw-r--r--lib/public/AppFramework/Http/FileDisplayResponse.php7
-rw-r--r--lib/public/Files/IAppData.php36
-rw-r--r--lib/public/Files/SimpleFS/ISimpleFile.php100
-rw-r--r--lib/public/Files/SimpleFS/ISimpleFolder.php88
-rw-r--r--lib/public/Files/SimpleFS/ISimpleRoot.php67
-rw-r--r--lib/public/IServerContainer.php1
-rw-r--r--settings/js/apps.js7
-rw-r--r--tests/lib/AvatarManagerTest.php20
-rw-r--r--tests/lib/AvatarTest.php22
-rw-r--r--tests/lib/Files/AppData/AppDataTest.php121
-rw-r--r--tests/lib/Files/AppData/FactoryTest.php55
-rw-r--r--tests/lib/Files/SimpleFS/SimpleFileTest.php104
-rw-r--r--tests/lib/Files/SimpleFS/SimpleFolderTest.php138
-rw-r--r--tests/lib/TestCase.php6
-rw-r--r--tests/phpunit-autotest.xml5
-rw-r--r--version.php2
52 files changed, 1604 insertions, 204 deletions
diff --git a/.drone.yml b/.drone.yml
index a3c3870dcdd..92dde90bf6d 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -301,7 +301,7 @@ pipeline:
when:
matrix:
TESTS: integration-sharees-features
- codecov:
+ nodb-codecov:
image: nextcloudci/php7.0:php7.0-2
commands:
- TEST_SELECTION=NODB ./autotest.sh sqlite
@@ -310,12 +310,22 @@ pipeline:
- sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t 117641e2-a9e8-4b7b-984b-ae872d9b05f5 -f tests/autotest-clover-sqlite.xml; fi"
when:
matrix:
- TESTS: codecov
-
+ TESTS: nodb-codecov
+ db-codecov:
+ image: nextcloudci/php7.0:php7.0-2
+ commands:
+ - TEST_SELECTION=QUICKDB ./autotest.sh sqlite
+ - wget https://codecov.io/bash -O codecov.sh
+ - sh -c "if [ '$DRONE_BUILD_EVENT' = 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -P $DRONE_PULL_REQUEST -t 117641e2-a9e8-4b7b-984b-ae872d9b05f5 -f tests/autotest-clover-sqlite.xml; fi"
+ - sh -c "if [ '$DRONE_BUILD_EVENT' != 'pull_request' ]; then bash codecov.sh -B $DRONE_BRANCH -C $DRONE_COMMIT -t 117641e2-a9e8-4b7b-984b-ae872d9b05f5 -f tests/autotest-clover-sqlite.xml; fi"
+ when:
+ matrix:
+ TESTS: db-codecov
matrix:
include:
- TESTS: signed-off-check
- - TESTS: codecov
+ - TESTS: nodb-codecov
+ - TESTS: db-codecov
- TESTS: integration-capabilities_features
- TESTS: integration-federation_features
- TESTS: integration-auth
diff --git a/README.md b/README.md
index 2c0f11b43bd..cd6122894af 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# Nextcloud
-[![Build Status](https://drone.weasel.rocks/api/badges/nextcloud/server/status.svg)](https://drone.weasel.rocks/nextcloud/server)
+[![Build Status](https://drone.nextcloud.com/api/badges/nextcloud/server/status.svg)](https://drone.nextcloud.com/nextcloud/server)
[![irc](https://img.shields.io/badge/IRC-%23nextcloud%20on%20freenode-orange.svg)](https://webchat.freenode.net/?channels=nextcloud)
[![irc](https://img.shields.io/badge/IRC-%23nextcloud--dev%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-dev)
diff --git a/apps/comments/appinfo/app.php b/apps/comments/appinfo/app.php
index 00085cf9148..df41bdfa32d 100644
--- a/apps/comments/appinfo/app.php
+++ b/apps/comments/appinfo/app.php
@@ -32,6 +32,7 @@ $eventDispatcher->addListener(
\OCP\Util::addScript('comments', 'commentsummarymodel');
\OCP\Util::addScript('comments', 'commentstabview');
\OCP\Util::addScript('comments', 'filesplugin');
+ \OCP\Util::addScript('comments', 'activitytabviewplugin');
\OCP\Util::addStyle('comments', 'comments');
}
);
diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css
index 7f64f1cf7db..103564c5faf 100644
--- a/apps/comments/css/comments.css
+++ b/apps/comments/css/comments.css
@@ -59,35 +59,39 @@
line-height: 32px;
}
+#activityTabView li.comment.collapsed .activitymessage,
#commentsTabView .comment.collapsed .message {
white-space: pre-wrap;
}
+#activityTabView li.comment.collapsed .activitymessage,
#commentsTabView .comment.collapsed .message {
max-height: 70px;
overflow: hidden;
}
+#activityTabView li.comment .message-overlay,
#commentsTabView .comment .message-overlay {
display: none;
}
+#activityTabView li.comment.collapsed .message-overlay,
#commentsTabView .comment.collapsed .message-overlay {
display: block;
- position: absolute;
+ position: absolute;
z-index: 2;
- height: 50px;
- pointer-events: none;
+ height: 50px;
+ pointer-events: none;
left: 0;
right: 0;
- bottom: 0;
+ bottom: 0;
background: -moz-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
background: -webkit-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
background: -o-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
background: -ms-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF');
- background-repeat: no-repeat;
+ background-repeat: no-repeat;
}
#commentsTabView .authorRow>div {
diff --git a/apps/comments/js/activitytabviewplugin.js b/apps/comments/js/activitytabviewplugin.js
new file mode 100644
index 00000000000..ca3253bd137
--- /dev/null
+++ b/apps/comments/js/activitytabviewplugin.js
@@ -0,0 +1,59 @@
+/*
+ * @author Joas Schilling <coding@schilljs.com>
+ * Copyright (c) 2016
+ *
+ * This file is licensed under the Affero General Public License version 3
+ * or later.
+ *
+ * See the COPYING-README file.
+ */
+
+(function() {
+ OCA.Comments.ActivityTabViewPlugin = {
+
+ /**
+ * Prepare activity for display
+ *
+ * @param {OCA.Activity.ActivityModel} model for this activity
+ * @param {jQuery} $el jQuery handle for this activity
+ * @param {string} view The view that displayes this activity
+ */
+ prepareModelForDisplay: function (model, $el, view) {
+ if (model.get('app') !== 'comments' || model.get('type') !== 'comments') {
+ return;
+ }
+
+ if (view === 'ActivityTabView') {
+ $el.addClass('comment');
+ if (this._isLong(model.get('message_prepared'))) {
+ $el.addClass('collapsed');
+ var $overlay = $('<div>').addClass('message-overlay');
+ $el.find('.activitymessage').after($overlay);
+ $el.on('click', this._onClickCollapsedComment);
+ }
+ }
+ },
+
+ /*
+ * Copy of CommentsTabView._onClickComment()
+ */
+ _onClickCollapsedComment: function(ev) {
+ var $row = $(ev.target);
+ if (!$row.is('.comment')) {
+ $row = $row.closest('.comment');
+ }
+ $row.removeClass('collapsed');
+ },
+
+ /*
+ * Copy of CommentsTabView._isLong()
+ */
+ _isLong: function(message) {
+ return message.length > 250 || (message.match(/\n/g) || []).length > 1;
+ }
+ };
+
+
+})();
+
+OC.Plugins.register('OCA.Activity.RenderingPlugins', OCA.Comments.ActivityTabViewPlugin);
diff --git a/apps/comments/lib/Activity/Extension.php b/apps/comments/lib/Activity/Extension.php
index 0a7503c1915..6bf7bc9ac0b 100644
--- a/apps/comments/lib/Activity/Extension.php
+++ b/apps/comments/lib/Activity/Extension.php
@@ -159,7 +159,7 @@ class Extension implements IExtension {
}
return (string) $l->t('%1$s commented', $params);
case self::ADD_COMMENT_MESSAGE:
- return $this->convertParameterToComment($params[0], 120);
+ return $this->convertParameterToComment($params[0]);
}
return false;
@@ -196,7 +196,6 @@ class Extension implements IExtension {
try {
return strip_tags($user) === $this->activityManager->getCurrentUserId();
} catch (\UnexpectedValueException $e) {
- // FIXME this is awkward, but we have no access to the current user in emails
return false;
}
}
@@ -247,14 +246,15 @@ class Extension implements IExtension {
public function getNavigation() {
$l = $this->getL10N();
return [
- 'apps' => [],
- 'top' => [
+ 'apps' => [
self::APP_NAME => [
'id' => self::APP_NAME,
+ 'icon' => 'icon-comment',
'name' => (string) $l->t('Comments'),
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::APP_NAME]),
],
],
+ 'top' => [],
];
}
@@ -300,21 +300,12 @@ class Extension implements IExtension {
* @param string $parameter
* @return string
*/
- protected function convertParameterToComment($parameter, $maxLength = 0) {
+ protected function convertParameterToComment($parameter) {
if (preg_match('/^\<parameter\>(\d*)\<\/parameter\>$/', $parameter, $matches)) {
try {
$comment = $this->commentsManager->get((int) $matches[1]);
$message = $comment->getMessage();
$message = str_replace("\n", '<br />', str_replace(['<', '>'], ['&lt;', '&gt;'], $message));
-
- if ($maxLength && isset($message[$maxLength + 20])) {
- $findSpace = strpos($message, ' ', $maxLength);
- if ($findSpace !== false && $findSpace < $maxLength + 20) {
- return substr($message, 0, $findSpace) . '…';
- }
- return substr($message, 0, $maxLength + 20) . '…';
- }
-
return $message;
} catch (NotFoundException $e) {
return '';
diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
index dd5f958ed4c..aa5bacea5bb 100644
--- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php
@@ -329,8 +329,7 @@ class FilesPlugin extends ServerPlugin {
});
}
- if ($node instanceof \OCA\DAV\Connector\Sabre\Node
- || $node instanceof \OCA\DAV\Files\FilesHome) {
+ if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
$propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) {
return $this->config->getSystemValue('data-fingerprint', '');
});
diff --git a/apps/dav/lib/Files/FilesHome.php b/apps/dav/lib/Files/FilesHome.php
index a4fb7d285a6..9c8f9835d7c 100644
--- a/apps/dav/lib/Files/FilesHome.php
+++ b/apps/dav/lib/Files/FilesHome.php
@@ -23,11 +23,9 @@ namespace OCA\DAV\Files;
use OCA\DAV\Connector\Sabre\Directory;
use Sabre\DAV\Exception\Forbidden;
-use Sabre\DAV\ICollection;
-use Sabre\DAV\SimpleCollection;
use Sabre\HTTP\URLUtil;
-class FilesHome implements ICollection {
+class FilesHome extends Directory {
/**
* @var array
@@ -41,30 +39,13 @@ class FilesHome implements ICollection {
*/
public function __construct($principalInfo) {
$this->principalInfo = $principalInfo;
- }
-
- function createFile($name, $data = null) {
- return $this->impl()->createFile($name, $data);
- }
-
- function createDirectory($name) {
- $this->impl()->createDirectory($name);
- }
-
- function getChild($name) {
- return $this->impl()->getChild($name);
- }
-
- function getChildren() {
- return $this->impl()->getChildren();
- }
-
- function childExists($name) {
- return $this->impl()->childExists($name);
+ $view = \OC\Files\Filesystem::getView();
+ $rootInfo = $view->getFileInfo('');
+ parent::__construct($view, $rootInfo);
}
function delete() {
- $this->impl()->delete();
+ throw new Forbidden('Permission denied to delete home folder');
}
function getName() {
@@ -75,30 +56,4 @@ class FilesHome implements ICollection {
function setName($name) {
throw new Forbidden('Permission denied to rename this folder');
}
-
- /**
- * Returns the last modification time, as a unix timestamp
- *
- * @return int
- */
- function getLastModified() {
- return $this->impl()->getLastModified();
- }
-
- /**
- * @return Directory
- */
- private function impl() {
- //
- // TODO: we need to mount filesystem of the give user
- //
- $user = \OC::$server->getUserSession()->getUser();
- if ($this->getName() !== $user->getUID()) {
- return new SimpleCollection($this->getName());
- }
- $view = \OC\Files\Filesystem::getView();
- $rootInfo = $view->getFileInfo('');
- $impl = new Directory($view, $rootInfo);
- return $impl;
- }
}
diff --git a/apps/dav/lib/Files/RootCollection.php b/apps/dav/lib/Files/RootCollection.php
index 10459aa8ada..57802d19573 100644
--- a/apps/dav/lib/Files/RootCollection.php
+++ b/apps/dav/lib/Files/RootCollection.php
@@ -22,7 +22,8 @@
namespace OCA\DAV\Files;
use Sabre\DAVACL\AbstractPrincipalCollection;
-use Sabre\DAVACL\IPrincipal;
+use Sabre\HTTP\URLUtil;
+use Sabre\DAV\SimpleCollection;
class RootCollection extends AbstractPrincipalCollection {
@@ -34,9 +35,17 @@ class RootCollection extends AbstractPrincipalCollection {
* supplied by the authentication backend.
*
* @param array $principalInfo
- * @return IPrincipal
+ * @return INode
*/
function getChildForPrincipal(array $principalInfo) {
+ list(,$name) = URLUtil::splitPath($principalInfo['uri']);
+ $user = \OC::$server->getUserSession()->getUser();
+ if ($name !== $user->getUID()) {
+ // a user is only allowed to see their own home contents, so in case another collection
+ // is accessed, we return a simple empty collection for now
+ // in the future this could be considered to be used for accessing shared files
+ return new SimpleCollection($name);
+ }
return new FilesHome($principalInfo);
}
diff --git a/apps/dav/lib/Upload/UploadHome.php b/apps/dav/lib/Upload/UploadHome.php
index 296eb2df3a9..df458e8bc4b 100644
--- a/apps/dav/lib/Upload/UploadHome.php
+++ b/apps/dav/lib/Upload/UploadHome.php
@@ -30,7 +30,7 @@ use Sabre\DAV\ICollection;
class UploadHome implements ICollection {
/**
- * FilesHome constructor.
+ * UploadHome constructor.
*
* @param array $principalInfo
*/
diff --git a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
index e2d63868af0..282a5b2f626 100644
--- a/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
+++ b/apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
@@ -217,58 +217,6 @@ class FilesPluginTest extends TestCase {
$this->assertEquals([self::SIZE_PROPERTYNAME], $propFind->get404Properties());
}
- public function testGetPropertiesForFileHome() {
- /** @var \OCA\DAV\Files\FilesHome | \PHPUnit_Framework_MockObject_MockObject $node */
- $node = $this->getMockBuilder('\OCA\DAV\Files\FilesHome')
- ->disableOriginalConstructor()
- ->getMock();
-
- $propFind = new PropFind(
- '/dummyPath',
- array(
- self::GETETAG_PROPERTYNAME,
- self::FILEID_PROPERTYNAME,
- self::INTERNAL_FILEID_PROPERTYNAME,
- self::SIZE_PROPERTYNAME,
- self::PERMISSIONS_PROPERTYNAME,
- self::DOWNLOADURL_PROPERTYNAME,
- self::OWNER_ID_PROPERTYNAME,
- self::OWNER_DISPLAY_NAME_PROPERTYNAME,
- self::DATA_FINGERPRINT_PROPERTYNAME,
- ),
- 0
- );
-
- $user = $this->getMockBuilder('\OC\User\User')
- ->disableOriginalConstructor()->getMock();
- $user->expects($this->never())->method('getUID');
- $user->expects($this->never())->method('getDisplayName');
-
- $this->plugin->handleGetProperties(
- $propFind,
- $node
- );
-
- $this->assertEquals(null, $propFind->get(self::GETETAG_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::FILEID_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::INTERNAL_FILEID_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::SIZE_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::PERMISSIONS_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::DOWNLOADURL_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::OWNER_ID_PROPERTYNAME));
- $this->assertEquals(null, $propFind->get(self::OWNER_DISPLAY_NAME_PROPERTYNAME));
- $this->assertEquals(['{DAV:}getetag',
- '{http://owncloud.org/ns}id',
- '{http://owncloud.org/ns}fileid',
- '{http://owncloud.org/ns}size',
- '{http://owncloud.org/ns}permissions',
- '{http://owncloud.org/ns}downloadURL',
- '{http://owncloud.org/ns}owner-id',
- '{http://owncloud.org/ns}owner-display-name'
- ], $propFind->get404Properties());
- $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME));
- }
-
public function testGetPropertiesStorageNotAvailable() {
/** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */
$node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File');
diff --git a/apps/files/lib/Activity.php b/apps/files/lib/Activity.php
index b9cc98cf7ea..5fc59f119e1 100644
--- a/apps/files/lib/Activity.php
+++ b/apps/files/lib/Activity.php
@@ -104,7 +104,7 @@ class Activity implements IExtension {
$l = $this->getL10N($languageCode);
return [
self::TYPE_SHARE_CREATED => (string) $l->t('A new file or folder has been <strong>created</strong>'),
- self::TYPE_SHARE_CHANGED => (string) $l->t('A file or folder has been <strong>changed</strong>'),
+ self::TYPE_SHARE_CHANGED => (string) $l->t('A file or folder has been <strong>changed</strong> or <strong>renamed</strong>'),
self::TYPE_FAVORITES => [
'desc' => (string) $l->t('Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>'),
'methods' => [self::METHOD_STREAM],
@@ -189,6 +189,14 @@ class Activity implements IExtension {
return (string) $l->t('You restored %1$s', $params);
case 'restored_by':
return (string) $l->t('%2$s restored %1$s', $params);
+ case 'renamed_self':
+ return (string) $l->t('You renamed %2$s to %1$s', $params);
+ case 'renamed_by':
+ return (string) $l->t('%2$s renamed %3$s to %1$s', $params);
+ case 'moved_self':
+ return (string) $l->t('You moved %2$s to %1$s', $params);
+ case 'moved_by':
+ return (string) $l->t('%2$s moved %3$s to %1$s', $params);
default:
return false;
@@ -209,6 +217,10 @@ class Activity implements IExtension {
return (string) $l->t('Deleted by %2$s', $params);
case 'restored_by':
return (string) $l->t('Restored by %2$s', $params);
+ case 'renamed_by':
+ return (string) $l->t('Renamed by %2$s', $params);
+ case 'moved_by':
+ return (string) $l->t('Moved by %2$s', $params);
default:
return false;
@@ -242,6 +254,19 @@ class Activity implements IExtension {
0 => 'file',
1 => 'username',
];
+ case 'renamed_self':
+ case 'moved_self':
+ return [
+ 0 => 'file',
+ 1 => 'file',
+ ];
+ case 'renamed_by':
+ case 'moved_by':
+ return [
+ 0 => 'file',
+ 1 => 'username',
+ 2 => 'file',
+ ];
}
}
@@ -306,6 +331,7 @@ class Activity implements IExtension {
'top' => [
self::FILTER_FAVORITES => [
'id' => self::FILTER_FAVORITES,
+ 'icon' => 'icon-favorite',
'name' => (string) $this->l->t('Favorites'),
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_FAVORITES]),
],
@@ -313,6 +339,7 @@ class Activity implements IExtension {
'apps' => [
self::FILTER_FILES => [
'id' => self::FILTER_FILES,
+ 'icon' => 'icon-files-dark',
'name' => (string) $this->l->t('Files'),
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_FILES]),
],
diff --git a/apps/files_sharing/lib/Activity.php b/apps/files_sharing/lib/Activity.php
index f69f86175f8..4d57cc8c7b2 100644
--- a/apps/files_sharing/lib/Activity.php
+++ b/apps/files_sharing/lib/Activity.php
@@ -429,6 +429,7 @@ class Activity implements IExtension {
'top' => [
self::FILTER_SHARES => [
'id' => self::FILTER_SHARES,
+ 'icon' => 'icon-share',
'name' => (string) $l->t('Shares'),
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_SHARES]),
],
diff --git a/apps/files_sharing/tests/EtagPropagationTest.php b/apps/files_sharing/tests/EtagPropagationTest.php
index 977f98f0497..4aba9e29113 100644
--- a/apps/files_sharing/tests/EtagPropagationTest.php
+++ b/apps/files_sharing/tests/EtagPropagationTest.php
@@ -34,7 +34,7 @@ use OC\Files\View;
/**
* Class EtagPropagationTest
*
- * @group DB
+ * @group SLOWDB
*
* @package OCA\Files_Sharing\Tests
*/
diff --git a/apps/files_sharing/tests/GroupEtagPropagationTest.php b/apps/files_sharing/tests/GroupEtagPropagationTest.php
index 0ff3a4c01c6..eeb3c06bc59 100644
--- a/apps/files_sharing/tests/GroupEtagPropagationTest.php
+++ b/apps/files_sharing/tests/GroupEtagPropagationTest.php
@@ -28,7 +28,7 @@ use OC\Files\Filesystem;
use OC\Files\View;
/**
- * @group DB
+ * @group SLOWDB
*
* @package OCA\Files_Sharing\Tests
*/
diff --git a/apps/files_sharing/tests/SharedMountTest.php b/apps/files_sharing/tests/SharedMountTest.php
index 7427304eb14..5f769852dc8 100644
--- a/apps/files_sharing/tests/SharedMountTest.php
+++ b/apps/files_sharing/tests/SharedMountTest.php
@@ -31,7 +31,7 @@ namespace OCA\Files_Sharing\Tests;
/**
* Class SharedMountTest
*
- * @group DB
+ * @group SLOWDB
*/
class SharedMountTest extends TestCase {
diff --git a/apps/systemtags/lib/Activity/Extension.php b/apps/systemtags/lib/Activity/Extension.php
index c7342bd2af7..9fac2ddbc62 100644
--- a/apps/systemtags/lib/Activity/Extension.php
+++ b/apps/systemtags/lib/Activity/Extension.php
@@ -98,7 +98,7 @@ class Extension implements IExtension {
public function getTypeIcon($type) {
switch ($type) {
case self::APP_NAME:
- return false;
+ return 'icon-tag';
}
return false;
diff --git a/autotest.sh b/autotest.sh
index 2dfa961a1a2..eca3d81c048 100755
--- a/autotest.sh
+++ b/autotest.sh
@@ -293,11 +293,14 @@ function execute_tests {
export XDEBUG_CONFIG=$_XDEBUG_CONFIG
fi
GROUP=''
+ if [ "$TEST_SELECTION" == "QUICKDB" ]; then
+ GROUP='--group DB --exclude-group=SLOWDB'
+ fi
if [ "$TEST_SELECTION" == "DB" ]; then
- GROUP='--group DB'
+ GROUP='--group DB,SLOWDB'
fi
if [ "$TEST_SELECTION" == "NODB" ]; then
- GROUP='--exclude-group DB'
+ GROUP='--exclude-group DB,SLOWDB'
fi
COVER=''
diff --git a/core/css/icons.css b/core/css/icons.css
index 45069a23c44..50dcf51fd3a 100644
--- a/core/css/icons.css
+++ b/core/css/icons.css
@@ -282,6 +282,10 @@ img.icon-loading-small-dark, object.icon-loading-small-dark, video.icon-loading-
background-image: url('../img/actions/sound-off.svg?v=1');
}
+.icon-favorite {
+ background-image: url('../img/actions/star-dark.svg?v=1');
+}
+
.icon-star,
.icon-starred:hover,
.icon-starred:focus {
@@ -365,6 +369,9 @@ img.icon-loading-small-dark, object.icon-loading-small-dark, video.icon-loading-
.icon-files {
background-image: url('../img/places/files.svg?v=1');
}
+.icon-files-dark {
+ background-image: url('../img/places/files-dark.svg?v=1');
+}
.icon-file,
.icon-filetype-text {
background-image: url('../img/filetypes/text.svg?v=1');
diff --git a/core/img/actions/star-dark.svg b/core/img/actions/star-dark.svg
new file mode 100644
index 00000000000..6edb7ea5000
--- /dev/null
+++ b/core/img/actions/star-dark.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="22" width="22"><path d="M11.017.06l2.946 7.384L22 8.077l-6.11 5.082L17.77 21l-6.72-4.242-6.876 4.213 1.957-7.703L0 8.03l7.932-.52z"/></svg>
diff --git a/core/img/places/files-dark.svg b/core/img/places/files-dark.svg
new file mode 100644
index 00000000000..dfcad56018a
--- /dev/null
+++ b/core/img/places/files-dark.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="32" width="32"><path d="M2.917 5.015c-.5 0-.92.42-.92.92v22.16c0 .516.402.92.92.92h26.157a.91.91 0 0 0 .92-.92V9.938c0-.5-.418-.926-.92-.926H15.997l-4-4z" fill-rule="evenodd"/></svg> \ No newline at end of file
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 2fa4df4d9e9..0ff46de07de 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -107,6 +107,7 @@ return array(
'OCP\\Files\\FileNameTooLongException' => $baseDir . '/lib/public/Files/FileNameTooLongException.php',
'OCP\\Files\\Folder' => $baseDir . '/lib/public/Files/Folder.php',
'OCP\\Files\\ForbiddenException' => $baseDir . '/lib/public/Files/ForbiddenException.php',
+ 'OCP\\Files\\IAppData' => $baseDir . '/lib/public/Files/IAppData.php',
'OCP\\Files\\IHomeStorage' => $baseDir . '/lib/public/Files/IHomeStorage.php',
'OCP\\Files\\IMimeTypeDetector' => $baseDir . '/lib/public/Files/IMimeTypeDetector.php',
'OCP\\Files\\IMimeTypeLoader' => $baseDir . '/lib/public/Files/IMimeTypeLoader.php',
@@ -123,6 +124,9 @@ return array(
'OCP\\Files\\NotPermittedException' => $baseDir . '/lib/public/Files/NotPermittedException.php',
'OCP\\Files\\ObjectStore\\IObjectStore' => $baseDir . '/lib/public/Files/ObjectStore/IObjectStore.php',
'OCP\\Files\\ReservedWordException' => $baseDir . '/lib/public/Files/ReservedWordException.php',
+ 'OCP\\Files\\SimpleFS\\ISimpleFile' => $baseDir . '/lib/public/Files/SimpleFS/ISimpleFile.php',
+ 'OCP\\Files\\SimpleFS\\ISimpleFolder' => $baseDir . '/lib/public/Files/SimpleFS/ISimpleFolder.php',
+ 'OCP\\Files\\SimpleFS\\ISimpleRoot' => $baseDir . '/lib/public/Files/SimpleFS/ISimpleRoot.php',
'OCP\\Files\\Storage' => $baseDir . '/lib/public/Files/Storage.php',
'OCP\\Files\\StorageAuthException' => $baseDir . '/lib/public/Files/StorageAuthException.php',
'OCP\\Files\\StorageBadConfigException' => $baseDir . '/lib/public/Files/StorageBadConfigException.php',
@@ -459,6 +463,8 @@ return array(
'OC\\Encryption\\Manager' => $baseDir . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => $baseDir . '/lib/private/Encryption/Update.php',
'OC\\Encryption\\Util' => $baseDir . '/lib/private/Encryption/Util.php',
+ 'OC\\Files\\AppData\\AppData' => $baseDir . '/lib/private/Files/AppData/AppData.php',
+ 'OC\\Files\\AppData\\Factory' => $baseDir . '/lib/private/Files/AppData/Factory.php',
'OC\\Files\\Cache\\Cache' => $baseDir . '/lib/private/Files/Cache/Cache.php',
'OC\\Files\\Cache\\CacheEntry' => $baseDir . '/lib/private/Files/Cache/CacheEntry.php',
'OC\\Files\\Cache\\FailedCache' => $baseDir . '/lib/private/Files/Cache/FailedCache.php',
@@ -500,6 +506,8 @@ return array(
'OC\\Files\\ObjectStore\\NoopScanner' => $baseDir . '/lib/private/Files/ObjectStore/NoopScanner.php',
'OC\\Files\\ObjectStore\\ObjectStoreStorage' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php',
'OC\\Files\\ObjectStore\\Swift' => $baseDir . '/lib/private/Files/ObjectStore/Swift.php',
+ 'OC\\Files\\SimpleFS\\SimpleFile' => $baseDir . '/lib/private/Files/SimpleFS/SimpleFile.php',
+ 'OC\\Files\\SimpleFS\\SimpleFolder' => $baseDir . '/lib/private/Files/SimpleFS/SimpleFolder.php',
'OC\\Files\\Storage\\Common' => $baseDir . '/lib/private/Files/Storage/Common.php',
'OC\\Files\\Storage\\CommonTest' => $baseDir . '/lib/private/Files/Storage/CommonTest.php',
'OC\\Files\\Storage\\DAV' => $baseDir . '/lib/private/Files/Storage/DAV.php',
@@ -638,6 +646,8 @@ return array(
'OC\\Repair\\FillETags' => $baseDir . '/lib/private/Repair/FillETags.php',
'OC\\Repair\\InnoDB' => $baseDir . '/lib/private/Repair/InnoDB.php',
'OC\\Repair\\MoveUpdaterStepFile' => $baseDir . '/lib/private/Repair/MoveUpdaterStepFile.php',
+ 'OC\\Repair\\NC11\\MoveAvatars' => $baseDir . '/lib/private/Repair/NC11/MoveAvatars.php',
+ 'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => $baseDir . '/lib/private/Repair/NC11/MoveAvatarBackgroundJob.php',
'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php',
'OC\\Repair\\Preview' => $baseDir . '/lib/private/Repair/Preview.php',
'OC\\Repair\\RemoveGetETagEntries' => $baseDir . '/lib/private/Repair/RemoveGetETagEntries.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index ad493bfb041..24058a22edb 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -137,6 +137,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Files\\FileNameTooLongException' => __DIR__ . '/../../..' . '/lib/public/Files/FileNameTooLongException.php',
'OCP\\Files\\Folder' => __DIR__ . '/../../..' . '/lib/public/Files/Folder.php',
'OCP\\Files\\ForbiddenException' => __DIR__ . '/../../..' . '/lib/public/Files/ForbiddenException.php',
+ 'OCP\\Files\\IAppData' => __DIR__ . '/../../..' . '/lib/public/Files/IAppData.php',
'OCP\\Files\\IHomeStorage' => __DIR__ . '/../../..' . '/lib/public/Files/IHomeStorage.php',
'OCP\\Files\\IMimeTypeDetector' => __DIR__ . '/../../..' . '/lib/public/Files/IMimeTypeDetector.php',
'OCP\\Files\\IMimeTypeLoader' => __DIR__ . '/../../..' . '/lib/public/Files/IMimeTypeLoader.php',
@@ -153,6 +154,9 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Files\\NotPermittedException' => __DIR__ . '/../../..' . '/lib/public/Files/NotPermittedException.php',
'OCP\\Files\\ObjectStore\\IObjectStore' => __DIR__ . '/../../..' . '/lib/public/Files/ObjectStore/IObjectStore.php',
'OCP\\Files\\ReservedWordException' => __DIR__ . '/../../..' . '/lib/public/Files/ReservedWordException.php',
+ 'OCP\\Files\\SimpleFS\\ISimpleFile' => __DIR__ . '/../../..' . '/lib/public/Files/SimpleFS/ISimpleFile.php',
+ 'OCP\\Files\\SimpleFS\\ISimpleFolder' => __DIR__ . '/../../..' . '/lib/public/Files/SimpleFS/ISimpleFolder.php',
+ 'OCP\\Files\\SimpleFS\\ISimpleRoot' => __DIR__ . '/../../..' . '/lib/public/Files/SimpleFS/ISimpleRoot.php',
'OCP\\Files\\Storage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage.php',
'OCP\\Files\\StorageAuthException' => __DIR__ . '/../../..' . '/lib/public/Files/StorageAuthException.php',
'OCP\\Files\\StorageBadConfigException' => __DIR__ . '/../../..' . '/lib/public/Files/StorageBadConfigException.php',
@@ -489,6 +493,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Encryption\\Manager' => __DIR__ . '/../../..' . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => __DIR__ . '/../../..' . '/lib/private/Encryption/Update.php',
'OC\\Encryption\\Util' => __DIR__ . '/../../..' . '/lib/private/Encryption/Util.php',
+ 'OC\\Files\\AppData\\AppData' => __DIR__ . '/../../..' . '/lib/private/Files/AppData/AppData.php',
+ 'OC\\Files\\AppData\\Factory' => __DIR__ . '/../../..' . '/lib/private/Files/AppData/Factory.php',
'OC\\Files\\Cache\\Cache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Cache.php',
'OC\\Files\\Cache\\CacheEntry' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/CacheEntry.php',
'OC\\Files\\Cache\\FailedCache' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/FailedCache.php',
@@ -530,6 +536,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Files\\ObjectStore\\NoopScanner' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/NoopScanner.php',
'OC\\Files\\ObjectStore\\ObjectStoreStorage' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php',
'OC\\Files\\ObjectStore\\Swift' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Swift.php',
+ 'OC\\Files\\SimpleFS\\SimpleFile' => __DIR__ . '/../../..' . '/lib/private/Files/SimpleFS/SimpleFile.php',
+ 'OC\\Files\\SimpleFS\\SimpleFolder' => __DIR__ . '/../../..' . '/lib/private/Files/SimpleFS/SimpleFolder.php',
'OC\\Files\\Storage\\Common' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Common.php',
'OC\\Files\\Storage\\CommonTest' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/CommonTest.php',
'OC\\Files\\Storage\\DAV' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/DAV.php',
@@ -668,6 +676,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Repair\\FillETags' => __DIR__ . '/../../..' . '/lib/private/Repair/FillETags.php',
'OC\\Repair\\InnoDB' => __DIR__ . '/../../..' . '/lib/private/Repair/InnoDB.php',
'OC\\Repair\\MoveUpdaterStepFile' => __DIR__ . '/../../..' . '/lib/private/Repair/MoveUpdaterStepFile.php',
+ 'OC\\Repair\\NC11\\MoveAvatars' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatars.php',
+ 'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatarBackgroundJob.php',
'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php',
'OC\\Repair\\Preview' => __DIR__ . '/../../..' . '/lib/private/Repair/Preview.php',
'OC\\Repair\\RemoveGetETagEntries' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveGetETagEntries.php',
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php
index 20351d1321c..b6f8d8f458d 100644
--- a/lib/private/AppFramework/DependencyInjection/DIContainer.php
+++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php
@@ -46,6 +46,7 @@ use OC\AppFramework\Utility\SimpleContainer;
use OC\Core\Middleware\TwoFactorMiddleware;
use OCP\AppFramework\IApi;
use OCP\AppFramework\IAppContainer;
+use OCP\Files\IAppData;
class DIContainer extends SimpleContainer implements IAppContainer {
@@ -164,6 +165,10 @@ class DIContainer extends SimpleContainer implements IAppContainer {
return $this->getServer()->getHTTPClientService();
});
+ $this->registerService(IAppData::class, function (SimpleContainer $c) {
+ return $this->getServer()->getAppDataDir($c->query('AppName'));
+ });
+
$this->registerService('OCP\\IGroupManager', function($c) {
return $this->getServer()->getGroupManager();
});
diff --git a/lib/private/Avatar.php b/lib/private/Avatar.php
index 9e8bd0136c2..c3a068701df 100644
--- a/lib/private/Avatar.php
+++ b/lib/private/Avatar.php
@@ -29,10 +29,10 @@
namespace OC;
use OC\User\User;
-use OCP\Files\Folder;
-use OCP\Files\File;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IAvatar;
use OCP\IConfig;
use OCP\IImage;
@@ -45,7 +45,7 @@ use OCP\ILogger;
*/
class Avatar implements IAvatar {
- /** @var Folder */
+ /** @var ISimpleFolder */
private $folder;
/** @var IL10N */
private $l;
@@ -59,13 +59,13 @@ class Avatar implements IAvatar {
/**
* constructor
*
- * @param Folder $folder The folder where the avatars are
+ * @param ISimpleFolder $folder The folder where the avatars are
* @param IL10N $l
* @param User $user
* @param ILogger $logger
* @param IConfig $config
*/
- public function __construct(Folder $folder,
+ public function __construct(ISimpleFolder $folder,
IL10N $l,
$user,
ILogger $logger,
@@ -98,7 +98,8 @@ class Avatar implements IAvatar {
* @return bool
*/
public function exists() {
- return $this->folder->nodeExists('avatar.jpg') || $this->folder->nodeExists('avatar.png');
+
+ return $this->folder->fileExists('avatar.jpg') || $this->folder->fileExists('avatar.png');
}
/**
@@ -170,15 +171,15 @@ class Avatar implements IAvatar {
}
try {
- $file = $this->folder->get($path);
+ $file = $this->folder->getFile($path);
} catch (NotFoundException $e) {
if ($size <= 0) {
throw new NotFoundException;
}
$avatar = new OC_Image();
- /** @var File $file */
- $file = $this->folder->get('avatar.' . $ext);
+ /** @var ISimpleFile $file */
+ $file = $this->folder->getFile('avatar.' . $ext);
$avatar->loadFromData($file->getContent());
if ($size !== -1) {
$avatar->resize($size);
@@ -201,9 +202,9 @@ class Avatar implements IAvatar {
* @throws NotFoundException
*/
private function getExtension() {
- if ($this->folder->nodeExists('avatar.jpg')) {
+ if ($this->folder->fileExists('avatar.jpg')) {
return 'jpg';
- } elseif ($this->folder->nodeExists('avatar.png')) {
+ } elseif ($this->folder->fileExists('avatar.png')) {
return 'png';
}
throw new NotFoundException;
diff --git a/lib/private/AvatarManager.php b/lib/private/AvatarManager.php
index df3247b8f00..b8c6c2a1eb6 100644
--- a/lib/private/AvatarManager.php
+++ b/lib/private/AvatarManager.php
@@ -27,13 +27,12 @@
namespace OC;
-use OCP\Files\Folder;
+use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\IAvatarManager;
use OCP\IConfig;
use OCP\ILogger;
use OCP\IUserManager;
-use OCP\Files\IRootFolder;
use OCP\IL10N;
/**
@@ -44,8 +43,8 @@ class AvatarManager implements IAvatarManager {
/** @var IUserManager */
private $userManager;
- /** @var IRootFolder */
- private $rootFolder;
+ /** @var IAppData */
+ private $appData;
/** @var IL10N */
private $l;
@@ -60,19 +59,19 @@ class AvatarManager implements IAvatarManager {
* AvatarManager constructor.
*
* @param IUserManager $userManager
- * @param IRootFolder $rootFolder
+ * @param IAppData $appData
* @param IL10N $l
* @param ILogger $logger
* @param IConfig $config
*/
public function __construct(
IUserManager $userManager,
- IRootFolder $rootFolder,
+ IAppData $appData,
IL10N $l,
ILogger $logger,
IConfig $config) {
$this->userManager = $userManager;
- $this->rootFolder = $rootFolder;
+ $this->appData = $appData;
$this->l = $l;
$this->logger = $logger;
$this->config = $config;
@@ -95,20 +94,12 @@ class AvatarManager implements IAvatarManager {
// sanitize userID - fixes casing issue (needed for the filesystem stuff that is done below)
$userId = $user->getUID();
- /*
- * Fix for #22119
- * Basically we do not want to copy the skeleton folder.
- *
- * For unit test purposes this is ignored when run in PHPUnit.
- */
- if(!defined('PHPUNIT_RUN')) {
- \OC\Files\Filesystem::initMountPoints($userId);
+ try {
+ $folder = $this->appData->getFolder($userId);
+ } catch (NotFoundException $e) {
+ $folder = $this->appData->newFolder($userId);
}
- $dir = '/' . $userId;
- /** @var Folder $folder */
- $folder = $this->rootFolder->get($dir);
-
return new Avatar($folder, $this->l, $user, $this->logger, $this->config);
}
}
diff --git a/lib/private/Files/AppData/AppData.php b/lib/private/Files/AppData/AppData.php
new file mode 100644
index 00000000000..270e834b8e5
--- /dev/null
+++ b/lib/private/Files/AppData/AppData.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Files\AppData;
+
+use OC\Files\SimpleFS\SimpleFolder;
+use OCP\Files\IAppData;
+use OCP\Files\IRootFolder;
+use OCP\Files\Folder;
+use OC\SystemConfig;
+use OCP\Files\Node;
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+
+class AppData implements IAppData {
+
+ /** @var IRootFolder */
+ private $rootFolder;
+
+ /** @var SystemConfig */
+ private $config;
+
+ /** @var string */
+ private $appId;
+
+ /** @var Folder */
+ private $folder;
+
+ /**
+ * AppData constructor.
+ *
+ * @param IRootFolder $rootFolder
+ * @param SystemConfig $systemConfig
+ * @param string $appId
+ */
+ public function __construct(IRootFolder $rootFolder,
+ SystemConfig $systemConfig,
+ $appId) {
+
+ $this->rootFolder = $rootFolder;
+ $this->config = $systemConfig;
+ $this->appId = $appId;
+ }
+
+ /**
+ * @return Folder
+ * @throws \RuntimeException
+ */
+ private function getAppDataFolder() {
+ if ($this->folder === null) {
+ $instanceId = $this->config->getValue('instanceid', null);
+ if ($instanceId === null) {
+ throw new \RuntimeException('no instance id!');
+ }
+
+ $name = 'appdata_' . $instanceId;
+
+ try {
+ $appDataFolder = $this->rootFolder->get($name);
+ } catch (NotFoundException $e) {
+ try {
+ $appDataFolder = $this->rootFolder->newFolder($name);
+ } catch (NotPermittedException $e) {
+ throw new \RuntimeException('Could not get appdata folder');
+ }
+ }
+
+ try {
+ $appDataFolder = $appDataFolder->get($this->appId);
+ } catch (NotFoundException $e) {
+ try {
+ $appDataFolder = $appDataFolder->newFolder($this->appId);
+ } catch (NotPermittedException $e) {
+ throw new \RuntimeException('Could not get appdata folder for ' . $this->appId);
+ }
+ }
+
+ $this->folder = $appDataFolder;
+ }
+
+ return $this->folder;
+ }
+
+ public function getFolder($name) {
+ $node = $this->getAppDataFolder()->get($name);
+
+ /** @var Folder $node */
+ return new SimpleFolder($node);
+ }
+
+ public function newFolder($name) {
+ $folder = $this->getAppDataFolder()->newFolder($name);
+
+ return new SimpleFolder($folder);
+ }
+
+ public function getDirectoryListing() {
+ $listing = $this->getAppDataFolder()->getDirectoryListing();
+
+ $fileListing = array_map(function(Node $folder) {
+ if ($folder instanceof Folder) {
+ return new SimpleFolder($folder);
+ }
+ return null;
+ }, $listing);
+
+ $fileListing = array_filter($fileListing);
+
+ return array_values($fileListing);
+ }
+}
diff --git a/lib/private/Files/AppData/Factory.php b/lib/private/Files/AppData/Factory.php
new file mode 100644
index 00000000000..85c75733796
--- /dev/null
+++ b/lib/private/Files/AppData/Factory.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Files\AppData;
+
+use OC\SystemConfig;
+use OCP\Files\IRootFolder;
+
+class Factory {
+
+ /** @var IRootFolder */
+ private $rootFolder;
+
+ /** @var SystemConfig */
+ private $config;
+
+ public function __construct(IRootFolder $rootFolder,
+ SystemConfig $systemConfig) {
+
+ $this->rootFolder = $rootFolder;
+ $this->config = $systemConfig;
+ }
+
+ /**
+ * @param string $appId
+ * @return AppData
+ */
+ public function get($appId) {
+ return new AppData($this->rootFolder, $this->config, $appId);
+ }
+}
diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php
new file mode 100644
index 00000000000..5eadfd98b60
--- /dev/null
+++ b/lib/private/Files/SimpleFS/SimpleFile.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Files\SimpleFS;
+
+use OCP\Files\File;
+use OCP\Files\NotPermittedException;
+use OCP\Files\SimpleFS\ISimpleFile;
+
+class SimpleFile implements ISimpleFile {
+
+ /** @var File $file */
+ private $file;
+
+ /**
+ * File constructor.
+ *
+ * @param File $file
+ */
+ public function __construct(File $file) {
+ $this->file = $file;
+ }
+
+ /**
+ * Get the name
+ *
+ * @return string
+ */
+ public function getName() {
+ return $this->file->getName();
+ }
+
+ /**
+ * Get the size in bytes
+ *
+ * @return int
+ */
+ public function getSize() {
+ return $this->file->getSize();
+ }
+
+ /**
+ * Get the ETag
+ *
+ * @return string
+ */
+ public function getETag() {
+ return $this->file->getEtag();
+ }
+
+ /**
+ * Get the last modification time
+ *
+ * @return int
+ */
+ public function getMTime() {
+ return $this->file->getMTime();
+ }
+
+ /**
+ * Get the content
+ *
+ * @return string
+ */
+ public function getContent() {
+ return $this->file->getContent();
+ }
+
+ /**
+ * Overwrite the file
+ *
+ * @param string $data
+ * @throws NotPermittedException
+ */
+ public function putContent($data) {
+ $this->file->putContent($data);
+ }
+
+ /**
+ * Delete the file
+ *
+ * @throws NotPermittedException
+ */
+ public function delete() {
+ $this->file->delete();
+ }
+
+ /**
+ * Get the MimeType
+ *
+ * @return string
+ */
+ public function getMimeType() {
+ return $this->file->getMimeType();
+ }
+}
diff --git a/lib/private/Files/SimpleFS/SimpleFolder.php b/lib/private/Files/SimpleFS/SimpleFolder.php
new file mode 100644
index 00000000000..5b55fe0f157
--- /dev/null
+++ b/lib/private/Files/SimpleFS/SimpleFolder.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Files\SimpleFS;
+
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\Node;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFolder;
+
+class SimpleFolder implements ISimpleFolder {
+
+ /** @var Folder */
+ private $folder;
+
+ /**
+ * Folder constructor.
+ *
+ * @param Folder $folder
+ */
+ public function __construct(Folder $folder) {
+ $this->folder = $folder;
+ }
+
+ public function getName() {
+ return $this->folder->getName();
+ }
+
+ public function getDirectoryListing() {
+ $listing = $this->folder->getDirectoryListing();
+
+ $fileListing = array_map(function(Node $file) {
+ if ($file instanceof File) {
+ return new SimpleFile($file);
+ }
+ return null;
+ }, $listing);
+
+ $fileListing = array_filter($fileListing);
+
+ return array_values($fileListing);
+ }
+
+ public function delete() {
+ $this->folder->delete();
+ }
+
+ public function fileExists($name) {
+ return $this->folder->nodeExists($name);
+ }
+
+ public function getFile($name) {
+ $file = $this->folder->get($name);
+
+ if (!($file instanceof File)) {
+ throw new NotFoundException();
+ }
+
+ return new SimpleFile($file);
+ }
+
+ public function newFile($name) {
+ $file = $this->folder->newFile($name);
+
+ return new SimpleFile($file);
+ }
+}
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index bf441d03c35..2ba118b9c37 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -36,6 +36,7 @@ use OC\Repair\CleanTags;
use OC\Repair\Collation;
use OC\Repair\DropOldJobs;
use OC\Repair\MoveUpdaterStepFile;
+use OC\Repair\NC11\MoveAvatars;
use OC\Repair\OldGroupMembershipShares;
use OC\Repair\RemoveGetETagEntries;
use OC\Repair\RemoveOldShares;
@@ -149,6 +150,10 @@ class Repair implements IOutput{
\OC::$server->getGroupManager()
),
new MoveUpdaterStepFile(\OC::$server->getConfig()),
+ new MoveAvatars(
+ \OC::$server->getJobList(),
+ \OC::$server->getSystemConfig()
+ ),
];
}
diff --git a/lib/private/Repair/NC11/MoveAvatarBackgroundJob.php b/lib/private/Repair/NC11/MoveAvatarBackgroundJob.php
new file mode 100644
index 00000000000..993235146c9
--- /dev/null
+++ b/lib/private/Repair/NC11/MoveAvatarBackgroundJob.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Repair\NC11;
+
+use OC\BackgroundJob\QueuedJob;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\IAppData;
+use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
+use OCP\ILogger;
+use OCP\IUser;
+use OCP\IUserManager;
+
+class MoveAvatarsBackgroundJob extends QueuedJob {
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /** @var IRootFolder */
+ private $rootFolder;
+
+ /** @var IAppData */
+ private $appData;
+
+ /** @var ILogger */
+ private $logger;
+
+ /**
+ * MoveAvatars constructor.
+ */
+ public function __construct() {
+ $this->userManager = \OC::$server->getUserManager();
+ $this->rootFolder = \OC::$server->getRootFolder();
+ $this->logger = \OC::$server->getLogger();
+ $this->appData = \OC::$server->getAppDataDir('avatar');
+ }
+
+ public function run($arguments) {
+ $this->logger->info('Started migrating avatars to AppData folder');
+ $this->moveAvatars();
+ $this->logger->info('All avatars migrated to AppData folder');
+ }
+
+ private function moveAvatars() {
+ $counter = 0;
+ $this->userManager->callForAllUsers(function (IUser $user) use ($counter) {
+ if ($user->getLastLogin() !== 0) {
+ $uid = $user->getUID();
+
+ \OC\Files\Filesystem::initMountPoints($uid);
+ /** @var Folder $userFolder */
+ $userFolder = $this->rootFolder->get($uid);
+
+ try {
+ $userData = $this->appData->getFolder($uid);
+ } catch (NotFoundException $e) {
+ $userData = $this->appData->newFolder($uid);
+ }
+
+
+ $regex = '/^avatar\.([0-9]+\.)?(jpg|png)$/';
+ $avatars = $userFolder->getDirectoryListing();
+
+ foreach ($avatars as $avatar) {
+ /** @var File $avatar */
+ if (preg_match($regex, $avatar->getName())) {
+ /*
+ * This is not the most effective but it is the most abstract way
+ * to handle this. Avatars should be small anyways.
+ */
+ $newAvatar = $userData->newFile($avatar->getName());
+ $newAvatar->putContent($avatar->getContent());
+ $avatar->delete();
+ }
+ }
+ }
+ $counter++;
+ if ($counter % 100) {
+ $this->logger->info('{amount} avatars migrated', ['amount' => $counter]);
+ }
+ });
+ }
+}
diff --git a/lib/private/Repair/NC11/MoveAvatars.php b/lib/private/Repair/NC11/MoveAvatars.php
new file mode 100644
index 00000000000..44402b1be4f
--- /dev/null
+++ b/lib/private/Repair/NC11/MoveAvatars.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OC\Repair\NC11;
+
+use OC\SystemConfig;
+use OCP\BackgroundJob\IJobList;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class MoveAvatars implements IRepairStep {
+
+ /** @var IJobList */
+ private $jobList;
+
+ /** @var SystemConfig */
+ private $systemConfig;
+
+ /**
+ * MoveAvatars constructor.
+ *
+ * @param IJobList $jobList
+ * @param SystemConfig $systemConfig
+ */
+ public function __construct(IJobList $jobList,
+ SystemConfig $systemConfig) {
+ $this->jobList = $jobList;
+ $this->systemConfig = $systemConfig;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return 'Add mover avatar background job';
+ }
+
+ public function run(IOutput $output) {
+ if ($this->systemConfig->getValue('enable_avatars', true) === false) {
+ $output->info('Avatars are disabled');
+ } else {
+ $this->jobList->add(MoveAvatarsBackgroundJob::class);
+ }
+ }
+}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 494387ab6ca..b49e94b554e 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -359,7 +359,7 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerService('AvatarManager', function (Server $c) {
return new AvatarManager(
$c->getUserManager(),
- $c->getRootFolder(),
+ $c->getAppDataDir('avatar'),
$c->getL10N('lib'),
$c->getLogger(),
$c->getConfig()
@@ -742,6 +742,12 @@ class Server extends ServerContainer implements IServerContainer {
);
return $manager;
});
+ $this->registerService(\OC\Files\AppData\Factory::class, function (Server $c) {
+ return new \OC\Files\AppData\Factory(
+ $c->getRootFolder(),
+ $c->getSystemConfig()
+ );
+ });
}
/**
@@ -876,6 +882,7 @@ class Server extends ServerContainer implements IServerContainer {
* Returns an app-specific view in ownClouds data directory
*
* @return \OCP\Files\Folder
+ * @deprecated since 9.2.0 use IAppData
*/
public function getAppFolder() {
$dir = '/' . \OC_App::getCurrentApp();
@@ -1456,4 +1463,13 @@ class Server extends ServerContainer implements IServerContainer {
public function getSettingsManager() {
return $this->query('SettingsManager');
}
+
+ /**
+ * @return \OCP\Files\IAppData
+ */
+ public function getAppDataDir($app) {
+ /** @var \OC\Files\AppData\Factory $factory */
+ $factory = $this->query(\OC\Files\AppData\Factory::class);
+ return $factory->get($app);
+ }
}
diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php
index d964212f3bb..c3d2d1d6ad4 100644
--- a/lib/private/legacy/app.php
+++ b/lib/private/legacy/app.php
@@ -662,15 +662,16 @@ class OC_App {
* Read all app metadata from the info.xml file
*
* @param string $appId id of the app or the path of the info.xml file
- * @param boolean $path (optional)
+ * @param bool $path
+ * @param string $lang
* @return array|null
* @note all data is read from info.xml, not just pre-defined fields
*/
- public static function getAppInfo($appId, $path = false) {
+ public static function getAppInfo($appId, $path = false, $lang = null) {
if ($path) {
$file = $appId;
} else {
- if (isset(self::$appInfo[$appId])) {
+ if ($lang === null && isset(self::$appInfo[$appId])) {
return self::$appInfo[$appId];
}
$appPath = self::getAppPath($appId);
@@ -684,7 +685,7 @@ class OC_App {
$data = $parser->parse($file);
if (is_array($data)) {
- $data = OC_App::parseAppInfo($data);
+ $data = OC_App::parseAppInfo($data, $lang);
}
if(isset($data['ocsid'])) {
$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
@@ -693,7 +694,9 @@ class OC_App {
}
}
- self::$appInfo[$appId] = $data;
+ if ($lang === null) {
+ self::$appInfo[$appId] = $data;
+ }
return $data;
}
@@ -843,11 +846,12 @@ class OC_App {
//we don't want to show configuration for these
$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
$appList = array();
+ $langCode = \OC::$server->getL10N('core')->getLanguageCode();
foreach ($installedApps as $app) {
if (array_search($app, $blacklist) === false) {
- $info = OC_App::getAppInfo($app);
+ $info = OC_App::getAppInfo($app, false, $langCode);
if (!is_array($info)) {
\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
continue;
@@ -1327,13 +1331,69 @@ class OC_App {
}
}
+ protected static function findBestL10NOption($options, $lang) {
+ $fallback = $similarLangFallback = $englishFallback = false;
+
+ $lang = strtolower($lang);
+ $similarLang = $lang;
+ if (strpos($similarLang, '_')) {
+ // For "de_DE" we want to find "de" and the other way around
+ $similarLang = substr($lang, 0, strpos($lang, '_'));
+ }
+
+ foreach ($options as $option) {
+ if (is_array($option)) {
+ if ($fallback === false) {
+ $fallback = $option['@value'];
+ }
+
+ if (!isset($option['@attributes']['lang'])) {
+ continue;
+ }
+
+ $attributeLang = strtolower($option['@attributes']['lang']);
+ if ($attributeLang === $lang) {
+ return $option['@value'];
+ }
+
+ if ($attributeLang === $similarLang) {
+ $similarLangFallback = $option['@value'];
+ } else if (strpos($attributeLang, $similarLang . '_') === 0) {
+ if ($similarLangFallback === false) {
+ $similarLangFallback = $option['@value'];
+ }
+ }
+ } else {
+ $englishFallback = $option;
+ }
+ }
+
+ if ($similarLangFallback !== false) {
+ return $similarLangFallback;
+ } else if ($englishFallback !== false) {
+ return $englishFallback;
+ }
+ return (string) $fallback;
+ }
+
/**
* parses the app data array and enhanced the 'description' value
*
* @param array $data the app data
+ * @param string $lang
* @return array improved app data
*/
- public static function parseAppInfo(array $data) {
+ public static function parseAppInfo(array $data, $lang = null) {
+
+ if ($lang && isset($data['name']) && is_array($data['name'])) {
+ $data['name'] = self::findBestL10NOption($data['name'], $lang);
+ }
+ if ($lang && isset($data['summary']) && is_array($data['summary'])) {
+ $data['summary'] = self::findBestL10NOption($data['summary'], $lang);
+ }
+ if ($lang && isset($data['description']) && is_array($data['description'])) {
+ $data['description'] = self::findBestL10NOption($data['description'], $lang);
+ }
// just modify the description if it is available
// otherwise this will create a $data element with an empty 'description'
diff --git a/lib/private/legacy/util.php b/lib/private/legacy/util.php
index cb52949779f..b8f3a93ba50 100644
--- a/lib/private/legacy/util.php
+++ b/lib/private/legacy/util.php
@@ -311,10 +311,20 @@ class OC_Util {
*
* @param String $userId
* @param \OCP\Files\Folder $userDirectory
+ * @throws \RuntimeException
*/
public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
- $skeletonDirectory = \OCP\Config::getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
+ $skeletonDirectory = \OC::$server->getConfig()->getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
+ $instanceId = \OC::$server->getConfig()->getSystemValue('instanceid', '');
+
+ if ($instanceId === null) {
+ throw new \RuntimeException('no instance id!');
+ }
+ $appdata = 'appdata_' . $instanceId;
+ if ($userId === $appdata) {
+ throw new \RuntimeException('username is reserved name: ' . $appdata);
+ }
if (!empty($skeletonDirectory)) {
\OCP\Util::writeLog(
diff --git a/lib/public/AppFramework/Http/FileDisplayResponse.php b/lib/public/AppFramework/Http/FileDisplayResponse.php
index 22171e2b379..03a6fbec2dd 100644
--- a/lib/public/AppFramework/Http/FileDisplayResponse.php
+++ b/lib/public/AppFramework/Http/FileDisplayResponse.php
@@ -23,7 +23,6 @@
namespace OCP\AppFramework\Http;
use OCP\AppFramework\Http;
-use OCP\Files\File;
/**
* Class FileDisplayResponse
@@ -33,18 +32,18 @@ use OCP\Files\File;
*/
class FileDisplayResponse extends Response implements ICallbackResponse {
- /** @var File */
+ /** @var \OCP\Files\File|\OCP\Files\SimpleFS\ISimpleFile */
private $file;
/**
* FileDisplayResponse constructor.
*
- * @param File $file
+ * @param \OCP\Files\File|\OCP\Files\SimpleFS\ISimpleFile $file
* @param int $statusCode
* @param array $headers
* @since 9.2.0
*/
- public function __construct(File $file, $statusCode=Http::STATUS_OK,
+ public function __construct($file, $statusCode=Http::STATUS_OK,
$headers=[]) {
$this->file = $file;
$this->setStatus($statusCode);
diff --git a/lib/public/Files/IAppData.php b/lib/public/Files/IAppData.php
new file mode 100644
index 00000000000..92e54fee366
--- /dev/null
+++ b/lib/public/Files/IAppData.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCP\Files;
+
+use OCP\Files\SimpleFS\ISimpleRoot;
+
+/**
+ * Interface IAppData
+ *
+ * @package OCP\Files
+ * @since 9.2.0
+ * @internal This interface is experimental and might change for NC12
+ */
+interface IAppData extends ISimpleRoot {
+
+}
diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php
new file mode 100644
index 00000000000..efd682e7855
--- /dev/null
+++ b/lib/public/Files/SimpleFS/ISimpleFile.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCP\Files\SimpleFS;
+
+use OCP\Files\NotPermittedException;
+
+/**
+ * Interface ISimpleFile
+ *
+ * @package OCP\Files\SimpleFS
+ * @since 9.2.0
+ * @internal This interface is experimental and might change for NC12
+ */
+interface ISimpleFile {
+
+ /**
+ * Get the name
+ *
+ * @return string
+ * @since 9.2.0
+ */
+ public function getName();
+
+ /**
+ * Get the size in bytes
+ *
+ * @return int
+ * @since 9.2.0
+ */
+ public function getSize();
+
+ /**
+ * Get the ETag
+ *
+ * @return string
+ * @since 9.2.0
+ */
+ public function getETag();
+
+ /**
+ * Get the last modification time
+ *
+ * @return int
+ * @since 9.2.0
+ */
+ public function getMTime();
+
+ /**
+ * Get the content
+ *
+ * @return string
+ * @since 9.2.0
+ */
+ public function getContent();
+
+ /**
+ * Overwrite the file
+ *
+ * @param string $data
+ * @throws NotPermittedException
+ * @since 9.2.0
+ */
+ public function putContent($data);
+
+ /**
+ * Delete the file
+ *
+ * @throws NotPermittedException
+ * @since 9.2.0
+ */
+ public function delete();
+
+ /**
+ * Get the MimeType
+ *
+ * @return string
+ * @since 9.2.0
+ */
+ public function getMimeType();
+}
diff --git a/lib/public/Files/SimpleFS/ISimpleFolder.php b/lib/public/Files/SimpleFS/ISimpleFolder.php
new file mode 100644
index 00000000000..406bb631159
--- /dev/null
+++ b/lib/public/Files/SimpleFS/ISimpleFolder.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCP\Files\SimpleFS;
+
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+
+/**
+ * Interface ISimpleFolder
+ *
+ * @package OCP\Files\SimpleFS
+ * @since 9.2.0
+ * @internal This interface is experimental and might change for NC12
+ */
+interface ISimpleFolder {
+ /**
+ * Get all the files in a folder
+ *
+ * @return ISimpleFile[]
+ * @since 9.2.0
+ */
+ public function getDirectoryListing();
+
+ /**
+ * Check if a file with $name exists
+ *
+ * @param string $name
+ * @return bool
+ * @since 9.2.0
+ */
+ public function fileExists($name);
+
+ /**
+ * Get the file named $name from the folder
+ *
+ * @param string $name
+ * @return ISimpleFile
+ * @throws NotFoundException
+ * @since 9.2.0
+ */
+ public function getFile($name);
+
+ /**
+ * Creates a new file with $name in the folder
+ *
+ * @param string $name
+ * @return ISimpleFile
+ * @throws NotPermittedException
+ * @since 9.2.0
+ */
+ public function newFile($name);
+
+ /**
+ * Remove the folder and all the files in it
+ *
+ * @throws NotPermittedException
+ * @since 9.2.0
+ */
+ public function delete();
+
+ /**
+ * Get the folder name
+ *
+ * @return string
+ * @since 9.2.0
+ */
+ public function getName();
+}
diff --git a/lib/public/Files/SimpleFS/ISimpleRoot.php b/lib/public/Files/SimpleFS/ISimpleRoot.php
new file mode 100644
index 00000000000..c2f9d4ff05d
--- /dev/null
+++ b/lib/public/Files/SimpleFS/ISimpleRoot.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCP\Files\SimpleFS;
+
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+
+/**
+ * Interface ISimpleRoot
+ *
+ * @package OCP\Files\SimpleFS
+ * @since 9.2.0
+ * @internal This interface is experimental and might change for NC12
+ */
+interface ISimpleRoot {
+ /**
+ * Get the folder with name $name
+ *
+ * @param string $name
+ * @return ISimpleFolder
+ * @throws NotFoundException
+ * @throws \RuntimeException
+ * @since 9.2.0
+ */
+ public function getFolder($name);
+
+ /**
+ * Get all the Folders
+ *
+ * @return ISimpleFolder[]
+ * @throws NotFoundException
+ * @throws \RuntimeException
+ * @since 9.2.0
+ */
+ public function getDirectoryListing();
+
+ /**
+ * Create a new folder named $name
+ *
+ * @param string $name
+ * @return ISimpleFolder
+ * @throws NotPermittedException
+ * @throws \RuntimeException
+ * @since 9.2.0
+ */
+ public function newFolder($name);
+}
diff --git a/lib/public/IServerContainer.php b/lib/public/IServerContainer.php
index b736af2899a..354e39bd8f9 100644
--- a/lib/public/IServerContainer.php
+++ b/lib/public/IServerContainer.php
@@ -115,6 +115,7 @@ interface IServerContainer {
*
* @return \OCP\Files\Folder
* @since 6.0.0
+ * @deprecated since 9.2.0 use IAppData
*/
public function getAppFolder();
diff --git a/settings/js/apps.js b/settings/js/apps.js
index 99246f323fe..5119b35178e 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -183,6 +183,10 @@ OC.Settings.Apps = OC.Settings.Apps || {
app.previewAsIcon = true;
}
+ if (_.isArray(app.author)) {
+ app.author = app.author.join(', ');
+ }
+
var html = template(app);
if (selector) {
selector.html(html);
@@ -513,6 +517,9 @@ OC.Settings.Apps = OC.Settings.Apps || {
// Author Name
apps = apps.concat(_.filter(OC.Settings.Apps.State.apps, function (app) {
+ if (_.isArray(app.author)) {
+ return app.author.join(', ').toLowerCase().indexOf(query) !== -1;
+ }
return app.author.toLowerCase().indexOf(query) !== -1;
}));
diff --git a/tests/lib/AvatarManagerTest.php b/tests/lib/AvatarManagerTest.php
index 0ad998af6d5..8ccc51d12e0 100644
--- a/tests/lib/AvatarManagerTest.php
+++ b/tests/lib/AvatarManagerTest.php
@@ -26,8 +26,8 @@ namespace Test;
use OC\Avatar;
use OC\AvatarManager;
-use OCP\Files\Folder;
-use OCP\Files\IRootFolder;
+use OCP\Files\IAppData;
+use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
use OCP\IL10N;
use OCP\ILogger;
@@ -40,8 +40,8 @@ use OCP\IUserManager;
class AvatarManagerTest extends \Test\TestCase {
/** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
private $userManager;
- /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
- private $rootFolder;
+ /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */
+ private $appData;
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
private $l10n;
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
@@ -55,14 +55,14 @@ class AvatarManagerTest extends \Test\TestCase {
parent::setUp();
$this->userManager = $this->createMock(IUserManager::class);
- $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->appData = $this->createMock(IAppData::class);
$this->l10n = $this->createMock(IL10N::class);
$this->logger = $this->createMock(ILogger::class);
$this->config = $this->createMock(IConfig::class);
$this->avatarManager = new AvatarManager(
$this->userManager,
- $this->rootFolder,
+ $this->appData,
$this->l10n,
$this->logger,
$this->config
@@ -94,11 +94,11 @@ class AvatarManagerTest extends \Test\TestCase {
->method('get')
->with('valid-user')
->willReturn($user);
- $folder = $this->createMock(Folder::class);
- $this->rootFolder
+ $folder = $this->createMock(ISimpleFolder::class);
+ $this->appData
->expects($this->once())
- ->method('get')
- ->with('/valid-user')
+ ->method('getFolder')
+ ->with('valid-user')
->willReturn($folder);
$expected = new Avatar($folder, $this->l10n, $user, $this->logger, $this->config);;
diff --git a/tests/lib/AvatarTest.php b/tests/lib/AvatarTest.php
index 7f012c895fd..cea3f9bed1a 100644
--- a/tests/lib/AvatarTest.php
+++ b/tests/lib/AvatarTest.php
@@ -8,6 +8,8 @@
namespace Test;
+use OC\Files\SimpleFS\SimpleFolder;
+use OC\User\User;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\IConfig;
@@ -30,11 +32,11 @@ class AvatarTest extends \Test\TestCase {
public function setUp() {
parent::setUp();
- $this->folder = $this->createMock(Folder::class);
+ $this->folder = $this->createMock(SimpleFolder::class);
/** @var \OCP\IL10N | \PHPUnit_Framework_MockObject_MockObject $l */
$l = $this->createMock(IL10N::class);
$l->method('t')->will($this->returnArgument(0));
- $this->user = $this->getMockBuilder('OC\User\User')->disableOriginalConstructor()->getMock();
+ $this->user = $this->createMock(User::class);
$this->config = $this->createMock(IConfig::class);
$this->avatar = new \OC\Avatar(
@@ -51,7 +53,7 @@ class AvatarTest extends \Test\TestCase {
}
public function testGetAvatarSizeMatch() {
- $this->folder->method('nodeExists')
+ $this->folder->method('fileExists')
->will($this->returnValueMap([
['avatar.jpg', true],
['avatar.128.jpg', true],
@@ -61,13 +63,13 @@ class AvatarTest extends \Test\TestCase {
$file = $this->createMock(File::class);
$file->method('getContent')->willReturn($expected->data());
- $this->folder->method('get')->with('avatar.128.jpg')->willReturn($file);
+ $this->folder->method('getFile')->with('avatar.128.jpg')->willReturn($file);
$this->assertEquals($expected->data(), $this->avatar->get(128)->data());
}
public function testGetAvatarSizeMinusOne() {
- $this->folder->method('nodeExists')
+ $this->folder->method('fileExists')
->will($this->returnValueMap([
['avatar.jpg', true],
]));
@@ -76,13 +78,13 @@ class AvatarTest extends \Test\TestCase {
$file = $this->createMock(File::class);
$file->method('getContent')->willReturn($expected->data());
- $this->folder->method('get')->with('avatar.jpg')->willReturn($file);
+ $this->folder->method('getFile')->with('avatar.jpg')->willReturn($file);
$this->assertEquals($expected->data(), $this->avatar->get(-1)->data());
}
public function testGetAvatarNoSizeMatch() {
- $this->folder->method('nodeExists')
+ $this->folder->method('fileExists')
->will($this->returnValueMap([
['avatar.png', true],
['avatar.32.png', false],
@@ -95,7 +97,7 @@ class AvatarTest extends \Test\TestCase {
$file = $this->createMock(File::class);
$file->method('getContent')->willReturn($expected->data());
- $this->folder->method('get')
+ $this->folder->method('getFile')
->will($this->returnCallback(
function($path) use ($file) {
if ($path === 'avatar.png') {
@@ -126,7 +128,7 @@ class AvatarTest extends \Test\TestCase {
}
public function testExiststJPG() {
- $this->folder->method('nodeExists')
+ $this->folder->method('fileExists')
->will($this->returnValueMap([
['avatar.jpg', true],
['avatar.png', false],
@@ -135,7 +137,7 @@ class AvatarTest extends \Test\TestCase {
}
public function testExistsPNG() {
- $this->folder->method('nodeExists')
+ $this->folder->method('fileExists')
->will($this->returnValueMap([
['avatar.jpg', false],
['avatar.png', true],
diff --git a/tests/lib/Files/AppData/AppDataTest.php b/tests/lib/Files/AppData/AppDataTest.php
new file mode 100644
index 00000000000..3247ce7ba99
--- /dev/null
+++ b/tests/lib/Files/AppData/AppDataTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace Test\Files\AppData;
+
+use OC\Files\AppData\AppData;
+use OC\SystemConfig;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\IAppData;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\Files\SimpleFS\ISimpleFolder;
+
+class AppDataTest extends \Test\TestCase {
+ /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
+ private $rootFolder;
+
+ /** @var SystemConfig|\PHPUnit_Framework_MockObject_MockObject */
+ private $systemConfig;
+
+ /** @var IAppData */
+ private $appData;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->systemConfig = $this->createMock(SystemConfig::class);
+ $this->appData = new AppData($this->rootFolder, $this->systemConfig, 'myApp');
+
+ $this->systemConfig->expects($this->any())
+ ->method('getValue')
+ ->with('instanceid', null)
+ ->willReturn('iid');
+ }
+
+ private function setupAppFolder() {
+ $dataFolder = $this->createMock(Folder::class);
+ $appFolder = $this->createMock(Folder::class);
+
+ $this->rootFolder->expects($this->once())
+ ->method('get')
+ ->with($this->equalTo('appdata_iid'))
+ ->willReturn($dataFolder);
+ $dataFolder->expects($this->once())
+ ->method('get')
+ ->with($this->equalTo('myApp'))
+ ->willReturn($appFolder);
+
+ return [$dataFolder, $appFolder];
+ }
+
+ public function testGetFolder() {
+ $folders = $this->setupAppFolder();
+ $appFolder = $folders[1];
+
+ $folder = $this->createMock(Folder::class);
+
+ $appFolder->expects($this->once())
+ ->method('get')
+ ->with($this->equalTo('folder'))
+ ->willReturn($folder);
+
+ $result = $this->appData->getFolder('folder');
+ $this->assertInstanceOf(ISimpleFolder::class, $result);
+ }
+
+ public function testNewFolder() {
+ $folders = $this->setupAppFolder();
+ $appFolder = $folders[1];
+
+ $folder = $this->createMock(Folder::class);
+
+ $appFolder->expects($this->once())
+ ->method('newFolder')
+ ->with($this->equalTo('folder'))
+ ->willReturn($folder);
+
+ $result = $this->appData->newFolder('folder');
+ $this->assertInstanceOf(ISimpleFolder::class, $result);
+ }
+
+ public function testGetDirectoryListing() {
+ $folders = $this->setupAppFolder();
+ $appFolder = $folders[1];
+
+ $file = $this->createMock(File::class);
+ $folder = $this->createMock(Folder::class);
+ $node = $this->createMock(Node::class);
+
+ $appFolder->expects($this->once())
+ ->method('getDirectoryListing')
+ ->willReturn([$file, $folder, $node]);
+
+ $result = $this->appData->getDirectoryListing();
+
+ $this->assertCount(1, $result);
+ $this->assertInstanceOf(ISimpleFolder::class, $result[0]);
+ }
+
+}
diff --git a/tests/lib/Files/AppData/FactoryTest.php b/tests/lib/Files/AppData/FactoryTest.php
new file mode 100644
index 00000000000..75999c8c7da
--- /dev/null
+++ b/tests/lib/Files/AppData/FactoryTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace Test\Files\AppData;
+
+use OC\Files\AppData\Factory;
+use OC\SystemConfig;
+use OCP\Files\IRootFolder;
+
+class FactoryTest extends \Test\TestCase {
+ /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
+ private $rootFolder;
+
+ /** @var SystemConfig|\PHPUnit_Framework_MockObject_MockObject */
+ private $systemConfig;
+
+ /** @var Factory */
+ private $factory;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->systemConfig = $this->createMock(SystemConfig::class);
+ $this->factory = new Factory($this->rootFolder, $this->systemConfig);
+ }
+
+ public function testGet() {
+ $this->rootFolder->expects($this->never())
+ ->method($this->anything());
+ $this->systemConfig->expects($this->never())
+ ->method($this->anything());
+
+ $this->factory->get('foo');
+ }
+}
diff --git a/tests/lib/Files/SimpleFS/SimpleFileTest.php b/tests/lib/Files/SimpleFS/SimpleFileTest.php
new file mode 100644
index 00000000000..4e623eafa22
--- /dev/null
+++ b/tests/lib/Files/SimpleFS/SimpleFileTest.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace Test\File\SimpleFS;
+
+use OC\Files\SimpleFS\SimpleFile;
+use OCP\Files\File;
+
+class SimpleFileTest extends \Test\TestCase {
+ /** @var File|\PHPUnit_Framework_MockObject_MockObject */
+ private $file;
+
+ /** @var SimpleFile */
+ private $simpleFile;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->file = $this->createMock(File::class);
+ $this->simpleFile = new SimpleFile($this->file);
+ }
+
+ public function testGetName() {
+ $this->file->expects($this->once())
+ ->method('getName')
+ ->willReturn('myname');
+
+ $this->assertEquals('myname', $this->simpleFile->getName());
+ }
+
+ public function testGetSize() {
+ $this->file->expects($this->once())
+ ->method('getSize')
+ ->willReturn(42);
+
+ $this->assertEquals(42, $this->simpleFile->getSize());
+ }
+
+ public function testGetETag() {
+ $this->file->expects($this->once())
+ ->method('getETag')
+ ->willReturn('etag');
+
+ $this->assertEquals('etag', $this->simpleFile->getETag());
+ }
+
+ public function testGetMTime() {
+ $this->file->expects($this->once())
+ ->method('getMTime')
+ ->willReturn(101);
+
+ $this->assertEquals(101, $this->simpleFile->getMTime());
+ }
+
+ public function testGetContent() {
+ $this->file->expects($this->once())
+ ->method('getContent')
+ ->willReturn('foo');
+
+ $this->assertEquals('foo', $this->simpleFile->getContent());
+ }
+
+ public function testPutContent() {
+ $this->file->expects($this->once())
+ ->method('putContent')
+ ->with($this->equalTo('bar'));
+
+ $this->simpleFile->putContent('bar');
+ }
+
+ public function testDelete() {
+ $this->file->expects($this->once())
+ ->method('delete');
+
+ $this->simpleFile->delete();
+ }
+
+ public function testGetMimeType() {
+ $this->file->expects($this->once())
+ ->method('getMimeType')
+ ->willReturn('app/awesome');
+
+ $this->assertEquals('app/awesome', $this->simpleFile->getMimeType());
+ }
+}
diff --git a/tests/lib/Files/SimpleFS/SimpleFolderTest.php b/tests/lib/Files/SimpleFS/SimpleFolderTest.php
new file mode 100644
index 00000000000..d86c705d880
--- /dev/null
+++ b/tests/lib/Files/SimpleFS/SimpleFolderTest.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace Test\File\SimpleFS;
+
+use OC\Files\SimpleFS\SimpleFolder;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\Node;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFile;
+
+class SimpleFolderTest extends \Test\TestCase {
+ /** @var Folder|\PHPUnit_Framework_MockObject_MockObject */
+ private $folder;
+
+ /** @var SimpleFolder */
+ private $simpleFolder;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->folder = $this->createMock(Folder::class);
+ $this->simpleFolder = new SimpleFolder($this->folder);
+ }
+
+ public function testGetName() {
+ $this->folder->expects($this->once())
+ ->method('getName')
+ ->willReturn('myname');
+
+ $this->assertEquals('myname', $this->simpleFolder->getName());
+ }
+
+ public function testDelete() {
+ $this->folder->expects($this->once())
+ ->method('delete');
+
+ $this->simpleFolder->delete();
+ }
+
+ public function dataFileExists() {
+ return [
+ [true],
+ [false],
+ ];
+ }
+
+ /**
+ * @dataProvider dataFileExists
+ * @param bool $exists
+ */
+ public function testFileExists($exists) {
+ $this->folder->expects($this->once())
+ ->method('nodeExists')
+ ->with($this->equalTo('file'))
+ ->willReturn($exists);
+
+ $this->assertEquals($exists, $this->simpleFolder->fileExists('file'));
+ }
+
+ public function dataGetFile() {
+ return [
+ [File::class, false],
+ [Folder::class, true],
+ [Node::class, true],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetFile
+ * @param string $class
+ * @param bool $exception
+ */
+ public function testGetFile($class, $exception) {
+ $node = $this->createMock($class);
+
+ $this->folder->expects($this->once())
+ ->method('get')
+ ->with($this->equalTo('file'))
+ ->willReturn($node);
+
+ try {
+ $result = $this->simpleFolder->getFile('file');
+ $this->assertFalse($exception);
+ $this->assertInstanceOf(ISimpleFile::class, $result);
+ } catch (NotFoundException $e) {
+ $this->assertTrue($exception);
+ }
+ }
+
+ public function testNewFile() {
+ $file = $this->createMock(File::class);
+
+ $this->folder->expects($this->once())
+ ->method('newFile')
+ ->with($this->equalTo('file'))
+ ->willReturn($file);
+
+ $result = $this->simpleFolder->newFile('file');
+ $this->assertInstanceOf(ISimpleFile::class, $result);
+ }
+
+ public function testGetDirectoryListing() {
+ $file = $this->createMock(File::class);
+ $folder = $this->createMock(Folder::class);
+ $node = $this->createMock(Node::class);
+
+ $this->folder->expects($this->once())
+ ->method('getDirectoryListing')
+ ->willReturn([$file, $folder, $node]);
+
+ $result = $this->simpleFolder->getDirectoryListing();
+
+ $this->assertCount(1, $result);
+ $this->assertInstanceOf(ISimpleFile::class, $result[0]);
+ }
+
+}
diff --git a/tests/lib/TestCase.php b/tests/lib/TestCase.php
index 0389ef5d46b..7ccff382357 100644
--- a/tests/lib/TestCase.php
+++ b/tests/lib/TestCase.php
@@ -435,8 +435,10 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
return true;
}
$annotations = $this->getAnnotations();
- if (isset($annotations['class']['group']) && in_array('DB', $annotations['class']['group'])) {
- return true;
+ if (isset($annotations['class']['group'])) {
+ if(in_array('DB', $annotations['class']['group']) || in_array('SLOWDB', $annotations['class']['group']) ) {
+ return true;
+ }
}
return false;
diff --git a/tests/phpunit-autotest.xml b/tests/phpunit-autotest.xml
index 301f63a375d..3a82a56ebbf 100644
--- a/tests/phpunit-autotest.xml
+++ b/tests/phpunit-autotest.xml
@@ -29,10 +29,15 @@
<directory suffix=".php">../apps/files_trashbin/tests</directory>
<directory suffix=".php">../apps/files_versions/tests</directory>
<directory suffix=".php">../apps/provisioning_api/tests</directory>
+ <directory suffix=".php">../apps/systemtags/tests</directory>
+ <directory suffix=".php">../apps/theming/tests</directory>
+ <directory suffix=".php">../apps/twofactor_backupcodes/tests</directory>
<directory suffix=".php">../apps/updatenotification/tests</directory>
<directory suffix=".php">../apps/user_ldap/tests</directory>
+ <directory suffix=".php">../apps/workflowengine/tests</directory>
<directory suffix=".php">../tests</directory>
<directory suffix=".php">../build</directory>
+ <directory suffix=".php">../lib/composer</directory>
</exclude>
</whitelist>
</filter>
diff --git a/version.php b/version.php
index 01a822708e3..96725a6bb4d 100644
--- a/version.php
+++ b/version.php
@@ -25,7 +25,7 @@
// We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
// when updating major/minor version number.
-$OC_Version = array(9, 2, 0, 3);
+$OC_Version = array(9, 2, 0, 4);
// The human readable string
$OC_VersionString = '11.0 alpha';