aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--apps/comments/lib/Notification/Notifier.php13
-rw-r--r--apps/comments/tests/Unit/AppInfo/ApplicationTest.php4
-rw-r--r--apps/comments/tests/Unit/Notification/NotifierTest.php102
-rw-r--r--apps/dav/lib/Connector/Sabre/FakeLockerPlugin.php2
-rw-r--r--apps/dav/lib/Connector/Sabre/File.php7
-rw-r--r--apps/dav/lib/Files/FileSearchBackend.php265
-rw-r--r--apps/dav/lib/Server.php9
-rw-r--r--apps/dav/tests/unit/Files/FileSearchBackendTest.php299
-rw-r--r--apps/federatedfilesharing/tests/TestCase.php18
-rw-r--r--apps/federation/appinfo/routes.php14
-rw-r--r--apps/files/js/file-upload.js2
-rw-r--r--apps/files/l10n/tr.js1
-rw-r--r--apps/files/l10n/tr.json1
-rw-r--r--apps/files_sharing/tests/TestCase.php25
-rw-r--r--apps/systemtags/l10n/fr.js4
-rw-r--r--apps/systemtags/l10n/fr.json4
-rw-r--r--apps/theming/l10n/hu.js27
-rw-r--r--apps/theming/l10n/hu.json25
-rw-r--r--apps/twofactor_backupcodes/l10n/tr.js9
-rw-r--r--apps/twofactor_backupcodes/l10n/tr.json9
-rw-r--r--apps/updatenotification/l10n/bg.js24
-rw-r--r--apps/updatenotification/l10n/bg.json22
-rw-r--r--apps/updatenotification/l10n/tr.js3
-rw-r--r--apps/updatenotification/l10n/tr.json3
-rw-r--r--apps/user_ldap/appinfo/app.php2
-rw-r--r--apps/user_ldap/lib/Access.php4
-rw-r--r--apps/user_ldap/tests/User_LDAPTest.php2
-rw-r--r--apps/workflowengine/l10n/bg.js1
-rw-r--r--apps/workflowengine/l10n/bg.json1
-rw-r--r--apps/workflowengine/l10n/tr.js71
-rw-r--r--apps/workflowengine/l10n/tr.json69
-rw-r--r--apps/workflowengine/lib/AppInfo/Application.php2
-rw-r--r--apps/workflowengine/lib/Check/FileMimeType.php21
-rw-r--r--core/css/fixes.scss (renamed from core/css/fixes.css)0
-rw-r--r--core/css/fonts.scss (renamed from core/css/fonts.css)0
-rw-r--r--core/css/global.scss (renamed from core/css/global.css)0
-rw-r--r--core/css/mobile.scss (renamed from core/css/mobile.css)0
-rw-r--r--core/css/server.scss11
-rw-r--r--core/l10n/fr.js2
-rw-r--r--core/l10n/fr.json2
-rw-r--r--core/l10n/id.js3
-rw-r--r--core/l10n/id.json3
-rw-r--r--core/l10n/tr.js94
-rw-r--r--core/l10n/tr.json94
-rw-r--r--cron.php4
-rw-r--r--lib/base.php4
-rw-r--r--lib/composer/composer/ClassLoader.php10
-rw-r--r--lib/composer/composer/LICENSE2
-rw-r--r--lib/composer/composer/autoload_classmap.php10
-rw-r--r--lib/composer/composer/autoload_static.php10
-rw-r--r--lib/private/AppFramework/Http/Request.php3
-rw-r--r--lib/private/Encryption/Util.php12
-rw-r--r--lib/private/Files/Cache/Cache.php43
-rw-r--r--lib/private/Files/Cache/FailedCache.php5
-rw-r--r--lib/private/Files/Cache/QuerySearchHelper.php160
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php6
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheWrapper.php6
-rw-r--r--lib/private/Files/Node/Folder.php9
-rw-r--r--lib/private/Files/Search/SearchBinaryOperator.php57
-rw-r--r--lib/private/Files/Search/SearchComparison.php67
-rw-r--r--lib/private/Files/Search/SearchOrder.php57
-rw-r--r--lib/private/Files/Search/SearchQuery.php80
-rw-r--r--lib/private/Lockdown/Filesystem/NullCache.php5
-rw-r--r--lib/private/OCS/Provider.php17
-rw-r--r--lib/private/Preview/MP3.php20
-rw-r--r--lib/private/Share/Share.php98
-rw-r--r--lib/private/Template/SCSSCacher.php21
-rw-r--r--lib/private/User/User.php10
-rw-r--r--lib/private/legacy/group.php302
-rw-r--r--lib/private/legacy/image.php6
-rw-r--r--lib/private/legacy/template.php12
-rw-r--r--lib/private/legacy/user.php4
-rw-r--r--lib/public/Files/Cache/ICache.php12
-rw-r--r--lib/public/Files/Folder.php3
-rw-r--r--lib/public/Files/Search/ISearchBinaryOperator.php51
-rw-r--r--lib/public/Files/Search/ISearchComparison.php60
-rw-r--r--lib/public/Files/Search/ISearchOperator.php29
-rw-r--r--lib/public/Files/Search/ISearchOrder.php46
-rw-r--r--lib/public/Files/Search/ISearchQuery.php57
-rw-r--r--settings/l10n/de.js1
-rw-r--r--settings/l10n/de.json1
-rw-r--r--settings/l10n/de_DE.js1
-rw-r--r--settings/l10n/de_DE.json1
-rw-r--r--settings/l10n/eu.js43
-rw-r--r--settings/l10n/eu.json43
-rw-r--r--settings/l10n/fr.js1
-rw-r--r--settings/l10n/fr.json1
-rw-r--r--settings/l10n/is.js7
-rw-r--r--settings/l10n/is.json7
-rw-r--r--settings/l10n/pl.js1
-rw-r--r--settings/l10n/pl.json1
-rw-r--r--settings/l10n/pt_BR.js1
-rw-r--r--settings/l10n/pt_BR.json1
-rw-r--r--settings/users.php2
-rw-r--r--tests/lib/AppFramework/Http/RequestTest.php25
-rw-r--r--tests/lib/Files/Cache/CacheTest.php74
-rw-r--r--tests/lib/Files/Cache/QuerySearchHelperTest.php204
-rw-r--r--tests/lib/Group/LegacyGroupTest.php208
-rw-r--r--tests/lib/OCS/ProviderTest.php66
100 files changed, 2493 insertions, 768 deletions
diff --git a/3rdparty b/3rdparty
-Subproject 489bcf4f81e462f4d74f0b76f58caeabd58e75d
+Subproject 98fa92c67d735f82ae012786395e660f1513bef
diff --git a/apps/comments/lib/Notification/Notifier.php b/apps/comments/lib/Notification/Notifier.php
index a9daef3031f..09092da539c 100644
--- a/apps/comments/lib/Notification/Notifier.php
+++ b/apps/comments/lib/Notification/Notifier.php
@@ -23,7 +23,7 @@ namespace OCA\Comments\Notification;
use OCP\Comments\ICommentsManager;
use OCP\Comments\NotFoundException;
-use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\L10N\IFactory;
@@ -35,8 +35,8 @@ class Notifier implements INotifier {
/** @var IFactory */
protected $l10nFactory;
- /** @var Folder */
- protected $userFolder;
+ /** @var IRootFolder */
+ protected $rootFolder;
/** @var ICommentsManager */
protected $commentsManager;
@@ -49,13 +49,13 @@ class Notifier implements INotifier {
public function __construct(
IFactory $l10nFactory,
- Folder $userFolder,
+ IRootFolder $rootFolder,
ICommentsManager $commentsManager,
IURLGenerator $url,
IUserManager $userManager
) {
$this->l10nFactory = $l10nFactory;
- $this->userFolder = $userFolder;
+ $this->rootFolder = $rootFolder;
$this->commentsManager = $commentsManager;
$this->url = $url;
$this->userManager = $userManager;
@@ -93,7 +93,8 @@ class Notifier implements INotifier {
if($parameters[0] !== 'files') {
throw new \InvalidArgumentException('Unsupported comment object');
}
- $nodes = $this->userFolder->getById($parameters[1]);
+ $userFolder = $this->rootFolder->getUserFolder($notification->getUser());
+ $nodes = $userFolder->getById($parameters[1]);
if(empty($nodes)) {
throw new \InvalidArgumentException('Cannot resolve file id to Node instance');
}
diff --git a/apps/comments/tests/Unit/AppInfo/ApplicationTest.php b/apps/comments/tests/Unit/AppInfo/ApplicationTest.php
index e0a47dbfff9..5adfbbcc635 100644
--- a/apps/comments/tests/Unit/AppInfo/ApplicationTest.php
+++ b/apps/comments/tests/Unit/AppInfo/ApplicationTest.php
@@ -22,6 +22,7 @@
namespace OCA\Comments\Tests\Unit\AppInfo;
use OCA\Comments\AppInfo\Application;
+use OCA\Comments\Notification\Notifier;
use Test\TestCase;
/**
@@ -56,7 +57,8 @@ class ApplicationTest extends TestCase {
'OCA\Comments\Activity\Listener',
'OCA\Comments\Activity\Provider',
'OCA\Comments\Activity\Setting',
- 'OCA\Comments\Notification\Listener'
+ 'OCA\Comments\Notification\Listener',
+ Notifier::class,
];
foreach($services as $service) {
diff --git a/apps/comments/tests/Unit/Notification/NotifierTest.php b/apps/comments/tests/Unit/Notification/NotifierTest.php
index 25b8b4b278d..0b08849030b 100644
--- a/apps/comments/tests/Unit/Notification/NotifierTest.php
+++ b/apps/comments/tests/Unit/Notification/NotifierTest.php
@@ -28,6 +28,7 @@ use OCP\Comments\IComment;
use OCP\Comments\ICommentsManager;
use OCP\Comments\NotFoundException;
use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\IL10N;
use OCP\IURLGenerator;
@@ -41,41 +42,33 @@ class NotifierTest extends TestCase {
/** @var Notifier */
protected $notifier;
-
/** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */
protected $l10nFactory;
-
- /** @var Folder|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
+ protected $l;
+ /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
protected $folder;
-
- /** @var ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */
protected $commentsManager;
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject */
protected $url;
- /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
protected $userManager;
-
-
- /** @var string */
- protected $lc = 'tlh_KX';
-
- /** @var INotification|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var INotification|\PHPUnit_Framework_MockObject_MockObject */
protected $notification;
-
- /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
- protected $l;
-
- /** @var IComment|\PHPUnit_Framework_MockObject_MockObject */
+ /** @var IComment|\PHPUnit_Framework_MockObject_MockObject */
protected $comment;
+ /** @var string */
+ protected $lc = 'tlh_KX';
protected function setUp() {
parent::setUp();
- $this->l10nFactory = $this->getMockBuilder('OCP\L10N\IFactory')->getMock();
- $this->folder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
- $this->commentsManager = $this->getMockBuilder('OCP\Comments\ICommentsManager')->getMock();
+ $this->l10nFactory = $this->createMock(IFactory::class);
+ $this->folder = $this->createMock(IRootFolder::class);
+ $this->commentsManager = $this->createMock(ICommentsManager::class);
$this->url = $this->createMock(IURLGenerator::class);
- $this->userManager = $this->getMockBuilder('OCP\IUserManager')->getMock();
+ $this->userManager = $this->createMock(IUserManager::class);
$this->notifier = new Notifier(
$this->l10nFactory,
@@ -92,8 +85,8 @@ class NotifierTest extends TestCase {
return vsprintf($text, $parameters);
}));
- $this->notification = $this->getMockBuilder('OCP\Notification\INotification')->getMock();
- $this->comment = $this->getMockBuilder('OCP\Comments\IComment')->getMock();
+ $this->notification = $this->createMock(INotification::class);
+ $this->comment = $this->createMock(IComment::class);
}
public function testPrepareSuccess() {
@@ -102,24 +95,31 @@ class NotifierTest extends TestCase {
$message = 'Huraga mentioned you in a comment on “Gre\'thor.odp”';
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
- $user = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user = $this->createMock(IUser::class);
$user->expects($this->once())
->method('getDisplayName')
->willReturn($displayName);
- /** @var Node|\PHPUnit_Framework_MockObject_MockObject */
- $node = $this->getMockBuilder('OCP\Files\Node')->getMock();
+ /** @var Node|\PHPUnit_Framework_MockObject_MockObject $node */
+ $node = $this->createMock(Node::class);
$node
->expects($this->atLeastOnce())
->method('getName')
->willReturn($fileName);
- $this->folder
- ->expects($this->once())
+ $userFolder = $this->createMock(Folder::class);
+ $this->folder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('you')
+ ->willReturn($userFolder);
+ $userFolder->expects($this->once())
->method('getById')
->with('678')
->willReturn([$node]);
+ $this->notification->expects($this->once())
+ ->method('getUser')
+ ->willReturn('you');
$this->notification
->expects($this->once())
->method('getApp')
@@ -172,7 +172,7 @@ class NotifierTest extends TestCase {
->willReturn('users');
$this->commentsManager
- ->expects(($this->once()))
+ ->expects($this->once())
->method('get')
->willReturn($this->comment);
@@ -189,19 +189,26 @@ class NotifierTest extends TestCase {
$fileName = 'Gre\'thor.odp';
$message = 'A (now) deleted user mentioned you in a comment on “Gre\'thor.odp”';
- /** @var Node|\PHPUnit_Framework_MockObject_MockObject */
- $node = $this->getMockBuilder('OCP\Files\Node')->getMock();
+ /** @var Node|\PHPUnit_Framework_MockObject_MockObject $node */
+ $node = $this->createMock(Node::class);
$node
->expects($this->atLeastOnce())
->method('getName')
->willReturn($fileName);
- $this->folder
- ->expects($this->once())
+ $userFolder = $this->createMock(Folder::class);
+ $this->folder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('you')
+ ->willReturn($userFolder);
+ $userFolder->expects($this->once())
->method('getById')
->with('678')
->willReturn([$node]);
+ $this->notification->expects($this->once())
+ ->method('getUser')
+ ->willReturn('you');
$this->notification
->expects($this->once())
->method('getApp')
@@ -254,7 +261,7 @@ class NotifierTest extends TestCase {
->willReturn(ICommentsManager::DELETED_USER);
$this->commentsManager
- ->expects(($this->once()))
+ ->expects($this->once())
->method('get')
->willReturn($this->comment);
@@ -292,7 +299,7 @@ class NotifierTest extends TestCase {
->method('get');
$this->commentsManager
- ->expects(($this->never()))
+ ->expects($this->never())
->method('get');
$this->userManager
@@ -329,7 +336,7 @@ class NotifierTest extends TestCase {
->method('get');
$this->commentsManager
- ->expects(($this->once()))
+ ->expects($this->once())
->method('get')
->willThrowException(new NotFoundException());
@@ -347,7 +354,7 @@ class NotifierTest extends TestCase {
$displayName = 'Huraga';
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
- $user = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user = $this->createMock(IUser::class);
$user->expects($this->once())
->method('getDisplayName')
->willReturn($displayName);
@@ -390,7 +397,7 @@ class NotifierTest extends TestCase {
->willReturn('users');
$this->commentsManager
- ->expects(($this->once()))
+ ->expects($this->once())
->method('get')
->willReturn($this->comment);
@@ -410,7 +417,7 @@ class NotifierTest extends TestCase {
$displayName = 'Huraga';
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
- $user = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user = $this->createMock(IUser::class);
$user->expects($this->once())
->method('getDisplayName')
->willReturn($displayName);
@@ -454,7 +461,7 @@ class NotifierTest extends TestCase {
->willReturn('users');
$this->commentsManager
- ->expects(($this->once()))
+ ->expects($this->once())
->method('get')
->willReturn($this->comment);
@@ -474,17 +481,24 @@ class NotifierTest extends TestCase {
$displayName = 'Huraga';
/** @var IUser|\PHPUnit_Framework_MockObject_MockObject $user */
- $user = $this->getMockBuilder('OCP\IUser')->getMock();
+ $user = $this->createMock(IUser::class);
$user->expects($this->once())
->method('getDisplayName')
->willReturn($displayName);
- $this->folder
- ->expects($this->once())
+ $userFolder = $this->createMock(Folder::class);
+ $this->folder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('you')
+ ->willReturn($userFolder);
+ $userFolder->expects($this->once())
->method('getById')
->with('678')
->willReturn([]);
+ $this->notification->expects($this->once())
+ ->method('getUser')
+ ->willReturn('you');
$this->notification
->expects($this->once())
->method('getApp')
@@ -520,7 +534,7 @@ class NotifierTest extends TestCase {
->willReturn('users');
$this->commentsManager
- ->expects(($this->once()))
+ ->expects($this->once())
->method('get')
->willReturn($this->comment);
diff --git a/apps/dav/lib/Connector/Sabre/FakeLockerPlugin.php b/apps/dav/lib/Connector/Sabre/FakeLockerPlugin.php
index c330e5d203a..3baacfc064a 100644
--- a/apps/dav/lib/Connector/Sabre/FakeLockerPlugin.php
+++ b/apps/dav/lib/Connector/Sabre/FakeLockerPlugin.php
@@ -136,7 +136,9 @@ class FakeLockerPlugin extends ServerPlugin {
new LockDiscovery([$lockInfo])
]);
+ $response->setStatus(200);
$response->setBody($body);
+ $response->setStatus(200);
return false;
}
diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php
index d0826ee5a8c..391d42393f5 100644
--- a/apps/dav/lib/Connector/Sabre/File.php
+++ b/apps/dav/lib/Connector/Sabre/File.php
@@ -206,7 +206,12 @@ class File extends Node implements IFile {
// allow sync clients to send the mtime along in a header
$request = \OC::$server->getRequest();
if (isset($request->server['HTTP_X_OC_MTIME'])) {
- if ($this->fileView->touch($this->path, $request->server['HTTP_X_OC_MTIME'])) {
+ $mtimeStr = $request->server['HTTP_X_OC_MTIME'];
+ if (!is_numeric($mtimeStr)) {
+ throw new \InvalidArgumentException('X-OC-Mtime header must be an integer (unix timestamp).');
+ }
+ $mtime = intval($mtimeStr);
+ if ($this->fileView->touch($this->path, $mtime)) {
header('X-OC-MTime: accepted');
}
}
diff --git a/apps/dav/lib/Files/FileSearchBackend.php b/apps/dav/lib/Files/FileSearchBackend.php
new file mode 100644
index 00000000000..c429a1727f8
--- /dev/null
+++ b/apps/dav/lib/Files/FileSearchBackend.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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 OCA\DAV\Files;
+
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OC\Files\Search\SearchOrder;
+use OC\Files\Search\SearchQuery;
+use OC\Files\View;
+use OCA\DAV\Connector\Sabre\Directory;
+use OCA\DAV\Connector\Sabre\FilesPlugin;
+use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\Files\Search\ISearchOperator;
+use OCP\Files\Search\ISearchOrder;
+use OCP\Files\Search\ISearchQuery;
+use OCP\IUser;
+use OCP\Share\IManager;
+use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\Tree;
+use SearchDAV\Backend\ISearchBackend;
+use SearchDAV\Backend\SearchPropertyDefinition;
+use SearchDAV\Backend\SearchResult;
+use SearchDAV\XML\BasicSearch;
+use SearchDAV\XML\Literal;
+use SearchDAV\XML\Operator;
+use SearchDAV\XML\Order;
+
+class FileSearchBackend implements ISearchBackend {
+ /** @var Tree */
+ private $tree;
+
+ /** @var IUser */
+ private $user;
+
+ /** @var IRootFolder */
+ private $rootFolder;
+
+ /** @var IManager */
+ private $shareManager;
+
+ /** @var View */
+ private $view;
+
+ /**
+ * FileSearchBackend constructor.
+ *
+ * @param Tree $tree
+ * @param IUser $user
+ * @param IRootFolder $rootFolder
+ * @param IManager $shareManager
+ * @param View $view
+ * @internal param IRootFolder $rootFolder
+ */
+ public function __construct(Tree $tree, IUser $user, IRootFolder $rootFolder, IManager $shareManager, View $view) {
+ $this->tree = $tree;
+ $this->user = $user;
+ $this->rootFolder = $rootFolder;
+ $this->shareManager = $shareManager;
+ $this->view = $view;
+ }
+
+ /**
+ * Search endpoint will be remote.php/dav
+ *
+ * @return string
+ */
+ public function getArbiterPath() {
+ return '';
+ }
+
+ public function isValidScope($href, $depth, $path) {
+ // only allow scopes inside the dav server
+ if (is_null($path)) {
+ return false;
+ }
+
+ try {
+ $node = $this->tree->getNodeForPath($path);
+ return $node instanceof Directory;
+ } catch (NotFound $e) {
+ return false;
+ }
+ }
+
+ public function getPropertyDefinitionsForScope($href, $path) {
+ // all valid scopes support the same schema
+
+ //todo dynamically load all propfind properties that are supported
+ return [
+ // queryable properties
+ new SearchPropertyDefinition('{DAV:}displayname', true, false, true),
+ new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true),
+ new SearchPropertyDefinition('{DAV:}getlastmodifed', true, true, true, SearchPropertyDefinition::DATATYPE_DATETIME),
+ new SearchPropertyDefinition(FilesPlugin::SIZE_PROPERTYNAME, true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
+
+ // select only properties
+ new SearchPropertyDefinition('{DAV:}resourcetype', false, true, false),
+ new SearchPropertyDefinition('{DAV:}getcontentlength', false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::CHECKSUMS_PROPERTYNAME, false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::PERMISSIONS_PROPERTYNAME, false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::GETETAG_PROPERTYNAME, false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::OWNER_ID_PROPERTYNAME, false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME, false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::DATA_FINGERPRINT_PROPERTYNAME, false, true, false),
+ new SearchPropertyDefinition(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, false, true, false, SearchPropertyDefinition::DATATYPE_BOOLEAN),
+ new SearchPropertyDefinition(FilesPlugin::INTERNAL_FILEID_PROPERTYNAME, false, true, false, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
+ new SearchPropertyDefinition(FilesPlugin::FILEID_PROPERTYNAME, false, true, false, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
+ ];
+ }
+
+ /**
+ * @param BasicSearch $search
+ * @return SearchResult[]
+ */
+ public function search(BasicSearch $search) {
+ if (count($search->from) !== 1) {
+ throw new \InvalidArgumentException('Searching more than one folder is not supported');
+ }
+ $query = $this->transformQuery($search);
+ $scope = $search->from[0];
+ if ($scope->path === null) {
+ throw new \InvalidArgumentException('Using uri\'s as scope is not supported, please use a path relative to the search arbiter instead');
+ }
+ $node = $this->tree->getNodeForPath($scope->path);
+ if (!$node instanceof Directory) {
+ throw new \InvalidArgumentException('Search is only supported on directories');
+ }
+
+ $fileInfo = $node->getFileInfo();
+ $folder = $this->rootFolder->get($fileInfo->getPath());
+ /** @var Folder $folder $results */
+ $results = $folder->search($query);
+
+ return array_map(function (Node $node) {
+ if ($node instanceof Folder) {
+ return new SearchResult(new \OCA\DAV\Connector\Sabre\Directory($this->view, $node, $this->tree, $this->shareManager), $this->getHrefForNode($node));
+ } else {
+ return new SearchResult(new \OCA\DAV\Connector\Sabre\File($this->view, $node, $this->shareManager), $this->getHrefForNode($node));
+ }
+ }, $results);
+ }
+
+ /**
+ * @param Node $node
+ * @return string
+ */
+ private function getHrefForNode(Node $node) {
+ $base = '/files/' . $this->user->getUID();
+ return $base . $this->view->getRelativePath($node->getPath());
+ }
+
+ /**
+ * @param BasicSearch $query
+ * @return ISearchQuery
+ */
+ private function transformQuery(BasicSearch $query) {
+ // TODO offset, limit
+ $orders = array_map([$this, 'mapSearchOrder'], $query->orderBy);
+ return new SearchQuery($this->transformSearchOperation($query->where), 0, 0, $orders);
+ }
+
+ /**
+ * @param Order $order
+ * @return ISearchOrder
+ */
+ private function mapSearchOrder(Order $order) {
+ return new SearchOrder($order->order === Order::ASC ? ISearchOrder::DIRECTION_ASCENDING : ISearchOrder::DIRECTION_DESCENDING, $this->mapPropertyNameToCollumn($order->property));
+ }
+
+ /**
+ * @param Operator $operator
+ * @return ISearchOperator
+ */
+ private function transformSearchOperation(Operator $operator) {
+ list(, $trimmedType) = explode('}', $operator->type);
+ switch ($operator->type) {
+ case Operator::OPERATION_AND:
+ case Operator::OPERATION_OR:
+ case Operator::OPERATION_NOT:
+ $arguments = array_map([$this, 'transformSearchOperation'], $operator->arguments);
+ return new SearchBinaryOperator($trimmedType, $arguments);
+ case Operator::OPERATION_EQUAL:
+ case Operator::OPERATION_GREATER_OR_EQUAL_THAN:
+ case Operator::OPERATION_GREATER_THAN:
+ case Operator::OPERATION_LESS_OR_EQUAL_THAN:
+ case Operator::OPERATION_LESS_THAN:
+ case Operator::OPERATION_IS_LIKE:
+ if (count($operator->arguments) !== 2) {
+ throw new \InvalidArgumentException('Invalid number of arguments for ' . $trimmedType . ' operation');
+ }
+ if (gettype($operator->arguments[0]) !== 'string') {
+ throw new \InvalidArgumentException('Invalid argument 1 for ' . $trimmedType . ' operation, expected property');
+ }
+ if (!($operator->arguments[1] instanceof Literal)) {
+ throw new \InvalidArgumentException('Invalid argument 2 for ' . $trimmedType . ' operation, expected literal');
+ }
+ return new SearchComparison($trimmedType, $this->mapPropertyNameToCollumn($operator->arguments[0]), $this->castValue($operator->arguments[0], $operator->arguments[1]->value));
+ case Operator::OPERATION_IS_COLLECTION:
+ return new SearchComparison('eq', 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE);
+ default:
+ throw new \InvalidArgumentException('Unsupported operation ' . $trimmedType. ' (' . $operator->type . ')');
+ }
+ }
+
+ /**
+ * @param string $propertyName
+ * @return string
+ */
+ private function mapPropertyNameToCollumn($propertyName) {
+ switch ($propertyName) {
+ case '{DAV:}displayname':
+ return 'name';
+ case '{DAV:}getcontenttype':
+ return 'mimetype';
+ case '{DAV:}getlastmodifed':
+ return 'mtime';
+ case FilesPlugin::SIZE_PROPERTYNAME:
+ return 'size';
+ default:
+ throw new \InvalidArgumentException('Unsupported property for search or order: ' . $propertyName);
+ }
+ }
+
+ private function castValue($propertyName, $value) {
+ $allProps = $this->getPropertyDefinitionsForScope('', '');
+ foreach ($allProps as $prop) {
+ if ($prop->name === $propertyName) {
+ $dataType = $prop->dataType;
+ switch ($dataType) {
+ case SearchPropertyDefinition::DATATYPE_BOOLEAN:
+ return $value === 'yes';
+ case SearchPropertyDefinition::DATATYPE_DECIMAL:
+ case SearchPropertyDefinition::DATATYPE_INTEGER:
+ case SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER:
+ return 0 + $value;
+ default:
+ return $value;
+ }
+ }
+ }
+ return $value;
+ }
+}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 79c4301a8d8..031bc1d3d81 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -51,6 +51,7 @@ use OCP\SabrePluginEvent;
use Sabre\CardDAV\VCFExportPlugin;
use Sabre\DAV\Auth\Plugin;
use OCA\DAV\Connector\Sabre\TagsPlugin;
+use SearchDAV\DAV\SearchPlugin;
class Server {
@@ -155,6 +156,7 @@ class Server {
if($request->isUserAgent([
'/WebDAVFS/',
'/Microsoft Office OneNote 2013/',
+ '/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
])) {
$this->server->addPlugin(new FakeLockerPlugin());
}
@@ -222,6 +224,13 @@ class Server {
\OC::$server->getGroupManager(),
$userFolder
));
+ $this->server->addPlugin(new SearchPlugin(new \OCA\DAV\Files\FileSearchBackend(
+ $this->server->tree,
+ $user,
+ \OC::$server->getRootFolder(),
+ \OC::$server->getShareManager(),
+ $view
+ )));
}
}
});
diff --git a/apps/dav/tests/unit/Files/FileSearchBackendTest.php b/apps/dav/tests/unit/Files/FileSearchBackendTest.php
new file mode 100644
index 00000000000..24b9a9c51e6
--- /dev/null
+++ b/apps/dav/tests/unit/Files/FileSearchBackendTest.php
@@ -0,0 +1,299 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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 OCA\DAV\Tests\Files;
+
+use OC\Files\Search\SearchComparison;
+use OC\Files\Search\SearchQuery;
+use OC\Files\View;
+use OCA\DAV\Connector\Sabre\Directory;
+use OCA\DAV\Connector\Sabre\File;
+use OCA\DAV\Connector\Sabre\FilesPlugin;
+use OCA\DAV\Files\FileSearchBackend;
+use OCP\Files\FileInfo;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Search\ISearchComparison;
+use OCP\IUser;
+use OCP\Share\IManager;
+use Sabre\DAV\Tree;
+use SearchDAV\XML\BasicSearch;
+use SearchDAV\XML\Literal;
+use SearchDAV\XML\Operator;
+use SearchDAV\XML\Scope;
+use Test\TestCase;
+
+class FileSearchBackendTest extends TestCase {
+ /** @var Tree|\PHPUnit_Framework_MockObject_MockObject */
+ private $tree;
+
+ /** @var IUser */
+ private $user;
+
+ /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
+ private $rootFolder;
+
+ /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
+ private $shareManager;
+
+ /** @var View|\PHPUnit_Framework_MockObject_MockObject */
+ private $view;
+
+ /** @var Folder|\PHPUnit_Framework_MockObject_MockObject */
+ private $searchFolder;
+
+ /** @var FileSearchBackend */
+ private $search;
+
+ /** @var Directory|\PHPUnit_Framework_MockObject_MockObject */
+ private $davFolder;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->user = $this->createMock(IUser::class);
+ $this->user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('test');
+
+ $this->tree = $this->getMockBuilder(Tree::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->view->expects($this->any())
+ ->method('getRelativePath')
+ ->willReturnArgument(0);
+
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+
+ $this->shareManager = $this->createMock(IManager::class);
+
+ $this->searchFolder = $this->createMock(Folder::class);
+
+ $fileInfo = $this->createMock(FileInfo::class);
+
+ $this->davFolder = $this->createMock(Directory::class);
+
+ $this->davFolder->expects($this->any())
+ ->method('getFileInfo')
+ ->willReturn($fileInfo);
+
+ $this->rootFolder->expects($this->any())
+ ->method('get')
+ ->willReturn($this->searchFolder);
+
+ $this->search = new FileSearchBackend($this->tree, $this->user, $this->rootFolder, $this->shareManager, $this->view);
+ }
+
+ public function testSearchFilename() {
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($this->davFolder);
+
+ $this->searchFolder->expects($this->once())
+ ->method('search')
+ ->with(new SearchQuery(
+ new SearchComparison(
+ ISearchComparison::COMPARE_EQUAL,
+ 'name',
+ 'foo'
+ ),
+ 0,
+ 0,
+ []
+ ))
+ ->will($this->returnValue([
+ new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path')
+ ]));
+
+ $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}displayname', 'foo');
+ $result = $this->search->search($query);
+
+ $this->assertCount(1, $result);
+ $this->assertEquals('/files/test/test/path', $result[0]->href);
+ }
+
+ public function testSearchMimetype() {
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($this->davFolder);
+
+ $this->searchFolder->expects($this->once())
+ ->method('search')
+ ->with(new SearchQuery(
+ new SearchComparison(
+ ISearchComparison::COMPARE_EQUAL,
+ 'mimetype',
+ 'foo'
+ ),
+ 0,
+ 0,
+ []
+ ))
+ ->will($this->returnValue([
+ new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path')
+ ]));
+
+ $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}getcontenttype', 'foo');
+ $result = $this->search->search($query);
+
+ $this->assertCount(1, $result);
+ $this->assertEquals('/files/test/test/path', $result[0]->href);
+ }
+
+ public function testSearchSize() {
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($this->davFolder);
+
+ $this->searchFolder->expects($this->once())
+ ->method('search')
+ ->with(new SearchQuery(
+ new SearchComparison(
+ ISearchComparison::COMPARE_GREATER_THAN,
+ 'size',
+ 10
+ ),
+ 0,
+ 0,
+ []
+ ))
+ ->will($this->returnValue([
+ new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path')
+ ]));
+
+ $query = $this->getBasicQuery(Operator::OPERATION_GREATER_THAN, FilesPlugin::SIZE_PROPERTYNAME, 10);
+ $result = $this->search->search($query);
+
+ $this->assertCount(1, $result);
+ $this->assertEquals('/files/test/test/path', $result[0]->href);
+ }
+
+ public function testSearchMtime() {
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($this->davFolder);
+
+ $this->searchFolder->expects($this->once())
+ ->method('search')
+ ->with(new SearchQuery(
+ new SearchComparison(
+ ISearchComparison::COMPARE_GREATER_THAN,
+ 'mtime',
+ 10
+ ),
+ 0,
+ 0,
+ []
+ ))
+ ->will($this->returnValue([
+ new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path')
+ ]));
+
+ $query = $this->getBasicQuery(Operator::OPERATION_GREATER_THAN, '{DAV:}getlastmodifed', 10);
+ $result = $this->search->search($query);
+
+ $this->assertCount(1, $result);
+ $this->assertEquals('/files/test/test/path', $result[0]->href);
+ }
+
+ public function testSearchIsCollection() {
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($this->davFolder);
+
+ $this->searchFolder->expects($this->once())
+ ->method('search')
+ ->with(new SearchQuery(
+ new SearchComparison(
+ ISearchComparison::COMPARE_EQUAL,
+ 'mimetype',
+ FileInfo::MIMETYPE_FOLDER
+ ),
+ 0,
+ 0,
+ []
+ ))
+ ->will($this->returnValue([
+ new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path')
+ ]));
+
+ $query = $this->getBasicQuery(Operator::OPERATION_IS_COLLECTION, 'yes');
+ $result = $this->search->search($query);
+
+ $this->assertCount(1, $result);
+ $this->assertEquals('/files/test/test/path', $result[0]->href);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSearchInvalidProp() {
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($this->davFolder);
+
+ $this->searchFolder->expects($this->never())
+ ->method('search');
+
+ $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}getetag', 'foo');
+ $this->search->search($query);
+ }
+
+ private function getBasicQuery($type, $property, $value = null) {
+ $query = new BasicSearch();
+ $scope = new Scope('/', 'infinite');
+ $scope->path = '/';
+ $query->from = [$scope];
+ $query->orderBy = [];
+ $query->select = [];
+ if (is_null($value)) {
+ $query->where = new Operator(
+ $type,
+ [new Literal($property)]
+ );
+ } else {
+ $query->where = new Operator(
+ $type,
+ [$property, new Literal($value)]
+ );
+ }
+ return $query;
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testSearchNonFolder() {
+ $davNode = $this->createMock(File::class);
+
+ $this->tree->expects($this->any())
+ ->method('getNodeForPath')
+ ->willReturn($davNode);
+
+ $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}displayname', 'foo');
+ $this->search->search($query);
+ }
+}
diff --git a/apps/federatedfilesharing/tests/TestCase.php b/apps/federatedfilesharing/tests/TestCase.php
index 7ccf76bbbc6..b31772e4e9e 100644
--- a/apps/federatedfilesharing/tests/TestCase.php
+++ b/apps/federatedfilesharing/tests/TestCase.php
@@ -42,7 +42,7 @@ abstract class TestCase extends \Test\TestCase {
// reset backend
\OC_User::clearBackends();
- \OC_Group::clearBackends();
+ \OC::$server->getGroupManager()->clearBackends();
// create users
$backend = new \Test\Util\User\Dummy();
@@ -76,8 +76,8 @@ abstract class TestCase extends \Test\TestCase {
// reset backend
\OC_User::clearBackends();
\OC_User::useBackend('database');
- \OC_Group::clearBackends();
- \OC_Group::useBackend(new Database());
+ \OC::$server->getGroupManager()->clearBackends();
+ \OC::$server->getGroupManager()->addBackend(new Database());
parent::tearDownAfterClass();
}
@@ -94,9 +94,15 @@ abstract class TestCase extends \Test\TestCase {
}
if ($create) {
- \OC::$server->getUserManager()->createUser($user, $password);
- \OC_Group::createGroup('group');
- \OC_Group::addToGroup($user, 'group');
+ $userManager = \OC::$server->getUserManager();
+ $groupManager = \OC::$server->getGroupManager();
+
+ $userObject = $userManager->createUser($user, $password);
+ $group = $groupManager->createGroup('group');
+
+ if ($group and $userObject) {
+ $group->addUser($userObject);
+ }
}
self::resetStorage();
diff --git a/apps/federation/appinfo/routes.php b/apps/federation/appinfo/routes.php
index b9515812a01..4c742dd705c 100644
--- a/apps/federation/appinfo/routes.php
+++ b/apps/federation/appinfo/routes.php
@@ -43,6 +43,7 @@ $application->registerRoutes(
],
],
'ocs' => [
+ // old endpoints, only used by Nextcloud and ownCloud
[
'name' => 'OCSAuthAPI#getSharedSecret',
'url' => '/api/v1/shared-secret',
@@ -53,6 +54,19 @@ $application->registerRoutes(
'url' => '/api/v1/request-shared-secret',
'verb' => 'POST',
],
+ // new endpoints, published as public api
+ [
+ 'name' => 'OCSAuthAPI#getSharedSecret',
+ 'root' => '/cloud',
+ 'url' => '/shared-secret',
+ 'verb' => 'GET',
+ ],
+ [
+ 'name' => 'OCSAuthAPI#requestSharedSecret',
+ 'root' => '/cloud',
+ 'url' => '/shared-secret',
+ 'verb' => 'POST',
+ ],
],
]
);
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index c93abd5244d..6f9fd9aafea 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -222,7 +222,7 @@ OC.FileUpload.prototype = {
if (file.lastModified) {
// preserve timestamp
- this.data.headers['X-OC-Mtime'] = file.lastModified / 1000;
+ this.data.headers['X-OC-Mtime'] = (file.lastModified / 1000).toFixed(0);
}
var userName = this.uploader.filesClient.getUserName();
diff --git a/apps/files/l10n/tr.js b/apps/files/l10n/tr.js
index e46a11abb6c..71250b967e1 100644
--- a/apps/files/l10n/tr.js
+++ b/apps/files/l10n/tr.js
@@ -85,6 +85,7 @@ OC.L10N.register(
"{user} created {file}" : "{user} tarafından {file} oluşturuldu",
"You changed {file}" : "Siz {file} dosyasını değiştirdiniz",
"You deleted {file}" : "Siz {file} dosyasını sildiniz",
+ "{user} deleted {file}" : "{user} tarafından {file} silindi",
"A new file or folder has been <strong>created</strong>" : "Yeni bir dosya veya klasör <strong>oluşturuldu</strong>",
"Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>" : "<strong>Sık kullanılan dosyalarınızın</strong> oluşturulma ve değiştirilme hakkındaki bildirimlerini sınırla <em>(Sadece akışta)</em>",
"Upload (max. %s)" : "Yükle (azami: %s)",
diff --git a/apps/files/l10n/tr.json b/apps/files/l10n/tr.json
index d5b70fa9b58..beaa034e6bc 100644
--- a/apps/files/l10n/tr.json
+++ b/apps/files/l10n/tr.json
@@ -83,6 +83,7 @@
"{user} created {file}" : "{user} tarafından {file} oluşturuldu",
"You changed {file}" : "Siz {file} dosyasını değiştirdiniz",
"You deleted {file}" : "Siz {file} dosyasını sildiniz",
+ "{user} deleted {file}" : "{user} tarafından {file} silindi",
"A new file or folder has been <strong>created</strong>" : "Yeni bir dosya veya klasör <strong>oluşturuldu</strong>",
"Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>" : "<strong>Sık kullanılan dosyalarınızın</strong> oluşturulma ve değiştirilme hakkındaki bildirimlerini sınırla <em>(Sadece akışta)</em>",
"Upload (max. %s)" : "Yükle (azami: %s)",
diff --git a/apps/files_sharing/tests/TestCase.php b/apps/files_sharing/tests/TestCase.php
index a9163a086bf..3b1ccb71a94 100644
--- a/apps/files_sharing/tests/TestCase.php
+++ b/apps/files_sharing/tests/TestCase.php
@@ -75,7 +75,7 @@ abstract class TestCase extends \Test\TestCase {
// reset backend
\OC_User::clearBackends();
- \OC_Group::clearBackends();
+ \OC::$server->getGroupManager()->clearBackends();
// clear share hooks
\OC_Hook::clear('OCP\\Share');
@@ -103,7 +103,7 @@ abstract class TestCase extends \Test\TestCase {
$groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER3, 'group2');
$groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER4, 'group3');
$groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_GROUP1);
- \OC_Group::useBackend($groupBackend);
+ \OC::$server->getGroupManager()->addBackend($groupBackend);
}
protected function setUp() {
@@ -136,7 +136,10 @@ abstract class TestCase extends \Test\TestCase {
if ($user !== null) { $user->delete(); }
// delete group
- \OC_Group::deleteGroup(self::TEST_FILES_SHARING_API_GROUP1);
+ $group = \OC::$server->getGroupManager()->get(self::TEST_FILES_SHARING_API_GROUP1);
+ if ($group) {
+ $group->delete();
+ }
\OC_Util::tearDownFS();
\OC_User::setUserId('');
@@ -145,8 +148,8 @@ abstract class TestCase extends \Test\TestCase {
// reset backend
\OC_User::clearBackends();
\OC_User::useBackend('database');
- \OC_Group::clearBackends();
- \OC_Group::useBackend(new \OC\Group\Database());
+ \OC::$server->getGroupManager()->clearBackends();
+ \OC::$server->getGroupManager()->addBackend(new \OC\Group\Database());
parent::tearDownAfterClass();
}
@@ -163,9 +166,15 @@ abstract class TestCase extends \Test\TestCase {
}
if ($create) {
- \OC::$server->getUserManager()->createUser($user, $password);
- \OC_Group::createGroup('group');
- \OC_Group::addToGroup($user, 'group');
+ $userManager = \OC::$server->getUserManager();
+ $groupManager = \OC::$server->getGroupManager();
+
+ $userObject = $userManager->createUser($user, $password);
+ $group = $groupManager->createGroup('group');
+
+ if ($group and $userObject) {
+ $group->addUser($userObject);
+ }
}
self::resetStorage();
diff --git a/apps/systemtags/l10n/fr.js b/apps/systemtags/l10n/fr.js
index c8ae9d40962..cb20b2ecbc1 100644
--- a/apps/systemtags/l10n/fr.js
+++ b/apps/systemtags/l10n/fr.js
@@ -6,9 +6,9 @@ OC.L10N.register(
"Create" : "Créer",
"Select tag…" : "Sélectionner une étiquette…",
"Tagged files" : "Fichiers étiquetés",
- "Select tags to filter by" : "Sélectionner les étiquettes par lesquelles filtrer",
+ "Select tags to filter by" : "Sélectionner les étiquettes à filtrer",
"No tags found" : "Aucune étiquette trouvée",
- "Please select tags to filter by" : "Veuillez sélectionner les étiquettes par lesquelles filtrer",
+ "Please select tags to filter by" : "Veuillez sélectionner les étiquettes à filtrer",
"No files found for the selected tags" : "Aucun fichier pour les étiquettes sélectionnées",
"Added system tag %1$s" : "Étiquette collaborative %1$s ajoutée",
"Added system tag {systemtag}" : "Étiquette collaborative {systemtag} ajoutée",
diff --git a/apps/systemtags/l10n/fr.json b/apps/systemtags/l10n/fr.json
index 6bf4ef57225..8d7ffb1ae30 100644
--- a/apps/systemtags/l10n/fr.json
+++ b/apps/systemtags/l10n/fr.json
@@ -4,9 +4,9 @@
"Create" : "Créer",
"Select tag…" : "Sélectionner une étiquette…",
"Tagged files" : "Fichiers étiquetés",
- "Select tags to filter by" : "Sélectionner les étiquettes par lesquelles filtrer",
+ "Select tags to filter by" : "Sélectionner les étiquettes à filtrer",
"No tags found" : "Aucune étiquette trouvée",
- "Please select tags to filter by" : "Veuillez sélectionner les étiquettes par lesquelles filtrer",
+ "Please select tags to filter by" : "Veuillez sélectionner les étiquettes à filtrer",
"No files found for the selected tags" : "Aucun fichier pour les étiquettes sélectionnées",
"Added system tag %1$s" : "Étiquette collaborative %1$s ajoutée",
"Added system tag {systemtag}" : "Étiquette collaborative {systemtag} ajoutée",
diff --git a/apps/theming/l10n/hu.js b/apps/theming/l10n/hu.js
new file mode 100644
index 00000000000..a0549dfd06b
--- /dev/null
+++ b/apps/theming/l10n/hu.js
@@ -0,0 +1,27 @@
+OC.L10N.register(
+ "theming",
+ {
+ "Admin" : "Adminisztrátor",
+ "a safe home for all your data" : "biztonságos hely az adataid számára",
+ "The given name is too long" : "A bevitt név túl hosszú",
+ "The given web address is too long" : "A bevitt webcím túl hosszú",
+ "The given slogan is too long" : "A bevitt szlogen túl hosszú",
+ "The given color is invalid" : "A bevitt szín érvénytelen",
+ "Saved" : "Mentve!",
+ "No file uploaded" : "Nincs fájl feltöltve",
+ "Unsupported image type" : "Nem támogatott képtípus",
+ "You are already using a custom theme" : "Már egyedi témát használ",
+ "Theming" : "Témázás",
+ "Name" : "Név",
+ "reset to default" : "Visszaállítás alapértelmezettre",
+ "Web address" : "Webcím",
+ "Web address https://…" : "Webcím https://...",
+ "Slogan" : "Szlogen",
+ "Color" : "Szín",
+ "Logo" : "Logó",
+ "Upload new logo" : "Új logó feltöltése",
+ "Login image" : "Bejelentkező kép",
+ "Upload new login background" : "Új bejelentkező kép feltöltése",
+ "Log in image" : "Bejelentkező kép"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/theming/l10n/hu.json b/apps/theming/l10n/hu.json
new file mode 100644
index 00000000000..6023637c81d
--- /dev/null
+++ b/apps/theming/l10n/hu.json
@@ -0,0 +1,25 @@
+{ "translations": {
+ "Admin" : "Adminisztrátor",
+ "a safe home for all your data" : "biztonságos hely az adataid számára",
+ "The given name is too long" : "A bevitt név túl hosszú",
+ "The given web address is too long" : "A bevitt webcím túl hosszú",
+ "The given slogan is too long" : "A bevitt szlogen túl hosszú",
+ "The given color is invalid" : "A bevitt szín érvénytelen",
+ "Saved" : "Mentve!",
+ "No file uploaded" : "Nincs fájl feltöltve",
+ "Unsupported image type" : "Nem támogatott képtípus",
+ "You are already using a custom theme" : "Már egyedi témát használ",
+ "Theming" : "Témázás",
+ "Name" : "Név",
+ "reset to default" : "Visszaállítás alapértelmezettre",
+ "Web address" : "Webcím",
+ "Web address https://…" : "Webcím https://...",
+ "Slogan" : "Szlogen",
+ "Color" : "Szín",
+ "Logo" : "Logó",
+ "Upload new logo" : "Új logó feltöltése",
+ "Login image" : "Bejelentkező kép",
+ "Upload new login background" : "Új bejelentkező kép feltöltése",
+ "Log in image" : "Bejelentkező kép"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/twofactor_backupcodes/l10n/tr.js b/apps/twofactor_backupcodes/l10n/tr.js
index a5c93acebfd..ff68c827c78 100644
--- a/apps/twofactor_backupcodes/l10n/tr.js
+++ b/apps/twofactor_backupcodes/l10n/tr.js
@@ -10,9 +10,12 @@ OC.L10N.register(
"If you regenerate backup codes, you automatically invalidate old codes." : "Yedek kodlarını yeniden oluşturursanız, eski kodlar geçersiz olur.",
"An error occurred while generating your backup codes" : "Yedek kodlar oluşturulurken bir sorun çıktı",
"Nextcloud backup codes" : "Nextcloud yedek kodları",
- "Two-factor authentication" : "Iki faktörlü kimlik doğrulama",
- "Backup code" : "Yedek kodu",
- "Use backup code" : "Yedek kodunu kullan",
+ "Two-factor authentication" : "Iki aşamalı kimlik doğrulama",
+ "You successfully logged in using two-factor authentication (%1$s)" : "İki aşamalı kimlik doğrulama ile oturum açtınız (%1$s)",
+ "A login attempt using two-factor authentication failed (%1$s)" : "İki aşamalı kimlik doğrulama ile oturum açma girişimi reddedildi (%1$s)",
+ "You created two-factor backup codes for your account" : "İki aşamalı kimlik doğrulama için yedek kodlarınızı oluşturdunuz",
+ "Backup code" : "Yedek kod",
+ "Use backup code" : "Yedek kodu kullan",
"Second-factor backup codes" : "İki aşamalı yedek kodları"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/twofactor_backupcodes/l10n/tr.json b/apps/twofactor_backupcodes/l10n/tr.json
index 44c86cd60cc..fb392c867ff 100644
--- a/apps/twofactor_backupcodes/l10n/tr.json
+++ b/apps/twofactor_backupcodes/l10n/tr.json
@@ -8,9 +8,12 @@
"If you regenerate backup codes, you automatically invalidate old codes." : "Yedek kodlarını yeniden oluşturursanız, eski kodlar geçersiz olur.",
"An error occurred while generating your backup codes" : "Yedek kodlar oluşturulurken bir sorun çıktı",
"Nextcloud backup codes" : "Nextcloud yedek kodları",
- "Two-factor authentication" : "Iki faktörlü kimlik doğrulama",
- "Backup code" : "Yedek kodu",
- "Use backup code" : "Yedek kodunu kullan",
+ "Two-factor authentication" : "Iki aşamalı kimlik doğrulama",
+ "You successfully logged in using two-factor authentication (%1$s)" : "İki aşamalı kimlik doğrulama ile oturum açtınız (%1$s)",
+ "A login attempt using two-factor authentication failed (%1$s)" : "İki aşamalı kimlik doğrulama ile oturum açma girişimi reddedildi (%1$s)",
+ "You created two-factor backup codes for your account" : "İki aşamalı kimlik doğrulama için yedek kodlarınızı oluşturdunuz",
+ "Backup code" : "Yedek kod",
+ "Use backup code" : "Yedek kodu kullan",
"Second-factor backup codes" : "İki aşamalı yedek kodları"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/updatenotification/l10n/bg.js b/apps/updatenotification/l10n/bg.js
new file mode 100644
index 00000000000..784b2bb2f36
--- /dev/null
+++ b/apps/updatenotification/l10n/bg.js
@@ -0,0 +1,24 @@
+OC.L10N.register(
+ "updatenotification",
+ {
+ "Update notifications" : "Известия за обновления",
+ "Could not start updater, please try the manual update" : "Актуализиращата програма не беше стартирана. Моля, опитайте ръчно обновление",
+ "{version} is available. Get more information on how to update." : "{version} е налична. Намерете повече информация за това как да актуализирате.",
+ "Channel updated" : "Канала е променен",
+ "Update to %1$s is available." : "Обновление към %1$s е налично.",
+ "Update for %1$s to version %2$s is available." : "Обновление за %1$s към версия %2$s е налично.",
+ "Update for {app} to version %s is available." : "Обновление за {app} до версия %s е налично.",
+ "A new version is available: %s" : "Налична е нова версия: %s",
+ "Open updater" : "Отвори актуализиращата програма",
+ "Download now" : "Изтегляне сега",
+ "Your version is up to date." : "Вие разполагате с последна версия",
+ "Checked on %s" : "Проверено за %s",
+ "Update channel:" : "Канал за обновяване:",
+ "You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel." : "Винаги може да оновите до по-нова версия / експирементален канал. Но неможете вече да върнете до по-стабилен канал..",
+ "Notify members of the following groups about available updates:" : "Известие до потребители от следните групи относно налични обновления:",
+ "Only notification for app updates are available." : "Налични са само уведомления за актуализации на приложенията.",
+ "The selected update channel makes dedicated notifications for the server obsolete." : "Избрания канал за обновления прави уведомленията за този сървър остарели.",
+ "The selected update channel does not support updates of the server." : "Избрания канал за обновления не поддържа сървърни актуализации.",
+ "You are running PHP %s. To allow you to upgrade to Nextcloud 11 and higher you need to run at least PHP 5.6. Once you upgraded your PHP version you will be able to receive update notifications for these newer versions." : "Вие използвате PHP %s. Актуализиране към Nextcloud 11 и по-висока версия изисква като минимум PHP 5.6. Само след като обновите версията на PHP ще бъдете в състояние да получавате известия за актуализации за тези нови версии."
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/updatenotification/l10n/bg.json b/apps/updatenotification/l10n/bg.json
new file mode 100644
index 00000000000..912ee8460b4
--- /dev/null
+++ b/apps/updatenotification/l10n/bg.json
@@ -0,0 +1,22 @@
+{ "translations": {
+ "Update notifications" : "Известия за обновления",
+ "Could not start updater, please try the manual update" : "Актуализиращата програма не беше стартирана. Моля, опитайте ръчно обновление",
+ "{version} is available. Get more information on how to update." : "{version} е налична. Намерете повече информация за това как да актуализирате.",
+ "Channel updated" : "Канала е променен",
+ "Update to %1$s is available." : "Обновление към %1$s е налично.",
+ "Update for %1$s to version %2$s is available." : "Обновление за %1$s към версия %2$s е налично.",
+ "Update for {app} to version %s is available." : "Обновление за {app} до версия %s е налично.",
+ "A new version is available: %s" : "Налична е нова версия: %s",
+ "Open updater" : "Отвори актуализиращата програма",
+ "Download now" : "Изтегляне сега",
+ "Your version is up to date." : "Вие разполагате с последна версия",
+ "Checked on %s" : "Проверено за %s",
+ "Update channel:" : "Канал за обновяване:",
+ "You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel." : "Винаги може да оновите до по-нова версия / експирементален канал. Но неможете вече да върнете до по-стабилен канал..",
+ "Notify members of the following groups about available updates:" : "Известие до потребители от следните групи относно налични обновления:",
+ "Only notification for app updates are available." : "Налични са само уведомления за актуализации на приложенията.",
+ "The selected update channel makes dedicated notifications for the server obsolete." : "Избрания канал за обновления прави уведомленията за този сървър остарели.",
+ "The selected update channel does not support updates of the server." : "Избрания канал за обновления не поддържа сървърни актуализации.",
+ "You are running PHP %s. To allow you to upgrade to Nextcloud 11 and higher you need to run at least PHP 5.6. Once you upgraded your PHP version you will be able to receive update notifications for these newer versions." : "Вие използвате PHP %s. Актуализиране към Nextcloud 11 и по-висока версия изисква като минимум PHP 5.6. Само след като обновите версията на PHP ще бъдете в състояние да получавате известия за актуализации за тези нови версии."
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/updatenotification/l10n/tr.js b/apps/updatenotification/l10n/tr.js
index b5160c7b6b3..21e5fde7504 100644
--- a/apps/updatenotification/l10n/tr.js
+++ b/apps/updatenotification/l10n/tr.js
@@ -18,6 +18,7 @@ OC.L10N.register(
"Notify members of the following groups about available updates:" : "Yayınlanan güncellemeler şu grupların üyelerine bildirilsin:",
"Only notification for app updates are available." : "Yalnız uygulama güncellemeleri kullanılabilir.",
"The selected update channel makes dedicated notifications for the server obsolete." : "Seçilmiş güncelleme kanalı kullanımdan kalkmış sunucu bildirimleri için kullanılıyor.",
- "The selected update channel does not support updates of the server." : "Seçilmiş güncelleme kanalı sunucunun güncellemelerini desteklemiyor."
+ "The selected update channel does not support updates of the server." : "Seçilmiş güncelleme kanalı sunucunun güncellemelerini desteklemiyor.",
+ "You are running PHP %s. To allow you to upgrade to Nextcloud 11 and higher you need to run at least PHP 5.6. Once you upgraded your PHP version you will be able to receive update notifications for these newer versions." : "PHP %s sürümünü kullanıyorsanız. Nextcloud 11 ve üzerindeki sürümleri kullanabilmek için PHP sürümünüz en az 5.6 olmalıdır. PHP sürümünüzü yükselttikten sonra yeni sürümler ile ilgili güncelleme bildirimlerini görebilirsiniz."
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/updatenotification/l10n/tr.json b/apps/updatenotification/l10n/tr.json
index 7eba40df793..d5536cf6da2 100644
--- a/apps/updatenotification/l10n/tr.json
+++ b/apps/updatenotification/l10n/tr.json
@@ -16,6 +16,7 @@
"Notify members of the following groups about available updates:" : "Yayınlanan güncellemeler şu grupların üyelerine bildirilsin:",
"Only notification for app updates are available." : "Yalnız uygulama güncellemeleri kullanılabilir.",
"The selected update channel makes dedicated notifications for the server obsolete." : "Seçilmiş güncelleme kanalı kullanımdan kalkmış sunucu bildirimleri için kullanılıyor.",
- "The selected update channel does not support updates of the server." : "Seçilmiş güncelleme kanalı sunucunun güncellemelerini desteklemiyor."
+ "The selected update channel does not support updates of the server." : "Seçilmiş güncelleme kanalı sunucunun güncellemelerini desteklemiyor.",
+ "You are running PHP %s. To allow you to upgrade to Nextcloud 11 and higher you need to run at least PHP 5.6. Once you upgraded your PHP version you will be able to receive update notifications for these newer versions." : "PHP %s sürümünü kullanıyorsanız. Nextcloud 11 ve üzerindeki sürümleri kullanabilmek için PHP sürümünüz en az 5.6 olmalıdır. PHP sürümünüzü yükselttikten sonra yeni sürümler ile ilgili güncelleme bildirimlerini görebilirsiniz."
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 995b1226649..6f930ea39f0 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -58,7 +58,7 @@ if(count($configPrefixes) === 1) {
if(count($configPrefixes) > 0) {
// register user backend
OC_User::useBackend($userBackend);
- OC_Group::useBackend($groupBackend);
+ \OC::$server->getGroupManager()->addBackend($groupBackend);
}
\OCP\Util::connectHook(
diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php
index cc0446ae523..ff95d96ebdb 100644
--- a/apps/user_ldap/lib/Access.php
+++ b/apps/user_ldap/lib/Access.php
@@ -570,7 +570,7 @@ class Access extends LDAPUtility implements IUserTools {
$originalTTL = $this->connection->ldapCacheTTL;
$this->connection->setConfiguration(array('ldapCacheTTL' => 0));
if(($isUser && !\OCP\User::userExists($intName))
- || (!$isUser && !\OC_Group::groupExists($intName))) {
+ || (!$isUser && !\OC::$server->getGroupManager()->groupExists($intName))) {
if($mapper->map($fdn, $intName, $uuid)) {
$this->connection->setConfiguration(array('ldapCacheTTL' => $originalTTL));
return $intName;
@@ -737,7 +737,7 @@ class Access extends LDAPUtility implements IUserTools {
// Check to be really sure it is unique
// while loop is just a precaution. If a name is not generated within
// 20 attempts, something else is very wrong. Avoids infinite loop.
- if(!\OC_Group::groupExists($altName)) {
+ if(!\OC::$server->getGroupManager()->groupExists($altName)) {
return $altName;
}
$altName = $name . '_' . ($lastNo + $attempts);
diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php
index 606eff4e7a7..f1a23f9a6c8 100644
--- a/apps/user_ldap/tests/User_LDAPTest.php
+++ b/apps/user_ldap/tests/User_LDAPTest.php
@@ -64,7 +64,7 @@ class User_LDAPTest extends TestCase {
parent::setUp();
\OC_User::clearBackends();
- \OC_Group::clearBackends();
+ \OC::$server->getGroupManager()->clearBackends();
}
/**
diff --git a/apps/workflowengine/l10n/bg.js b/apps/workflowengine/l10n/bg.js
index ec24d4f01ae..abd148bd827 100644
--- a/apps/workflowengine/l10n/bg.js
+++ b/apps/workflowengine/l10n/bg.js
@@ -13,6 +13,7 @@ OC.L10N.register(
"less" : "по-малко",
"less or equals" : "по-малко или равно",
"greater or equals" : "по-голямо или равно",
+ "greater" : "по-голям",
"File system tag" : "Таг на файлова система",
"is tagged with" : "е тагнат с",
"is not tagged with" : "не е тагнат с",
diff --git a/apps/workflowengine/l10n/bg.json b/apps/workflowengine/l10n/bg.json
index 492410c9bf4..155250ecb34 100644
--- a/apps/workflowengine/l10n/bg.json
+++ b/apps/workflowengine/l10n/bg.json
@@ -11,6 +11,7 @@
"less" : "по-малко",
"less or equals" : "по-малко или равно",
"greater or equals" : "по-голямо или равно",
+ "greater" : "по-голям",
"File system tag" : "Таг на файлова система",
"is tagged with" : "е тагнат с",
"is not tagged with" : "не е тагнат с",
diff --git a/apps/workflowengine/l10n/tr.js b/apps/workflowengine/l10n/tr.js
new file mode 100644
index 00000000000..d07c5471fe7
--- /dev/null
+++ b/apps/workflowengine/l10n/tr.js
@@ -0,0 +1,71 @@
+OC.L10N.register(
+ "workflowengine",
+ {
+ "Successfully saved" : "Kaydedildi",
+ "Saving failed:" : "Kaydedilemedi:",
+ "File mime type" : "Dosya MIME türü",
+ "is" : "şu olan",
+ "is not" : "şu olmayan",
+ "matches" : "şuna uyan",
+ "does not match" : "şuna uymayan",
+ "Example: {placeholder}" : "Örnek: {placeholder}",
+ "File size (upload)" : "Dosya boyutu (yükleme)",
+ "less" : "şundan küçük",
+ "less or equals" : "şundan küçük ya da eşit",
+ "greater or equals" : "şundan büyük ya da eşit",
+ "greater" : "şundan büyük",
+ "File system tag" : "Dosya sistemi etiketi",
+ "is tagged with" : "şununla etiketlenmiş",
+ "is not tagged with" : "şununla etiketlenmemiş",
+ "Select tag…" : "Etiketi seçin...",
+ "Request remote address" : "Uzak adres isteği",
+ "matches IPv4" : "şu IPv4 adresine uyan",
+ "does not match IPv4" : "şu IPv4 adresine uymayan",
+ "matches IPv6" : "şu IPv6 adresine uyan",
+ "does not match IPv6" : "şu IPv6 adresine uymayan",
+ "Request time" : "İstek zamanı",
+ "between" : "şunların arasında olan",
+ "not between" : "şunların arasında olmayan",
+ "Start" : "Başlangıç",
+ "End" : "Bitiş",
+ "Select timezone…" : "Saat dilimini seçin...",
+ "Request URL" : "İstek Adresi",
+ "Predefined URLs" : "Hazır Adresler",
+ "Files WebDAV" : "Dosya WebDAV",
+ "Request user agent" : "Kullanıcı yazılımı istensin",
+ "Sync clients" : "İstemciler eşitlensin",
+ "Android client" : "Android istemcisi",
+ "iOS client" : "iOS istemcisi",
+ "Desktop client" : "Masaüstü istemcisi",
+ "User group membership" : "Kullanıcı grubu üyeliği",
+ "is member of" : "şunun üyesi olan",
+ "is not member of" : "şunun üyesi olmayan",
+ "The given operator is invalid" : "Belirtilen işlem geçersiz",
+ "The given regular expression is invalid" : "Belirtilen kurallı ifade geçersiz",
+ "The given file size is invalid" : "Belirtilen dosya boyutu geçersiz",
+ "The given tag id is invalid" : "Belirtilen etiket kodu geçersiz",
+ "The given IP range is invalid" : "Belirtilen IP adresi aralığı geçersiz",
+ "The given IP range is not valid for IPv4" : "Belirtilen IP adresi aralığı IPv4 için geçersiz",
+ "The given IP range is not valid for IPv6" : "Belirtilen IP adresi aralığı IPv6 için geçersiz",
+ "The given time span is invalid" : "Belirtilen zaman aralığı geçersiz",
+ "The given start time is invalid" : "Belirtilen başlangıç zamanı geçersiz",
+ "The given end time is invalid" : "Belirtilen bitiş zamanı geçersiz",
+ "The given group does not exist" : "Belirtilen grup bulunamadı",
+ "Check %s is invalid or does not exist" : "%s denetimi geçersiz ya da bulunamadı",
+ "Operation #%s does not exist" : "#%s işlemi bulunamadı",
+ "Operation %s does not exist" : "%s işlemi bulunamadı",
+ "Operation %s is invalid" : "%s işlemi geçersiz",
+ "Check %s does not exist" : "%s denetimi bulunamadı",
+ "Check %s is invalid" : "%s denetimi geçersiz",
+ "Check #%s does not exist" : "#%s denetimi bulunamadı",
+ "Workflow" : "İş akışı",
+ "Open documentation" : "Belgeleri aç",
+ "Add rule group" : "Kural grubu ekle",
+ "Short rule description" : "Kısa kural açıklaması",
+ "Add rule" : "Kural ekle",
+ "Reset" : "Sıfırla",
+ "Save" : "Kaydet",
+ "Saving…" : "Kaydediliyor...",
+ "Loading…" : "Yükleniyor..."
+},
+"nplurals=2; plural=(n > 1);");
diff --git a/apps/workflowengine/l10n/tr.json b/apps/workflowengine/l10n/tr.json
new file mode 100644
index 00000000000..8996dffcb95
--- /dev/null
+++ b/apps/workflowengine/l10n/tr.json
@@ -0,0 +1,69 @@
+{ "translations": {
+ "Successfully saved" : "Kaydedildi",
+ "Saving failed:" : "Kaydedilemedi:",
+ "File mime type" : "Dosya MIME türü",
+ "is" : "şu olan",
+ "is not" : "şu olmayan",
+ "matches" : "şuna uyan",
+ "does not match" : "şuna uymayan",
+ "Example: {placeholder}" : "Örnek: {placeholder}",
+ "File size (upload)" : "Dosya boyutu (yükleme)",
+ "less" : "şundan küçük",
+ "less or equals" : "şundan küçük ya da eşit",
+ "greater or equals" : "şundan büyük ya da eşit",
+ "greater" : "şundan büyük",
+ "File system tag" : "Dosya sistemi etiketi",
+ "is tagged with" : "şununla etiketlenmiş",
+ "is not tagged with" : "şununla etiketlenmemiş",
+ "Select tag…" : "Etiketi seçin...",
+ "Request remote address" : "Uzak adres isteği",
+ "matches IPv4" : "şu IPv4 adresine uyan",
+ "does not match IPv4" : "şu IPv4 adresine uymayan",
+ "matches IPv6" : "şu IPv6 adresine uyan",
+ "does not match IPv6" : "şu IPv6 adresine uymayan",
+ "Request time" : "İstek zamanı",
+ "between" : "şunların arasında olan",
+ "not between" : "şunların arasında olmayan",
+ "Start" : "Başlangıç",
+ "End" : "Bitiş",
+ "Select timezone…" : "Saat dilimini seçin...",
+ "Request URL" : "İstek Adresi",
+ "Predefined URLs" : "Hazır Adresler",
+ "Files WebDAV" : "Dosya WebDAV",
+ "Request user agent" : "Kullanıcı yazılımı istensin",
+ "Sync clients" : "İstemciler eşitlensin",
+ "Android client" : "Android istemcisi",
+ "iOS client" : "iOS istemcisi",
+ "Desktop client" : "Masaüstü istemcisi",
+ "User group membership" : "Kullanıcı grubu üyeliği",
+ "is member of" : "şunun üyesi olan",
+ "is not member of" : "şunun üyesi olmayan",
+ "The given operator is invalid" : "Belirtilen işlem geçersiz",
+ "The given regular expression is invalid" : "Belirtilen kurallı ifade geçersiz",
+ "The given file size is invalid" : "Belirtilen dosya boyutu geçersiz",
+ "The given tag id is invalid" : "Belirtilen etiket kodu geçersiz",
+ "The given IP range is invalid" : "Belirtilen IP adresi aralığı geçersiz",
+ "The given IP range is not valid for IPv4" : "Belirtilen IP adresi aralığı IPv4 için geçersiz",
+ "The given IP range is not valid for IPv6" : "Belirtilen IP adresi aralığı IPv6 için geçersiz",
+ "The given time span is invalid" : "Belirtilen zaman aralığı geçersiz",
+ "The given start time is invalid" : "Belirtilen başlangıç zamanı geçersiz",
+ "The given end time is invalid" : "Belirtilen bitiş zamanı geçersiz",
+ "The given group does not exist" : "Belirtilen grup bulunamadı",
+ "Check %s is invalid or does not exist" : "%s denetimi geçersiz ya da bulunamadı",
+ "Operation #%s does not exist" : "#%s işlemi bulunamadı",
+ "Operation %s does not exist" : "%s işlemi bulunamadı",
+ "Operation %s is invalid" : "%s işlemi geçersiz",
+ "Check %s does not exist" : "%s denetimi bulunamadı",
+ "Check %s is invalid" : "%s denetimi geçersiz",
+ "Check #%s does not exist" : "#%s denetimi bulunamadı",
+ "Workflow" : "İş akışı",
+ "Open documentation" : "Belgeleri aç",
+ "Add rule group" : "Kural grubu ekle",
+ "Short rule description" : "Kısa kural açıklaması",
+ "Add rule" : "Kural ekle",
+ "Reset" : "Sıfırla",
+ "Save" : "Kaydet",
+ "Saving…" : "Kaydediliyor...",
+ "Loading…" : "Yükleniyor..."
+},"pluralForm" :"nplurals=2; plural=(n > 1);"
+} \ No newline at end of file
diff --git a/apps/workflowengine/lib/AppInfo/Application.php b/apps/workflowengine/lib/AppInfo/Application.php
index e968b40612f..28e32092419 100644
--- a/apps/workflowengine/lib/AppInfo/Application.php
+++ b/apps/workflowengine/lib/AppInfo/Application.php
@@ -48,6 +48,8 @@ class Application extends \OCP\AppFramework\App {
]);
script('core', [
+ 'files/fileinfo',
+ 'files/client',
'oc-backbone-webdav',
'systemtags/systemtags',
'systemtags/systemtagmodel',
diff --git a/apps/workflowengine/lib/Check/FileMimeType.php b/apps/workflowengine/lib/Check/FileMimeType.php
index 4a985840e60..8608fffd4e2 100644
--- a/apps/workflowengine/lib/Check/FileMimeType.php
+++ b/apps/workflowengine/lib/Check/FileMimeType.php
@@ -76,13 +76,22 @@ class FileMimeType extends AbstractStringCheck {
return $this->mimeType[$this->storage->getId()][$this->path];
}
- $this->mimeType[$this->storage->getId()][$this->path] = '';
if ($this->isWebDAVRequest()) {
if ($this->request->getMethod() === 'PUT') {
$path = $this->request->getPathInfo();
$this->mimeType[$this->storage->getId()][$this->path] = $this->mimeTypeDetector->detectPath($path);
return $this->mimeType[$this->storage->getId()][$this->path];
}
+ } else if ($this->isPublicWebDAVRequest()) {
+ if ($this->request->getMethod() === 'PUT') {
+ $path = $this->request->getPathInfo();
+ if (strpos($path, '/webdav/') === 0) {
+ $path = substr($path, strlen('/webdav'));
+ }
+ $path = $this->path . $path;
+ $this->mimeType[$this->storage->getId()][$path] = $this->mimeTypeDetector->detectPath($path);
+ return $this->mimeType[$this->storage->getId()][$path];
+ }
}
if (in_array($this->request->getMethod(), ['POST', 'PUT'])) {
@@ -159,4 +168,14 @@ class FileMimeType extends AbstractStringCheck {
strpos($this->request->getPathInfo(), '/dav/files/') === 0
);
}
+
+ /**
+ * @return bool
+ */
+ protected function isPublicWebDAVRequest() {
+ return substr($this->request->getScriptName(), 0 - strlen('/public.php')) === '/public.php' && (
+ $this->request->getPathInfo() === '/webdav' ||
+ strpos($this->request->getPathInfo(), '/webdav/') === 0
+ );
+ }
}
diff --git a/core/css/fixes.css b/core/css/fixes.scss
index 3cb89c6599f..3cb89c6599f 100644
--- a/core/css/fixes.css
+++ b/core/css/fixes.scss
diff --git a/core/css/fonts.css b/core/css/fonts.scss
index f72aa2930cf..f72aa2930cf 100644
--- a/core/css/fonts.css
+++ b/core/css/fonts.scss
diff --git a/core/css/global.css b/core/css/global.scss
index 9511d4324fa..9511d4324fa 100644
--- a/core/css/global.css
+++ b/core/css/global.scss
diff --git a/core/css/mobile.css b/core/css/mobile.scss
index b0f8421345c..b0f8421345c 100644
--- a/core/css/mobile.css
+++ b/core/css/mobile.scss
diff --git a/core/css/server.scss b/core/css/server.scss
new file mode 100644
index 00000000000..516220f2ad5
--- /dev/null
+++ b/core/css/server.scss
@@ -0,0 +1,11 @@
+@import 'styles.scss';
+@import 'inputs.scss';
+@import 'header.scss';
+@import 'icons.scss';
+@import 'fonts.scss';
+@import 'apps.scss';
+@import 'global.scss';
+@import 'fixes.scss';
+@import 'multiselect.scss';
+@import 'mobile.scss';
+@import 'tooltip.scss';
diff --git a/core/l10n/fr.js b/core/l10n/fr.js
index 208d94ae526..f08ec70c1e1 100644
--- a/core/l10n/fr.js
+++ b/core/l10n/fr.js
@@ -189,7 +189,7 @@ OC.L10N.register(
"The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "La mise à jour a échoué. Pour plus d'informations <a href=\"{url}\">consultez notre publication sur le forum</a> à propos de ce problème.",
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud community</a>." : "La mise à jour a échoué. Veuillez reporter le problème à la <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">communauté Nextcloud</a>.",
"Continue to Nextcloud" : "Continuer sur Nextcloud",
- "The update was successful. Redirecting you to Nextcloud now." : "La mise à jour a réussi. Vous allez être redirigé vers votre Nextcloud.",
+ "The update was successful. Redirecting you to Nextcloud now." : "La mise à jour est terminée. Vous allez être redirigé vers Nextcloud.",
"Searching other places" : "Recherche en cours dans d'autres emplacements",
"No search results in other folders for '{tag}{filter}{endtag}'" : "Aucun résultat dans d'autres dossiers n'a été trouvé pour '{tag}{filter}{endtag}'",
"_{count} search result in another folder_::_{count} search results in other folders_" : ["{count} résultat dans un autre dossier","{count} résultats dans d'autres dossiers"],
diff --git a/core/l10n/fr.json b/core/l10n/fr.json
index 5ff2c07e5d6..5bd78462c08 100644
--- a/core/l10n/fr.json
+++ b/core/l10n/fr.json
@@ -187,7 +187,7 @@
"The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "La mise à jour a échoué. Pour plus d'informations <a href=\"{url}\">consultez notre publication sur le forum</a> à propos de ce problème.",
"The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud community</a>." : "La mise à jour a échoué. Veuillez reporter le problème à la <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">communauté Nextcloud</a>.",
"Continue to Nextcloud" : "Continuer sur Nextcloud",
- "The update was successful. Redirecting you to Nextcloud now." : "La mise à jour a réussi. Vous allez être redirigé vers votre Nextcloud.",
+ "The update was successful. Redirecting you to Nextcloud now." : "La mise à jour est terminée. Vous allez être redirigé vers Nextcloud.",
"Searching other places" : "Recherche en cours dans d'autres emplacements",
"No search results in other folders for '{tag}{filter}{endtag}'" : "Aucun résultat dans d'autres dossiers n'a été trouvé pour '{tag}{filter}{endtag}'",
"_{count} search result in another folder_::_{count} search results in other folders_" : ["{count} résultat dans un autre dossier","{count} résultats dans d'autres dossiers"],
diff --git a/core/l10n/id.js b/core/l10n/id.js
index e80b0a11552..f7328371df1 100644
--- a/core/l10n/id.js
+++ b/core/l10n/id.js
@@ -96,6 +96,7 @@ OC.L10N.register(
"The reverse proxy headers configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If you are not accessing Nextcloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to Nextcloud. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Konfigurasi proxy header terbalik salah, atau Anda mengakses Nextcloud dari proxy terpercaya. Apabila Anda tidak mengakses Nextcloud dari proxy terpercaya, ini adalah masalah keamanan dan penyerang dapat memalsukan alamat IP mereka ke Nextcloud. Informasi selanjutnya bisa ditemukan di <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentasi</a> kami.",
"Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "Memcached terkonfigurasi sebagai cache terdistribusi, tetapi modul PHP \"memcache\" yang salah terpasang. \\OC\\Memcache\\Memcached hanya mendukung \"memcached\" dan bukan \"memcache\". Lihat <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">wiki memcached tentang kedua modul</a>.",
"Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Beberapa berkas tidak lulus cek integritas. Informasi lebih lanjut tentang cara mengatasi masalah ini dapat ditemukan di <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentasi</a> kami. (<a href=\"{codeIntegrityDownloadEndpoint}\">Daftar berkas yang tidak valid…</a> / <a href=\"{rescanEndpoint}\">Pindai ulang…</a>)",
+ "The PHP Opcache is not properly configured. <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">For better performance we recommend ↗</a> to use following settings in the <code>php.ini</code>:" : "PHP Opcache tidak dikonfigurasi secara baik. <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">Untuk performa lebih baik kami merekomendasikan ↗</a> untuk menggunakan pengaturan berikut di <code>php.ini</code>:",
"Error occurred while checking server setup" : "Kesalahan tidak terduga saat memeriksa setelan server",
"Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Direktori data dan berkas Anda kemungkinan dapat diakses dari Internet. Berkas .htaccess tidak bekerja. Kami sangat menyarankan Anda untuk mengkonfigurasi server web agar direktori data tidak lagi dapat diakses atau pindahkan direktori data Anda di luar root dokumen server web.",
"The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "Header HTTP \"{header}\" tidak dikonfigurasi sama dengan \"{expected}\". Hal ini berpotensi pada resiko keamanan dan privasi. Kami sarankan untuk menyesuaikan pengaturan ini.",
@@ -141,6 +142,8 @@ OC.L10N.register(
"access control" : "kontrol akses",
"Could not unshare" : "Tidak dapat membatalkan pembagian",
"Share details could not be loaded for this item." : "Rincian berbagi tidak dapat dimuat untuk item ini.",
+ "_At least {count} character is needed for autocompletion_::_At least {count} characters are needed for autocompletion_" : ["Sekurangnya {count} karakter dibutuhkan untuk autocompletion"],
+ "This list is maybe truncated - please refine your search term to see more results." : "Daftar ini mungkin terpotong - harap sari kata pencarian anda untuk melihat hasil yang lebih.",
"No users or groups found for {search}" : "Tidak ada pengguna atau grup ditemukan untuk {search}",
"No users found for {search}" : "Tidak ada pengguna ditemukan untuk {search}",
"An error occurred. Please try again" : "Terjadi kesalahan. Silakan coba lagi",
diff --git a/core/l10n/id.json b/core/l10n/id.json
index f8b2f738437..70a5080a806 100644
--- a/core/l10n/id.json
+++ b/core/l10n/id.json
@@ -94,6 +94,7 @@
"The reverse proxy headers configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If you are not accessing Nextcloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to Nextcloud. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Konfigurasi proxy header terbalik salah, atau Anda mengakses Nextcloud dari proxy terpercaya. Apabila Anda tidak mengakses Nextcloud dari proxy terpercaya, ini adalah masalah keamanan dan penyerang dapat memalsukan alamat IP mereka ke Nextcloud. Informasi selanjutnya bisa ditemukan di <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentasi</a> kami.",
"Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "Memcached terkonfigurasi sebagai cache terdistribusi, tetapi modul PHP \"memcache\" yang salah terpasang. \\OC\\Memcache\\Memcached hanya mendukung \"memcached\" dan bukan \"memcache\". Lihat <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">wiki memcached tentang kedua modul</a>.",
"Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Beberapa berkas tidak lulus cek integritas. Informasi lebih lanjut tentang cara mengatasi masalah ini dapat ditemukan di <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentasi</a> kami. (<a href=\"{codeIntegrityDownloadEndpoint}\">Daftar berkas yang tidak valid…</a> / <a href=\"{rescanEndpoint}\">Pindai ulang…</a>)",
+ "The PHP Opcache is not properly configured. <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">For better performance we recommend ↗</a> to use following settings in the <code>php.ini</code>:" : "PHP Opcache tidak dikonfigurasi secara baik. <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">Untuk performa lebih baik kami merekomendasikan ↗</a> untuk menggunakan pengaturan berikut di <code>php.ini</code>:",
"Error occurred while checking server setup" : "Kesalahan tidak terduga saat memeriksa setelan server",
"Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Direktori data dan berkas Anda kemungkinan dapat diakses dari Internet. Berkas .htaccess tidak bekerja. Kami sangat menyarankan Anda untuk mengkonfigurasi server web agar direktori data tidak lagi dapat diakses atau pindahkan direktori data Anda di luar root dokumen server web.",
"The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "Header HTTP \"{header}\" tidak dikonfigurasi sama dengan \"{expected}\". Hal ini berpotensi pada resiko keamanan dan privasi. Kami sarankan untuk menyesuaikan pengaturan ini.",
@@ -139,6 +140,8 @@
"access control" : "kontrol akses",
"Could not unshare" : "Tidak dapat membatalkan pembagian",
"Share details could not be loaded for this item." : "Rincian berbagi tidak dapat dimuat untuk item ini.",
+ "_At least {count} character is needed for autocompletion_::_At least {count} characters are needed for autocompletion_" : ["Sekurangnya {count} karakter dibutuhkan untuk autocompletion"],
+ "This list is maybe truncated - please refine your search term to see more results." : "Daftar ini mungkin terpotong - harap sari kata pencarian anda untuk melihat hasil yang lebih.",
"No users or groups found for {search}" : "Tidak ada pengguna atau grup ditemukan untuk {search}",
"No users found for {search}" : "Tidak ada pengguna ditemukan untuk {search}",
"An error occurred. Please try again" : "Terjadi kesalahan. Silakan coba lagi",
diff --git a/core/l10n/tr.js b/core/l10n/tr.js
index 8e6b02f4239..66a4295d39e 100644
--- a/core/l10n/tr.js
+++ b/core/l10n/tr.js
@@ -3,78 +3,90 @@ OC.L10N.register(
{
"Please select a file." : "Lütfen bir dosya seçin.",
"File is too big" : "Dosya çok büyük",
- "Invalid file provided" : "Geçersiz dosya sağlandı",
- "No image or file provided" : "Resim veya dosya belirtilmedi",
- "Unknown filetype" : "Bilinmeyen dosya türü",
- "Invalid image" : "Geçersiz resim",
- "An error occurred. Please contact your admin." : "Bir hata oluştu. Lütfen yöneticinize başvurun.",
- "No temporary profile picture available, try again" : "Kullanılabilir geçici profil resmi yok, tekrar deneyin",
- "No crop data provided" : "Kesme verisi sağlanmamış",
- "No valid crop data provided" : "Geçerli kırpma verisi sağlanmadı",
- "Crop is not square" : "Kırpma kare değil",
- "Couldn't reset password because the token is invalid" : "Belirteç geçersiz olduğundan parola sıfırlanamadı",
- "Couldn't reset password because the token is expired" : "Jeton zaman aşımına uğradığından parola sıfırlanamadı",
+ "The selected file is not an image." : "Seçilmiş dosya bir görsel dosyası değil.",
+ "The selected file cannot be read." : "Seçilmiş dosya okunamadı.",
+ "Invalid file provided" : "Belirtilen dosya geçersiz",
+ "No image or file provided" : "Bir görsel ya da dosya belirtilmemiş",
+ "Unknown filetype" : "Dosya türü bilinmiyor",
+ "Invalid image" : "Görsel geçersiz",
+ "An error occurred. Please contact your admin." : "Bir sorun çıktı. Lütfen yöneticinizle görüşün.",
+ "No temporary profile picture available, try again" : "Kullanılabilecek geçici bir profil görseli bulunamadı. Yeniden deneyin",
+ "No crop data provided" : "Kırpma verileri belirtilmemiş",
+ "No valid crop data provided" : "Geçerli bir kırpma verisi belirtilmemiş",
+ "Crop is not square" : "Kırpma kare şeklinde değil",
+ "Couldn't reset password because the token is invalid" : "Kod geçersiz olduğundan parola sıfırlanamadı",
+ "Couldn't reset password because the token is expired" : "Kodun süresi geçtiğinden parola sıfırlanamadı",
"Couldn't send reset email. Please make sure your username is correct." : "Sıfırlama e-postası gönderilemedi. Lütfen kullanıcı adınızın doğru olduğundan emin olun.",
- "Could not send reset email because there is no email address for this username. Please contact your administrator." : "Sıfırlama e-postası, bu kullanıcı için bir e-posta adresi olmadığından gönderilemedi. Lütfen yöneticiniz ile iletişime geçin.",
+ "Could not send reset email because there is no email address for this username. Please contact your administrator." : "Bu kullanıcı için bir e-posta adresi olmadığından sıfırlama e-postası gönderilemedi. Lütfen yöneticiniz ile görüşün.",
"%s password reset" : "%s parola sıfırlama",
- "Couldn't send reset email. Please contact your administrator." : "Sıfırlama e-postası gönderilemedi. Lütfen yöneticiniz ile iletişime geçin.",
+ "Couldn't send reset email. Please contact your administrator." : "Sıfırlama e-postası gönderilemedi. Lütfen yöneticiniz ile görüşün.",
"Preparing update" : "Güncelleme hazırlanıyor",
"[%d / %d]: %s" : "[%d / %d]: %s",
"Repair warning: " : "Onarım uyarısı:",
"Repair error: " : "Onarım hatası:",
- "Please use the command line updater because automatic updating is disabled in the config.php." : "Otomatik güncellemeler config.php dosyasından pasif duruma getirildiği için, lütfen komut satırı güncelleyicisini kullanın. Oto",
- "[%d / %d]: Checking table %s" : "[%d / %d]: Tablo kontroi ediliyor %s",
+ "Please use the command line updater because automatic updating is disabled in the config.php." : "Otomatik güncellemeler config.php dosyasında devre dışı bırakılmış olduğundan, komut satırı güncelleyicisini kullanın.",
+ "[%d / %d]: Checking table %s" : "[%d / %d]: %s tablosu denetleniyor",
"Turned on maintenance mode" : "Bakım kipi etkinleştirildi",
- "Turned off maintenance mode" : "Bakım kipi kapatıldı",
+ "Turned off maintenance mode" : "Bakım kipi devre dışı bırakıldı",
"Maintenance mode is kept active" : "Bakım kipi etkin tutuldu",
"Updating database schema" : "Veritabanı şeması güncelleniyor",
"Updated database" : "Veritabanı güncellendi",
- "Checking whether the database schema can be updated (this can take a long time depending on the database size)" : "Veritabanı şeması güncellenebilirliği denetleniyor (Veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
- "Checked database schema update" : "Veritabanı şema güncellemesi denetlendi",
- "Checking updates of apps" : "Uygulamaların güncellemeleri denetleniyor",
- "Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)" : "%s için veritabanı güncellenebilirliği denetleniyor (Veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
+ "Checking whether the database schema can be updated (this can take a long time depending on the database size)" : "Veritabanı şeması güncellemesi denetleniyor (veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
+ "Checked database schema update" : "Veritabanı şeması güncellemesi denetlendi",
+ "Checking updates of apps" : "Uygulama güncellemeleri denetleniyor",
+ "Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)" : "%s için veritabanı şeması güncellemesi denetleniyor (veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
"Checked database schema update for apps" : "Uygulamalar için veritabanı şema güncellemesi denetlendi",
"Updated \"%s\" to %s" : "\"%s\", %s sürümüne güncellendi",
- "Set log level to debug" : "Günlük seviyesini hata ayıklama olarak ayarla",
- "Reset log level" : "Günlük seviyesini sıfırla",
+ "Set log level to debug" : "Günlükleme düzeyini Hata Ayıklama olarak ayarla",
+ "Reset log level" : "Günlükleme düzeyini sıfırla",
"Starting code integrity check" : "Kod bütünlük sınaması başlatılıyor",
"Finished code integrity check" : "Kod bütünlük sınaması bitti",
- "%s (3rdparty)" : "%s (3. parti)",
+ "%s (3rdparty)" : "%s (3. taraf)",
"%s (incompatible)" : "%s (uyumsuz)",
"Following apps have been disabled: %s" : "Aşağıdaki uygulamalar devre dışı bırakıldı: %s",
"Already up to date" : "Zaten güncel",
- "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Kod bütünlük sınamasında sorunlar oluştu. Daha fazla bilgi…</a>",
+ "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Kod bütünlük sınamasında sorunlar çıktı. Ayrıntılı bilgi…</a>",
"Settings" : "Ayarlar",
+ "Connection to server lost" : "Sunucu bağlantısı kesildi",
+ "_Problem loading page, reloading in %n second_::_Problem loading page, reloading in %n seconds_" : ["Sayfa yüklenirken bir sorun çıktı. %n saniye sonra yeniden yüklenecek","Sayfa yüklenirken bir sorun çıktı. %n saniye sonra yeniden yüklenecek"],
"Saving..." : "Kaydediliyor...",
- "Dismiss" : "İptal et",
+ "Dismiss" : "Yoksay",
+ "This action requires you to confirm your password" : "Bu işlemi yapabilmek için parolanızı yazmalısınız",
+ "Authentication required" : "Kimlik doğrulaması gerekli",
"Password" : "Parola",
"Cancel" : "İptal",
- "seconds ago" : "saniyeler önce",
- "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Parolanızı değiştirme bağlantısı e-posta adresinize gönderildi. Makul bir süre içerisinde almadıysanız spam/gereksiz klasörlerini kontrol ediniz.<br>Bu konumlarda da yoksa yerel sistem yöneticinize sorunuz.",
+ "Confirm" : "Onayla",
+ "Failed to authenticate, try again" : "Kimlik doğrulanamadı, yeniden deneyin",
+ "seconds ago" : "saniye önce",
+ "Logging in …" : "Oturum açılıyor ...",
+ "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Parola sıfırlama bağlantısı e-posta adresinize gönderildi. Bir kaç dakika içinde e-postayı almazsanız spam/gereksiz klasörlerinize bakın.<br>E-postayı göremiyorsanız yerel sistem yöneticinizle görüşün.",
+ "Your files are encrypted. There will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Dosyalarınız şifrelenmiş. Parola sıfırlama işleminden sonra verilerinize erişemeyeceksiniz.<br />Ne yapacağınızdan emin değilseniz, ilerlemeden önce sistem yöneticiniz ile görüşün.<br />Gerçekten devam etmek istiyor musunuz?",
"I know what I'm doing" : "Ne yaptığımı biliyorum",
- "Password can not be changed. Please contact your administrator." : "Parola değiştirilemedi. Lütfen yöneticiniz ile iletişime geçin.",
+ "Password can not be changed. Please contact your administrator." : "Parola değiştirilemedi. Lütfen yöneticiniz ile görüşün.",
"No" : "Hayır",
"Yes" : "Evet",
- "Choose" : "Seç",
- "Error loading file picker template: {error}" : "Dosya seçici şablonu yüklenirken hata: {error}",
+ "No files in here" : "Burada herhangi bir dosya yok",
+ "Choose" : "Seçin",
+ "Error loading file picker template: {error}" : "Dosya seçme kalıbı yüklenirken sorun çıktı: {error}",
"Ok" : "Tamam",
- "Error loading message template: {error}" : "İleti şablonu yüklenirken hata: {error}",
+ "Error loading message template: {error}" : "İleti kalıbı yüklenirken sorun çıktı: {error}",
"read-only" : "salt okunur",
"_{count} file conflict_::_{count} file conflicts_" : ["{count} dosya çakışması","{count} dosya çakışması"],
"One file conflict" : "Bir dosya çakışması",
"New Files" : "Yeni Dosyalar",
- "Already existing files" : "Zaten mevcut olan dosyalar",
+ "Already existing files" : "Zaten var olan dosyalar",
"Which files do you want to keep?" : "Hangi dosyaları saklamak istiyorsunuz?",
- "If you select both versions, the copied file will have a number added to its name." : "İki sürümü de seçerseniz, kopyalanan dosyanın ismine bir sayı ilave edilecektir.",
+ "If you select both versions, the copied file will have a number added to its name." : "İki sürümü de seçerseniz, kopyalanan dosyanın adına bir sayı eklenir.",
"Continue" : "Devam et",
- "(all selected)" : "(tümü seçildi)",
- "({count} selected)" : "({count} seçildi)",
- "Error loading file exists template" : "Dosya mevcut şablonu yüklenirken hata",
- "Very weak password" : "Çok güçsüz parola",
- "Weak password" : "Güçsüz parola",
- "So-so password" : "Normal parola",
- "Good password" : "İyi parola",
- "Strong password" : "Güçlü parola",
+ "(all selected)" : "(tüm seçilmişler)",
+ "({count} selected)" : "({count} seçilmiş)",
+ "Error loading file exists template" : "Dosya var kalıbı yüklenirken sorun çıktı",
+ "Pending" : "Bekliyor",
+ "Very weak password" : "Parola çok zayıf",
+ "Weak password" : "Parola zayıf",
+ "So-so password" : "Parola idare eder",
+ "Good password" : "Parola iyi",
+ "Strong password" : "Parola güçlü",
"Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "Web sunucunuz dosya transferi için düzgün bir şekilde yapılandırılmamış. WevDAV arabirimini sorunlu gözüküyor.",
"Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Web sunucunuz \"{url}\" adresini çözümleyecek şekilde uygun yapılandırılmamış. Daha fazla bilgi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulunabilir.",
"This server has no working Internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Bu sunucunun çalışan bir İnternet bağlantısı yok. Birden fazla uç noktaya ulaşılamıyor. Bu, harici depolama alanı bağlama, güncelleştirme bildirimleri veya üçüncü parti uygulama kurma gibi bazı özellikler çalışmayacak demektir. Uzak dosyalara erişim ve e-posta ile bildirim gönderme de çalışmayacaktır. Eğer bu özelliklerin tamamını kullanmak istiyorsanız, sunucu için İnternet bağlantısını etkinleştirmenizi öneriyoruz.",
diff --git a/core/l10n/tr.json b/core/l10n/tr.json
index 09737016722..56ff4f0e3e6 100644
--- a/core/l10n/tr.json
+++ b/core/l10n/tr.json
@@ -1,78 +1,90 @@
{ "translations": {
"Please select a file." : "Lütfen bir dosya seçin.",
"File is too big" : "Dosya çok büyük",
- "Invalid file provided" : "Geçersiz dosya sağlandı",
- "No image or file provided" : "Resim veya dosya belirtilmedi",
- "Unknown filetype" : "Bilinmeyen dosya türü",
- "Invalid image" : "Geçersiz resim",
- "An error occurred. Please contact your admin." : "Bir hata oluştu. Lütfen yöneticinize başvurun.",
- "No temporary profile picture available, try again" : "Kullanılabilir geçici profil resmi yok, tekrar deneyin",
- "No crop data provided" : "Kesme verisi sağlanmamış",
- "No valid crop data provided" : "Geçerli kırpma verisi sağlanmadı",
- "Crop is not square" : "Kırpma kare değil",
- "Couldn't reset password because the token is invalid" : "Belirteç geçersiz olduğundan parola sıfırlanamadı",
- "Couldn't reset password because the token is expired" : "Jeton zaman aşımına uğradığından parola sıfırlanamadı",
+ "The selected file is not an image." : "Seçilmiş dosya bir görsel dosyası değil.",
+ "The selected file cannot be read." : "Seçilmiş dosya okunamadı.",
+ "Invalid file provided" : "Belirtilen dosya geçersiz",
+ "No image or file provided" : "Bir görsel ya da dosya belirtilmemiş",
+ "Unknown filetype" : "Dosya türü bilinmiyor",
+ "Invalid image" : "Görsel geçersiz",
+ "An error occurred. Please contact your admin." : "Bir sorun çıktı. Lütfen yöneticinizle görüşün.",
+ "No temporary profile picture available, try again" : "Kullanılabilecek geçici bir profil görseli bulunamadı. Yeniden deneyin",
+ "No crop data provided" : "Kırpma verileri belirtilmemiş",
+ "No valid crop data provided" : "Geçerli bir kırpma verisi belirtilmemiş",
+ "Crop is not square" : "Kırpma kare şeklinde değil",
+ "Couldn't reset password because the token is invalid" : "Kod geçersiz olduğundan parola sıfırlanamadı",
+ "Couldn't reset password because the token is expired" : "Kodun süresi geçtiğinden parola sıfırlanamadı",
"Couldn't send reset email. Please make sure your username is correct." : "Sıfırlama e-postası gönderilemedi. Lütfen kullanıcı adınızın doğru olduğundan emin olun.",
- "Could not send reset email because there is no email address for this username. Please contact your administrator." : "Sıfırlama e-postası, bu kullanıcı için bir e-posta adresi olmadığından gönderilemedi. Lütfen yöneticiniz ile iletişime geçin.",
+ "Could not send reset email because there is no email address for this username. Please contact your administrator." : "Bu kullanıcı için bir e-posta adresi olmadığından sıfırlama e-postası gönderilemedi. Lütfen yöneticiniz ile görüşün.",
"%s password reset" : "%s parola sıfırlama",
- "Couldn't send reset email. Please contact your administrator." : "Sıfırlama e-postası gönderilemedi. Lütfen yöneticiniz ile iletişime geçin.",
+ "Couldn't send reset email. Please contact your administrator." : "Sıfırlama e-postası gönderilemedi. Lütfen yöneticiniz ile görüşün.",
"Preparing update" : "Güncelleme hazırlanıyor",
"[%d / %d]: %s" : "[%d / %d]: %s",
"Repair warning: " : "Onarım uyarısı:",
"Repair error: " : "Onarım hatası:",
- "Please use the command line updater because automatic updating is disabled in the config.php." : "Otomatik güncellemeler config.php dosyasından pasif duruma getirildiği için, lütfen komut satırı güncelleyicisini kullanın. Oto",
- "[%d / %d]: Checking table %s" : "[%d / %d]: Tablo kontroi ediliyor %s",
+ "Please use the command line updater because automatic updating is disabled in the config.php." : "Otomatik güncellemeler config.php dosyasında devre dışı bırakılmış olduğundan, komut satırı güncelleyicisini kullanın.",
+ "[%d / %d]: Checking table %s" : "[%d / %d]: %s tablosu denetleniyor",
"Turned on maintenance mode" : "Bakım kipi etkinleştirildi",
- "Turned off maintenance mode" : "Bakım kipi kapatıldı",
+ "Turned off maintenance mode" : "Bakım kipi devre dışı bırakıldı",
"Maintenance mode is kept active" : "Bakım kipi etkin tutuldu",
"Updating database schema" : "Veritabanı şeması güncelleniyor",
"Updated database" : "Veritabanı güncellendi",
- "Checking whether the database schema can be updated (this can take a long time depending on the database size)" : "Veritabanı şeması güncellenebilirliği denetleniyor (Veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
- "Checked database schema update" : "Veritabanı şema güncellemesi denetlendi",
- "Checking updates of apps" : "Uygulamaların güncellemeleri denetleniyor",
- "Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)" : "%s için veritabanı güncellenebilirliği denetleniyor (Veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
+ "Checking whether the database schema can be updated (this can take a long time depending on the database size)" : "Veritabanı şeması güncellemesi denetleniyor (veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
+ "Checked database schema update" : "Veritabanı şeması güncellemesi denetlendi",
+ "Checking updates of apps" : "Uygulama güncellemeleri denetleniyor",
+ "Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)" : "%s için veritabanı şeması güncellemesi denetleniyor (veritabanının büyüklüğüne bağlı olarak uzun sürebilir)",
"Checked database schema update for apps" : "Uygulamalar için veritabanı şema güncellemesi denetlendi",
"Updated \"%s\" to %s" : "\"%s\", %s sürümüne güncellendi",
- "Set log level to debug" : "Günlük seviyesini hata ayıklama olarak ayarla",
- "Reset log level" : "Günlük seviyesini sıfırla",
+ "Set log level to debug" : "Günlükleme düzeyini Hata Ayıklama olarak ayarla",
+ "Reset log level" : "Günlükleme düzeyini sıfırla",
"Starting code integrity check" : "Kod bütünlük sınaması başlatılıyor",
"Finished code integrity check" : "Kod bütünlük sınaması bitti",
- "%s (3rdparty)" : "%s (3. parti)",
+ "%s (3rdparty)" : "%s (3. taraf)",
"%s (incompatible)" : "%s (uyumsuz)",
"Following apps have been disabled: %s" : "Aşağıdaki uygulamalar devre dışı bırakıldı: %s",
"Already up to date" : "Zaten güncel",
- "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Kod bütünlük sınamasında sorunlar oluştu. Daha fazla bilgi…</a>",
+ "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Kod bütünlük sınamasında sorunlar çıktı. Ayrıntılı bilgi…</a>",
"Settings" : "Ayarlar",
+ "Connection to server lost" : "Sunucu bağlantısı kesildi",
+ "_Problem loading page, reloading in %n second_::_Problem loading page, reloading in %n seconds_" : ["Sayfa yüklenirken bir sorun çıktı. %n saniye sonra yeniden yüklenecek","Sayfa yüklenirken bir sorun çıktı. %n saniye sonra yeniden yüklenecek"],
"Saving..." : "Kaydediliyor...",
- "Dismiss" : "İptal et",
+ "Dismiss" : "Yoksay",
+ "This action requires you to confirm your password" : "Bu işlemi yapabilmek için parolanızı yazmalısınız",
+ "Authentication required" : "Kimlik doğrulaması gerekli",
"Password" : "Parola",
"Cancel" : "İptal",
- "seconds ago" : "saniyeler önce",
- "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Parolanızı değiştirme bağlantısı e-posta adresinize gönderildi. Makul bir süre içerisinde almadıysanız spam/gereksiz klasörlerini kontrol ediniz.<br>Bu konumlarda da yoksa yerel sistem yöneticinize sorunuz.",
+ "Confirm" : "Onayla",
+ "Failed to authenticate, try again" : "Kimlik doğrulanamadı, yeniden deneyin",
+ "seconds ago" : "saniye önce",
+ "Logging in …" : "Oturum açılıyor ...",
+ "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Parola sıfırlama bağlantısı e-posta adresinize gönderildi. Bir kaç dakika içinde e-postayı almazsanız spam/gereksiz klasörlerinize bakın.<br>E-postayı göremiyorsanız yerel sistem yöneticinizle görüşün.",
+ "Your files are encrypted. There will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Dosyalarınız şifrelenmiş. Parola sıfırlama işleminden sonra verilerinize erişemeyeceksiniz.<br />Ne yapacağınızdan emin değilseniz, ilerlemeden önce sistem yöneticiniz ile görüşün.<br />Gerçekten devam etmek istiyor musunuz?",
"I know what I'm doing" : "Ne yaptığımı biliyorum",
- "Password can not be changed. Please contact your administrator." : "Parola değiştirilemedi. Lütfen yöneticiniz ile iletişime geçin.",
+ "Password can not be changed. Please contact your administrator." : "Parola değiştirilemedi. Lütfen yöneticiniz ile görüşün.",
"No" : "Hayır",
"Yes" : "Evet",
- "Choose" : "Seç",
- "Error loading file picker template: {error}" : "Dosya seçici şablonu yüklenirken hata: {error}",
+ "No files in here" : "Burada herhangi bir dosya yok",
+ "Choose" : "Seçin",
+ "Error loading file picker template: {error}" : "Dosya seçme kalıbı yüklenirken sorun çıktı: {error}",
"Ok" : "Tamam",
- "Error loading message template: {error}" : "İleti şablonu yüklenirken hata: {error}",
+ "Error loading message template: {error}" : "İleti kalıbı yüklenirken sorun çıktı: {error}",
"read-only" : "salt okunur",
"_{count} file conflict_::_{count} file conflicts_" : ["{count} dosya çakışması","{count} dosya çakışması"],
"One file conflict" : "Bir dosya çakışması",
"New Files" : "Yeni Dosyalar",
- "Already existing files" : "Zaten mevcut olan dosyalar",
+ "Already existing files" : "Zaten var olan dosyalar",
"Which files do you want to keep?" : "Hangi dosyaları saklamak istiyorsunuz?",
- "If you select both versions, the copied file will have a number added to its name." : "İki sürümü de seçerseniz, kopyalanan dosyanın ismine bir sayı ilave edilecektir.",
+ "If you select both versions, the copied file will have a number added to its name." : "İki sürümü de seçerseniz, kopyalanan dosyanın adına bir sayı eklenir.",
"Continue" : "Devam et",
- "(all selected)" : "(tümü seçildi)",
- "({count} selected)" : "({count} seçildi)",
- "Error loading file exists template" : "Dosya mevcut şablonu yüklenirken hata",
- "Very weak password" : "Çok güçsüz parola",
- "Weak password" : "Güçsüz parola",
- "So-so password" : "Normal parola",
- "Good password" : "İyi parola",
- "Strong password" : "Güçlü parola",
+ "(all selected)" : "(tüm seçilmişler)",
+ "({count} selected)" : "({count} seçilmiş)",
+ "Error loading file exists template" : "Dosya var kalıbı yüklenirken sorun çıktı",
+ "Pending" : "Bekliyor",
+ "Very weak password" : "Parola çok zayıf",
+ "Weak password" : "Parola zayıf",
+ "So-so password" : "Parola idare eder",
+ "Good password" : "Parola iyi",
+ "Strong password" : "Parola güçlü",
"Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "Web sunucunuz dosya transferi için düzgün bir şekilde yapılandırılmamış. WevDAV arabirimini sorunlu gözüküyor.",
"Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Web sunucunuz \"{url}\" adresini çözümleyecek şekilde uygun yapılandırılmamış. Daha fazla bilgi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulunabilir.",
"This server has no working Internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Bu sunucunun çalışan bir İnternet bağlantısı yok. Birden fazla uç noktaya ulaşılamıyor. Bu, harici depolama alanı bağlama, güncelleştirme bildirimleri veya üçüncü parti uygulama kurma gibi bazı özellikler çalışmayacak demektir. Uzak dosyalara erişim ve e-posta ile bildirim gönderme de çalışmayacaktır. Eğer bu özelliklerin tamamını kullanmak istiyorsanız, sunucu için İnternet bağlantısını etkinleştirmenizi öneriyoruz.",
diff --git a/cron.php b/cron.php
index 55666fbc937..feb680bd9c2 100644
--- a/cron.php
+++ b/cron.php
@@ -89,7 +89,7 @@ try {
// the cron job must be executed with the right user
if (!function_exists('posix_getuid')) {
echo "The posix extensions are required - see http://php.net/manual/en/book.posix.php" . PHP_EOL;
- exit(0);
+ exit(1);
}
$user = posix_getpwuid(posix_getuid());
$configUser = posix_getpwuid(fileowner(OC::$configDir . 'config.php'));
@@ -97,7 +97,7 @@ try {
echo "Console has to be executed with the same user as the web server is operated" . PHP_EOL;
echo "Current user: " . $user['name'] . PHP_EOL;
echo "Web server user: " . $configUser['name'] . PHP_EOL;
- exit(0);
+ exit(1);
}
// We call ownCloud from the CLI (aka cron)
diff --git a/lib/base.php b/lib/base.php
index a4bb4f584f8..68178b06c5b 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -528,7 +528,7 @@ class OC {
//
// Questions about this code? Ask Lukas ;-)
$currentUrl = substr(explode('?',$request->getRequestUri(), 2)[0], strlen(\OC::$WEBROOT));
- if($currentUrl === '/index.php/apps/user_saml/saml/acs') {
+ if($currentUrl === '/index.php/apps/user_saml/saml/acs' || $currentUrl === '/apps/user_saml/saml/acs') {
return;
}
// For the "index.php" endpoint only a lax cookie is required.
@@ -698,7 +698,7 @@ class OC {
}
OC_User::useBackend(new \OC\User\Database());
- OC_Group::useBackend(new \OC\Group\Database());
+ \OC::$server->getGroupManager()->addBackend(new \OC\Group\Database());
// Subscribe to the hook
\OCP\Util::connectHook(
diff --git a/lib/composer/composer/ClassLoader.php b/lib/composer/composer/ClassLoader.php
index 4626994fd4d..2c72175e772 100644
--- a/lib/composer/composer/ClassLoader.php
+++ b/lib/composer/composer/ClassLoader.php
@@ -374,9 +374,13 @@ class ClassLoader
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
- foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
- if (0 === strpos($class, $prefix)) {
- foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath.'\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ $length = $this->prefixLengthsPsr4[$first][$search];
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
diff --git a/lib/composer/composer/LICENSE b/lib/composer/composer/LICENSE
index 1a28124886d..f27399a042d 100644
--- a/lib/composer/composer/LICENSE
+++ b/lib/composer/composer/LICENSE
@@ -1,5 +1,5 @@
-Copyright (c) 2016 Nils Adermann, Jordi Boggiano
+Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index a4850fb4b38..c87bcce194f 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -141,6 +141,11 @@ return array(
'OCP\\Files\\Notify\\IRenameChange' => $baseDir . '/lib/public/Files/Notify/IRenameChange.php',
'OCP\\Files\\ObjectStore\\IObjectStore' => $baseDir . '/lib/public/Files/ObjectStore/IObjectStore.php',
'OCP\\Files\\ReservedWordException' => $baseDir . '/lib/public/Files/ReservedWordException.php',
+ 'OCP\\Files\\Search\\ISearchBinaryOperator' => $baseDir . '/lib/public/Files/Search/ISearchBinaryOperator.php',
+ 'OCP\\Files\\Search\\ISearchComparison' => $baseDir . '/lib/public/Files/Search/ISearchComparison.php',
+ 'OCP\\Files\\Search\\ISearchOperator' => $baseDir . '/lib/public/Files/Search/ISearchOperator.php',
+ 'OCP\\Files\\Search\\ISearchOrder' => $baseDir . '/lib/public/Files/Search/ISearchOrder.php',
+ 'OCP\\Files\\Search\\ISearchQuery' => $baseDir . '/lib/public/Files/Search/ISearchQuery.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',
@@ -509,6 +514,7 @@ return array(
'OC\\Files\\Cache\\HomePropagator' => $baseDir . '/lib/private/Files/Cache/HomePropagator.php',
'OC\\Files\\Cache\\MoveFromCacheTrait' => $baseDir . '/lib/private/Files/Cache/MoveFromCacheTrait.php',
'OC\\Files\\Cache\\Propagator' => $baseDir . '/lib/private/Files/Cache/Propagator.php',
+ 'OC\\Files\\Cache\\QuerySearchHelper' => $baseDir . '/lib/private/Files/Cache/QuerySearchHelper.php',
'OC\\Files\\Cache\\Scanner' => $baseDir . '/lib/private/Files/Cache/Scanner.php',
'OC\\Files\\Cache\\Storage' => $baseDir . '/lib/private/Files/Cache/Storage.php',
'OC\\Files\\Cache\\StorageGlobal' => $baseDir . '/lib/private/Files/Cache/StorageGlobal.php',
@@ -548,6 +554,10 @@ return array(
'OC\\Files\\ObjectStore\\S3ConnectionTrait' => $baseDir . '/lib/private/Files/ObjectStore/S3ConnectionTrait.php',
'OC\\Files\\ObjectStore\\StorageObjectStore' => $baseDir . '/lib/private/Files/ObjectStore/StorageObjectStore.php',
'OC\\Files\\ObjectStore\\Swift' => $baseDir . '/lib/private/Files/ObjectStore/Swift.php',
+ 'OC\\Files\\Search\\SearchBinaryOperator' => $baseDir . '/lib/private/Files/Search/SearchBinaryOperator.php',
+ 'OC\\Files\\Search\\SearchComparison' => $baseDir . '/lib/private/Files/Search/SearchComparison.php',
+ 'OC\\Files\\Search\\SearchOrder' => $baseDir . '/lib/private/Files/Search/SearchOrder.php',
+ 'OC\\Files\\Search\\SearchQuery' => $baseDir . '/lib/private/Files/Search/SearchQuery.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',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 654161214b2..eb7188b69b3 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -171,6 +171,11 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Files\\Notify\\IRenameChange' => __DIR__ . '/../../..' . '/lib/public/Files/Notify/IRenameChange.php',
'OCP\\Files\\ObjectStore\\IObjectStore' => __DIR__ . '/../../..' . '/lib/public/Files/ObjectStore/IObjectStore.php',
'OCP\\Files\\ReservedWordException' => __DIR__ . '/../../..' . '/lib/public/Files/ReservedWordException.php',
+ 'OCP\\Files\\Search\\ISearchBinaryOperator' => __DIR__ . '/../../..' . '/lib/public/Files/Search/ISearchBinaryOperator.php',
+ 'OCP\\Files\\Search\\ISearchComparison' => __DIR__ . '/../../..' . '/lib/public/Files/Search/ISearchComparison.php',
+ 'OCP\\Files\\Search\\ISearchOperator' => __DIR__ . '/../../..' . '/lib/public/Files/Search/ISearchOperator.php',
+ 'OCP\\Files\\Search\\ISearchOrder' => __DIR__ . '/../../..' . '/lib/public/Files/Search/ISearchOrder.php',
+ 'OCP\\Files\\Search\\ISearchQuery' => __DIR__ . '/../../..' . '/lib/public/Files/Search/ISearchQuery.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',
@@ -539,6 +544,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Files\\Cache\\HomePropagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/HomePropagator.php',
'OC\\Files\\Cache\\MoveFromCacheTrait' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/MoveFromCacheTrait.php',
'OC\\Files\\Cache\\Propagator' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Propagator.php',
+ 'OC\\Files\\Cache\\QuerySearchHelper' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/QuerySearchHelper.php',
'OC\\Files\\Cache\\Scanner' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Scanner.php',
'OC\\Files\\Cache\\Storage' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/Storage.php',
'OC\\Files\\Cache\\StorageGlobal' => __DIR__ . '/../../..' . '/lib/private/Files/Cache/StorageGlobal.php',
@@ -578,6 +584,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Files\\ObjectStore\\S3ConnectionTrait' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3ConnectionTrait.php',
'OC\\Files\\ObjectStore\\StorageObjectStore' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/StorageObjectStore.php',
'OC\\Files\\ObjectStore\\Swift' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Swift.php',
+ 'OC\\Files\\Search\\SearchBinaryOperator' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchBinaryOperator.php',
+ 'OC\\Files\\Search\\SearchComparison' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchComparison.php',
+ 'OC\\Files\\Search\\SearchOrder' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchOrder.php',
+ 'OC\\Files\\Search\\SearchQuery' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchQuery.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',
diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php
index be35f4d172f..fd43d468568 100644
--- a/lib/private/AppFramework/Http/Request.php
+++ b/lib/private/AppFramework/Http/Request.php
@@ -490,6 +490,9 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return bool
*/
private function cookieCheckRequired() {
+ if ($this->getHeader('OCS-APIREQUEST')) {
+ return false;
+ }
if($this->getCookie(session_name()) === null && $this->getCookie('nc_token') === null) {
return false;
}
diff --git a/lib/private/Encryption/Util.php b/lib/private/Encryption/Util.php
index 3afa1bb9596..76e1200a1cb 100644
--- a/lib/private/Encryption/Util.php
+++ b/lib/private/Encryption/Util.php
@@ -273,8 +273,18 @@ class Util {
$result = \OCP\User::getUsers();
} else {
$result = array_merge($result, $users);
+
+ $groupManager = \OC::$server->getGroupManager();
foreach ($groups as $group) {
- $result = array_merge($result, \OC_Group::usersInGroup($group));
+ $groupObject = $groupManager->get($group);
+ if ($groupObject) {
+ $foundUsers = $groupObject->searchUsers('', -1, 0);
+ $userIds = [];
+ foreach ($foundUsers as $user) {
+ $userIds[] = $user->getUID();
+ }
+ $result = array_merge($result, $userIds);
+ }
}
}
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index 7e7ebd795a0..b0527d801d6 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -36,9 +36,11 @@
namespace OC\Files\Cache;
+use Doctrine\DBAL\Driver\Statement;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use \OCP\Files\IMimeTypeLoader;
+use OCP\Files\Search\ISearchQuery;
use OCP\IDBConnection;
/**
@@ -79,6 +81,9 @@ class Cache implements ICache {
*/
protected $connection;
+ /** @var QuerySearchHelper */
+ protected $querySearchHelper;
+
/**
* @param \OC\Files\Storage\Storage|string $storage
*/
@@ -95,6 +100,7 @@ class Cache implements ICache {
$this->storageCache = new Storage($storage);
$this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
$this->connection = \OC::$server->getDatabaseConnection();
+ $this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
}
/**
@@ -350,7 +356,7 @@ class Cache implements ICache {
$queryParts[] = '`mtime`';
}
} elseif ($name === 'encrypted') {
- if(isset($data['encryptedVersion'])) {
+ if (isset($data['encryptedVersion'])) {
$value = $data['encryptedVersion'];
} else {
// Boolean to integer conversion
@@ -599,9 +605,17 @@ class Cache implements ICache {
[$this->getNumericStorageId(), $pattern]
);
+ return $this->searchResultToCacheEntries($result);
+ }
+
+ /**
+ * @param Statement $result
+ * @return CacheEntry[]
+ */
+ private function searchResultToCacheEntries(Statement $result) {
$files = $result->fetchAll();
- return array_map(function(array $data) {
+ return array_map(function (array $data) {
return self::cacheEntryFromData($data, $this->mimetypeLoader);
}, $files);
}
@@ -624,14 +638,29 @@ class Cache implements ICache {
$mimetype = $this->mimetypeLoader->getId($mimetype);
$result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
- $files = $result->fetchAll();
+ return $this->searchResultToCacheEntries($result);
+ }
- return array_map(function (array $data) {
- return self::cacheEntryFromData($data, $this->mimetypeLoader);
- }, $files);
+ public function searchQuery(ISearchQuery $searchQuery) {
+ $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+
+ $query = $builder->select(['fileid', 'storage', 'path', 'parent', 'name', 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum'])
+ ->from('filecache')
+ ->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->getNumericStorageId())))
+ ->andWhere($this->querySearchHelper->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation()));
+
+ if ($searchQuery->getLimit()) {
+ $query->setMaxResults($searchQuery->getLimit());
+ }
+ if ($searchQuery->getOffset()) {
+ $query->setFirstResult($searchQuery->getOffset());
+ }
+
+ $result = $query->execute();
+ return $this->searchResultToCacheEntries($result);
}
- /**
+ /**
* Search for files by tag of a given users.
*
* Note that every user can tag files differently.
diff --git a/lib/private/Files/Cache/FailedCache.php b/lib/private/Files/Cache/FailedCache.php
index 3a0424b5e26..932a5e5181a 100644
--- a/lib/private/Files/Cache/FailedCache.php
+++ b/lib/private/Files/Cache/FailedCache.php
@@ -24,6 +24,7 @@ namespace OC\Files\Cache;
use OCP\Constants;
use OCP\Files\Cache\ICache;
+use OCP\Files\Search\ISearchQuery;
/**
* Storage placeholder to represent a missing precondition, storage unavailable
@@ -125,6 +126,10 @@ class FailedCache implements ICache {
return [];
}
+ public function searchQuery(ISearchQuery $query) {
+ return [];
+ }
+
public function getAll() {
return [];
}
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
new file mode 100644
index 00000000000..931f258ec5b
--- /dev/null
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Cache;
+
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\Files\IMimeTypeLoader;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use OCP\Files\Search\ISearchOperator;
+
+/**
+ * Tools for transforming search queries into database queries
+ */
+class QuerySearchHelper {
+ static protected $searchOperatorMap = [
+ ISearchComparison::COMPARE_LIKE => 'iLike',
+ ISearchComparison::COMPARE_EQUAL => 'eq',
+ ISearchComparison::COMPARE_GREATER_THAN => 'gt',
+ ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'gte',
+ ISearchComparison::COMPARE_LESS_THAN => 'lt',
+ ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lte'
+ ];
+
+ static protected $searchOperatorNegativeMap = [
+ ISearchComparison::COMPARE_LIKE => 'notLike',
+ ISearchComparison::COMPARE_EQUAL => 'neq',
+ ISearchComparison::COMPARE_GREATER_THAN => 'lte',
+ ISearchComparison::COMPARE_GREATER_THAN_EQUAL => 'lt',
+ ISearchComparison::COMPARE_LESS_THAN => 'gte',
+ ISearchComparison::COMPARE_LESS_THAN_EQUAL => 'lt'
+ ];
+
+ /** @var IMimeTypeLoader */
+ private $mimetypeLoader;
+
+ /**
+ * QuerySearchUtil constructor.
+ *
+ * @param IMimeTypeLoader $mimetypeLoader
+ */
+ public function __construct(IMimeTypeLoader $mimetypeLoader) {
+ $this->mimetypeLoader = $mimetypeLoader;
+ }
+
+ public function searchOperatorToDBExpr(IQueryBuilder $builder, ISearchOperator $operator) {
+ $expr = $builder->expr();
+ if ($operator instanceof ISearchBinaryOperator) {
+ switch ($operator->getType()) {
+ case ISearchBinaryOperator::OPERATOR_NOT:
+ $negativeOperator = $operator->getArguments()[0];
+ if ($negativeOperator instanceof ISearchComparison) {
+ return $this->searchComparisonToDBExpr($builder, $negativeOperator, self::$searchOperatorNegativeMap);
+ } else {
+ throw new \InvalidArgumentException('Binary operators inside "not" is not supported');
+ }
+ case ISearchBinaryOperator::OPERATOR_AND:
+ return $expr->andX($this->searchOperatorToDBExpr($builder, $operator->getArguments()[0]), $this->searchOperatorToDBExpr($builder, $operator->getArguments()[1]));
+ case ISearchBinaryOperator::OPERATOR_OR:
+ return $expr->orX($this->searchOperatorToDBExpr($builder, $operator->getArguments()[0]), $this->searchOperatorToDBExpr($builder, $operator->getArguments()[1]));
+ default:
+ throw new \InvalidArgumentException('Invalid operator type: ' . $operator->getType());
+ }
+ } else if ($operator instanceof ISearchComparison) {
+ return $this->searchComparisonToDBExpr($builder, $operator, self::$searchOperatorMap);
+ } else {
+ throw new \InvalidArgumentException('Invalid operator type: ' . get_class($operator));
+ }
+ }
+
+ private function searchComparisonToDBExpr(IQueryBuilder $builder, ISearchComparison $comparison, array $operatorMap) {
+ $this->validateComparison($comparison);
+
+ list($field, $value, $type) = $this->getOperatorFieldAndValue($comparison);
+ if (isset($operatorMap[$type])) {
+ $queryOperator = $operatorMap[$type];
+ return $builder->expr()->$queryOperator($field, $this->getParameterForValue($builder, $value));
+ } else {
+ throw new \InvalidArgumentException('Invalid operator type: ' . $comparison->getType());
+ }
+ }
+
+ private function getOperatorFieldAndValue(ISearchComparison $operator) {
+ $field = $operator->getField();
+ $value = $operator->getValue();
+ $type = $operator->getType();
+ if ($field === 'mimetype') {
+ if ($operator->getType() === ISearchComparison::COMPARE_EQUAL) {
+ $value = $this->mimetypeLoader->getId($value);
+ } else if ($operator->getType() === ISearchComparison::COMPARE_LIKE) {
+ // transform "mimetype='foo/%'" to "mimepart='foo'"
+ if (preg_match('|(.+)/%|', $value, $matches)) {
+ $field = 'mimepart';
+ $value = $this->mimetypeLoader->getId($matches[1]);
+ $type = ISearchComparison::COMPARE_EQUAL;
+ }
+ if (strpos($value, '%') !== false) {
+ throw new \InvalidArgumentException('Unsupported query value for mimetype: ' . $value . ', only values in the format "mime/type" or "mime/%" are supported');
+ }
+ }
+ }
+ return [$field, $value, $type];
+ }
+
+ private function validateComparison(ISearchComparison $operator) {
+ $types = [
+ 'mimetype' => 'string',
+ 'mtime' => 'integer',
+ 'name' => 'string',
+ 'size' => 'integer'
+ ];
+ $comparisons = [
+ 'mimetype' => ['eq', 'like'],
+ 'mtime' => ['eq', 'gt', 'lt', 'gte', 'lte'],
+ 'name' => ['eq', 'like'],
+ 'size' => ['eq', 'gt', 'lt', 'gte', 'lte']
+ ];
+
+ if (!isset($types[$operator->getField()])) {
+ throw new \InvalidArgumentException('Unsupported comparison field ' . $operator->getField());
+ }
+ $type = $types[$operator->getField()];
+ if (gettype($operator->getValue()) !== $type) {
+ throw new \InvalidArgumentException('Invalid type for field ' . $operator->getField());
+ }
+ if (!in_array($operator->getType(), $comparisons[$operator->getField()])) {
+ throw new \InvalidArgumentException('Unsupported comparison for field ' . $operator->getField() . ': ' . $operator->getType());
+ }
+ }
+
+ private function getParameterForValue(IQueryBuilder $builder, $value) {
+ if ($value instanceof \DateTime) {
+ $value = $value->getTimestamp();
+ }
+ if (is_numeric($value)) {
+ $type = IQueryBuilder::PARAM_INT;
+ } else {
+ $type = IQueryBuilder::PARAM_STR;
+ }
+ return $builder->createNamedParameter($value, $type);
+ }
+}
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index 894fbcc803d..ebab20fbaed 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -28,6 +28,7 @@
namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\Search\ISearchQuery;
/**
* Jail to a subdirectory of the wrapped cache
@@ -218,6 +219,11 @@ class CacheJail extends CacheWrapper {
return $this->formatSearchResults($results);
}
+ public function searchQuery(ISearchQuery $query) {
+ $results = $this->getCache()->searchQuery($query);
+ return $this->formatSearchResults($results);
+ }
+
/**
* search for files by mimetype
*
diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
index 83fe7e5f43e..1463d1467b8 100644
--- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php
+++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
@@ -31,6 +31,7 @@ namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Cache\ICache;
+use OCP\Files\Search\ISearchQuery;
class CacheWrapper extends Cache {
/**
@@ -229,6 +230,11 @@ class CacheWrapper extends Cache {
return array_map(array($this, 'formatCacheEntry'), $results);
}
+ public function searchQuery(ISearchQuery $query) {
+ $results = $this->getCache()->searchQuery($query);
+ return array_map(array($this, 'formatCacheEntry'), $results);
+ }
+
/**
* search for files by tag
*
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index fd907f708f3..45372d0fedf 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -33,6 +33,7 @@ use OCP\Files\FileInfo;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Files\Search\ISearchOperator;
class Folder extends Node implements \OCP\Files\Folder {
/**
@@ -190,11 +191,15 @@ class Folder extends Node implements \OCP\Files\Folder {
/**
* search for files with the name matching $query
*
- * @param string $query
+ * @param string|ISearchOperator $query
* @return \OC\Files\Node\Node[]
*/
public function search($query) {
- return $this->searchCommon('search', array('%' . $query . '%'));
+ if (is_string($query)) {
+ return $this->searchCommon('search', array('%' . $query . '%'));
+ } else {
+ return $this->searchCommon('searchQuery', array($query));
+ }
}
/**
diff --git a/lib/private/Files/Search/SearchBinaryOperator.php b/lib/private/Files/Search/SearchBinaryOperator.php
new file mode 100644
index 00000000000..c9466d8b9ea
--- /dev/null
+++ b/lib/private/Files/Search/SearchBinaryOperator.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchOperator;
+
+class SearchBinaryOperator implements ISearchBinaryOperator {
+ /** @var string */
+ private $type;
+ /** @var ISearchOperator[] */
+ private $arguments;
+
+ /**
+ * SearchBinaryOperator constructor.
+ *
+ * @param string $type
+ * @param ISearchOperator[] $arguments
+ */
+ public function __construct($type, array $arguments) {
+ $this->type = $type;
+ $this->arguments = $arguments;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * @return ISearchOperator[]
+ */
+ public function getArguments() {
+ return $this->arguments;
+ }
+}
diff --git a/lib/private/Files/Search/SearchComparison.php b/lib/private/Files/Search/SearchComparison.php
new file mode 100644
index 00000000000..32c4ad0e5aa
--- /dev/null
+++ b/lib/private/Files/Search/SearchComparison.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+use OCP\Files\Search\ISearchComparison;
+
+class SearchComparison implements ISearchComparison {
+ /** @var string */
+ private $type;
+ /** @var string */
+ private $field;
+ /** @var string|integer|\DateTime */
+ private $value;
+
+ /**
+ * SearchComparison constructor.
+ *
+ * @param string $type
+ * @param string $field
+ * @param \DateTime|int|string $value
+ */
+ public function __construct($type, $field, $value) {
+ $this->type = $type;
+ $this->field = $field;
+ $this->value = $value;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getField() {
+ return $this->field;
+ }
+
+ /**
+ * @return \DateTime|int|string
+ */
+ public function getValue() {
+ return $this->value;
+ }
+}
diff --git a/lib/private/Files/Search/SearchOrder.php b/lib/private/Files/Search/SearchOrder.php
new file mode 100644
index 00000000000..c76d6f2e25e
--- /dev/null
+++ b/lib/private/Files/Search/SearchOrder.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+
+use OCP\Files\Search\ISearchOrder;
+
+class SearchOrder implements ISearchOrder {
+ /** @var string */
+ private $direction;
+ /** @var string */
+ private $field;
+
+ /**
+ * SearchOrder constructor.
+ *
+ * @param string $direction
+ * @param string $field
+ */
+ public function __construct($direction, $field) {
+ $this->direction = $direction;
+ $this->field = $field;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDirection() {
+ return $this->direction;
+ }
+
+ /**
+ * @return string
+ */
+ public function getField() {
+ return $this->field;
+ }
+}
diff --git a/lib/private/Files/Search/SearchQuery.php b/lib/private/Files/Search/SearchQuery.php
new file mode 100644
index 00000000000..8a0478ae98e
--- /dev/null
+++ b/lib/private/Files/Search/SearchQuery.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+use OCP\Files\Search\ISearchOperator;
+use OCP\Files\Search\ISearchOrder;
+use OCP\Files\Search\ISearchQuery;
+
+class SearchQuery implements ISearchQuery {
+ /** @var ISearchOperator */
+ private $searchOperation;
+ /** @var integer */
+ private $limit;
+ /** @var integer */
+ private $offset;
+ /** @var ISearchOrder[] */
+ private $order;
+
+ /**
+ * SearchQuery constructor.
+ *
+ * @param ISearchOperator $searchOperation
+ * @param int $limit
+ * @param int $offset
+ * @param array $order
+ */
+ public function __construct(ISearchOperator $searchOperation, $limit, $offset, array $order) {
+ $this->searchOperation = $searchOperation;
+ $this->limit = $limit;
+ $this->offset = $offset;
+ $this->order = $order;
+ }
+
+ /**
+ * @return ISearchOperator
+ */
+ public function getSearchOperation() {
+ return $this->searchOperation;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLimit() {
+ return $this->limit;
+ }
+
+ /**
+ * @return int
+ */
+ public function getOffset() {
+ return $this->offset;
+ }
+
+ /**
+ * @return ISearchOrder[]
+ */
+ public function getOrder() {
+ return $this->order;
+ }
+}
diff --git a/lib/private/Lockdown/Filesystem/NullCache.php b/lib/private/Lockdown/Filesystem/NullCache.php
index 8c6b5258aa8..9cb8016194b 100644
--- a/lib/private/Lockdown/Filesystem/NullCache.php
+++ b/lib/private/Lockdown/Filesystem/NullCache.php
@@ -24,6 +24,7 @@ use OCP\Constants;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo;
+use OCP\Files\Search\ISearchQuery;
class NullCache implements ICache {
public function getNumericStorageId() {
@@ -103,6 +104,10 @@ class NullCache implements ICache {
return [];
}
+ public function searchQuery(ISearchQuery $query) {
+ return [];
+ }
+
public function searchByTag($tag, $userId) {
return [];
}
diff --git a/lib/private/OCS/Provider.php b/lib/private/OCS/Provider.php
index 7d53479c6e2..2e9ed85b67b 100644
--- a/lib/private/OCS/Provider.php
+++ b/lib/private/OCS/Provider.php
@@ -70,6 +70,23 @@ class Provider extends \OCP\AppFramework\Controller {
];
}
+ if ($this->appManager->isEnabledForUser('federation')) {
+ if (isset($services['FEDERATED_SHARING'])) {
+ $services['FEDERATED_SHARING']['endpoints']['shared-secret'] = '/ocs/v2.php/cloud/shared-secret';
+ $services['FEDERATED_SHARING']['endpoints']['system-address-book'] = '/remote.php/dav/addressbooks/system/system/system';
+ $services['FEDERATED_SHARING']['endpoints']['carddav-user'] = 'system';
+ } else {
+ $services['FEDERATED_SHARING'] = [
+ 'version' => 1,
+ 'endpoints' => [
+ 'shared-secret' => '/ocs/v2.php/cloud/shared-secret',
+ 'system-address-book' => '/remote.php/dav/addressbooks/system/system/system',
+ 'carddav-user' => 'system'
+ ],
+ ];
+ }
+ }
+
if($this->appManager->isEnabledForUser('activity')) {
$services['ACTIVITY'] = [
'version' => 1,
diff --git a/lib/private/Preview/MP3.php b/lib/private/Preview/MP3.php
index 804ec7fbcd9..05cd7c0edb1 100644
--- a/lib/private/Preview/MP3.php
+++ b/lib/private/Preview/MP3.php
@@ -61,24 +61,6 @@ class MP3 extends Provider {
}
}
- return $this->getNoCoverThumbnail();
+ return false;
}
-
- /**
- * Generates a default image when the file has no cover
- *
- * @return bool|\OCP\IImage false if the default image is missing or invalid
- */
- private function getNoCoverThumbnail() {
- $icon = \OC::$SERVERROOT . '/core/img/filetypes/audio.svg';
-
- if(!file_exists($icon)) {
- return false;
- }
-
- $image = new \OC_Image();
- $image->loadFromFile($icon);
- return $image->valid() ? $image : false;
- }
-
}
diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php
index 6abaa7dd413..da4b7dda91c 100644
--- a/lib/private/Share/Share.php
+++ b/lib/private/Share/Share.php
@@ -237,8 +237,19 @@ class Share extends Constants {
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
} else {
+ $groupManager = \OC::$server->getGroupManager();
while ($row = $result->fetchRow()) {
- $usersInGroup = \OC_Group::usersInGroup($row['share_with']);
+
+ $usersInGroup = [];
+ $group = $groupManager->get($row['share_with']);
+ if ($group) {
+ $users = $group->searchUsers('', -1, 0);
+ $userIds = array();
+ foreach ($users as $user) {
+ $userIds[] = $user->getUID();
+ }
+ $usersInGroup = $userIds;
+ }
$shares = array_merge($shares, $usersInGroup);
if ($returnUserPaths) {
foreach ($usersInGroup as $user) {
@@ -468,7 +479,11 @@ class Share extends Constants {
//if didn't found a result than let's look for a group share.
if(empty($shares) && $user !== null) {
- $groups = \OC_Group::getUserGroups($user);
+ $userObject = \OC::$server->getUserManager()->get($user);
+ $groups = [];
+ if ($userObject) {
+ $groups = \OC::$server->getGroupManager()->getUserGroupIds($userObject);
+ }
if (!empty($groups)) {
$where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
@@ -628,7 +643,18 @@ class Share extends Constants {
if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
$users[] = $item['share_with'];
} else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
- $users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
+
+ $group = \OC::$server->getGroupManager()->get($item['share_with']);
+ $userIds = [];
+ if ($group) {
+ $users = $group->searchUsers('', -1, 0);
+ foreach ($users as $user) {
+ $userIds[] = $user->getUID();
+ }
+ return $userIds;
+ }
+
+ $users = array_merge($users, $userIds);
}
}
}
@@ -740,7 +766,19 @@ class Share extends Constants {
throw new \Exception($message_t);
}
if ($shareWithinGroupOnly) {
- $inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith));
+ $userManager = \OC::$server->getUserManager();
+ $groupManager = \OC::$server->getGroupManager();
+ $userOwner = $userManager->get($uidOwner);
+ $userShareWith = $userManager->get($shareWith);
+ $groupsOwner = [];
+ $groupsShareWith = [];
+ if ($userOwner) {
+ $groupsOwner = $groupManager->getUserGroupIds($userOwner);
+ }
+ if ($userShareWith) {
+ $groupsShareWith = $groupManager->getUserGroupIds($userShareWith);
+ }
+ $inGroup = array_intersect($groupsOwner, $groupsShareWith);
if (empty($inGroup)) {
$message = 'Sharing %s failed, because the user '
.'%s is not a member of any groups that %s is a member of';
@@ -775,18 +813,22 @@ class Share extends Constants {
}
}
} else if ($shareType === self::SHARE_TYPE_GROUP) {
- if (!\OC_Group::groupExists($shareWith)) {
+ if (!\OC::$server->getGroupManager()->groupExists($shareWith)) {
$message = 'Sharing %s failed, because the group %s does not exist';
$message_t = $l->t('Sharing %s failed, because the group %s does not exist', array($itemSourceName, $shareWith));
\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
throw new \Exception($message_t);
}
if ($shareWithinGroupOnly && !\OC_Group::inGroup($uidOwner, $shareWith)) {
- $message = 'Sharing %s failed, because '
- .'%s is not a member of the group %s';
- $message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', array($itemSourceName, $uidOwner, $shareWith));
- \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OCP\Util::DEBUG);
- throw new \Exception($message_t);
+ $group = \OC::$server->getGroupManager()->get($shareWith);
+ $user = \OC::$server->getUserManager()->get($uidOwner);
+ if (!$group || !$user || !$group->inGroup($user)) {
+ $message = 'Sharing %s failed, because '
+ . '%s is not a member of the group %s';
+ $message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', array($itemSourceName, $uidOwner, $shareWith));
+ \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OCP\Util::DEBUG);
+ throw new \Exception($message_t);
+ }
}
// Check if the item source is already shared with the group, either from the same owner or a different user
// The check for each user in the group is done inside the put() function
@@ -804,7 +846,18 @@ class Share extends Constants {
$group = $shareWith;
$shareWith = array();
$shareWith['group'] = $group;
- $shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
+
+
+ $groupObject = \OC::$server->getGroupManager()->get($group);
+ $userIds = [];
+ if ($groupObject) {
+ $users = $groupObject->searchUsers('', -1, 0);
+ foreach ($users as $user) {
+ $userIds[] = $user->getUID();
+ }
+ }
+
+ $shareWith['users'] = array_diff($userIds, array($uidOwner));
} else if ($shareType === self::SHARE_TYPE_LINK) {
$updateExistingShare = false;
if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
@@ -1057,7 +1110,9 @@ class Share extends Constants {
$itemUnshared = true;
break;
} elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
- if (\OC_Group::inGroup($uid, $share['share_with'])) {
+ $group = \OC::$server->getGroupManager()->get($share['share_with']);
+ $user = \OC::$server->getUserManager()->get($uid);
+ if ($group && $user && $group->inGroup($user)) {
$groupShare = $share;
}
} elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique &&
@@ -1746,7 +1801,12 @@ class Share extends Constants {
$queryArgs[] = self::SHARE_TYPE_USER;
$queryArgs[] = self::$shareTypeGroupUserUnique;
$queryArgs[] = $shareWith;
- $groups = \OC_Group::getUserGroups($shareWith);
+
+ $user = \OC::$server->getUserManager()->get($shareWith);
+ $groups = [];
+ if ($user) {
+ $groups = \OC::$server->getGroupManager()->getUserGroupIds($user);
+ }
if (!empty($groups)) {
$placeholders = join(',', array_fill(0, count($groups), '?'));
$where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) ';
@@ -2171,7 +2231,17 @@ class Share extends Constants {
if (isset($shareWith['users'])) {
$users = $shareWith['users'];
} else {
- $users = \OC_Group::usersInGroup($shareWith['group']);
+ $group = \OC::$server->getGroupManager()->get($shareWith['group']);
+ if ($group) {
+ $users = $group->searchUsers('', -1, 0);
+ $userIds = [];
+ foreach ($users as $user) {
+ $userIds[] = $user->getUID();
+ }
+ $users = $userIds;
+ } else {
+ $users = [];
+ }
}
// remove current user from list
if (in_array(\OCP\User::getUser(), $users)) {
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
index d6f5a2c6fd3..744ea80761e 100644
--- a/lib/private/Template/SCSSCacher.php
+++ b/lib/private/Template/SCSSCacher.php
@@ -103,10 +103,17 @@ class SCSSCacher {
private function isCached($fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $path) {
try{
$cachedFile = $folder->getFile($fileNameCSS);
- if( $cachedFile->getMTime() > filemtime($path.'/'.$fileNameSCSS)
- && $cachedFile->getSize() > 0 ) {
- return true;
+ if ($cachedFile->getSize() > 0) {
+ $depFile = $folder->getFile($fileNameCSS . '.deps');
+ $deps = json_decode($depFile->getContent(), true);
+
+ foreach ($deps as $file=>$mtime) {
+ if (!file_exists($file) || filemtime($file) > $mtime) {
+ return false;
+ }
+ }
}
+ return true;
} catch(NotFoundException $e) {
return false;
}
@@ -140,6 +147,13 @@ class SCSSCacher {
$cachedfile = $folder->newFile($fileNameCSS);
}
+ $depFileName = $fileNameCSS . '.deps';
+ try {
+ $depFile = $folder->getFile($depFileName);
+ } catch (NotFoundException $e) {
+ $depFile = $folder->newFile($depFileName);
+ }
+
// Compile
try {
$compiledScss = $scss->compile('@import "'.$fileNameSCSS.'";');
@@ -150,6 +164,7 @@ class SCSSCacher {
try {
$cachedfile->putContent($this->rebaseUrls($compiledScss, $webDir));
+ $depFile->putContent(json_encode($scss->getParsedFiles()));
$this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
return true;
} catch(NotFoundException $e) {
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index 961f70f8a8e..bca9c46bfd0 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -204,9 +204,15 @@ class User implements IUser {
// FIXME: Feels like an hack - suggestions?
+ $groupManager = \OC::$server->getGroupManager();
// We have to delete the user from all groups
- foreach (\OC::$server->getGroupManager()->getUserGroupIds($this) as $groupId) {
- \OC_Group::removeFromGroup($this->uid, $groupId);
+ foreach ($groupManager->getUserGroupIds($this) as $groupId) {
+ $group = $groupManager->get($groupId);
+ if ($group) {
+ \OC_Hook::emit("OC_Group", "pre_removeFromGroup", ["run" => true, "uid" => $this->uid, "gid" => $groupId]);
+ $group->removeUser($this);
+ \OC_Hook::emit("OC_User", "post_removeFromGroup", ["uid" => $this->uid, "gid" => $groupId]);
+ }
}
// Delete the user's keys in preferences
\OC::$server->getConfig()->deleteAllUserValues($this->uid);
diff --git a/lib/private/legacy/group.php b/lib/private/legacy/group.php
deleted file mode 100644
index 6b58cb4c834..00000000000
--- a/lib/private/legacy/group.php
+++ /dev/null
@@ -1,302 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Georg Ehrke <georg@owncloud.com>
- * @author goodkiller <markopraakli@gmail.com>
- * @author Jakob Sack <mail@jakobsack.de>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author macjohnny <estebanmarin@gmx.ch>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Qingping Hou <dave2008713@gmail.com>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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/>
- *
- */
-
-/**
- * This class provides all methods needed for managing groups.
- *
- * Note that &run is deprecated and won't work anymore.
- * Hooks provided:
- * pre_createGroup(&run, gid)
- * post_createGroup(gid)
- * pre_deleteGroup(&run, gid)
- * post_deleteGroup(gid)
- * pre_addToGroup(&run, uid, gid)
- * post_addToGroup(uid, gid)
- * pre_removeFromGroup(&run, uid, gid)
- * post_removeFromGroup(uid, gid)
- */
-class OC_Group {
-
- /**
- * @return \OC\Group\Manager
- * @deprecated Use \OC::$server->getGroupManager();
- */
- public static function getManager() {
- return \OC::$server->getGroupManager();
- }
-
- /**
- * @return \OC\User\Manager
- * @deprecated Use \OC::$server->getUserManager()
- */
- private static function getUserManager() {
- return \OC::$server->getUserManager();
- }
-
- /**
- * set the group backend
- * @param \OC\Group\Backend $backend The backend to use for user management
- * @return bool
- */
- public static function useBackend($backend) {
- self::getManager()->addBackend($backend);
- return true;
- }
-
- /**
- * remove all used backends
- */
- public static function clearBackends() {
- self::getManager()->clearBackends();
- }
-
- /**
- * Try to create a new group
- * @param string $gid The name of the group to create
- * @return bool
- *
- * Tries to create a new group. If the group name already exists, false will
- * be returned. Basic checking of Group name
- * @deprecated Use \OC::$server->getGroupManager()->createGroup() instead
- */
- public static function createGroup($gid) {
- if (self::getManager()->createGroup($gid)) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * delete a group
- * @param string $gid gid of the group to delete
- * @return bool
- *
- * Deletes a group and removes it from the group_user-table
- * @deprecated Use \OC::$server->getGroupManager()->delete() instead
- */
- public static function deleteGroup($gid) {
- $group = self::getManager()->get($gid);
- if ($group) {
- if ($group->delete()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * is user in group?
- * @param string $uid uid of the user
- * @param string $gid gid of the group
- * @return bool
- *
- * Checks whether the user is member of a group or not.
- * @deprecated Use \OC::$server->getGroupManager->inGroup($user);
- */
- public static function inGroup($uid, $gid) {
- $group = self::getManager()->get($gid);
- $user = self::getUserManager()->get($uid);
- if ($group and $user) {
- return $group->inGroup($user);
- }
- return false;
- }
-
- /**
- * Add a user to a group
- * @param string $uid Name of the user to add to group
- * @param string $gid Name of the group in which add the user
- * @return bool
- *
- * Adds a user to a group.
- * @deprecated Use \OC::$server->getGroupManager->addUser();
- */
- public static function addToGroup($uid, $gid) {
- $group = self::getManager()->get($gid);
- $user = self::getUserManager()->get($uid);
- if ($group and $user) {
- $group->addUser($user);
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Removes a user from a group
- * @param string $uid Name of the user to remove from group
- * @param string $gid Name of the group from which remove the user
- * @return bool
- *
- * removes the user from a group.
- */
- public static function removeFromGroup($uid, $gid) {
- $group = self::getManager()->get($gid);
- $user = self::getUserManager()->get($uid);
- if ($group and $user) {
- OC_Hook::emit("OC_Group", "pre_removeFromGroup", array("run" => true, "uid" => $uid, "gid" => $gid));
- $group->removeUser($user);
- OC_Hook::emit("OC_User", "post_removeFromGroup", array("uid" => $uid, "gid" => $gid));
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Get all groups a user belongs to
- * @param string $uid Name of the user
- * @return array an array of group names
- *
- * This function fetches all groups a user belongs to. It does not check
- * if the user exists at all.
- * @deprecated Use \OC::$server->getGroupManager->getUserGroupIds($user)
- */
- public static function getUserGroups($uid) {
- $user = self::getUserManager()->get($uid);
- if ($user) {
- return self::getManager()->getUserGroupIds($user);
- } else {
- return array();
- }
- }
-
- /**
- * get a list of all groups
- * @param string $search
- * @param int|null $limit
- * @param int|null $offset
- * @return array an array of group names
- *
- * Returns a list with all groups
- */
- public static function getGroups($search = '', $limit = null, $offset = null) {
- $groups = self::getManager()->search($search, $limit, $offset);
- $groupIds = array();
- foreach ($groups as $group) {
- $groupIds[] = $group->getGID();
- }
- return $groupIds;
- }
-
- /**
- * check if a group exists
- *
- * @param string $gid
- * @return bool
- * @deprecated Use \OC::$server->getGroupManager->groupExists($gid)
- */
- public static function groupExists($gid) {
- return self::getManager()->groupExists($gid);
- }
-
- /**
- * get a list of all users in a group
- * @param string $gid
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array an array of user ids
- */
- public static function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- $group = self::getManager()->get($gid);
- if ($group) {
- $users = $group->searchUsers($search, $limit, $offset);
- $userIds = array();
- foreach ($users as $user) {
- $userIds[] = $user->getUID();
- }
- return $userIds;
- } else {
- return array();
- }
- }
-
- /**
- * get a list of all users in several groups
- * @param string[] $gids
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array an array of user ids
- */
- public static function usersInGroups($gids, $search = '', $limit = -1, $offset = 0) {
- $users = array();
- foreach ($gids as $gid) {
- // TODO Need to apply limits to groups as total
- $users = array_merge(array_diff(self::usersInGroup($gid, $search, $limit, $offset), $users), $users);
- }
- return $users;
- }
-
- /**
- * get a list of all display names in a group
- * @param string $gid
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array an array of display names (value) and user ids(key)
- * @deprecated Use \OC::$server->getGroupManager->displayNamesInGroup($gid, $search, $limit, $offset)
- */
- public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) {
- return self::getManager()->displayNamesInGroup($gid, $search, $limit, $offset);
- }
-
- /**
- * get a list of all display names in several groups
- * @param array $gids
- * @param string $search
- * @param int $limit
- * @param int $offset
- * @return array an array of display names (Key) user ids (value)
- */
- public static function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) {
- $displayNames = array();
- foreach ($gids as $gid) {
- // TODO Need to apply limits to groups as total
- $diff = array_diff(
- self::displayNamesInGroup($gid, $search, $limit, $offset),
- $displayNames
- );
- if ($diff) {
- // A fix for LDAP users. array_merge loses keys...
- $displayNames = $diff + $displayNames;
- }
- }
- return $displayNames;
- }
-}
diff --git a/lib/private/legacy/image.php b/lib/private/legacy/image.php
index ed7dfce29a6..e26148bdf15 100644
--- a/lib/private/legacy/image.php
+++ b/lib/private/legacy/image.php
@@ -562,7 +562,11 @@ class OC_Image implements \OCP\IImage {
break;
case IMAGETYPE_JPEG:
if (imagetypes() & IMG_JPG) {
- $this->resource = imagecreatefromjpeg($imagePath);
+ if (getimagesize($imagePath) !== false) {
+ $this->resource = imagecreatefromjpeg($imagePath);
+ } else {
+ $this->logger->debug('OC_Image->loadFromFile, JPG image not valid: ' . $imagePath, array('app' => 'core'));
+ }
} else {
$this->logger->debug('OC_Image->loadFromFile, JPG images not supported: ' . $imagePath, array('app' => 'core'));
}
diff --git a/lib/private/legacy/template.php b/lib/private/legacy/template.php
index 09e3d130f49..8535e018879 100644
--- a/lib/private/legacy/template.php
+++ b/lib/private/legacy/template.php
@@ -106,19 +106,9 @@ class OC_Template extends \OC\Template\Base {
}
}
- OC_Util::addStyle("tooltip",null,true);
OC_Util::addStyle('jquery-ui-fixes',null,true);
OC_Util::addVendorStyle('jquery-ui/themes/base/jquery-ui',null,true);
- OC_Util::addStyle("mobile",null,true);
- OC_Util::addStyle("multiselect",null,true);
- OC_Util::addStyle("fixes",null,true);
- OC_Util::addStyle("global",null,true);
- OC_Util::addStyle("apps",null,true);
- OC_Util::addStyle("fonts",null,true);
- OC_Util::addStyle("icons",null,true);
- OC_Util::addStyle("header",null,true);
- OC_Util::addStyle("inputs");
- OC_Util::addStyle("styles",null,true);
+ OC_Util::addStyle('server', null, true);
// avatars
\OC_Util::addScript('jquery.avatar', null, true);
diff --git a/lib/private/legacy/user.php b/lib/private/legacy/user.php
index 661242a659a..621ea3535b1 100644
--- a/lib/private/legacy/user.php
+++ b/lib/private/legacy/user.php
@@ -333,7 +333,9 @@ class OC_User {
* @return bool
*/
public static function isAdminUser($uid) {
- if (OC_Group::inGroup($uid, 'admin') && self::$incognitoMode === false) {
+ $group = \OC::$server->getGroupManager()->get('admin');
+ $user = \OC::$server->getUserManager()->get($uid);
+ if ($group && $user && $group->inGroup($user) && self::$incognitoMode === false) {
return true;
}
return false;
diff --git a/lib/public/Files/Cache/ICache.php b/lib/public/Files/Cache/ICache.php
index 7d01b1a2908..63993d0a8cb 100644
--- a/lib/public/Files/Cache/ICache.php
+++ b/lib/public/Files/Cache/ICache.php
@@ -21,6 +21,8 @@
*/
namespace OCP\Files\Cache;
+use OCP\Files\Search\ISearchOperator;
+use OCP\Files\Search\ISearchQuery;
/**
* Metadata cache for a storage
@@ -213,6 +215,16 @@ interface ICache {
public function searchByMime($mimetype);
/**
+ * Search for files with a flexible query
+ *
+ * @param ISearchQuery $query
+ * @return ICacheEntry[]
+ * @throw \InvalidArgumentException if the cache is unable to perform the query
+ * @since 12.0.0
+ */
+ public function searchQuery(ISearchQuery $query);
+
+ /**
* Search for files by tag of a given users.
*
* Note that every user can tag files differently.
diff --git a/lib/public/Files/Folder.php b/lib/public/Files/Folder.php
index 8f8576d8503..52a4b303196 100644
--- a/lib/public/Files/Folder.php
+++ b/lib/public/Files/Folder.php
@@ -30,6 +30,7 @@
// use OCP namespace for all classes that are considered public.
// This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP\Files;
+use OCP\Files\Search\ISearchQuery;
/**
* @since 6.0.0
@@ -115,7 +116,7 @@ interface Folder extends Node {
/**
* search for files with the name matching $query
*
- * @param string $query
+ * @param string|ISearchQuery $query
* @return \OCP\Files\Node[]
* @since 6.0.0
*/
diff --git a/lib/public/Files/Search/ISearchBinaryOperator.php b/lib/public/Files/Search/ISearchBinaryOperator.php
new file mode 100644
index 00000000000..d5a2d5dc02d
--- /dev/null
+++ b/lib/public/Files/Search/ISearchBinaryOperator.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+/**
+ * @since 12.0.0
+ */
+interface ISearchBinaryOperator extends ISearchOperator {
+ const OPERATOR_AND = 'and';
+ const OPERATOR_OR = 'or';
+ const OPERATOR_NOT = 'not';
+
+ /**
+ * The type of binary operator
+ *
+ * One of the ISearchBinaryOperator::OPERATOR_* constants
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getType();
+
+ /**
+ * The arguments for the binary operator
+ *
+ * One argument for the 'not' operator and two for 'and' and 'or'
+ *
+ * @return ISearchOperator[]
+ * @since 12.0.0
+ */
+ public function getArguments();
+}
diff --git a/lib/public/Files/Search/ISearchComparison.php b/lib/public/Files/Search/ISearchComparison.php
new file mode 100644
index 00000000000..5468260f001
--- /dev/null
+++ b/lib/public/Files/Search/ISearchComparison.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+/**
+ * @since 12.0.0
+ */
+interface ISearchComparison extends ISearchOperator {
+ const COMPARE_EQUAL = 'eq';
+ const COMPARE_GREATER_THAN = 'gt';
+ const COMPARE_GREATER_THAN_EQUAL = 'gte';
+ const COMPARE_LESS_THAN = 'lt';
+ const COMPARE_LESS_THAN_EQUAL = 'lte';
+ const COMPARE_LIKE = 'like';
+
+ /**
+ * Get the type of comparison, one of the ISearchComparison::COMPARE_* constants
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getType();
+
+ /**
+ * Get the name of the field to compare with
+ *
+ * i.e. 'size', 'name' or 'mimetype'
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getField();
+
+ /**
+ * Get the value to compare the field with
+ *
+ * @return string|integer|\DateTime
+ * @since 12.0.0
+ */
+ public function getValue();
+}
diff --git a/lib/public/Files/Search/ISearchOperator.php b/lib/public/Files/Search/ISearchOperator.php
new file mode 100644
index 00000000000..047792bc782
--- /dev/null
+++ b/lib/public/Files/Search/ISearchOperator.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+/**
+ * @since 12.0.0
+ */
+interface ISearchOperator {
+
+}
diff --git a/lib/public/Files/Search/ISearchOrder.php b/lib/public/Files/Search/ISearchOrder.php
new file mode 100644
index 00000000000..1abfd7506d5
--- /dev/null
+++ b/lib/public/Files/Search/ISearchOrder.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+/**
+ * @since 12.0.0
+ */
+interface ISearchOrder {
+ const DIRECTION_ASCENDING = 'asc';
+ const DIRECTION_DESCENDING = 'desc';
+
+ /**
+ * The direction to sort in, either ISearchOrder::DIRECTION_ASCENDING or ISearchOrder::DIRECTION_DESCENDING
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getDirection();
+
+ /**
+ * The field to sort on
+ *
+ * @return string
+ * @since 12.0.0
+ */
+ public function getField();
+}
diff --git a/lib/public/Files/Search/ISearchQuery.php b/lib/public/Files/Search/ISearchQuery.php
new file mode 100644
index 00000000000..5a701b321b1
--- /dev/null
+++ b/lib/public/Files/Search/ISearchQuery.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Search;
+
+/**
+ * @since 12.0.0
+ */
+interface ISearchQuery {
+ /**
+ * @return ISearchOperator
+ * @since 12.0.0
+ */
+ public function getSearchOperation();
+
+ /**
+ * Get the maximum number of results to return
+ *
+ * @return integer
+ * @since 12.0.0
+ */
+ public function getLimit();
+
+ /**
+ * Get the offset for returned results
+ *
+ * @return integer
+ * @since 12.0.0
+ */
+ public function getOffset();
+
+ /**
+ * The fields and directions to order by
+ *
+ * @return ISearchOrder[]
+ * @since 12.0.0
+ */
+ public function getOrder();
+}
diff --git a/settings/l10n/de.js b/settings/l10n/de.js
index 2843806b069..ac55f6e8f7e 100644
--- a/settings/l10n/de.js
+++ b/settings/l10n/de.js
@@ -125,6 +125,7 @@ OC.L10N.register(
"undo" : "rückgängig machen",
"never" : "niemals",
"deleted {userName}" : "{userName} gelöscht",
+ "No user found for <strong>{pattern}</strong>" : "Keine Benutzer für <strong>{pattern}</strong> gefunden",
"Unable to add user to group {group}" : "Benutzer kann nicht zur Gruppe {group} hinzugefügt werden ",
"Unable to remove user from group {group}" : "Benutzer kann nicht aus der Gruppe {group} entfernt werden ",
"Add group" : "Gruppe hinzufügen",
diff --git a/settings/l10n/de.json b/settings/l10n/de.json
index 115d89312ff..fa061a7eadf 100644
--- a/settings/l10n/de.json
+++ b/settings/l10n/de.json
@@ -123,6 +123,7 @@
"undo" : "rückgängig machen",
"never" : "niemals",
"deleted {userName}" : "{userName} gelöscht",
+ "No user found for <strong>{pattern}</strong>" : "Keine Benutzer für <strong>{pattern}</strong> gefunden",
"Unable to add user to group {group}" : "Benutzer kann nicht zur Gruppe {group} hinzugefügt werden ",
"Unable to remove user from group {group}" : "Benutzer kann nicht aus der Gruppe {group} entfernt werden ",
"Add group" : "Gruppe hinzufügen",
diff --git a/settings/l10n/de_DE.js b/settings/l10n/de_DE.js
index 63a68200bd7..4e41e2cb317 100644
--- a/settings/l10n/de_DE.js
+++ b/settings/l10n/de_DE.js
@@ -125,6 +125,7 @@ OC.L10N.register(
"undo" : "rückgängig machen",
"never" : "niemals",
"deleted {userName}" : "{userName} gelöscht",
+ "No user found for <strong>{pattern}</strong>" : "Keine Benutzer für <strong>{pattern}</strong> gefunden",
"Unable to add user to group {group}" : "Benutzer kann nicht zur Gruppe {group} hinzugefügt werden ",
"Unable to remove user from group {group}" : "Benutzer kann nicht aus der Gruppe {group} entfernt werden ",
"Add group" : "Gruppe hinzufügen",
diff --git a/settings/l10n/de_DE.json b/settings/l10n/de_DE.json
index 3e0ab8eab9e..9ee6357457c 100644
--- a/settings/l10n/de_DE.json
+++ b/settings/l10n/de_DE.json
@@ -123,6 +123,7 @@
"undo" : "rückgängig machen",
"never" : "niemals",
"deleted {userName}" : "{userName} gelöscht",
+ "No user found for <strong>{pattern}</strong>" : "Keine Benutzer für <strong>{pattern}</strong> gefunden",
"Unable to add user to group {group}" : "Benutzer kann nicht zur Gruppe {group} hinzugefügt werden ",
"Unable to remove user from group {group}" : "Benutzer kann nicht aus der Gruppe {group} entfernt werden ",
"Add group" : "Gruppe hinzufügen",
diff --git a/settings/l10n/eu.js b/settings/l10n/eu.js
index e533f692df0..b3a360cace5 100644
--- a/settings/l10n/eu.js
+++ b/settings/l10n/eu.js
@@ -57,6 +57,7 @@ OC.L10N.register(
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Official apps are developed by and within the community. They offer central functionality and are ready for production use.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "This app is not checked for security issues and is new or known to be unstable. Install at your own risk.",
+ "Disabling app …" : "Aplikazioa desgaitzen...",
"Error while disabling app" : "Erroea izan da aplikazioa desgaitzerakoan",
"Disable" : "Ez-gaitu",
"Enable" : "Gaitu",
@@ -109,6 +110,7 @@ OC.L10N.register(
"Contacts" : "Kontaktuak",
"Visible to local users and to trusted servers" : "Bertako erabiltzaile eta zerbitzarien jendearentzat ikusgai",
"Public" : "Publikoa",
+ "Will be synced to a global and public address book" : "Helbide liburu global eta publikoan sinkronizatuko da",
"Select a profile picture" : "Profilaren irudia aukeratu",
"Very weak password" : "Pasahitz oso ahula",
"Weak password" : "Pasahitz ahula",
@@ -123,6 +125,7 @@ OC.L10N.register(
"undo" : "desegin",
"never" : "inoiz",
"deleted {userName}" : "{userName} ezabatuta",
+ "No user found for <strong>{pattern}</strong>" : "Ez da aurkitu <strong>{pattern}</strong>erabiltzailea",
"Unable to add user to group {group}" : "Ezin erabiltzailea {group} taldera gehitu",
"Unable to remove user from group {group}" : "Ezin erabiltzailea {group} taldetik kendu",
"Add group" : "Taldea gehitu",
@@ -173,6 +176,7 @@ OC.L10N.register(
"It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data.",
"This is the final warning: Do you really want to enable encryption?" : "This is the final warning: Do you really want to enable encryption?",
"Enable encryption" : "Gaitu enkriptatzea",
+ "Security & setup warnings" : "Segurtasun eta konfigurazio abisuak",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Bakarrik irakurtzeko konfigurazioa gaitu da. Honek web-interfazearen bidez konfigurazio batzuk aldatzea ekiditzen du. Are gehiago, fitxategia eskuz ezarri behar da idazteko moduan eguneraketa bakoitzerako.",
"PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "Badirudi PHP konfiguratuta dagoela lineako dokumentu blokeak aldatzeko. Honek zenbait oinarrizko aplikazio eskuraezin bihurtuko ditu.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Hau ziur aski cache/accelerator batek eragin du, hala nola Zend OPcache edo eAccelerator.",
@@ -181,11 +185,15 @@ OC.L10N.register(
"This means that there might be problems with certain characters in file names." : "Honek esan nahi du fitxategien izenetako karaktere batzuekin arazoak egon daitezkeela.",
"We strongly suggest installing the required packages on your system to support one of the following locales: %s." : "Biziki gomendatzen dizugu beharrezkoak diren paketea zure sisteman instalatzea honi euskarria eman ahal izateko: %s.",
"If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwrite.cli.url\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Zure instalazioa ez badago domeinuaren sustraian egina eta erabiltzen badu sistemaren cron-a, arazoak izan daitezke URL sorreran. Arazo horiek saihesteko ezarri \"overwrite.cli.url\" opzioa zure config.php fitxategian zure instalazioaren webroot bidera (Proposatua: \"%s\")",
+ "All checks passed." : "Egiaztapen guztiak gaindituta.",
"Cron" : "Cron",
+ "Last cron job execution: %s." : "Azken cron lan exekuzioa: %s.",
+ "Last cron job execution: %s. Something seems wrong." : "Azken cron lan exekuzioa: %s. Zerbait gaizki dirudi.",
"Cron was not executed yet!" : "Cron-a oraindik ez da exekutatu!",
"Execute one task with each page loaded" : "Exekutatu zeregin bat orri karga bakoitzean",
"cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php webcron zerbitzu batean erregistratua dago cron.php 15 minuturo http bidez deitzeko.",
"Use system's cron service to call the cron.php file every 15 minutes." : "Erabili sistemaren cron zerbitzua deitzeko cron.php fitxategia 15 minutuan behin.",
+ "The cron.php needs to be executed by the system user \"%s\"." : "Sistemako \"%s\" erabiltzaileak, cron.php exekutatu behar du.",
"Version" : "Bertsioa",
"Sharing" : "Partekatzea",
"Allow apps to use the Share API" : "Baimendu aplikazioak partekatzeko APIa erabiltzeko",
@@ -197,9 +205,11 @@ OC.L10N.register(
"days" : "egun",
"Enforce expiration date" : "Muga data betearazi",
"Allow resharing" : "Baimendu birpartekatzea",
+ "Allow sharing with groups" : "Onartu taldeekin partekatzen",
"Restrict users to only share with users in their groups" : "Mugatu partekatzeak taldeko erabiltzaileetara",
"Exclude groups from sharing" : "Baztertu taldeak partekatzean",
"These groups will still be able to receive shares, but not to initiate them." : "Talde hauek oraindik jaso ahal izango dute partekatzeak, baina ezingo dute partekatu",
+ "Allow username autocompletion in share dialog. If this is disabled the full username needs to be entered." : "Onartu elkarbanatze elkarrizketan, erabiltzaile osatze automatikoa. Desgaituta badago, erabiltzaile izena osoa sartu behar da.",
"Tips & tricks" : "Aholkuak eta trikimailuak",
"To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation ↗</a>." : "To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation ↗</a>.",
"How to do backups" : "Nola egin babes kopiak",
@@ -215,6 +225,7 @@ OC.L10N.register(
"User documentation" : "Erabiltzailearen dokumentazioa",
"Admin documentation" : "Administratzailearen dokumentazioa",
"Visit website" : "Web orria ikusi",
+ "Report a bug" : "Akats baten berri eman",
"Show description …" : "Erakutsi deskribapena ...",
"Hide description …" : "Ezkutatu deskribapena ...",
"This app has an update available." : "Aplikazio honek eguneraketa bat eskuragarri ditu.",
@@ -232,9 +243,14 @@ OC.L10N.register(
"Cheers!" : "Ongi izan!",
"Hey there,\n\njust letting you know that you now have a %s account.\n\nYour username: %s\nAccess it: %s\n\n" : "Kaixo,\n\nJakinarazi nahi dizugu, badaukazula %s kontua.\n\nZure erabiltzaile izena: %s \nSar zaitez: %s\n",
"Administrator documentation" : "Administratzaile dokumentazioa",
+ "Online documentation" : "Online dokumentazioa",
"Forum" : "Foroa",
+ "Getting help" : "Laguntza lortzen",
+ "Commercial support" : "Merkataritza laguntza",
+ "You are using <strong>%s</strong> of <strong>%s</strong>" : "Zuk <strong>%s</strong> erabiltzen ari zara <strong>%s</strong>-tik",
"Profile picture" : "Zure irudia",
"Upload new" : "Igo berria",
+ "Select from Files" : "Aukeratu fitxategien artean",
"Remove image" : "Irudia ezabatu",
"Picture provided by original account" : "Irudia jatorrizko kontutik hartuta",
"Cancel" : "Ezeztatu",
@@ -244,12 +260,16 @@ OC.L10N.register(
"Email" : "E-posta",
"Your email address" : "Zure e-posta",
"No email address set" : "Ez da eposta helbidea ezarri",
+ "For password reset and notifications" : "Pasahitza berrezartzeko eta jakinarazpenerako",
"Phone number" : "Telefono zenbakia",
"Your phone number" : "Zure telefono zenbakia",
"Address" : "Helbidea",
"Your postal address" : "Zure helbidea",
"Website" : "Web orria",
"Your website" : "Zure web orria",
+ "Twitter" : "Twitter",
+ "Your Twitter handle" : "Zure Twitter erabiltzailea",
+ "You are member of the following groups:" : "Zuk honako talde kide zara:",
"Password" : "Pasahitza",
"Current password" : "Uneko pasahitza",
"New password" : "Pasahitz berria",
@@ -261,7 +281,15 @@ OC.L10N.register(
"Android app" : "Android aplikazioa",
"iOS app" : "iOS aplikazioa",
"Show First Run Wizard again" : "Erakutsi berriz Lehenengo Aldiko Morroia",
+ "Web, desktop and mobile clients currently logged in to your account." : "Web-gune, mahaigain eta mugikorrean zure kontuan saioa hasita dago.",
+ "Device" : "Gailu",
+ "Last activity" : "Azken jarduera",
+ "Passcodes that give an app or device permissions to access your account." : "Zure kontuan sartzeko aplikazio edo gailuei baimena ematen dien pasahitzak.",
"Name" : "Izena",
+ "App name" : "Aplikazioaren izena",
+ "Create new app password" : "Sortu app pasahitza berria",
+ "Use the credentials below to configure your app or device." : "Erabili kredentzialak beheko zure aplikazioa edo gailua konfiguratzeko.",
+ "For security reasons this password will only be shown once." : "Segurtasun arrazoiengatik, pasahitz hau behin soilik erakutsiko da.",
"Username" : "Erabiltzaile izena",
"Done" : "Egina",
"Show storage location" : "Erakutsi biltegiaren kokapena",
@@ -273,11 +301,17 @@ OC.L10N.register(
"Create" : "Sortu",
"Admin Recovery Password" : "Administratzailearen pasahitza berreskuratzea",
"Enter the recovery password in order to recover the users files during password change" : "Berreskuratze pasahitza idatzi pasahitz aldaketan erabiltzaileen fitxategiak berreskuratzeko",
+ "Group name" : "Taldearen izena",
"Everyone" : "Edonor",
"Admins" : "Administratzaileak",
+ "Default quota" : "Kuota lehenetsia",
"Please enter storage quota (ex: \"512 MB\" or \"12 GB\")" : "Mesedez sartu biltegiratze kouta (adb: \"512 MB\" edo \"12 GB\")",
"Other" : "Bestelakoa",
+ "Group admin for" : "Talde honen administratzailea",
"Quota" : "Kuota",
+ "Storage location" : "Biltegiratze kokapena",
+ "User backend" : "Erabiltzaile jatorria",
+ "Last login" : "Azken saioa",
"change full name" : "aldatu izena",
"set new password" : "ezarri pasahitz berria",
"change email address" : "aldatu eposta helbidea",
@@ -289,6 +323,7 @@ OC.L10N.register(
"Unable to remove user from group %s" : "Ezin izan da erabiltzailea %s taldetik ezabatu",
"Are you really sure you want add \"{domain}\" as trusted domain?" : "Ziur zaude gehitu nahi duzula \"{domain}\" domeinu fidagarri gisa?",
"Please wait...." : "Itxoin mesedez...",
+ "add group" : "Taldea gehitu",
"Everything (fatal issues, errors, warnings, info, debug)" : "Dena (arazo larriak, erroreak, abisuak, informazioa, arazketa)",
"Info, warnings, errors and fatal issues" : "Informazioa, abisuak, erroreak eta arazo larriak.",
"Warnings, errors and fatal issues" : "Abisuak, erroreak eta arazo larriak",
@@ -303,7 +338,13 @@ OC.L10N.register(
"Uninstall App" : "Desinstalatu aplikazioa",
"Hey there,<br><br>just letting you know that you now have an %s account.<br><br>Your username: %s<br>Access it: <a href=\"%s\">%s</a><br><br>" : "Kaixo,<br><br>orain %s kontu bat duzula esateko besterik ez.<br><br>Zure erabiltzailea: %s<br>Sar zaitez: <a href=\"%s\">%s</a><br><br>",
"Hey there,\n\njust letting you know that you now have an %s account.\n\nYour username: %s\nAccess it: %s\n\n" : "Kaixo,\n\norain %s kontu bat duzula esateko besterik ez.\n\nZure erabiltzailea: %s\nSar zaitez: %s\n\n",
+ "Add Group" : "Gehitu taldea",
"Group" : "Taldea",
- "Full Name" : "Izen osoa"
+ "Default Quota" : "Lehenetsitako kuota",
+ "Full Name" : "Izen osoa",
+ "Group Admin for" : "Talde honen administratzailea",
+ "Storage Location" : "Biltegiratze kokapena",
+ "User Backend" : "Erabiltzaile jatorria",
+ "Last Login" : "Azken saioa"
},
"nplurals=2; plural=(n != 1);");
diff --git a/settings/l10n/eu.json b/settings/l10n/eu.json
index b5421f74f07..f7c05b2a41b 100644
--- a/settings/l10n/eu.json
+++ b/settings/l10n/eu.json
@@ -55,6 +55,7 @@
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Official apps are developed by and within the community. They offer central functionality and are ready for production use.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "This app is not checked for security issues and is new or known to be unstable. Install at your own risk.",
+ "Disabling app …" : "Aplikazioa desgaitzen...",
"Error while disabling app" : "Erroea izan da aplikazioa desgaitzerakoan",
"Disable" : "Ez-gaitu",
"Enable" : "Gaitu",
@@ -107,6 +108,7 @@
"Contacts" : "Kontaktuak",
"Visible to local users and to trusted servers" : "Bertako erabiltzaile eta zerbitzarien jendearentzat ikusgai",
"Public" : "Publikoa",
+ "Will be synced to a global and public address book" : "Helbide liburu global eta publikoan sinkronizatuko da",
"Select a profile picture" : "Profilaren irudia aukeratu",
"Very weak password" : "Pasahitz oso ahula",
"Weak password" : "Pasahitz ahula",
@@ -121,6 +123,7 @@
"undo" : "desegin",
"never" : "inoiz",
"deleted {userName}" : "{userName} ezabatuta",
+ "No user found for <strong>{pattern}</strong>" : "Ez da aurkitu <strong>{pattern}</strong>erabiltzailea",
"Unable to add user to group {group}" : "Ezin erabiltzailea {group} taldera gehitu",
"Unable to remove user from group {group}" : "Ezin erabiltzailea {group} taldetik kendu",
"Add group" : "Taldea gehitu",
@@ -171,6 +174,7 @@
"It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data.",
"This is the final warning: Do you really want to enable encryption?" : "This is the final warning: Do you really want to enable encryption?",
"Enable encryption" : "Gaitu enkriptatzea",
+ "Security & setup warnings" : "Segurtasun eta konfigurazio abisuak",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Bakarrik irakurtzeko konfigurazioa gaitu da. Honek web-interfazearen bidez konfigurazio batzuk aldatzea ekiditzen du. Are gehiago, fitxategia eskuz ezarri behar da idazteko moduan eguneraketa bakoitzerako.",
"PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "Badirudi PHP konfiguratuta dagoela lineako dokumentu blokeak aldatzeko. Honek zenbait oinarrizko aplikazio eskuraezin bihurtuko ditu.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Hau ziur aski cache/accelerator batek eragin du, hala nola Zend OPcache edo eAccelerator.",
@@ -179,11 +183,15 @@
"This means that there might be problems with certain characters in file names." : "Honek esan nahi du fitxategien izenetako karaktere batzuekin arazoak egon daitezkeela.",
"We strongly suggest installing the required packages on your system to support one of the following locales: %s." : "Biziki gomendatzen dizugu beharrezkoak diren paketea zure sisteman instalatzea honi euskarria eman ahal izateko: %s.",
"If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwrite.cli.url\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Zure instalazioa ez badago domeinuaren sustraian egina eta erabiltzen badu sistemaren cron-a, arazoak izan daitezke URL sorreran. Arazo horiek saihesteko ezarri \"overwrite.cli.url\" opzioa zure config.php fitxategian zure instalazioaren webroot bidera (Proposatua: \"%s\")",
+ "All checks passed." : "Egiaztapen guztiak gaindituta.",
"Cron" : "Cron",
+ "Last cron job execution: %s." : "Azken cron lan exekuzioa: %s.",
+ "Last cron job execution: %s. Something seems wrong." : "Azken cron lan exekuzioa: %s. Zerbait gaizki dirudi.",
"Cron was not executed yet!" : "Cron-a oraindik ez da exekutatu!",
"Execute one task with each page loaded" : "Exekutatu zeregin bat orri karga bakoitzean",
"cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php webcron zerbitzu batean erregistratua dago cron.php 15 minuturo http bidez deitzeko.",
"Use system's cron service to call the cron.php file every 15 minutes." : "Erabili sistemaren cron zerbitzua deitzeko cron.php fitxategia 15 minutuan behin.",
+ "The cron.php needs to be executed by the system user \"%s\"." : "Sistemako \"%s\" erabiltzaileak, cron.php exekutatu behar du.",
"Version" : "Bertsioa",
"Sharing" : "Partekatzea",
"Allow apps to use the Share API" : "Baimendu aplikazioak partekatzeko APIa erabiltzeko",
@@ -195,9 +203,11 @@
"days" : "egun",
"Enforce expiration date" : "Muga data betearazi",
"Allow resharing" : "Baimendu birpartekatzea",
+ "Allow sharing with groups" : "Onartu taldeekin partekatzen",
"Restrict users to only share with users in their groups" : "Mugatu partekatzeak taldeko erabiltzaileetara",
"Exclude groups from sharing" : "Baztertu taldeak partekatzean",
"These groups will still be able to receive shares, but not to initiate them." : "Talde hauek oraindik jaso ahal izango dute partekatzeak, baina ezingo dute partekatu",
+ "Allow username autocompletion in share dialog. If this is disabled the full username needs to be entered." : "Onartu elkarbanatze elkarrizketan, erabiltzaile osatze automatikoa. Desgaituta badago, erabiltzaile izena osoa sartu behar da.",
"Tips & tricks" : "Aholkuak eta trikimailuak",
"To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation ↗</a>." : "To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation ↗</a>.",
"How to do backups" : "Nola egin babes kopiak",
@@ -213,6 +223,7 @@
"User documentation" : "Erabiltzailearen dokumentazioa",
"Admin documentation" : "Administratzailearen dokumentazioa",
"Visit website" : "Web orria ikusi",
+ "Report a bug" : "Akats baten berri eman",
"Show description …" : "Erakutsi deskribapena ...",
"Hide description …" : "Ezkutatu deskribapena ...",
"This app has an update available." : "Aplikazio honek eguneraketa bat eskuragarri ditu.",
@@ -230,9 +241,14 @@
"Cheers!" : "Ongi izan!",
"Hey there,\n\njust letting you know that you now have a %s account.\n\nYour username: %s\nAccess it: %s\n\n" : "Kaixo,\n\nJakinarazi nahi dizugu, badaukazula %s kontua.\n\nZure erabiltzaile izena: %s \nSar zaitez: %s\n",
"Administrator documentation" : "Administratzaile dokumentazioa",
+ "Online documentation" : "Online dokumentazioa",
"Forum" : "Foroa",
+ "Getting help" : "Laguntza lortzen",
+ "Commercial support" : "Merkataritza laguntza",
+ "You are using <strong>%s</strong> of <strong>%s</strong>" : "Zuk <strong>%s</strong> erabiltzen ari zara <strong>%s</strong>-tik",
"Profile picture" : "Zure irudia",
"Upload new" : "Igo berria",
+ "Select from Files" : "Aukeratu fitxategien artean",
"Remove image" : "Irudia ezabatu",
"Picture provided by original account" : "Irudia jatorrizko kontutik hartuta",
"Cancel" : "Ezeztatu",
@@ -242,12 +258,16 @@
"Email" : "E-posta",
"Your email address" : "Zure e-posta",
"No email address set" : "Ez da eposta helbidea ezarri",
+ "For password reset and notifications" : "Pasahitza berrezartzeko eta jakinarazpenerako",
"Phone number" : "Telefono zenbakia",
"Your phone number" : "Zure telefono zenbakia",
"Address" : "Helbidea",
"Your postal address" : "Zure helbidea",
"Website" : "Web orria",
"Your website" : "Zure web orria",
+ "Twitter" : "Twitter",
+ "Your Twitter handle" : "Zure Twitter erabiltzailea",
+ "You are member of the following groups:" : "Zuk honako talde kide zara:",
"Password" : "Pasahitza",
"Current password" : "Uneko pasahitza",
"New password" : "Pasahitz berria",
@@ -259,7 +279,15 @@
"Android app" : "Android aplikazioa",
"iOS app" : "iOS aplikazioa",
"Show First Run Wizard again" : "Erakutsi berriz Lehenengo Aldiko Morroia",
+ "Web, desktop and mobile clients currently logged in to your account." : "Web-gune, mahaigain eta mugikorrean zure kontuan saioa hasita dago.",
+ "Device" : "Gailu",
+ "Last activity" : "Azken jarduera",
+ "Passcodes that give an app or device permissions to access your account." : "Zure kontuan sartzeko aplikazio edo gailuei baimena ematen dien pasahitzak.",
"Name" : "Izena",
+ "App name" : "Aplikazioaren izena",
+ "Create new app password" : "Sortu app pasahitza berria",
+ "Use the credentials below to configure your app or device." : "Erabili kredentzialak beheko zure aplikazioa edo gailua konfiguratzeko.",
+ "For security reasons this password will only be shown once." : "Segurtasun arrazoiengatik, pasahitz hau behin soilik erakutsiko da.",
"Username" : "Erabiltzaile izena",
"Done" : "Egina",
"Show storage location" : "Erakutsi biltegiaren kokapena",
@@ -271,11 +299,17 @@
"Create" : "Sortu",
"Admin Recovery Password" : "Administratzailearen pasahitza berreskuratzea",
"Enter the recovery password in order to recover the users files during password change" : "Berreskuratze pasahitza idatzi pasahitz aldaketan erabiltzaileen fitxategiak berreskuratzeko",
+ "Group name" : "Taldearen izena",
"Everyone" : "Edonor",
"Admins" : "Administratzaileak",
+ "Default quota" : "Kuota lehenetsia",
"Please enter storage quota (ex: \"512 MB\" or \"12 GB\")" : "Mesedez sartu biltegiratze kouta (adb: \"512 MB\" edo \"12 GB\")",
"Other" : "Bestelakoa",
+ "Group admin for" : "Talde honen administratzailea",
"Quota" : "Kuota",
+ "Storage location" : "Biltegiratze kokapena",
+ "User backend" : "Erabiltzaile jatorria",
+ "Last login" : "Azken saioa",
"change full name" : "aldatu izena",
"set new password" : "ezarri pasahitz berria",
"change email address" : "aldatu eposta helbidea",
@@ -287,6 +321,7 @@
"Unable to remove user from group %s" : "Ezin izan da erabiltzailea %s taldetik ezabatu",
"Are you really sure you want add \"{domain}\" as trusted domain?" : "Ziur zaude gehitu nahi duzula \"{domain}\" domeinu fidagarri gisa?",
"Please wait...." : "Itxoin mesedez...",
+ "add group" : "Taldea gehitu",
"Everything (fatal issues, errors, warnings, info, debug)" : "Dena (arazo larriak, erroreak, abisuak, informazioa, arazketa)",
"Info, warnings, errors and fatal issues" : "Informazioa, abisuak, erroreak eta arazo larriak.",
"Warnings, errors and fatal issues" : "Abisuak, erroreak eta arazo larriak",
@@ -301,7 +336,13 @@
"Uninstall App" : "Desinstalatu aplikazioa",
"Hey there,<br><br>just letting you know that you now have an %s account.<br><br>Your username: %s<br>Access it: <a href=\"%s\">%s</a><br><br>" : "Kaixo,<br><br>orain %s kontu bat duzula esateko besterik ez.<br><br>Zure erabiltzailea: %s<br>Sar zaitez: <a href=\"%s\">%s</a><br><br>",
"Hey there,\n\njust letting you know that you now have an %s account.\n\nYour username: %s\nAccess it: %s\n\n" : "Kaixo,\n\norain %s kontu bat duzula esateko besterik ez.\n\nZure erabiltzailea: %s\nSar zaitez: %s\n\n",
+ "Add Group" : "Gehitu taldea",
"Group" : "Taldea",
- "Full Name" : "Izen osoa"
+ "Default Quota" : "Lehenetsitako kuota",
+ "Full Name" : "Izen osoa",
+ "Group Admin for" : "Talde honen administratzailea",
+ "Storage Location" : "Biltegiratze kokapena",
+ "User Backend" : "Erabiltzaile jatorria",
+ "Last Login" : "Azken saioa"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/settings/l10n/fr.js b/settings/l10n/fr.js
index ab82fb252cb..ec41e297957 100644
--- a/settings/l10n/fr.js
+++ b/settings/l10n/fr.js
@@ -125,6 +125,7 @@ OC.L10N.register(
"undo" : "annuler",
"never" : "jamais",
"deleted {userName}" : "{userName} supprimé",
+ "No user found for <strong>{pattern}</strong>" : "Aucun utilisateur trouvé pour <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Impossible d'ajouter l'utilisateur au groupe {group}",
"Unable to remove user from group {group}" : "Impossible de supprimer l'utilisateur du groupe {group}",
"Add group" : "Ajouter un groupe",
diff --git a/settings/l10n/fr.json b/settings/l10n/fr.json
index 60c50acb5d9..37fb3cf0e5b 100644
--- a/settings/l10n/fr.json
+++ b/settings/l10n/fr.json
@@ -123,6 +123,7 @@
"undo" : "annuler",
"never" : "jamais",
"deleted {userName}" : "{userName} supprimé",
+ "No user found for <strong>{pattern}</strong>" : "Aucun utilisateur trouvé pour <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Impossible d'ajouter l'utilisateur au groupe {group}",
"Unable to remove user from group {group}" : "Impossible de supprimer l'utilisateur du groupe {group}",
"Add group" : "Ajouter un groupe",
diff --git a/settings/l10n/is.js b/settings/l10n/is.js
index cedd821dd17..1065d806b58 100644
--- a/settings/l10n/is.js
+++ b/settings/l10n/is.js
@@ -57,6 +57,7 @@ OC.L10N.register(
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Opinber forrit eru þróuð af og innan samfélagsins. Þau bjóða upp á ýmsa kjarnaeiginleika og eru tilbúin til notkunar í raunvinnslu.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Samþykkt forrit eru þróuð af treystum forriturum og hafa gengist undir lauslegar öryggisprófanir. Þau eru í virku viðhaldi í opnum hugbúnaðarsöfnum og umsjónarmenn þeirra dæma þau nógu stöðug til notkunar í allri venjulegri vinnslu.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Þetta forrit hefur ekki verið öryggisprófað, er nýtt erða þekkt fyrir ótöðugleika við vissar aðstæður. Uppsetning er á þína ábyrgð.",
+ "Disabling app …" : "Geri forrit óvirkt …",
"Error while disabling app" : "Villa við að afvirkja forrit",
"Disable" : "Gera óvirkt",
"Enable" : "Virkja",
@@ -124,6 +125,7 @@ OC.L10N.register(
"undo" : "afturkalla",
"never" : "aldrei",
"deleted {userName}" : "eyddi {userName}",
+ "No user found for <strong>{pattern}</strong>" : "Enginn notandi fannst fyrir <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Tókst ekki að bæta notanda við hópinn {group}",
"Unable to remove user from group {group}" : "Ekki tókst að fjarlægja notanda úr hópnum {group}",
"Add group" : "Bæta við hópi",
@@ -168,6 +170,7 @@ OC.L10N.register(
"Server-side encryption" : "Dulritun á þjóni",
"Enable server-side encryption" : "Virkja dulritun á þjóni",
"Please read carefully before activating server-side encryption: " : "Lestu eftirfarandi gaumgæfilega áður en þú virkjar dulritun á þjóni: ",
+ "Once encryption is enabled, all files uploaded to the server from that point forward will be encrypted at rest on the server. It will only be possible to disable encryption at a later date if the active encryption module supports that function, and all pre-conditions (e.g. setting a recover key) are met." : "Þegar dulritun er virkjuð, munu frá þeim tímapunkti allar skrár sem sendar eru inn á þjóninn verða dulritaðar inni á honum. Einungis mun verða hægt að afvirkja dulritun síðar, ef virka dulritunareiningin styður þá aðgerð, og ef allar forsendur (t.d. að setja endurheimtulykil) eru uppfylltar.",
"Encryption alone does not guarantee security of the system. Please see documentation for more information about how the encryption app works, and the supported use cases." : "Dulritun ein og sér tryggir ekki öryggi kerfisins. Endilega skoðaðu hjálparskjölin um hvernig dulritunarforritið virkar, og dæmi um hvaða uppsetningar eru studdar.",
"Be aware that encryption always increases the file size." : "Hafðu í huga að dulritun eykur alltaf skráastærð.",
"It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Það er góður siður að taka regluleg öryggisafrit af gögnunum þínum; ef um dulrituð gögn er að ræða, gakktu úr skugga um að einnig sé tekið öryggisafrit af dulritunarlyklum ásamt gögnunum.",
@@ -182,13 +185,16 @@ OC.L10N.register(
"php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "Það lítur út eins og að PHP sé ekki rétt sett upp varðandi fyrirspurnir um umhverfisbreytur. Prófun með getenv(\"PATH\") skilar auðu svari.",
"Please check the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">installation documentation ↗</a> for php configuration notes and the php configuration of your server, especially when using php-fpm." : "Endilega skoðaðu <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">hjálparskjöl uppsetningarinnar ↗</a> varðandi athugasemdir vegna uppsetningar PHP og sjálfa uppsetningu PHP-þjónsins, Sérstaklega ef þú notar php-fpm.",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Skrifvarða stillingaskráin hefur verið virkjuð. Þetta kemur í veg fyrir að hægt sé að sýsla með sumar stillingar í gegnum vefviðmótið. Að auki þarf þessi skrá að vera skrifanleg við hverja uppfærslu.",
+ "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "PHP virðist vera sett upp to fjarlægja innantextablokkir (inline doc blocks). Þetta mun gera ýmis kjarnaforrit óaðgengileg.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Þessu veldur væntanlega biðminni/hraðall á borð við Zend OPcache eða eAccelerator.",
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Gagnagrunnurinn keyrir ekki með \"READ COMMITTED\" færsluaðgreiningarstiginu. Þetta getur valdið vandamálum þegar margar aðgerðir eru keyrðar í einu.",
"%1$s below version %2$s is installed, for stability and performance reasons we recommend updating to a newer %1$s version." : "%1$s eldra en útgáfa %2$s er uppsett, en vegna stöðugleika og afkasta mælum við með að útgáfa %1$s verði sett upp.",
"The PHP module 'fileinfo' is missing. We strongly recommend to enable this module to get best results with mime-type detection." : "PHP-eininguna 'fileinfo' vantar. Við mælum eindregið með notkun þessarar einingar til að fá bestu útkomu við greiningu á MIME-skráagerðum.",
+ "Transactional file locking is disabled, this might lead to issues with race conditions. Enable 'filelocking.enabled' in config.php to avoid these problems. See the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation ↗</a> for more information." : "Færslulæsing skráa (transactional file locking) er óvirk, þetta gæti leitt til vandamála út frá forgangsskilyrðum (race conditions). Virkjaðu 'filelocking.enabled' í config.php til að forðast slík vandamál. Skoðaðu <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">hjálparskjölin ↗</a> til að sjá nánari upplýsingar.",
"System locale can not be set to a one which supports UTF-8." : "Ekki var hægt að setja staðfærslu kerfisins á neina sem styður UTF-8.",
"This means that there might be problems with certain characters in file names." : "Þetta þýðir að það geta komið upp vandamál við að birta ákveðna stafi í skráaheitum.",
"We strongly suggest installing the required packages on your system to support one of the following locales: %s." : "Við mælum eindregið með því að þessir nauðsynlegu pakkar séu á kerfinu til stuðnings einnar af eftirfarandi staðfærslum: %s",
+ "If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwrite.cli.url\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Ef uppsetningin þín er ekki á rót lénsins og þú notar cron stýrikerfisins, þá geta komið upp vandamál við gerð URL-slóða. Til að forðast slík vandamál, skaltu stilla \"overwrite.cli.url\" valkostinn í config.php skránni þinni á slóð vefrótarinnar (webroot) í uppsetningunni (tillaga: \"%s\")",
"It was not possible to execute the cronjob via CLI. The following technical errors have appeared:" : "Ekki var hægt að keyra cron-verkið á skipanalínu. Eftirfarandi tæknilegar villur komu upp:",
"Please double check the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">installation guides ↗</a>, and check for any errors or warnings in the <a href=\"%s\">log</a>." : "Yfirfarðu vandlega <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">uppsetningarleiðbeiningarnar ↗</a>, og athugaðu hvort nokkrar villumeldingar eða aðvaranir séu í <a href=\"%s\">annálnum</a>.",
"All checks passed." : "Stóðst allar prófanir.",
@@ -367,6 +373,7 @@ OC.L10N.register(
"Hey there,<br><br>just letting you know that you now have an %s account.<br><br>Your username: %s<br>Access it: <a href=\"%s\">%s</a><br><br>" : "Hæ þú,<br><br>bara að láta þig vita að þú átt núna %s aðgang.<br><br>Notandanafnið þitt: %s<br>Tengstu honum: <a href=\"%s\">%s</a><br><br>",
"Hey there,\n\njust letting you know that you now have an %s account.\n\nYour username: %s\nAccess it: %s\n\n" : "Hæ þú,\n\nbara að láta þig vita að þú átt núna %s aðgang.\n\nNotandanafnið þitt: %s\nTengstu honum: %s\n\n",
"For password recovery and notifications" : "Fyrir tilkynningar og endurheimtingu lykilorðs",
+ "If you want to support the project\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">join development</a>\n\t\tor\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">spread the word</a>!" : "Ef þú vilt styðja við verkefnið\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">taktu þátt í þróuninni</a>\n\t\teða\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">láttu orð út ganga</a>!",
"Add Group" : "Bæta við hópi",
"Group" : "Hópur",
"Default Quota" : "Sjálfgefinn kvóti",
diff --git a/settings/l10n/is.json b/settings/l10n/is.json
index 286323f8c11..147a4ba5476 100644
--- a/settings/l10n/is.json
+++ b/settings/l10n/is.json
@@ -55,6 +55,7 @@
"Official apps are developed by and within the community. They offer central functionality and are ready for production use." : "Opinber forrit eru þróuð af og innan samfélagsins. Þau bjóða upp á ýmsa kjarnaeiginleika og eru tilbúin til notkunar í raunvinnslu.",
"Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Samþykkt forrit eru þróuð af treystum forriturum og hafa gengist undir lauslegar öryggisprófanir. Þau eru í virku viðhaldi í opnum hugbúnaðarsöfnum og umsjónarmenn þeirra dæma þau nógu stöðug til notkunar í allri venjulegri vinnslu.",
"This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Þetta forrit hefur ekki verið öryggisprófað, er nýtt erða þekkt fyrir ótöðugleika við vissar aðstæður. Uppsetning er á þína ábyrgð.",
+ "Disabling app …" : "Geri forrit óvirkt …",
"Error while disabling app" : "Villa við að afvirkja forrit",
"Disable" : "Gera óvirkt",
"Enable" : "Virkja",
@@ -122,6 +123,7 @@
"undo" : "afturkalla",
"never" : "aldrei",
"deleted {userName}" : "eyddi {userName}",
+ "No user found for <strong>{pattern}</strong>" : "Enginn notandi fannst fyrir <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Tókst ekki að bæta notanda við hópinn {group}",
"Unable to remove user from group {group}" : "Ekki tókst að fjarlægja notanda úr hópnum {group}",
"Add group" : "Bæta við hópi",
@@ -166,6 +168,7 @@
"Server-side encryption" : "Dulritun á þjóni",
"Enable server-side encryption" : "Virkja dulritun á þjóni",
"Please read carefully before activating server-side encryption: " : "Lestu eftirfarandi gaumgæfilega áður en þú virkjar dulritun á þjóni: ",
+ "Once encryption is enabled, all files uploaded to the server from that point forward will be encrypted at rest on the server. It will only be possible to disable encryption at a later date if the active encryption module supports that function, and all pre-conditions (e.g. setting a recover key) are met." : "Þegar dulritun er virkjuð, munu frá þeim tímapunkti allar skrár sem sendar eru inn á þjóninn verða dulritaðar inni á honum. Einungis mun verða hægt að afvirkja dulritun síðar, ef virka dulritunareiningin styður þá aðgerð, og ef allar forsendur (t.d. að setja endurheimtulykil) eru uppfylltar.",
"Encryption alone does not guarantee security of the system. Please see documentation for more information about how the encryption app works, and the supported use cases." : "Dulritun ein og sér tryggir ekki öryggi kerfisins. Endilega skoðaðu hjálparskjölin um hvernig dulritunarforritið virkar, og dæmi um hvaða uppsetningar eru studdar.",
"Be aware that encryption always increases the file size." : "Hafðu í huga að dulritun eykur alltaf skráastærð.",
"It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Það er góður siður að taka regluleg öryggisafrit af gögnunum þínum; ef um dulrituð gögn er að ræða, gakktu úr skugga um að einnig sé tekið öryggisafrit af dulritunarlyklum ásamt gögnunum.",
@@ -180,13 +183,16 @@
"php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "Það lítur út eins og að PHP sé ekki rétt sett upp varðandi fyrirspurnir um umhverfisbreytur. Prófun með getenv(\"PATH\") skilar auðu svari.",
"Please check the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">installation documentation ↗</a> for php configuration notes and the php configuration of your server, especially when using php-fpm." : "Endilega skoðaðu <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">hjálparskjöl uppsetningarinnar ↗</a> varðandi athugasemdir vegna uppsetningar PHP og sjálfa uppsetningu PHP-þjónsins, Sérstaklega ef þú notar php-fpm.",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Skrifvarða stillingaskráin hefur verið virkjuð. Þetta kemur í veg fyrir að hægt sé að sýsla með sumar stillingar í gegnum vefviðmótið. Að auki þarf þessi skrá að vera skrifanleg við hverja uppfærslu.",
+ "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "PHP virðist vera sett upp to fjarlægja innantextablokkir (inline doc blocks). Þetta mun gera ýmis kjarnaforrit óaðgengileg.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Þessu veldur væntanlega biðminni/hraðall á borð við Zend OPcache eða eAccelerator.",
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Gagnagrunnurinn keyrir ekki með \"READ COMMITTED\" færsluaðgreiningarstiginu. Þetta getur valdið vandamálum þegar margar aðgerðir eru keyrðar í einu.",
"%1$s below version %2$s is installed, for stability and performance reasons we recommend updating to a newer %1$s version." : "%1$s eldra en útgáfa %2$s er uppsett, en vegna stöðugleika og afkasta mælum við með að útgáfa %1$s verði sett upp.",
"The PHP module 'fileinfo' is missing. We strongly recommend to enable this module to get best results with mime-type detection." : "PHP-eininguna 'fileinfo' vantar. Við mælum eindregið með notkun þessarar einingar til að fá bestu útkomu við greiningu á MIME-skráagerðum.",
+ "Transactional file locking is disabled, this might lead to issues with race conditions. Enable 'filelocking.enabled' in config.php to avoid these problems. See the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentation ↗</a> for more information." : "Færslulæsing skráa (transactional file locking) er óvirk, þetta gæti leitt til vandamála út frá forgangsskilyrðum (race conditions). Virkjaðu 'filelocking.enabled' í config.php til að forðast slík vandamál. Skoðaðu <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">hjálparskjölin ↗</a> til að sjá nánari upplýsingar.",
"System locale can not be set to a one which supports UTF-8." : "Ekki var hægt að setja staðfærslu kerfisins á neina sem styður UTF-8.",
"This means that there might be problems with certain characters in file names." : "Þetta þýðir að það geta komið upp vandamál við að birta ákveðna stafi í skráaheitum.",
"We strongly suggest installing the required packages on your system to support one of the following locales: %s." : "Við mælum eindregið með því að þessir nauðsynlegu pakkar séu á kerfinu til stuðnings einnar af eftirfarandi staðfærslum: %s",
+ "If your installation is not installed in the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwrite.cli.url\" option in your config.php file to the webroot path of your installation (Suggested: \"%s\")" : "Ef uppsetningin þín er ekki á rót lénsins og þú notar cron stýrikerfisins, þá geta komið upp vandamál við gerð URL-slóða. Til að forðast slík vandamál, skaltu stilla \"overwrite.cli.url\" valkostinn í config.php skránni þinni á slóð vefrótarinnar (webroot) í uppsetningunni (tillaga: \"%s\")",
"It was not possible to execute the cronjob via CLI. The following technical errors have appeared:" : "Ekki var hægt að keyra cron-verkið á skipanalínu. Eftirfarandi tæknilegar villur komu upp:",
"Please double check the <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">installation guides ↗</a>, and check for any errors or warnings in the <a href=\"%s\">log</a>." : "Yfirfarðu vandlega <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">uppsetningarleiðbeiningarnar ↗</a>, og athugaðu hvort nokkrar villumeldingar eða aðvaranir séu í <a href=\"%s\">annálnum</a>.",
"All checks passed." : "Stóðst allar prófanir.",
@@ -365,6 +371,7 @@
"Hey there,<br><br>just letting you know that you now have an %s account.<br><br>Your username: %s<br>Access it: <a href=\"%s\">%s</a><br><br>" : "Hæ þú,<br><br>bara að láta þig vita að þú átt núna %s aðgang.<br><br>Notandanafnið þitt: %s<br>Tengstu honum: <a href=\"%s\">%s</a><br><br>",
"Hey there,\n\njust letting you know that you now have an %s account.\n\nYour username: %s\nAccess it: %s\n\n" : "Hæ þú,\n\nbara að láta þig vita að þú átt núna %s aðgang.\n\nNotandanafnið þitt: %s\nTengstu honum: %s\n\n",
"For password recovery and notifications" : "Fyrir tilkynningar og endurheimtingu lykilorðs",
+ "If you want to support the project\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">join development</a>\n\t\tor\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">spread the word</a>!" : "Ef þú vilt styðja við verkefnið\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">taktu þátt í þróuninni</a>\n\t\teða\n\t\t<a href=\"https://nextcloud.com/contribute\"\n\t\t\ttarget=\"_blank\" rel=\"noreferrer\">láttu orð út ganga</a>!",
"Add Group" : "Bæta við hópi",
"Group" : "Hópur",
"Default Quota" : "Sjálfgefinn kvóti",
diff --git a/settings/l10n/pl.js b/settings/l10n/pl.js
index f46fa84052a..2db3db32d80 100644
--- a/settings/l10n/pl.js
+++ b/settings/l10n/pl.js
@@ -125,6 +125,7 @@ OC.L10N.register(
"undo" : "cofnij",
"never" : "nigdy",
"deleted {userName}" : "usunięto {userName}",
+ "No user found for <strong>{pattern}</strong>" : "Nie znaleziono użytkownika dla <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Nie mogę dodać użytkownika do grupy {group}",
"Unable to remove user from group {group}" : "Nie mogę usunąć użytkownika z grupy {group}",
"Add group" : "Dodaj grupę",
diff --git a/settings/l10n/pl.json b/settings/l10n/pl.json
index 6bcb77480a4..bd10e734041 100644
--- a/settings/l10n/pl.json
+++ b/settings/l10n/pl.json
@@ -123,6 +123,7 @@
"undo" : "cofnij",
"never" : "nigdy",
"deleted {userName}" : "usunięto {userName}",
+ "No user found for <strong>{pattern}</strong>" : "Nie znaleziono użytkownika dla <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Nie mogę dodać użytkownika do grupy {group}",
"Unable to remove user from group {group}" : "Nie mogę usunąć użytkownika z grupy {group}",
"Add group" : "Dodaj grupę",
diff --git a/settings/l10n/pt_BR.js b/settings/l10n/pt_BR.js
index 14e52679104..1c27236f476 100644
--- a/settings/l10n/pt_BR.js
+++ b/settings/l10n/pt_BR.js
@@ -125,6 +125,7 @@ OC.L10N.register(
"undo" : "desfazer",
"never" : "nunca",
"deleted {userName}" : "eliminado {userName}",
+ "No user found for <strong>{pattern}</strong>" : "Nenhum usuário encontrado para <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Não é possível adicionar usuário ao grupo {group}",
"Unable to remove user from group {group}" : "Não é possível remover usuário do grupo {group}",
"Add group" : "Adicionar grupo",
diff --git a/settings/l10n/pt_BR.json b/settings/l10n/pt_BR.json
index 803ee756a89..164cb7e5eef 100644
--- a/settings/l10n/pt_BR.json
+++ b/settings/l10n/pt_BR.json
@@ -123,6 +123,7 @@
"undo" : "desfazer",
"never" : "nunca",
"deleted {userName}" : "eliminado {userName}",
+ "No user found for <strong>{pattern}</strong>" : "Nenhum usuário encontrado para <strong>{pattern}</strong>",
"Unable to add user to group {group}" : "Não é possível adicionar usuário ao grupo {group}",
"Unable to remove user from group {group}" : "Não é possível remover usuário do grupo {group}",
"Add group" : "Adicionar grupo",
diff --git a/settings/users.php b/settings/users.php
index 1b0f4f7b8e8..1986592af75 100644
--- a/settings/users.php
+++ b/settings/users.php
@@ -40,7 +40,7 @@ OC_Util::checkSubAdminUser();
\OC::$server->getNavigationManager()->setActiveEntry('core_users');
$userManager = \OC::$server->getUserManager();
-$groupManager = \OC_Group::getManager();
+$groupManager = \OC::$server->getGroupManager();
// Set the sort option: SORT_USERCOUNT or SORT_GROUPNAME
$sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php
index 6c6504b4de8..cc4bbee2d8d 100644
--- a/tests/lib/AppFramework/Http/RequestTest.php
+++ b/tests/lib/AppFramework/Http/RequestTest.php
@@ -1787,6 +1787,31 @@ class RequestTest extends \Test\TestCase {
$this->assertFalse($request->passesLaxCookieCheck());
}
+ public function testSkipCookieCheckForOCSRequests() {
+ /** @var Request $request */
+ $request = $this->getMockBuilder('\OC\AppFramework\Http\Request')
+ ->setMethods(['getScriptName'])
+ ->setConstructorArgs([
+ [
+ 'server' => [
+ 'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
+ 'HTTP_OCS_APIREQUEST' => 'true',
+ ],
+ 'cookies' => [
+ session_name() => 'asdf',
+ 'nc_sameSiteCookiestrict' => 'false',
+ ],
+ ],
+ $this->secureRandom,
+ $this->config,
+ $this->csrfTokenManager,
+ $this->stream
+ ])
+ ->getMock();
+
+ $this->assertTrue($request->passesStrictCookieCheck());
+ }
+
/**
* @return array
*/
diff --git a/tests/lib/Files/Cache/CacheTest.php b/tests/lib/Files/Cache/CacheTest.php
index 4c4f43d63d5..1bcf8832c63 100644
--- a/tests/lib/Files/Cache/CacheTest.php
+++ b/tests/lib/Files/Cache/CacheTest.php
@@ -11,6 +11,9 @@ namespace Test\Files\Cache;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use OC\Files\Cache\Cache;
+use OC\Files\Search\SearchComparison;
+use OC\Files\Search\SearchQuery;
+use OCP\Files\Search\ISearchComparison;
class LongId extends \OC\Files\Storage\Temporary {
public function getId() {
@@ -111,15 +114,15 @@ class CacheTest extends \Test\TestCase {
* @dataProvider folderDataProvider
*/
public function testFolder($folder) {
- if(strpos($folder, 'F09F9890')) {
+ if (strpos($folder, 'F09F9890')) {
// 4 byte UTF doesn't work on mysql
$params = \OC::$server->getDatabaseConnection()->getParams();
- if(\OC::$server->getDatabaseConnection()->getDatabasePlatform() instanceof MySqlPlatform && $params['charset'] !== 'utf8mb4') {
+ if (\OC::$server->getDatabaseConnection()->getDatabasePlatform() instanceof MySqlPlatform && $params['charset'] !== 'utf8mb4') {
$this->markTestSkipped('MySQL doesn\'t support 4 byte UTF-8');
}
}
- $file2 = $folder.'/bar';
- $file3 = $folder.'/foo';
+ $file2 = $folder . '/bar';
+ $file3 = $folder . '/foo';
$data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory');
$fileData = array();
$fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
@@ -138,7 +141,7 @@ class CacheTest extends \Test\TestCase {
}
}
- $file4 = $folder.'/unkownSize';
+ $file4 = $folder . '/unkownSize';
$fileData['unkownSize'] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'foo/file');
$this->cache->put($file4, $fileData['unkownSize']);
@@ -155,8 +158,8 @@ class CacheTest extends \Test\TestCase {
$this->assertEquals(0, $this->cache->calculateFolderSize($folder));
$this->cache->remove($folder);
- $this->assertFalse($this->cache->inCache($folder.'/foo'));
- $this->assertFalse($this->cache->inCache($folder.'/bar'));
+ $this->assertFalse($this->cache->inCache($folder . '/foo'));
+ $this->assertFalse($this->cache->inCache($folder . '/bar'));
}
public function testRemoveRecursive() {
@@ -165,7 +168,7 @@ class CacheTest extends \Test\TestCase {
$folders = ['folder', 'folder/subfolder', 'folder/sub2', 'folder/sub2/sub3'];
$files = ['folder/foo.txt', 'folder/bar.txt', 'folder/subfolder/asd.txt', 'folder/sub2/qwerty.txt', 'folder/sub2/sub3/foo.txt'];
- foreach($folders as $folder){
+ foreach ($folders as $folder) {
$this->cache->put($folder, $folderData);
}
foreach ($files as $file) {
@@ -360,7 +363,9 @@ class CacheTest extends \Test\TestCase {
$this->assertEquals(2, count($results));
- usort($results, function($value1, $value2) { return $value1['name'] >= $value2['name']; });
+ usort($results, function ($value1, $value2) {
+ return $value1['name'] >= $value2['name'];
+ });
$this->assertEquals('folder', $results[0]['name']);
$this->assertEquals('foo', $results[1]['name']);
@@ -368,11 +373,15 @@ class CacheTest extends \Test\TestCase {
// use tag id
$tags = $tagManager->getTagsForUser($userId);
$this->assertNotEmpty($tags);
- $tags = array_filter($tags, function($tag) { return $tag->getName() === 'tag2'; });
+ $tags = array_filter($tags, function ($tag) {
+ return $tag->getName() === 'tag2';
+ });
$results = $this->cache->searchByTag(current($tags)->getId(), $userId);
$this->assertEquals(3, count($results));
- usort($results, function($value1, $value2) { return $value1['name'] >= $value2['name']; });
+ usort($results, function ($value1, $value2) {
+ return $value1['name'] >= $value2['name'];
+ });
$this->assertEquals('folder', $results[0]['name']);
$this->assertEquals('foo2', $results[1]['name']);
@@ -383,7 +392,42 @@ class CacheTest extends \Test\TestCase {
$this->logout();
$user = \OC::$server->getUserManager()->get($userId);
- if ($user !== null) { $user->delete(); }
+ if ($user !== null) {
+ $user->delete();
+ }
+ }
+
+ function testSearchByQuery() {
+ $file1 = 'folder';
+ $file2 = 'folder/foobar';
+ $file3 = 'folder/foo';
+ $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder');
+ $fileData = array();
+ $fileData['foobar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file');
+ $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file');
+
+ $this->cache->put($file1, $data1);
+ $this->cache->put($file2, $fileData['foobar']);
+ $this->cache->put($file3, $fileData['foo']);
+
+ $this->assertCount(1, $this->cache->searchQuery(new SearchQuery(
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foo')
+ , 10, 0, [])));
+ $this->assertCount(2, $this->cache->searchQuery(new SearchQuery(
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', 'foo%')
+ , 10, 0, [])));
+ $this->assertCount(2, $this->cache->searchQuery(new SearchQuery(
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'foo/file')
+ , 10, 0, [])));
+ $this->assertCount(3, $this->cache->searchQuery(new SearchQuery(
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'foo/%')
+ , 10, 0, [])));
+ $this->assertCount(1, $this->cache->searchQuery(new SearchQuery(
+ new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'size', 100)
+ , 10, 0, [])));
+ $this->assertCount(2, $this->cache->searchQuery(new SearchQuery(
+ new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN_EQUAL, 'size', 100)
+ , 10, 0, [])));
}
function testMove() {
@@ -626,9 +670,9 @@ class CacheTest extends \Test\TestCase {
public function escapingProvider() {
return [
- ['foo'],
- ['o%'],
- ['oth_r'],
+ ['foo'],
+ ['o%'],
+ ['oth_r'],
];
}
diff --git a/tests/lib/Files/Cache/QuerySearchHelperTest.php b/tests/lib/Files/Cache/QuerySearchHelperTest.php
new file mode 100644
index 00000000000..f458ef039e1
--- /dev/null
+++ b/tests/lib/Files/Cache/QuerySearchHelperTest.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.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\Cache;
+
+use OC\DB\QueryBuilder\Literal;
+use OC\Files\Cache\QuerySearchHelper;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\Files\IMimeTypeLoader;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use OCP\Files\Search\ISearchOperator;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class QuerySearchHelperTest extends TestCase {
+ /** @var IQueryBuilder */
+ private $builder;
+
+ /** @var IMimeTypeLoader|\PHPUnit_Framework_MockObject_MockObject */
+ private $mimetypeLoader;
+
+ /** @var QuerySearchHelper */
+ private $querySearchHelper;
+
+ /** @var integer */
+ private $numericStorageId;
+
+ public function setUp() {
+ parent::setUp();
+ $this->builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+ $this->mimetypeLoader = $this->createMock(IMimeTypeLoader::class);
+
+ $this->mimetypeLoader->expects($this->any())
+ ->method('getId')
+ ->willReturnMap([
+ ['text', 1],
+ ['text/plain', 2],
+ ['text/xml', 3],
+ ['image/jpg', 4],
+ ['image/png', 5],
+ ['image', 6],
+ ]);
+
+ $this->mimetypeLoader->expects($this->any())
+ ->method('getMimetypeById')
+ ->willReturnMap([
+ [1, 'text'],
+ [2, 'text/plain'],
+ [3, 'text/xml'],
+ [4, 'image/jpg'],
+ [5, 'image/png'],
+ [6, 'image']
+ ]);
+
+ $this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
+ $this->numericStorageId = 10000;
+
+ $this->builder->select(['fileid'])
+ ->from('filecache')
+ ->where($this->builder->expr()->eq('storage', new Literal($this->numericStorageId)));
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+
+ $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+
+ $builder->delete('filecache')
+ ->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->numericStorageId, IQueryBuilder::PARAM_INT)));
+
+ $builder->execute();
+ }
+
+ private function addCacheEntry(array $data) {
+ $data['storage'] = $this->numericStorageId;
+ $data['etag'] = 'unimportant';
+ $data['storage_mtime'] = $data['mtime'];
+ if (!isset($data['path'])) {
+ $data['path'] = 'random/' . $this->getUniqueID();
+ }
+ $data['path_hash'] = md5($data['path']);
+ if (!isset($data['mtime'])) {
+ $data['mtime'] = 100;
+ }
+ if (!isset($data['size'])) {
+ $data['size'] = 100;
+ }
+ $data['name'] = basename($data['path']);
+ $data['parent'] = -1;
+ if (isset($data['mimetype'])) {
+ list($mimepart,) = explode('/', $data['mimetype']);
+ $data['mimepart'] = $this->mimetypeLoader->getId($mimepart);
+ $data['mimetype'] = $this->mimetypeLoader->getId($data['mimetype']);
+ } else {
+ $data['mimepart'] = 1;
+ $data['mimetype'] = 1;
+ }
+
+ $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
+
+ $values = [];
+ foreach ($data as $key => $value) {
+ $values[$key] = $builder->createNamedParameter($value);
+ }
+
+ $builder->insert('filecache')
+ ->values($values)
+ ->execute();
+ }
+
+ private function search(ISearchOperator $operator) {
+ $dbOperator = $this->querySearchHelper->searchOperatorToDBExpr($this->builder, $operator);
+ $this->builder->andWhere($dbOperator);
+ return $this->builder->execute()->fetchAll(\PDO::FETCH_COLUMN);
+ }
+
+ public function comparisonProvider() {
+ return [
+ [new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125), [1002]],
+ [new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [1001]],
+ [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 125), []],
+ [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50), [1001, 1002]],
+ [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), [1001]],
+ [new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', 'foo%'), [1001, 1002]],
+ [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpg'), [1001]],
+ [new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'image/%'), [1001, 1002]],
+ [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
+ new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [1001]
+ ]), [1001]],
+ [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 100),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
+ ]), [1001, 1002]],
+ [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
+ ]), [1001]],
+ [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
+ new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125),
+ ]), [1001]],
+ [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
+ new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
+ ]), [1002]],
+ [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%bar'),
+ ]), [1002]],
+
+ ];
+ }
+
+ /**
+ * @dataProvider comparisonProvider
+ *
+ * @param ISearchOperator $operator
+ * @param array $fileIds
+ */
+ public function testComparison(ISearchOperator $operator, array $fileIds) {
+ $this->addCacheEntry([
+ 'path' => 'foobar',
+ 'fileid' => 1001,
+ 'mtime' => 100,
+ 'size' => 50,
+ 'mimetype' => 'image/jpg'
+ ]);
+
+ $this->addCacheEntry([
+ 'path' => 'fooasd',
+ 'fileid' => 1002,
+ 'mtime' => 150,
+ 'size' => 50,
+ 'mimetype' => 'image/png'
+ ]);
+
+ $results = $this->search($operator);
+
+ sort($fileIds);
+ sort($results);
+
+ $this->assertEquals($fileIds, $results);
+ }
+}
diff --git a/tests/lib/Group/LegacyGroupTest.php b/tests/lib/Group/LegacyGroupTest.php
deleted file mode 100644
index b7d13437a64..00000000000
--- a/tests/lib/Group/LegacyGroupTest.php
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-/**
- * ownCloud
- *
- * @author Robin Appelman
- * @author Bernhard Posselt
- * @copyright 2012 Robin Appelman <icewind@owncloud.com>
- * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-namespace Test\Group;
-
-use OC_Group;
-use OC_User;
-
-/**
- * Class LegacyGroupTest
- *
- * @package Test\Group
- * @group DB
- */
-class LegacyGroupTest extends \Test\TestCase {
- protected function setUp() {
- parent::setUp();
- OC_Group::clearBackends();
- OC_User::clearBackends();
- }
-
- public function testSingleBackend() {
- $userBackend = new \Test\Util\User\Dummy();
- \OC::$server->getUserManager()->registerBackend($userBackend);
- OC_Group::useBackend(new \Test\Util\Group\Dummy());
-
- $group1 = $this->getUniqueID();
- $group2 = $this->getUniqueID();
- OC_Group::createGroup($group1);
- OC_Group::createGroup($group2);
-
- $user1 = $this->getUniqueID();
- $user2 = $this->getUniqueID();
- $userBackend->createUser($user1, '');
- $userBackend->createUser($user2, '');
-
- $this->assertFalse(OC_Group::inGroup($user1, $group1), 'Asserting that user1 is not in group1');
- $this->assertFalse(OC_Group::inGroup($user2, $group1), 'Asserting that user2 is not in group1');
- $this->assertFalse(OC_Group::inGroup($user1, $group2), 'Asserting that user1 is not in group2');
- $this->assertFalse(OC_Group::inGroup($user2, $group2), 'Asserting that user2 is not in group2');
-
- $this->assertTrue(OC_Group::addToGroup($user1, $group1));
-
- $this->assertTrue(OC_Group::inGroup($user1, $group1), 'Asserting that user1 is in group1');
- $this->assertFalse(OC_Group::inGroup($user2, $group1), 'Asserting that user2 is not in group1');
- $this->assertFalse(OC_Group::inGroup($user1, $group2), 'Asserting that user1 is not in group2');
- $this->assertFalse(OC_Group::inGroup($user2, $group2), 'Asserting that user2 is not in group2');
-
- $this->assertTrue(OC_Group::addToGroup($user1, $group1));
-
- $this->assertEquals(array($user1), OC_Group::usersInGroup($group1));
- $this->assertEquals(array(), OC_Group::usersInGroup($group2));
-
- $this->assertEquals(array($group1), OC_Group::getUserGroups($user1));
- $this->assertEquals(array(), OC_Group::getUserGroups($user2));
-
- OC_Group::deleteGroup($group1);
- $this->assertEquals(array(), OC_Group::getUserGroups($user1));
- $this->assertEquals(array(), OC_Group::usersInGroup($group1));
- $this->assertFalse(OC_Group::inGroup($user1, $group1));
- }
-
-
- public function testNoEmptyGIDs() {
- OC_Group::useBackend(new \Test\Util\Group\Dummy());
- $emptyGroup = null;
-
- $this->assertFalse(OC_Group::createGroup($emptyGroup));
- }
-
-
- public function testNoGroupsTwice() {
- OC_Group::useBackend(new \Test\Util\Group\Dummy());
- $group = $this->getUniqueID();
- OC_Group::createGroup($group);
-
- $groupCopy = $group;
-
- OC_Group::createGroup($groupCopy);
- $this->assertEquals(array($group), OC_Group::getGroups());
- }
-
-
- public function testDontDeleteAdminGroup() {
- OC_Group::useBackend(new \Test\Util\Group\Dummy());
- $adminGroup = 'admin';
- OC_Group::createGroup($adminGroup);
-
- $this->assertFalse(OC_Group::deleteGroup($adminGroup));
- $this->assertEquals(array($adminGroup), OC_Group::getGroups());
- }
-
-
- public function testDontAddUserToNonexistentGroup() {
- OC_Group::useBackend(new \Test\Util\Group\Dummy());
- $groupNonExistent = 'notExistent';
- $user = $this->getUniqueID();
-
- $this->assertEquals(false, OC_Group::addToGroup($user, $groupNonExistent));
- $this->assertEquals(array(), OC_Group::getGroups());
- }
-
- public function testUsersInGroup() {
- OC_Group::useBackend(new \Test\Util\Group\Dummy());
- $userBackend = new \Test\Util\User\Dummy();
- \OC::$server->getUserManager()->registerBackend($userBackend);
-
- $group1 = $this->getUniqueID();
- $group2 = $this->getUniqueID();
- $group3 = $this->getUniqueID();
- $user1 = $this->getUniqueID();
- $user2 = $this->getUniqueID();
- $user3 = $this->getUniqueID();
- OC_Group::createGroup($group1);
- OC_Group::createGroup($group2);
- OC_Group::createGroup($group3);
-
- $userBackend->createUser($user1, '');
- $userBackend->createUser($user2, '');
- $userBackend->createUser($user3, '');
-
- OC_Group::addToGroup($user1, $group1);
- OC_Group::addToGroup($user2, $group1);
- OC_Group::addToGroup($user3, $group1);
- OC_Group::addToGroup($user3, $group2);
-
- $this->assertEquals(array($user1, $user2, $user3),
- OC_Group::usersInGroups(array($group1, $group2, $group3)));
-
- // FIXME: needs more parameter variation
- }
-
- public function testMultiBackend() {
- $userBackend = new \Test\Util\User\Dummy();
- \OC::$server->getUserManager()->registerBackend($userBackend);
- $backend1 = new \Test\Util\Group\Dummy();
- $backend2 = new \Test\Util\Group\Dummy();
- OC_Group::useBackend($backend1);
- OC_Group::useBackend($backend2);
-
- $group1 = $this->getUniqueID();
- $group2 = $this->getUniqueID();
- OC_Group::createGroup($group1);
-
- //groups should be added to the first registered backend
- $this->assertEquals(array($group1), $backend1->getGroups());
- $this->assertEquals(array(), $backend2->getGroups());
-
- $this->assertEquals(array($group1), OC_Group::getGroups());
- $this->assertTrue(OC_Group::groupExists($group1));
- $this->assertFalse(OC_Group::groupExists($group2));
-
- $backend1->createGroup($group2);
-
- $this->assertEquals(array($group1, $group2), OC_Group::getGroups());
- $this->assertTrue(OC_Group::groupExists($group1));
- $this->assertTrue(OC_Group::groupExists($group2));
-
- $user1 = $this->getUniqueID();
- $user2 = $this->getUniqueID();
-
- $userBackend->createUser($user1, '');
- $userBackend->createUser($user2, '');
-
- $this->assertFalse(OC_Group::inGroup($user1, $group1));
- $this->assertFalse(OC_Group::inGroup($user2, $group1));
-
-
- $this->assertTrue(OC_Group::addToGroup($user1, $group1));
-
- $this->assertTrue(OC_Group::inGroup($user1, $group1));
- $this->assertFalse(OC_Group::inGroup($user2, $group1));
- $this->assertFalse($backend2->inGroup($user1, $group1));
-
- OC_Group::addToGroup($user1, $group1);
-
- $this->assertEquals(array($user1), OC_Group::usersInGroup($group1));
-
- $this->assertEquals(array($group1), OC_Group::getUserGroups($user1));
- $this->assertEquals(array(), OC_Group::getUserGroups($user2));
-
- OC_Group::deleteGroup($group1);
- $this->assertEquals(array(), OC_Group::getUserGroups($user1));
- $this->assertEquals(array(), OC_Group::usersInGroup($group1));
- $this->assertFalse(OC_Group::inGroup($user1, $group1));
- }
-}
diff --git a/tests/lib/OCS/ProviderTest.php b/tests/lib/OCS/ProviderTest.php
index 399fd3933d9..9444544d12a 100644
--- a/tests/lib/OCS/ProviderTest.php
+++ b/tests/lib/OCS/ProviderTest.php
@@ -48,11 +48,16 @@ class ProviderTest extends \Test\TestCase {
$this->appManager
->expects($this->at(1))
->method('isEnabledForUser')
- ->with('activity')
+ ->with('federation')
->will($this->returnValue(false));
$this->appManager
->expects($this->at(2))
->method('isEnabledForUser')
+ ->with('activity')
+ ->will($this->returnValue(false));
+ $this->appManager
+ ->expects($this->at(3))
+ ->method('isEnabledForUser')
->with('provisioning_api')
->will($this->returnValue(false));
@@ -84,11 +89,16 @@ class ProviderTest extends \Test\TestCase {
$this->appManager
->expects($this->at(1))
->method('isEnabledForUser')
- ->with('activity')
+ ->with('federation')
->will($this->returnValue(false));
$this->appManager
->expects($this->at(2))
->method('isEnabledForUser')
+ ->with('activity')
+ ->will($this->returnValue(false));
+ $this->appManager
+ ->expects($this->at(3))
+ ->method('isEnabledForUser')
->with('provisioning_api')
->will($this->returnValue(false));
@@ -124,6 +134,55 @@ class ProviderTest extends \Test\TestCase {
$this->assertEquals($expected, $this->ocsProvider->buildProviderList());
}
+ public function testBuildProviderListWithFederationEnabled() {
+ $this->appManager
+ ->expects($this->at(0))
+ ->method('isEnabledForUser')
+ ->with('files_sharing')
+ ->will($this->returnValue(false));
+ $this->appManager
+ ->expects($this->at(1))
+ ->method('isEnabledForUser')
+ ->with('federation')
+ ->will($this->returnValue(true));
+ $this->appManager
+ ->expects($this->at(2))
+ ->method('isEnabledForUser')
+ ->with('activity')
+ ->will($this->returnValue(false));
+ $this->appManager
+ ->expects($this->at(3))
+ ->method('isEnabledForUser')
+ ->with('provisioning_api')
+ ->will($this->returnValue(false));
+
+ $expected = new \OCP\AppFramework\Http\JSONResponse(
+ [
+ 'version' => 2,
+ 'services' => [
+ 'PRIVATE_DATA' => [
+ 'version' => 1,
+ 'endpoints' => [
+ 'store' => '/ocs/v2.php/privatedata/setattribute',
+ 'read' => '/ocs/v2.php/privatedata/getattribute',
+ 'delete' => '/ocs/v2.php/privatedata/deleteattribute',
+ ],
+ ],
+ 'FEDERATED_SHARING' => [
+ 'version' => 1,
+ 'endpoints' => [
+ 'shared-secret' => '/ocs/v2.php/cloud/shared-secret',
+ 'system-address-book' => '/remote.php/dav/addressbooks/system/system/system',
+ 'carddav-user' => 'system'
+ ],
+ ],
+ ],
+ ]
+ );
+
+ $this->assertEquals($expected, $this->ocsProvider->buildProviderList());
+ }
+
public function testBuildProviderListWithEverythingEnabled() {
$this->appManager
->expects($this->any())
@@ -147,6 +206,9 @@ class ProviderTest extends \Test\TestCase {
'endpoints' => [
'share' => '/ocs/v2.php/cloud/shares',
'webdav' => '/public.php/webdav/',
+ 'shared-secret' => '/ocs/v2.php/cloud/shared-secret',
+ 'system-address-book' => '/remote.php/dav/addressbooks/system/system/system',
+ 'carddav-user' => 'system'
],
],
'SHARING' => [