diff options
126 files changed, 2741 insertions, 855 deletions
diff --git a/.drone.yml b/.drone.yml index 5e4f18af9f6..5d4ab2ca963 100644 --- a/.drone.yml +++ b/.drone.yml @@ -565,3 +565,5 @@ services: when: matrix: OBJECT_STORE: s3 + +branches: [ master, stable* ] 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/ca.js b/apps/files/l10n/ca.js index f43200a5a05..7ab199c4c42 100644 --- a/apps/files/l10n/ca.js +++ b/apps/files/l10n/ca.js @@ -47,6 +47,7 @@ OC.L10N.register( "_%n folder_::_%n folders_" : ["%n carpeta","%n carpetes"], "_%n file_::_%n files_" : ["%n fitxer","%n fitxers"], "{dirs} and {files}" : "{dirs} i {files}", + "_including %n hidden_::_including %n hidden_" : ["incloent %n ocult","incloent %n ocults"], "You don’t have permission to upload or create files here" : "No teniu permisos per a pujar o crear els fitxers aquí", "_Uploading %n file_::_Uploading %n files_" : ["Pujant %n fitxer","Pujant %n fitxers"], "New" : "Nou", @@ -59,6 +60,7 @@ OC.L10N.register( "_matches '{filter}'_::_match '{filter}'_" : ["coincidències '{filter}'","coincidència '{filter}'"], "View in folder" : "Veure a la carpeta", "Path" : "Ruta", + "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"], "Favorited" : "Agregat a favorits", "Favorite" : "Preferits", "Copy local link" : "C", @@ -76,6 +78,7 @@ OC.L10N.register( "Restored by {user}" : "Restaurat per {user}", "Renamed by {user}" : "Reanomenat per {user}", "Moved by {user}" : "Mogut per {user}", + "You created {file}" : "Has creat {file}", "You deleted {file}" : "Heu esborrat {file}", "You renamed {oldfile} to {newfile}" : "Heu reanomenat {oldfile} a {newfile}", "{user} renamed {oldfile} to {newfile}" : "{user} ha reanomenat {oldfile} a {newfile}", diff --git a/apps/files/l10n/ca.json b/apps/files/l10n/ca.json index 0f52e17bdbb..40d96e8afda 100644 --- a/apps/files/l10n/ca.json +++ b/apps/files/l10n/ca.json @@ -45,6 +45,7 @@ "_%n folder_::_%n folders_" : ["%n carpeta","%n carpetes"], "_%n file_::_%n files_" : ["%n fitxer","%n fitxers"], "{dirs} and {files}" : "{dirs} i {files}", + "_including %n hidden_::_including %n hidden_" : ["incloent %n ocult","incloent %n ocults"], "You don’t have permission to upload or create files here" : "No teniu permisos per a pujar o crear els fitxers aquí", "_Uploading %n file_::_Uploading %n files_" : ["Pujant %n fitxer","Pujant %n fitxers"], "New" : "Nou", @@ -57,6 +58,7 @@ "_matches '{filter}'_::_match '{filter}'_" : ["coincidències '{filter}'","coincidència '{filter}'"], "View in folder" : "Veure a la carpeta", "Path" : "Ruta", + "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"], "Favorited" : "Agregat a favorits", "Favorite" : "Preferits", "Copy local link" : "C", @@ -74,6 +76,7 @@ "Restored by {user}" : "Restaurat per {user}", "Renamed by {user}" : "Reanomenat per {user}", "Moved by {user}" : "Mogut per {user}", + "You created {file}" : "Has creat {file}", "You deleted {file}" : "Heu esborrat {file}", "You renamed {oldfile} to {newfile}" : "Heu reanomenat {oldfile} a {newfile}", "{user} renamed {oldfile} to {newfile}" : "{user} ha reanomenat {oldfile} a {newfile}", diff --git a/apps/files/l10n/ja.js b/apps/files/l10n/ja.js index 58585944f9c..f01be7e1b85 100644 --- a/apps/files/l10n/ja.js +++ b/apps/files/l10n/ja.js @@ -174,6 +174,9 @@ OC.L10N.register( "%2$s restored %1$s" : "%2$s は、 %1$s を復元しました", "Changed by %2$s" : "%2$s により更新", "Deleted by %2$s" : "%2$s により削除", - "Restored by %2$s" : "%2$s により復元" + "Restored by %2$s" : "%2$s により復元", + "_{hours}:{minutes}:{seconds} hour left_::_{hours}:{minutes}:{seconds} hours left_" : ["残り {hours}:{minutes}:{seconds} 時間"], + "_{minutes}:{seconds} minute left_::_{minutes}:{seconds} minutes left_" : ["残り {minutes}:{seconds} 分"], + "_{seconds} second left_::_{seconds} seconds left_" : ["残り {seconds} 秒"] }, "nplurals=1; plural=0;"); diff --git a/apps/files/l10n/ja.json b/apps/files/l10n/ja.json index 12cf9d4907c..7a69ccf1b7e 100644 --- a/apps/files/l10n/ja.json +++ b/apps/files/l10n/ja.json @@ -172,6 +172,9 @@ "%2$s restored %1$s" : "%2$s は、 %1$s を復元しました", "Changed by %2$s" : "%2$s により更新", "Deleted by %2$s" : "%2$s により削除", - "Restored by %2$s" : "%2$s により復元" + "Restored by %2$s" : "%2$s により復元", + "_{hours}:{minutes}:{seconds} hour left_::_{hours}:{minutes}:{seconds} hours left_" : ["残り {hours}:{minutes}:{seconds} 時間"], + "_{minutes}:{seconds} minute left_::_{minutes}:{seconds} minutes left_" : ["残り {minutes}:{seconds} 分"], + "_{seconds} second left_::_{seconds} seconds left_" : ["残り {seconds} 秒"] },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file 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/theming/l10n/pt_BR.js b/apps/theming/l10n/pt_BR.js index 35bafd769a3..7a2e6d9986b 100644 --- a/apps/theming/l10n/pt_BR.js +++ b/apps/theming/l10n/pt_BR.js @@ -1,7 +1,7 @@ OC.L10N.register( "theming", { - "Admin" : "Admin", + "Admin" : "Administrador", "a safe home for all your data" : "um lugar seguro para todos os seus dados", "The given name is too long" : "O nome é demasiado longo", "The given web address is too long" : "O endereço da Web fornecido é muito longo", @@ -11,7 +11,7 @@ OC.L10N.register( "No file uploaded" : "Nenhum arquivo enviado", "Unsupported image type" : "Tipo de imagem não suportado", "You are already using a custom theme" : "Você já está usando um tema personalizado", - "Theming" : "Dando formato", + "Theming" : "Personalizando", "Name" : "Nome", "reset to default" : "restaurar ao padrão", "Web address" : "Endereço da Web", @@ -21,7 +21,7 @@ OC.L10N.register( "Logo" : "Logo", "Upload new logo" : "Enviar novo logotipo", "Login image" : "Imagem de login", - "Upload new login background" : "Enviar novo login em background", - "Log in image" : "Log em imagem" + "Upload new login background" : "Enviar novo fundo para o login", + "Log in image" : "Imagem do login" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/theming/l10n/pt_BR.json b/apps/theming/l10n/pt_BR.json index d27c222635f..9396173e985 100644 --- a/apps/theming/l10n/pt_BR.json +++ b/apps/theming/l10n/pt_BR.json @@ -1,5 +1,5 @@ { "translations": { - "Admin" : "Admin", + "Admin" : "Administrador", "a safe home for all your data" : "um lugar seguro para todos os seus dados", "The given name is too long" : "O nome é demasiado longo", "The given web address is too long" : "O endereço da Web fornecido é muito longo", @@ -9,7 +9,7 @@ "No file uploaded" : "Nenhum arquivo enviado", "Unsupported image type" : "Tipo de imagem não suportado", "You are already using a custom theme" : "Você já está usando um tema personalizado", - "Theming" : "Dando formato", + "Theming" : "Personalizando", "Name" : "Nome", "reset to default" : "restaurar ao padrão", "Web address" : "Endereço da Web", @@ -19,7 +19,7 @@ "Logo" : "Logo", "Upload new logo" : "Enviar novo logotipo", "Login image" : "Imagem de login", - "Upload new login background" : "Enviar novo login em background", - "Log in image" : "Log em imagem" + "Upload new login background" : "Enviar novo fundo para o login", + "Log in image" : "Imagem do login" },"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/guest.css b/core/css/guest.css index e9538e380e6..e6e194f6417 100644 --- a/core/css/guest.css +++ b/core/css/guest.css @@ -148,6 +148,7 @@ select { cursor: pointer; } input[type='text'], +input[type='tel'], input[type='password'], input[type='email'] { width: 249px; @@ -623,3 +624,16 @@ footer, .push { height: 70px; } + +.hidden { + display: none; +} + +.hidden-visually { + position: absolute; + left:-10000px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; +} 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/ca.js b/core/l10n/ca.js index d907297a45d..19129c4700d 100644 --- a/core/l10n/ca.js +++ b/core/l10n/ca.js @@ -27,13 +27,16 @@ OC.L10N.register( "Turned on maintenance mode" : "Activat el mode de manteniment", "Turned off maintenance mode" : "Desactivat el mode de manteniment", "Maintenance mode is kept active" : "El mode de manteniment es manté activat", + "Updating database schema" : "Actualitzant l'esquema de la base de dades", "Updated database" : "Actualitzada la base de dades", "Checked database schema update" : "S'ha comprobat l'actualització de l'esquema de la base de dades", "Checked database schema update for apps" : "S'ha comprobat l'actualització de l'esquema de la base de dades per les apps", "Updated \"%s\" to %s" : "Actualitzat \"%s\" a %s", + "%s (3rdparty)" : "%s (de tercers)", "Following apps have been disabled: %s" : "Les aplicacions següents s'han deshabilitat: %s", "Already up to date" : "Ja actualitzat", "Settings" : "Configuració", + "Connection to server lost" : "S'ha perdut la connexió amb el servidor", "Saving..." : "Desant...", "Dismiss" : "Rebutja", "Authentication required" : "Es requereix autenticació", diff --git a/core/l10n/ca.json b/core/l10n/ca.json index 49c17f21b63..0c3c42d7f2f 100644 --- a/core/l10n/ca.json +++ b/core/l10n/ca.json @@ -25,13 +25,16 @@ "Turned on maintenance mode" : "Activat el mode de manteniment", "Turned off maintenance mode" : "Desactivat el mode de manteniment", "Maintenance mode is kept active" : "El mode de manteniment es manté activat", + "Updating database schema" : "Actualitzant l'esquema de la base de dades", "Updated database" : "Actualitzada la base de dades", "Checked database schema update" : "S'ha comprobat l'actualització de l'esquema de la base de dades", "Checked database schema update for apps" : "S'ha comprobat l'actualització de l'esquema de la base de dades per les apps", "Updated \"%s\" to %s" : "Actualitzat \"%s\" a %s", + "%s (3rdparty)" : "%s (de tercers)", "Following apps have been disabled: %s" : "Les aplicacions següents s'han deshabilitat: %s", "Already up to date" : "Ja actualitzat", "Settings" : "Configuració", + "Connection to server lost" : "S'ha perdut la connexió amb el servidor", "Saving..." : "Desant...", "Dismiss" : "Rebutja", "Authentication required" : "Es requereix autenticació", 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/ja.js b/core/l10n/ja.js index ad71d7f28d6..e8e96b38b0a 100644 --- a/core/l10n/ja.js +++ b/core/l10n/ja.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>." : "リバースプロキシヘッダーの設定が正しくないか、信頼できるプロキシからNextcloudにアクセスしています。信頼できるプロキシからNextcloudにアクセスしていない場合、これはセキュリティ上の問題であり、攻撃者が自分のIPアドレスを偽装してNextcloudに見えるようにしている可能性があります。詳細については、<a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">ドキュメント</a>をご覧ください。", "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 は分散キャッシュとして設定されています。しかし、PHPモジュール \"memcache\"が間違ってインストールされています。 \\OC\\Memcache\\Memcached は、\"memcached\" のみをサポートしています。\"memcache\" ではありません。<a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki で両方のモジュールの情報</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>)" : "いくつかのファイルでチェックサムが適合しませんでした。この問題を解決するためは、<a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">ドキュメント</a>の詳細を見てください。(<a href=\"{codeIntegrityDownloadEndpoint}\">不適合ファイルのリスト…</a> / <a href=\"{rescanEndpoint}\">再チェック…</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 が正しく設定されていません。 <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">パフォーマンスを向上させるため ↗</a> <code>php.ini</code> で次の設定を使用することをお勧めします:", "Error occurred while checking server setup" : "サーバー設定のチェック中にエラーが発生しました", "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." : "データディレクトリとファイルがインターネットからアクセス可能になっている可能性があります。.htaccessファイルが機能していません。データディレクトリがアクセスされないようにWebサーバーを設定するか、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 ヘッダは \"{expected}\" に設定されていません。これは潜在的なセキュリティリスクもしくはプライバシーリスクとなる可能性があるため、この設定を見直すことをおすすめします。", diff --git a/core/l10n/ja.json b/core/l10n/ja.json index 34e9d81823b..28ea4f40913 100644 --- a/core/l10n/ja.json +++ b/core/l10n/ja.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>." : "リバースプロキシヘッダーの設定が正しくないか、信頼できるプロキシからNextcloudにアクセスしています。信頼できるプロキシからNextcloudにアクセスしていない場合、これはセキュリティ上の問題であり、攻撃者が自分のIPアドレスを偽装してNextcloudに見えるようにしている可能性があります。詳細については、<a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">ドキュメント</a>をご覧ください。", "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 は分散キャッシュとして設定されています。しかし、PHPモジュール \"memcache\"が間違ってインストールされています。 \\OC\\Memcache\\Memcached は、\"memcached\" のみをサポートしています。\"memcache\" ではありません。<a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki で両方のモジュールの情報</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>)" : "いくつかのファイルでチェックサムが適合しませんでした。この問題を解決するためは、<a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">ドキュメント</a>の詳細を見てください。(<a href=\"{codeIntegrityDownloadEndpoint}\">不適合ファイルのリスト…</a> / <a href=\"{rescanEndpoint}\">再チェック…</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 が正しく設定されていません。 <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">パフォーマンスを向上させるため ↗</a> <code>php.ini</code> で次の設定を使用することをお勧めします:", "Error occurred while checking server setup" : "サーバー設定のチェック中にエラーが発生しました", "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." : "データディレクトリとファイルがインターネットからアクセス可能になっている可能性があります。.htaccessファイルが機能していません。データディレクトリがアクセスされないようにWebサーバーを設定するか、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 ヘッダは \"{expected}\" に設定されていません。これは潜在的なセキュリティリスクもしくはプライバシーリスクとなる可能性があるため、この設定を見直すことをおすすめします。", diff --git a/core/l10n/tr.js b/core/l10n/tr.js index 8e6b02f4239..1c2f00dd694 100644 --- a/core/l10n/tr.js +++ b/core/l10n/tr.js @@ -3,162 +3,201 @@ 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", - "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.", + "(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 eşitlemesi için doğru şekilde ayarlanmamış. WevDAV arabirimi sorunlu görünü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}\" adresi çözümlemesi için doğru şekilde ayarlanmamış. Ayrıntılı bilgi almak için <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelere</a> bakabilirsiniz.", "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.", "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Hafıza önbelleği yapılandırılmamış. İmkanı varsa performansı iyileştirmek için bir önbellek yapılandırması yapın. Daha fazla bilgiyi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulabilirsiniz.", "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Güvenlik nedeniyle çokça önerilen /dev/urandom PHP tarafından okunamıyor. Daha fazla bilgiyi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulabilirsiniz.", "You are currently running PHP {version}. We encourage you to upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "Halen PHP {version} kullanıyorsunuz. Dağıtımınız destekler desteklemez PHP sürümünüzü güncelleyerek <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">performans ve güvenlik geliştirmelerinden</a> faydalanmanızı öneriyoruz.", "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 dağıtık bellek olarak yapılandırılmış ama hatalı PHP \"memcache\" modülü kurulmuş. \\OC\\Memcache\\Memcached sadece \"memcached\" modülünü destekler, \"memcache\"i değil. <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wikisinde iki modül hakkında da</a> bilgi bulabilirsiniz.", "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>)" : "Bazı dosyalar bütünlük kontrolünü geçemedi. Bu sorunun üstesinden nasıl geleceğinizi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulabilirsiniz. (<a href=\"{codeIntegrityDownloadEndpoint}\">Geçersiz dosyaların listesi…</a> / <a href=\"{rescanEndpoint}\">Tekrar tara…</a>)", - "Error occurred while checking server setup" : "Sunucu yapılandırması denetlenirken hata oluştu", + "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 doğru şekilde ayarlanmamış. Daha iyi sonuç almak için <code>php.ini</code> dosyasında <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">şu ayarların kullanılması önerilir ↗</a>:", + "Error occurred while checking server setup" : "Sunucu ayarları denetlenirken bir sorun çıktı", "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." : "data dizininiz ve dosyalarınız büyük ihtimalle İnternet üzerinden erişilebilir. .htaccess dosyası çalışmıyor. Web sunucunuzu yapılandırarak data dizinine erişimi kapatmanızı veya data dizinini web sunucu belge dizini dışına almanızı şiddetle tavsiye ederiz.", "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 başlığı \"{expected}\" ile eşleşmek üzere yapılandırılmamış. Bu muhtemel bir güvenlik veya gizlilik riski olduğundan bu ayarı düzeltmenizi öneririz.", "The \"Strict-Transport-Security\" HTTP header is not configured to at least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\" rel=\"noreferrer\">security tips</a>." : "\"Strict-Transport-Security\" HTTP başlığı en azından\"{seconds}\" saniyedir yapılandırılmamış. Gelişmiş güvenlik için <a href=\"{docUrl}\" rel=\"noreferrer\">güvenlik ipuçlarında</a> tarif edildiği gibi HSTS'nin etkinleştirilmesini öneririz.", "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Bu siteye HTTP aracılığıyla erişiyorsunuz. Sunucunuzu <a href=\"{docUrl}\">güvenlik ipuçlarımızda</a> gösterildiği şekilde HTTPS kullanımını zorlamak üzere yapılandırmanızı şiddetle öneririz.", - "Shared" : "Paylaşılan", + "Shared" : "Paylaşılmış", "Shared with {recipients}" : "{recipients} ile paylaşılmış", "Error" : "Hata", - "Error while sharing" : "Paylaşım sırasında hata", - "Error while unsharing" : "Paylaşım iptal edilirken hata", - "Error setting expiration date" : "Son kullanma tarihi ayarlama hatası", - "The public link will expire no later than {days} days after it is created" : "Herkese açık bağlantı, oluşturulduktan en geç {days} gün sonra sona erecek", + "Error while sharing" : "Paylaşılırken sorun çıktı", + "Error while unsharing" : "Paylaşımdan kaldırılırken sorun çıktı", + "Error setting expiration date" : "Son kullanma tarihi ayarlanırken sorun çıktı", + "The public link will expire no later than {days} days after it is created" : "Herkese açık bağlantı, oluşturulduktan {days} gün sonra kullanımdan kaldırılacak", "Set expiration date" : "Son kullanma tarihini ayarla", - "Expiration" : "Bitiş", - "Expiration date" : "Son kullanım tarihi", + "Expiration" : "Son kullanma", + "Expiration date" : "Son kullanma tarihi", "Choose a password for the public link" : "Herkese açık bağlantı için bir parola seçin", "Copied!" : "Kopyalandı!", + "Copy" : "Kopyala", "Not supported!" : "Desteklenmiyor!", - "Press ⌘-C to copy." : "Kopyalamak için ⌘-C kullanın.", - "Press Ctrl-C to copy." : "Kopyalamak için Ctrl-C kullanın.", - "Resharing is not allowed" : "Tekrar paylaşmaya izin verilmiyor", + "Press ⌘-C to copy." : "Kopyalamak için ⌘-C tuşlarına basın.", + "Press Ctrl-C to copy." : "Kopyalamak için Ctrl-C tuşlarına basın.", + "Resharing is not allowed" : "Yeniden paylaşıma izin verilmiyor", "Share link" : "Paylaşma bağlantısı", "Link" : "Bağlantı", "Password protect" : "Parola koruması", - "Allow editing" : "Düzenlemeye izin ver", + "Allow upload and editing" : "Yükleme ve düzenleme yapılabilsin", + "Allow editing" : "Düzenleme yapılabilsin", + "File drop (upload only)" : "Dosya bırakma (yalnız yükleme)", "Email link to person" : "Bağlantıyı e-posta ile gönder", "Send" : "Gönder", - "Shared with you and the group {group} by {owner}" : "{owner} tarafından sizinle ve {group} ile paylaştırılmış", - "Shared with you by {owner}" : "{owner} tarafından sizinle paylaşıldı", + "Shared with you and the group {group} by {owner}" : "{owner} tarafından sizinle ve {group} ile paylaşılmış", + "Shared with you by {owner}" : "{owner} tarafından sizinle paylaşılmış", + "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} bağlantı ile paylaşılmış", "group" : "grup", "remote" : "uzak", - "Unshare" : "Paylaşmayı Kaldır", + "email" : "e-posta", + "Unshare" : "Paylaşımdan Kaldır", + "can reshare" : "yeniden paylaşabilir", "can edit" : "düzenleyebilir", - "access control" : "erişim kontrolü", + "can create" : "ekleyebilir", + "can change" : "değiştirebilir", + "can delete" : "silebilir", + "access control" : "erişim denetimi", "Could not unshare" : "Paylaşım kaldırılamadı", "Share details could not be loaded for this item." : "Bu öge için paylaşma ayrıntıları yüklenemedi.", - "No users or groups found for {search}" : "{search} için kullanıcı veya grup bulunamadı", - "No users found for {search}" : "{search} için hiç bir kullanıcı bulunamadı", - "An error occurred. Please try again" : "Bir hata oluştu. Lütfen yeniden deneyin", + "_At least {count} character is needed for autocompletion_::_At least {count} characters are needed for autocompletion_" : ["Otomatik tamamlama için en az {count} karakter gereklidir","Otomatik tamamlama için en az {count} karakter gereklidir"], + "This list is maybe truncated - please refine your search term to see more results." : "Bu liste budanmış olabilir. Lütfen daha fazla sonuç görmek için arama ifadenizi daraltın.", + "No users or groups found for {search}" : "{search} araması sonucunda uygun bir kullanıcı ya da grup bulunamadı", + "No users found for {search}" : "{search} araması sonucunda uygun bir kullanıcı bulunamadı", + "An error occurred. Please try again" : "Bir sorun çıktı. Lütfen yeniden deneyin", "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (harici)", + "{sharee} (remote)" : "{sharee} (uzak)", + "{sharee} (email)" : "{sharee} (e-posta)", "Share" : "Paylaş", - "Error removing share" : "Paylaşım kaldırılırken hata", - "Non-existing tag #{tag}" : "Mevcut olmayan etiket #{tag}", - "restricted" : "yasaklı", + "Share with people on other servers using their Federated Cloud ID username@example.com/nextcloud" : "Birleşmiş Bulut Kodu ile diğer sunucular üzerindeki kişiler ile paylaş username@example.com/nextcloud", + "Share with users or by mail..." : "Kullanıcılar ya da e-posta ile paylaş...", + "Share with users or remote users..." : "Kullanıcılar ya da uzak kullanıcılar ile paylaş...", + "Share with users, remote users or by mail..." : "Kullanıcılar, uzak kullanıcılar ya da e-posta ile paylaş...", + "Share with users or groups..." : "Kullanıcı ya da gruplar ile paylaş...", + "Share with users, groups or by mail..." : "Kullanıcılar, gruplar ya da e-posta ile paylaş...", + "Share with users, groups or remote users..." : "Kullanıcılar, gruplar ya da uzak kullanıcılar ile paylaş...", + "Share with users, groups, remote users or by mail..." : "Kullanıcılar, gruplar, uzak kullanıcılar ya da e-posta ile paylaş...", + "Share with users..." : "Kullanıcılar ile paylaş...", + "Error removing share" : "Paylaşımdan kaldırılırken sorun çıktı", + "Non-existing tag #{tag}" : "#{tag} etiketi bulunamadı", + "restricted" : "kısıtlı", "invisible" : "görünmez", "({scope})" : "({scope})", "Delete" : "Sil", - "Rename" : "Yeniden adlandır", - "Collaborative tags" : "İşbirlikçi etiketler", + "Rename" : "Yeniden Adlandır", + "Collaborative tags" : "İşbirliği etiketleri", + "No tags found" : "Herhangi bir etiket bulunamadı", "The object type is not specified." : "Nesne türü belirtilmemiş.", - "Enter new" : "Yeni girin", + "Enter new" : "Yeni ekle", "Add" : "Ekle", "Edit tags" : "Etiketleri düzenle", - "Error loading dialog template: {error}" : "İletişim şablonu yüklenirken hata: {error}", - "No tags selected for deletion." : "Silmek için bir etiket seçilmedi.", + "Error loading dialog template: {error}" : "İletişim kalıbı yüklenirken sorun çıktı: {error}", + "No tags selected for deletion." : "Silinecek bir etiket seçilmemiş.", "unknown text" : "bilinmeyen metin", "Hello world!" : "Merhaba dünya!", "sunny" : "güneşli", "Hello {name}, the weather is {weather}" : "Merhaba {name}, hava durumu {weather}", "Hello {name}" : "Merhaba {name}", - "new" : "Yeni", - "_download %n file_::_download %n files_" : ["%n dosya indir","%n dosya indir"], - "An error occurred." : "Bir hata oluştu", + "new" : "yeni", + "_download %n file_::_download %n files_" : ["%n dosyayı indir","%n dosyayı indir"], + "The update is in progress, leaving this page might interrupt the process in some environments." : "Güncelleniyor. Bu sayfadan ayrılırsanız bazı işlemler yarım kalabilir.", + "Update to {version}" : "{version} sürümüne güncelle", + "An error occurred." : "Bir sorun çıktı.", "Please reload the page." : "Lütfen sayfayı yeniden yükleyin.", - "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "Güncelleme başarısız oldu. Daha fazla bilgi için bu sorunu kapsayan <a href=\"{url}\">forum gönderimize</a> bakın.", - "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud community</a>." : "Güncelleme işlemi maalesef başarısızlığa uğradı. Lütfen bu surunu <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud topluluğu</a>na bildirin. ", - "The update was successful. Redirecting you to Nextcloud now." : "Güncelleme başarılı oldu. Nextcloud'a yönlendiriliyorsunuz.", + "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "Uygulama güncellenemedi. Ayrıntılı bilgi almak için bu sorunu kapsayan <a href=\"{url}\">forum iletimize</a> bakın.", + "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud community</a>." : "Uygulama güncellenemedi. Lütfen bu sorunu <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud topluluğuna</a> bildirin.", + "Continue to Nextcloud" : "Nextcloud kullanmaya geç", + "The update was successful. Redirecting you to Nextcloud now." : "Uygulama güncellendi. Nextcloud kullanmaya yönlendiriliyorsunuz.", "Searching other places" : "Diğer konumlarda aranıyor", - "_{count} search result in another folder_::_{count} search results in other folders_" : ["Diğer klasörlerde {count} arama sonucu","Diğer bir klasörde {count} arama sonucu"], + "No search results in other folders for '{tag}{filter}{endtag}'" : "'{tag}{filter}{endtag}' araması için diğer klasörlerde uygun bir sonuç yok", + "_{count} search result in another folder_::_{count} search results in other folders_" : ["Diğer klasörlerde {count} arama sonucu","Diğer klasörlerde {count} arama sonucu"], "Personal" : "Kişisel", "Users" : "Kullanıcılar", "Apps" : "Uygulamalar", "Admin" : "Yönetici", "Help" : "Yardım", - "Access forbidden" : "Erişim yasak", + "Access forbidden" : "Erişim engellendi", "File not found" : "Dosya bulunamadı", "The specified document has not been found on the server." : "Belirtilen dosya sunucuda bulunamadı.", "You can click here to return to %s." : "%s ana sayfasına dönmek için buraya tıklayabilirsiniz.", diff --git a/core/l10n/tr.json b/core/l10n/tr.json index 09737016722..a68e67add76 100644 --- a/core/l10n/tr.json +++ b/core/l10n/tr.json @@ -1,162 +1,201 @@ { "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", - "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.", + "(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 eşitlemesi için doğru şekilde ayarlanmamış. WevDAV arabirimi sorunlu görünü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}\" adresi çözümlemesi için doğru şekilde ayarlanmamış. Ayrıntılı bilgi almak için <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelere</a> bakabilirsiniz.", "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.", "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Hafıza önbelleği yapılandırılmamış. İmkanı varsa performansı iyileştirmek için bir önbellek yapılandırması yapın. Daha fazla bilgiyi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulabilirsiniz.", "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Güvenlik nedeniyle çokça önerilen /dev/urandom PHP tarafından okunamıyor. Daha fazla bilgiyi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulabilirsiniz.", "You are currently running PHP {version}. We encourage you to upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "Halen PHP {version} kullanıyorsunuz. Dağıtımınız destekler desteklemez PHP sürümünüzü güncelleyerek <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">performans ve güvenlik geliştirmelerinden</a> faydalanmanızı öneriyoruz.", "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 dağıtık bellek olarak yapılandırılmış ama hatalı PHP \"memcache\" modülü kurulmuş. \\OC\\Memcache\\Memcached sadece \"memcached\" modülünü destekler, \"memcache\"i değil. <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wikisinde iki modül hakkında da</a> bilgi bulabilirsiniz.", "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>)" : "Bazı dosyalar bütünlük kontrolünü geçemedi. Bu sorunun üstesinden nasıl geleceğinizi <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">belgelendirmemizde</a> bulabilirsiniz. (<a href=\"{codeIntegrityDownloadEndpoint}\">Geçersiz dosyaların listesi…</a> / <a href=\"{rescanEndpoint}\">Tekrar tara…</a>)", - "Error occurred while checking server setup" : "Sunucu yapılandırması denetlenirken hata oluştu", + "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 doğru şekilde ayarlanmamış. Daha iyi sonuç almak için <code>php.ini</code> dosyasında <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">şu ayarların kullanılması önerilir ↗</a>:", + "Error occurred while checking server setup" : "Sunucu ayarları denetlenirken bir sorun çıktı", "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." : "data dizininiz ve dosyalarınız büyük ihtimalle İnternet üzerinden erişilebilir. .htaccess dosyası çalışmıyor. Web sunucunuzu yapılandırarak data dizinine erişimi kapatmanızı veya data dizinini web sunucu belge dizini dışına almanızı şiddetle tavsiye ederiz.", "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 başlığı \"{expected}\" ile eşleşmek üzere yapılandırılmamış. Bu muhtemel bir güvenlik veya gizlilik riski olduğundan bu ayarı düzeltmenizi öneririz.", "The \"Strict-Transport-Security\" HTTP header is not configured to at least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\" rel=\"noreferrer\">security tips</a>." : "\"Strict-Transport-Security\" HTTP başlığı en azından\"{seconds}\" saniyedir yapılandırılmamış. Gelişmiş güvenlik için <a href=\"{docUrl}\" rel=\"noreferrer\">güvenlik ipuçlarında</a> tarif edildiği gibi HSTS'nin etkinleştirilmesini öneririz.", "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Bu siteye HTTP aracılığıyla erişiyorsunuz. Sunucunuzu <a href=\"{docUrl}\">güvenlik ipuçlarımızda</a> gösterildiği şekilde HTTPS kullanımını zorlamak üzere yapılandırmanızı şiddetle öneririz.", - "Shared" : "Paylaşılan", + "Shared" : "Paylaşılmış", "Shared with {recipients}" : "{recipients} ile paylaşılmış", "Error" : "Hata", - "Error while sharing" : "Paylaşım sırasında hata", - "Error while unsharing" : "Paylaşım iptal edilirken hata", - "Error setting expiration date" : "Son kullanma tarihi ayarlama hatası", - "The public link will expire no later than {days} days after it is created" : "Herkese açık bağlantı, oluşturulduktan en geç {days} gün sonra sona erecek", + "Error while sharing" : "Paylaşılırken sorun çıktı", + "Error while unsharing" : "Paylaşımdan kaldırılırken sorun çıktı", + "Error setting expiration date" : "Son kullanma tarihi ayarlanırken sorun çıktı", + "The public link will expire no later than {days} days after it is created" : "Herkese açık bağlantı, oluşturulduktan {days} gün sonra kullanımdan kaldırılacak", "Set expiration date" : "Son kullanma tarihini ayarla", - "Expiration" : "Bitiş", - "Expiration date" : "Son kullanım tarihi", + "Expiration" : "Son kullanma", + "Expiration date" : "Son kullanma tarihi", "Choose a password for the public link" : "Herkese açık bağlantı için bir parola seçin", "Copied!" : "Kopyalandı!", + "Copy" : "Kopyala", "Not supported!" : "Desteklenmiyor!", - "Press ⌘-C to copy." : "Kopyalamak için ⌘-C kullanın.", - "Press Ctrl-C to copy." : "Kopyalamak için Ctrl-C kullanın.", - "Resharing is not allowed" : "Tekrar paylaşmaya izin verilmiyor", + "Press ⌘-C to copy." : "Kopyalamak için ⌘-C tuşlarına basın.", + "Press Ctrl-C to copy." : "Kopyalamak için Ctrl-C tuşlarına basın.", + "Resharing is not allowed" : "Yeniden paylaşıma izin verilmiyor", "Share link" : "Paylaşma bağlantısı", "Link" : "Bağlantı", "Password protect" : "Parola koruması", - "Allow editing" : "Düzenlemeye izin ver", + "Allow upload and editing" : "Yükleme ve düzenleme yapılabilsin", + "Allow editing" : "Düzenleme yapılabilsin", + "File drop (upload only)" : "Dosya bırakma (yalnız yükleme)", "Email link to person" : "Bağlantıyı e-posta ile gönder", "Send" : "Gönder", - "Shared with you and the group {group} by {owner}" : "{owner} tarafından sizinle ve {group} ile paylaştırılmış", - "Shared with you by {owner}" : "{owner} tarafından sizinle paylaşıldı", + "Shared with you and the group {group} by {owner}" : "{owner} tarafından sizinle ve {group} ile paylaşılmış", + "Shared with you by {owner}" : "{owner} tarafından sizinle paylaşılmış", + "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} bağlantı ile paylaşılmış", "group" : "grup", "remote" : "uzak", - "Unshare" : "Paylaşmayı Kaldır", + "email" : "e-posta", + "Unshare" : "Paylaşımdan Kaldır", + "can reshare" : "yeniden paylaşabilir", "can edit" : "düzenleyebilir", - "access control" : "erişim kontrolü", + "can create" : "ekleyebilir", + "can change" : "değiştirebilir", + "can delete" : "silebilir", + "access control" : "erişim denetimi", "Could not unshare" : "Paylaşım kaldırılamadı", "Share details could not be loaded for this item." : "Bu öge için paylaşma ayrıntıları yüklenemedi.", - "No users or groups found for {search}" : "{search} için kullanıcı veya grup bulunamadı", - "No users found for {search}" : "{search} için hiç bir kullanıcı bulunamadı", - "An error occurred. Please try again" : "Bir hata oluştu. Lütfen yeniden deneyin", + "_At least {count} character is needed for autocompletion_::_At least {count} characters are needed for autocompletion_" : ["Otomatik tamamlama için en az {count} karakter gereklidir","Otomatik tamamlama için en az {count} karakter gereklidir"], + "This list is maybe truncated - please refine your search term to see more results." : "Bu liste budanmış olabilir. Lütfen daha fazla sonuç görmek için arama ifadenizi daraltın.", + "No users or groups found for {search}" : "{search} araması sonucunda uygun bir kullanıcı ya da grup bulunamadı", + "No users found for {search}" : "{search} araması sonucunda uygun bir kullanıcı bulunamadı", + "An error occurred. Please try again" : "Bir sorun çıktı. Lütfen yeniden deneyin", "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (harici)", + "{sharee} (remote)" : "{sharee} (uzak)", + "{sharee} (email)" : "{sharee} (e-posta)", "Share" : "Paylaş", - "Error removing share" : "Paylaşım kaldırılırken hata", - "Non-existing tag #{tag}" : "Mevcut olmayan etiket #{tag}", - "restricted" : "yasaklı", + "Share with people on other servers using their Federated Cloud ID username@example.com/nextcloud" : "Birleşmiş Bulut Kodu ile diğer sunucular üzerindeki kişiler ile paylaş username@example.com/nextcloud", + "Share with users or by mail..." : "Kullanıcılar ya da e-posta ile paylaş...", + "Share with users or remote users..." : "Kullanıcılar ya da uzak kullanıcılar ile paylaş...", + "Share with users, remote users or by mail..." : "Kullanıcılar, uzak kullanıcılar ya da e-posta ile paylaş...", + "Share with users or groups..." : "Kullanıcı ya da gruplar ile paylaş...", + "Share with users, groups or by mail..." : "Kullanıcılar, gruplar ya da e-posta ile paylaş...", + "Share with users, groups or remote users..." : "Kullanıcılar, gruplar ya da uzak kullanıcılar ile paylaş...", + "Share with users, groups, remote users or by mail..." : "Kullanıcılar, gruplar, uzak kullanıcılar ya da e-posta ile paylaş...", + "Share with users..." : "Kullanıcılar ile paylaş...", + "Error removing share" : "Paylaşımdan kaldırılırken sorun çıktı", + "Non-existing tag #{tag}" : "#{tag} etiketi bulunamadı", + "restricted" : "kısıtlı", "invisible" : "görünmez", "({scope})" : "({scope})", "Delete" : "Sil", - "Rename" : "Yeniden adlandır", - "Collaborative tags" : "İşbirlikçi etiketler", + "Rename" : "Yeniden Adlandır", + "Collaborative tags" : "İşbirliği etiketleri", + "No tags found" : "Herhangi bir etiket bulunamadı", "The object type is not specified." : "Nesne türü belirtilmemiş.", - "Enter new" : "Yeni girin", + "Enter new" : "Yeni ekle", "Add" : "Ekle", "Edit tags" : "Etiketleri düzenle", - "Error loading dialog template: {error}" : "İletişim şablonu yüklenirken hata: {error}", - "No tags selected for deletion." : "Silmek için bir etiket seçilmedi.", + "Error loading dialog template: {error}" : "İletişim kalıbı yüklenirken sorun çıktı: {error}", + "No tags selected for deletion." : "Silinecek bir etiket seçilmemiş.", "unknown text" : "bilinmeyen metin", "Hello world!" : "Merhaba dünya!", "sunny" : "güneşli", "Hello {name}, the weather is {weather}" : "Merhaba {name}, hava durumu {weather}", "Hello {name}" : "Merhaba {name}", - "new" : "Yeni", - "_download %n file_::_download %n files_" : ["%n dosya indir","%n dosya indir"], - "An error occurred." : "Bir hata oluştu", + "new" : "yeni", + "_download %n file_::_download %n files_" : ["%n dosyayı indir","%n dosyayı indir"], + "The update is in progress, leaving this page might interrupt the process in some environments." : "Güncelleniyor. Bu sayfadan ayrılırsanız bazı işlemler yarım kalabilir.", + "Update to {version}" : "{version} sürümüne güncelle", + "An error occurred." : "Bir sorun çıktı.", "Please reload the page." : "Lütfen sayfayı yeniden yükleyin.", - "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "Güncelleme başarısız oldu. Daha fazla bilgi için bu sorunu kapsayan <a href=\"{url}\">forum gönderimize</a> bakın.", - "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud community</a>." : "Güncelleme işlemi maalesef başarısızlığa uğradı. Lütfen bu surunu <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud topluluğu</a>na bildirin. ", - "The update was successful. Redirecting you to Nextcloud now." : "Güncelleme başarılı oldu. Nextcloud'a yönlendiriliyorsunuz.", + "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "Uygulama güncellenemedi. Ayrıntılı bilgi almak için bu sorunu kapsayan <a href=\"{url}\">forum iletimize</a> bakın.", + "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud community</a>." : "Uygulama güncellenemedi. Lütfen bu sorunu <a href=\"https://github.com/nextcloud/server/issues\" target=\"_blank\">Nextcloud topluluğuna</a> bildirin.", + "Continue to Nextcloud" : "Nextcloud kullanmaya geç", + "The update was successful. Redirecting you to Nextcloud now." : "Uygulama güncellendi. Nextcloud kullanmaya yönlendiriliyorsunuz.", "Searching other places" : "Diğer konumlarda aranıyor", - "_{count} search result in another folder_::_{count} search results in other folders_" : ["Diğer klasörlerde {count} arama sonucu","Diğer bir klasörde {count} arama sonucu"], + "No search results in other folders for '{tag}{filter}{endtag}'" : "'{tag}{filter}{endtag}' araması için diğer klasörlerde uygun bir sonuç yok", + "_{count} search result in another folder_::_{count} search results in other folders_" : ["Diğer klasörlerde {count} arama sonucu","Diğer klasörlerde {count} arama sonucu"], "Personal" : "Kişisel", "Users" : "Kullanıcılar", "Apps" : "Uygulamalar", "Admin" : "Yönetici", "Help" : "Yardım", - "Access forbidden" : "Erişim yasak", + "Access forbidden" : "Erişim engellendi", "File not found" : "Dosya bulunamadı", "The specified document has not been found on the server." : "Belirtilen dosya sunucuda bulunamadı.", "You can click here to return to %s." : "%s ana sayfasına dönmek için buraya tıklayabilirsiniz.", @@ -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/l10n/ca.js b/lib/l10n/ca.js index daa9ae7a3d6..fbbf8fdd543 100644 --- a/lib/l10n/ca.js +++ b/lib/l10n/ca.js @@ -12,6 +12,7 @@ OC.L10N.register( "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s i %4$s", "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s i %5$s", "PHP %s or higher is required." : "Es requereix PHP %s o superior.", + "%sbit or higher PHP required." : "Es requereix PHP %s o superior.", "Server version %s or higher is required." : "Es requereix una versió de servidor %s o superior", "Server version %s or lower is required." : "Es requereix una versió de servidor %s o inferior", "Unknown filetype" : "Tipus de fitxer desconegut", diff --git a/lib/l10n/ca.json b/lib/l10n/ca.json index f6c692aef0d..13358e42a4f 100644 --- a/lib/l10n/ca.json +++ b/lib/l10n/ca.json @@ -10,6 +10,7 @@ "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s i %4$s", "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s i %5$s", "PHP %s or higher is required." : "Es requereix PHP %s o superior.", + "%sbit or higher PHP required." : "Es requereix PHP %s o superior.", "Server version %s or higher is required." : "Es requereix una versió de servidor %s o superior", "Server version %s or lower is required." : "Es requereix una versió de servidor %s o inferior", "Unknown filetype" : "Tipus de fitxer desconegut", 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/css/settings.css b/settings/css/settings.css index c0c79ca65ef..884fe1d50d0 100644 --- a/settings/css/settings.css +++ b/settings/css/settings.css @@ -28,7 +28,7 @@ input#openid, input#webdav { width:20em; } } #avatarform { - width: 160px; + width: 145px; padding-right: 0; } #avatarform .avatardiv { @@ -37,6 +37,13 @@ input#openid, input#webdav { width:20em; } #avatarform .warning { width: 100%; } +#displayavatar { + text-align: center; +} +#displayavatar p { + text-align: left; +} + #uploadavatarbutton, #selectavatar, #removeavatar { diff --git a/settings/js/users/users.js b/settings/js/users/users.js index db9f6b6006b..46bfea4b35c 100644 --- a/settings/js/users/users.js +++ b/settings/js/users/users.js @@ -10,6 +10,7 @@ var $userList; var $userListBody; +var $emptyContainer; var UserDeleteHandler; var UserList = { @@ -396,15 +397,25 @@ var UserList = { } UserList.add(user); }); + if (result.length > 0) { UserList.doSort(); $userList.siblings('.loading').css('visibility', 'hidden'); // reset state on load UserList.noMoreEntries = false; + $userListHead.show(); + $emptyContainer.hide(); + $emptyContainer.find('h2').text(''); } else { UserList.noMoreEntries = true; $userList.siblings('.loading').remove(); + + if (pattern !== ""){ + $userListHead.hide(); + $emptyContainer.show(); + $emptyContainer.find('h2').html(t('settings', 'No user found for <strong>{pattern}</strong>', {pattern: pattern})); + } } UserList.offset += limit; }).always(function() { @@ -668,6 +679,8 @@ var UserList = { $(document).ready(function () { $userList = $('#userlist'); $userListBody = $userList.find('tbody'); + $userListHead = $userList.find('thead'); + $emptyContainer = $userList.siblings('.emptycontent'); UserList.initDeleteHandling(); @@ -899,6 +912,13 @@ $(document).ready(function () { $(this).find('#default_quota').singleSelect().on('change', UserList.onQuotaSelect); }); + $('#newuser input').click(function() { + // empty the container also here to avoid visual delay + $emptyContainer.hide(); + OC.Search = new OCA.Search($('#searchbox'), $('#searchresults')); + OC.Search.clear(); + }); + UserList._updateGroupListLabel($('#newuser .groups'), []); var _submitNewUserForm = function (event) { event.preventDefault(); diff --git a/settings/l10n/bg.js b/settings/l10n/bg.js index f63c5dfd2eb..4883d331239 100644 --- a/settings/l10n/bg.js +++ b/settings/l10n/bg.js @@ -26,6 +26,7 @@ OC.L10N.register( "Unable to delete user." : "Неуспешно изтриване на потребител.", "Settings saved" : "Настройките са запазени", "Unable to change full name" : "Неуспешна промяна на пълното име.", + "Unable to change email address" : "Неуспешна промяна на адрес на електронна поща", "Your full name has been changed." : "Вашето пълно име е променено.", "Forbidden" : "Забранено", "Invalid user" : "Невалиден протребител", @@ -38,9 +39,11 @@ OC.L10N.register( "All" : "Всички", "Update to %s" : "Обнови до %s", "No apps found for your version" : "Няма намерени приложения за версията, която ползвате", + "Disabling app …" : "Забраняване на приложение ...", "Error while disabling app" : "Грешка при изключване на приложението", "Disable" : "Изключване", "Enable" : "Включване", + "Enabling app …" : "Разрешаване на приложение ...", "Error while enabling app" : "Грешка при включване на приложението", "Updating...." : "Обновяване...", "Error while updating app" : "Грешка при обновяване на приложението", @@ -115,6 +118,8 @@ OC.L10N.register( "Store credentials" : "Запазвай креденциите", "Test email settings" : "Настройки на проверяващия имейл", "Send email" : "Изпрати имейл", + "Enable encryption" : "Включване на криптиране", + "Select default encryption module:" : "Избор на модул за криптиране по подразбиране:", "Start migration" : "Начало на миграцията", "Security & setup warnings" : "Предупреждения за сигурност и настройки", "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "PHP е настроен да премахва inline doc блокове. Това ще направи няколко основни приложения недостъпни.", @@ -155,17 +160,23 @@ OC.L10N.register( "Developer documentation" : "Документация за разработчици", "by %s" : "от %s", "Documentation:" : "Документация:", + "Visit website" : "Посещаване на интернет страница", + "Report a bug" : "Докладване на грешка", "Show description …" : "Покажи описание ...", "Hide description …" : "Скрии описание ...", + "This app has an update available." : "Това приложение има налично обновление.", "This app cannot be installed because the following dependencies are not fulfilled:" : "Приложението не може да бъде инсталирано, защото следните зависимости не са удовлетворени:", "Enable only for specific groups" : "Включи само за определени групи", + "Uninstall app" : "Премахване на приложението", "Common Name" : "Познато Име", "Valid until" : "Валиден до", "Issued By" : "Издаден от", "Valid until %s" : "Валиден до %s", "Import root certificate" : "Импортиране на основен сертификат", "Cheers!" : "Поздрави!", + "Online documentation" : "Онлайн документация", "Forum" : "Форум", + "Commercial support" : "Платена поддръжка", "You are using <strong>%s</strong> of <strong>%s</strong>" : "Ползвате <strong>%s</strong> от <strong>%s</strong>", "Profile picture" : "Аватар", "Upload new" : "Качи нов", @@ -200,6 +211,7 @@ OC.L10N.register( "Device" : "Устройство", "Last activity" : "Последна активност", "Name" : "Име", + "App name" : "Име на приложението", "Username" : "Потребител", "Done" : "Завършен", "Subscribe to our newsletter!" : "Абонирайте се за нашата емисия!", @@ -211,6 +223,7 @@ OC.L10N.register( "Create" : "Създаване", "Admin Recovery Password" : "Възстановяване на администраторската парола", "Enter the recovery password in order to recover the users files during password change" : "Въведете паролата за възстановяване, за да възстановиш файловете на потребителите при промяна на паролата.", + "Group name" : "Име на група", "Everyone" : "Всички", "Admins" : "Администратори", "Default quota" : "Стандартна квота", @@ -231,6 +244,7 @@ OC.L10N.register( "Unable to remove user from group %s" : "Неуспешно премахване на потребител от групата %s.", "Are you really sure you want add \"{domain}\" as trusted domain?" : "Сигурен/на ли сте, че искате \"{domain}\" да бъде добавен като сигурен домейн?", "Please wait...." : "Моля, изчакайте....", + "add group" : "добавяне на група", "Everything (fatal issues, errors, warnings, info, debug)" : "Всичко (фатални проблеми, грешки, предупреждения, информация, дебъгване)", "Info, warnings, errors and fatal issues" : "информация, предупреждения, грешки и фатални проблеми", "Warnings, errors and fatal issues" : "Предупреждения, грешки и фатални проблеми", @@ -246,6 +260,7 @@ OC.L10N.register( "SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "SQLite е използваната база данни. За по-големи инсталации Ви препоръчваме да изберете друг сървър за бази данни.", "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "Използването на SQLite не се препоръчва, особено ако ползвате клиента за настолен компютър.", "Uninstall App" : "Премахни приложението", + "Enable experimental apps" : "Разрешаване на експериментални приложения", "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>" : "Здрасти,<br><br>Само да ти кажа, че имаш %s профил<br><br> Потребителя ти е: %s<br>Достъпи го: <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" : "Здрасти,\n\nСамо да ти кажа, че имаш %s профил.\n\nПотребителя ти е: %s\nДостъпи го: %s\n", "Group" : "Група", diff --git a/settings/l10n/bg.json b/settings/l10n/bg.json index c951a5f8925..1e3fd1c9f20 100644 --- a/settings/l10n/bg.json +++ b/settings/l10n/bg.json @@ -24,6 +24,7 @@ "Unable to delete user." : "Неуспешно изтриване на потребител.", "Settings saved" : "Настройките са запазени", "Unable to change full name" : "Неуспешна промяна на пълното име.", + "Unable to change email address" : "Неуспешна промяна на адрес на електронна поща", "Your full name has been changed." : "Вашето пълно име е променено.", "Forbidden" : "Забранено", "Invalid user" : "Невалиден протребител", @@ -36,9 +37,11 @@ "All" : "Всички", "Update to %s" : "Обнови до %s", "No apps found for your version" : "Няма намерени приложения за версията, която ползвате", + "Disabling app …" : "Забраняване на приложение ...", "Error while disabling app" : "Грешка при изключване на приложението", "Disable" : "Изключване", "Enable" : "Включване", + "Enabling app …" : "Разрешаване на приложение ...", "Error while enabling app" : "Грешка при включване на приложението", "Updating...." : "Обновяване...", "Error while updating app" : "Грешка при обновяване на приложението", @@ -113,6 +116,8 @@ "Store credentials" : "Запазвай креденциите", "Test email settings" : "Настройки на проверяващия имейл", "Send email" : "Изпрати имейл", + "Enable encryption" : "Включване на криптиране", + "Select default encryption module:" : "Избор на модул за криптиране по подразбиране:", "Start migration" : "Начало на миграцията", "Security & setup warnings" : "Предупреждения за сигурност и настройки", "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "PHP е настроен да премахва inline doc блокове. Това ще направи няколко основни приложения недостъпни.", @@ -153,17 +158,23 @@ "Developer documentation" : "Документация за разработчици", "by %s" : "от %s", "Documentation:" : "Документация:", + "Visit website" : "Посещаване на интернет страница", + "Report a bug" : "Докладване на грешка", "Show description …" : "Покажи описание ...", "Hide description …" : "Скрии описание ...", + "This app has an update available." : "Това приложение има налично обновление.", "This app cannot be installed because the following dependencies are not fulfilled:" : "Приложението не може да бъде инсталирано, защото следните зависимости не са удовлетворени:", "Enable only for specific groups" : "Включи само за определени групи", + "Uninstall app" : "Премахване на приложението", "Common Name" : "Познато Име", "Valid until" : "Валиден до", "Issued By" : "Издаден от", "Valid until %s" : "Валиден до %s", "Import root certificate" : "Импортиране на основен сертификат", "Cheers!" : "Поздрави!", + "Online documentation" : "Онлайн документация", "Forum" : "Форум", + "Commercial support" : "Платена поддръжка", "You are using <strong>%s</strong> of <strong>%s</strong>" : "Ползвате <strong>%s</strong> от <strong>%s</strong>", "Profile picture" : "Аватар", "Upload new" : "Качи нов", @@ -198,6 +209,7 @@ "Device" : "Устройство", "Last activity" : "Последна активност", "Name" : "Име", + "App name" : "Име на приложението", "Username" : "Потребител", "Done" : "Завършен", "Subscribe to our newsletter!" : "Абонирайте се за нашата емисия!", @@ -209,6 +221,7 @@ "Create" : "Създаване", "Admin Recovery Password" : "Възстановяване на администраторската парола", "Enter the recovery password in order to recover the users files during password change" : "Въведете паролата за възстановяване, за да възстановиш файловете на потребителите при промяна на паролата.", + "Group name" : "Име на група", "Everyone" : "Всички", "Admins" : "Администратори", "Default quota" : "Стандартна квота", @@ -229,6 +242,7 @@ "Unable to remove user from group %s" : "Неуспешно премахване на потребител от групата %s.", "Are you really sure you want add \"{domain}\" as trusted domain?" : "Сигурен/на ли сте, че искате \"{domain}\" да бъде добавен като сигурен домейн?", "Please wait...." : "Моля, изчакайте....", + "add group" : "добавяне на група", "Everything (fatal issues, errors, warnings, info, debug)" : "Всичко (фатални проблеми, грешки, предупреждения, информация, дебъгване)", "Info, warnings, errors and fatal issues" : "информация, предупреждения, грешки и фатални проблеми", "Warnings, errors and fatal issues" : "Предупреждения, грешки и фатални проблеми", @@ -244,6 +258,7 @@ "SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "SQLite е използваната база данни. За по-големи инсталации Ви препоръчваме да изберете друг сървър за бази данни.", "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "Използването на SQLite не се препоръчва, особено ако ползвате клиента за настолен компютър.", "Uninstall App" : "Премахни приложението", + "Enable experimental apps" : "Разрешаване на експериментални приложения", "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>" : "Здрасти,<br><br>Само да ти кажа, че имаш %s профил<br><br> Потребителя ти е: %s<br>Достъпи го: <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" : "Здрасти,\n\nСамо да ти кажа, че имаш %s профил.\n\nПотребителя ти е: %s\nДостъпи го: %s\n", "Group" : "Група", 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/es.js b/settings/l10n/es.js index 6f4fda38a6b..9dda2e38579 100644 --- a/settings/l10n/es.js +++ b/settings/l10n/es.js @@ -125,6 +125,7 @@ OC.L10N.register( "undo" : "deshacer", "never" : "nunca", "deleted {userName}" : "borrado {userName}", + "No user found for <strong>{pattern}</strong>" : "No se encontró usuario para <strong>{pattern}</strong>", "Unable to add user to group {group}" : "No se puede añadir el usuario al grupo {group}", "Unable to remove user from group {group}" : "No se puede eliminar el usuario del grupo {group}", "Add group" : "Añadir grupo", diff --git a/settings/l10n/es.json b/settings/l10n/es.json index 77691ab80e8..886a3a44157 100644 --- a/settings/l10n/es.json +++ b/settings/l10n/es.json @@ -123,6 +123,7 @@ "undo" : "deshacer", "never" : "nunca", "deleted {userName}" : "borrado {userName}", + "No user found for <strong>{pattern}</strong>" : "No se encontró usuario para <strong>{pattern}</strong>", "Unable to add user to group {group}" : "No se puede añadir el usuario al grupo {group}", "Unable to remove user from group {group}" : "No se puede eliminar el usuario del grupo {group}", "Add group" : "Añadir grupo", 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/nl.js b/settings/l10n/nl.js index c5c23bad83c..5d922790612 100644 --- a/settings/l10n/nl.js +++ b/settings/l10n/nl.js @@ -125,6 +125,7 @@ OC.L10N.register( "undo" : "ongedaan maken", "never" : "geen", "deleted {userName}" : "verwijderd {userName}", + "No user found for <strong>{pattern}</strong>" : "Geen gebruikers gevonden voor <strong>{pattern}</strong>", "Unable to add user to group {group}" : "Kan niet worden toegevoegd aan gebruikersgroep {group}", "Unable to remove user from group {group}" : "Gebruiker kan niet worden verwijderd van groep {group}", "Add group" : "Groep toevoegen", diff --git a/settings/l10n/nl.json b/settings/l10n/nl.json index 8de3e5d5e6f..38818b5ea1e 100644 --- a/settings/l10n/nl.json +++ b/settings/l10n/nl.json @@ -123,6 +123,7 @@ "undo" : "ongedaan maken", "never" : "geen", "deleted {userName}" : "verwijderd {userName}", + "No user found for <strong>{pattern}</strong>" : "Geen gebruikers gevonden voor <strong>{pattern}</strong>", "Unable to add user to group {group}" : "Kan niet worden toegevoegd aan gebruikersgroep {group}", "Unable to remove user from group {group}" : "Gebruiker kan niet worden verwijderd van groep {group}", "Add group" : "Groep toevoegen", 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/l10n/ru.js b/settings/l10n/ru.js index 051659a36b6..966dcd535d7 100644 --- a/settings/l10n/ru.js +++ b/settings/l10n/ru.js @@ -125,6 +125,7 @@ OC.L10N.register( "undo" : "отмена", "never" : "никогда", "deleted {userName}" : "удалён {userName}", + "No user found for <strong>{pattern}</strong>" : "По шаблону <strong>{pattern}</strong> пользователей не найдено", "Unable to add user to group {group}" : "Невозможно добавить пользователя в группу {group}", "Unable to remove user from group {group}" : "Невозможно удалить пользователя из группы {group}", "Add group" : "Добавить группу", diff --git a/settings/l10n/ru.json b/settings/l10n/ru.json index ef49c52e404..d5a01795030 100644 --- a/settings/l10n/ru.json +++ b/settings/l10n/ru.json @@ -123,6 +123,7 @@ "undo" : "отмена", "never" : "никогда", "deleted {userName}" : "удалён {userName}", + "No user found for <strong>{pattern}</strong>" : "По шаблону <strong>{pattern}</strong> пользователей не найдено", "Unable to add user to group {group}" : "Невозможно добавить пользователя в группу {group}", "Unable to remove user from group {group}" : "Невозможно удалить пользователя из группы {group}", "Add group" : "Добавить группу", diff --git a/settings/templates/admin/tipstricks.php b/settings/templates/admin/tipstricks.php index 0282deda420..cee5cd8032d 100644 --- a/settings/templates/admin/tipstricks.php +++ b/settings/templates/admin/tipstricks.php @@ -44,6 +44,7 @@ <li><a target="_blank" rel="noreferrer" href="<?php p(link_to_docs('admin-performance')); ?>"><?php p($l->t('Performance tuning'));?> ↗</a></li> <li><a target="_blank" rel="noreferrer" href="<?php p(link_to_docs('admin-config')); ?>"><?php p($l->t('Improving the config.php'));?> ↗</a></li> <li><a target="_blank" rel="noreferrer" href="<?php p(link_to_docs('developer-theming')); ?>"><?php p($l->t('Theming'));?> ↗</a></li> + <li><a target="_blank" rel="noreferrer" href="https://scan.nextcloud.com"><?php p($l->t('Check the security of your Nextcloud over our security scan'));?> ↗</a></li> <li><a target="_blank" rel="noreferrer" href="<?php p(link_to_docs('admin-security')); ?>"><?php p($l->t('Hardening and security guidance'));?> ↗</a></li> </ul> </div> diff --git a/settings/templates/users/part.userlist.php b/settings/templates/users/part.userlist.php index 4cf395ff62d..7e7e1561e2f 100644 --- a/settings/templates/users/part.userlist.php +++ b/settings/templates/users/part.userlist.php @@ -67,3 +67,8 @@ </tr> </tbody> </table> + +<div class="emptycontent" style="display:none"> + <div class="icon-search"></div> + <h2></h2> +</div> 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' => [ |