aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--apps/comments/lib/Activity/Listener.php6
-rw-r--r--apps/comments/tests/Unit/Activity/ListenerTest.php187
-rw-r--r--apps/dav/tests/unit/ServerTest.php2
-rw-r--r--apps/encryption/l10n/pt_PT.js7
-rw-r--r--apps/encryption/l10n/pt_PT.json7
-rw-r--r--apps/files/img/change.pngbin594 -> 560 bytes
-rw-r--r--apps/files/img/change.svg2
-rw-r--r--apps/files/js/fileactions.js17
-rw-r--r--apps/files/js/filelist.js34
-rw-r--r--apps/files/l10n/pt_PT.js2
-rw-r--r--apps/files/l10n/pt_PT.json2
-rw-r--r--apps/files/templates/list.php2
-rw-r--r--apps/files/tests/js/fileactionsmenuSpec.js3
-rw-r--r--apps/files/tests/js/filelistSpec.js9
-rw-r--r--apps/files_external/js/settings.js1
-rw-r--r--apps/files_external/l10n/pt_PT.js27
-rw-r--r--apps/files_external/l10n/pt_PT.json27
-rw-r--r--apps/files_external/lib/Config/ConfigAdapter.php2
-rw-r--r--apps/files_external/lib/Lib/PersonalMount.php4
-rw-r--r--apps/files_external/templates/list.php3
-rw-r--r--apps/files_external/templates/settings.php5
-rw-r--r--apps/files_sharing/l10n/pt_PT.js3
-rw-r--r--apps/files_sharing/l10n/pt_PT.json3
-rw-r--r--apps/oauth2/l10n/pt_PT.js14
-rw-r--r--apps/oauth2/l10n/pt_PT.json12
-rw-r--r--apps/sharebymail/lib/ShareByMailProvider.php4
-rw-r--r--apps/systemtags/lib/Activity/Listener.php3
-rw-r--r--apps/user_ldap/lib/Group_LDAP.php13
-rw-r--r--apps/user_ldap/tests/Group_LDAPTest.php87
-rw-r--r--build/integration/features/comments.feature12
-rw-r--r--build/integration/features/tags.feature6
-rw-r--r--core/Command/App/Install.php13
-rw-r--r--core/Command/Db/ConvertFilecacheBigInt.php2
-rw-r--r--core/Controller/LostController.php4
-rw-r--r--core/js/sharedialogshareelistview.js26
-rw-r--r--core/js/shareitemmodel.js26
-rw-r--r--core/js/tests/specs/sharedialogshareelistview.js50
-rw-r--r--core/templates/exception.php14
-rw-r--r--lib/private/AppFramework/Http/Request.php124
-rw-r--r--lib/private/Installer.php2
-rw-r--r--lib/private/L10N/L10N.php8
-rw-r--r--lib/private/Mail/EMailTemplate.php28
-rw-r--r--lib/private/Server.php2
-rw-r--r--lib/private/Share20/Manager.php2
-rw-r--r--lib/public/IL10N.php4
-rw-r--r--lib/public/IRequest.php41
-rw-r--r--lib/public/Mail/IEMailTemplate.php12
-rw-r--r--settings/img/change.svg2
-rw-r--r--settings/l10n/pt_PT.js65
-rw-r--r--settings/l10n/pt_PT.json65
-rw-r--r--settings/l10n/sk.js23
-rw-r--r--settings/l10n/sk.json23
-rw-r--r--tests/lib/AppFramework/Http/RequestTest.php2
54 files changed, 872 insertions, 172 deletions
diff --git a/3rdparty b/3rdparty
-Subproject 600b0a7ab4c8f3c5e0fb48c68e171190f1c9006
+Subproject 8168fc1d0f33445ec4158867421dfaa9a0e241d
diff --git a/apps/comments/lib/Activity/Listener.php b/apps/comments/lib/Activity/Listener.php
index e9a41f8f6b2..b5378e996dc 100644
--- a/apps/comments/lib/Activity/Listener.php
+++ b/apps/comments/lib/Activity/Listener.php
@@ -98,7 +98,7 @@ class Listener {
/** @var Node $node */
$node = array_shift($nodes);
$al = $this->shareHelper->getPathsForAccessList($node);
- $users = array_merge($users, $al['users']);
+ $users += $al['users'];
}
}
@@ -119,7 +119,9 @@ class Listener {
]);
foreach ($users as $user => $path) {
- $activity->setAffectedUser($user);
+ // numerical user ids end up as integers from array keys, but string
+ // is required
+ $activity->setAffectedUser((string)$user);
$activity->setSubject('add_comment_subject', [
'actor' => $actor,
diff --git a/apps/comments/tests/Unit/Activity/ListenerTest.php b/apps/comments/tests/Unit/Activity/ListenerTest.php
new file mode 100644
index 00000000000..4454101bb38
--- /dev/null
+++ b/apps/comments/tests/Unit/Activity/ListenerTest.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @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\Comments\Tests\Unit\Activity;
+
+use OCA\Comments\Activity\Listener;
+use OCP\Activity\IEvent;
+use OCP\Activity\IManager;
+use OCP\App\IAppManager;
+use OCP\Comments\CommentsEvent;
+use OCP\Comments\IComment;
+use OCP\Files\Config\ICachedMountFileInfo;
+use OCP\Files\Config\IMountProviderCollection;
+use OCP\Files\Config\IUserMountCache;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Share\IShareHelper;
+use Test\TestCase;
+
+class ListenerTest extends TestCase {
+
+ /** @var Listener */
+ protected $listener;
+
+ /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $activityManager;
+
+ /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
+ protected $session;
+
+ /** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $appManager;
+
+ /** @var IMountProviderCollection|\PHPUnit_Framework_MockObject_MockObject */
+ protected $mountProviderCollection;
+
+ /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
+ protected $rootFolder;
+
+ /** @var IShareHelper|\PHPUnit_Framework_MockObject_MockObject */
+ protected $shareHelper;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->activityManager = $this->createMock(IManager::class);
+ $this->session = $this->createMock(IUserSession::class);
+ $this->appManager = $this->createMock(IAppManager::class);
+ $this->mountProviderCollection = $this->createMock(IMountProviderCollection::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->shareHelper = $this->createMock(IShareHelper::class);
+
+ $this->listener = new Listener(
+ $this->activityManager,
+ $this->session,
+ $this->appManager,
+ $this->mountProviderCollection,
+ $this->rootFolder,
+ $this->shareHelper
+ );
+ }
+
+ public function testCommentEvent() {
+ $this->appManager->expects($this->any())
+ ->method('isInstalled')
+ ->with('activity')
+ ->willReturn(true);
+
+ $comment = $this->createMock(IComment::class);
+ $comment->expects($this->any())
+ ->method('getObjectType')
+ ->willReturn('files');
+
+ /** @var CommentsEvent|\PHPUnit_Framework_MockObject_MockObject $event */
+ $event = $this->createMock(CommentsEvent::class);
+ $event->expects($this->any())
+ ->method('getComment')
+ ->willReturn($comment);
+ $event->expects($this->any())
+ ->method('getEvent')
+ ->willReturn(CommentsEvent::EVENT_ADD);
+
+ /** @var IUser|\PHPUnit_Framework_MockObject_MockObject $ownerUser */
+ $ownerUser = $this->createMock(IUser::class);
+ $ownerUser->expects($this->any())
+ ->method('getUID')
+ ->willReturn('937393');
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject $mount */
+ $mount = $this->createMock(ICachedMountFileInfo::class);
+ $mount->expects($this->any())
+ ->method('getUser')
+ ->willReturn($ownerUser); // perhaps not the right user, but does not matter in this scenario
+
+ $mounts = [ $mount, $mount ]; // to make sure duplicates are dealt with
+
+ $userMountCache = $this->createMock(IUserMountCache::class);
+ $userMountCache->expects($this->any())
+ ->method('getMountsForFileId')
+ ->willReturn($mounts);
+
+ $this->mountProviderCollection->expects($this->any())
+ ->method('getMountCache')
+ ->willReturn($userMountCache);
+
+ $node = $this->createMock(Node::class);
+ $nodes = [ $node ];
+
+ $ownerFolder = $this->createMock(Folder::class);
+ $ownerFolder->expects($this->any())
+ ->method('getById')
+ ->willReturn($nodes);
+
+ $this->rootFolder->expects($this->any())
+ ->method('getUserFolder')
+ ->willReturn($ownerFolder);
+
+ $al = [ 'users' => [
+ '873304' => 'i/got/it/here',
+ '254342' => 'there/i/have/it',
+ 'sandra' => 'and/here/i/placed/it'
+ ]];
+ $this->shareHelper->expects($this->any())
+ ->method('getPathsForAccessList')
+ ->willReturn($al);
+
+ $this->session->expects($this->any())
+ ->method('getUser')
+ ->willReturn($ownerUser);
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject $activity */
+ $activity = $this->createMock(IEvent::class);
+ $activity->expects($this->exactly(count($al['users'])))
+ ->method('setAffectedUser');
+ $activity->expects($this->once())
+ ->method('setApp')
+ ->with('comments')
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setType')
+ ->with('comments')
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setAuthor')
+ ->with($ownerUser->getUID())
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setObject')
+ ->with('files', $this->anything())
+ ->willReturnSelf();
+ $activity->expects($this->once())
+ ->method('setMessage')
+ ->with('add_comment_message', $this->anything())
+ ->willReturnSelf();
+
+ $this->activityManager->expects($this->once())
+ ->method('generateEvent')
+ ->willReturn($activity);
+ $this->activityManager->expects($this->exactly(count($al['users'])))
+ ->method('publish');
+
+ $this->listener->commentEvent($event);
+ }
+}
diff --git a/apps/dav/tests/unit/ServerTest.php b/apps/dav/tests/unit/ServerTest.php
index d502b24adcf..58c77c1b0ec 100644
--- a/apps/dav/tests/unit/ServerTest.php
+++ b/apps/dav/tests/unit/ServerTest.php
@@ -41,6 +41,8 @@ class ServerTest extends \Test\TestCase {
public function test() {
/** @var IRequest $r */
$r = $this->createMock(IRequest::class);
+ $r->method('getRequestUri')
+ ->willReturn('/');
$s = new Server($r, '/');
$this->assertInstanceOf('OCA\DAV\Server', $s);
}
diff --git a/apps/encryption/l10n/pt_PT.js b/apps/encryption/l10n/pt_PT.js
index b5b26cefd07..99d3ab28b9a 100644
--- a/apps/encryption/l10n/pt_PT.js
+++ b/apps/encryption/l10n/pt_PT.js
@@ -22,15 +22,21 @@ OC.L10N.register(
"The current log-in password was not correct, please try again." : "A palavra-passe de iniciar a sessão atual não estava correta, por favor, tente de novo.",
"Private key password successfully updated." : "A palavra-passe da chave privada foi atualizada com sucesso. ",
"You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run 'occ encryption:migrate' or contact your administrator" : "Precisa de migrar as suas chaves de encriptação da encriptação antiga (ownCloud <= 8.0) para a nova. Por favor, execute 'occ encryption:migrate' ou contacte o seu administrador",
+ "Invalid private key for encryption app. Please update your private key password in your personal settings to recover access to your encrypted files." : "Chave privada inválida para a aplicação de cifra. Por favor actualize a sua chave privada nas definições pessoais para recuperar acesso aos seus ficheiros cifrados.",
+ "Encryption App is enabled, but your keys are not initialized. Please log-out and log-in again." : "Aplicação de cifra está activa, mas as suas chaves não estão inicializaras. Por favor, faça logout e autentique-se novamente.",
+ "Please enable server side encryption in the admin settings in order to use the encryption module." : "Por favor active cifragem no servidor nas definições de administrador para usar o módulo de cifra.",
+ "Encryption app is enabled and ready" : "Aplicação de cifra activa e pronta a usar",
"Bad Signature" : "Má Assinatura",
"Missing Signature" : "Assinatura em Falta",
"one-time password for server-side-encryption" : "palavra-passe de utilização única para a encriptação do lado do servidor",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não é possível desencriptar este ficheiro, provavelmente é um ficheiro partilhado. Por favor, peça ao proprietário do ficheiro para voltar a partilhar o ficheiro consigo.",
"Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não é possível ler este ficheiro, provavelmente isto é um ficheiro compartilhado. Por favor, peça ao dono do ficheiro para voltar a partilhar o ficheiro consigo.",
+ "Default encryption module" : "Módulo de cifra padrão",
"Hey there,\n\nthe admin enabled server-side-encryption. Your files were encrypted using the password '%s'.\n\nPlease login to the web interface, go to the section 'basic encryption module' of your personal settings and update your encryption password by entering this password into the 'old log-in password' field and your current login-password.\n\n" : "Olá,\n\no administrador ativou a encriptação do lado do servidor. Os teus ficheiros foram encriptados usando a palavra-passe '%s'.\n\nPor favor, faz login via browser, vai à secção 'Módulo de encriptação básica' nas tuas definições pessoais e atualiza a tua palavra-passe de encriptação ao introduzir esta palavra-passe no campo 'palavra-passe antiga' e também a tua palavra-passe atual.\n\n",
"The share will expire on %s." : "Esta partilha irá expirar em %s.",
"Cheers!" : "Parabéns!",
"Hey there,<br><br>the admin enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>Please login to the web interface, go to the section \"basic encryption module\" of your personal settings and update your encryption password by entering this password into the \"old log-in password\" field and your current login-password.<br><br>" : "Olá,<br><br>o administrador ativou a encriptação do lado do servidor. Os teus ficheiros foram encriptados usando a palavra-passe <strong>%s</strong>.<br><br>Por favor, faz login via browser, vai à secção 'Módulo de encriptação básica' nas tuas definições pessoais e atualiza a tua palavra-passe de encriptação ao introduzir esta palavra-passe no campo 'palavra-passe antiga' e também a tua palavra-passe atual.<br><br>",
+ "Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Aplicação de cifra está activa, mas as suas chaves não estão inicializaras. Por favor, faça logout e autentique-se novamente.",
"Encrypt the home storage" : "Encriptar o armazenamento do início",
"Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Ativando esta opção todos os ficheiros armazenados no armazenamento principal serão encriptados, senão serão encriptados todos os ficheiros no armazenamento externo",
"Enable recovery key" : "Ativar a chave de recuperação",
@@ -43,6 +49,7 @@ OC.L10N.register(
"New recovery key password" : "Nova palavra-passe da chave de recuperação",
"Repeat new recovery key password" : "Repetir palavra-passe da chave de recuperação",
"Change Password" : "Alterar Palavra-passe",
+ "Basic encryption module" : "Módulo de cifra básica",
"Your private key password no longer matches your log-in password." : "A palavra-passe da sua chave privada já não coincide com a palavra-passe da sua sessão.",
"Set your old private key password to your current log-in password:" : "Defina a sua palavra-passe antiga da chave privada para a sua palavra-passe atual da sessão:",
" If you don't remember your old password you can ask your administrator to recover your files." : "Se não se lembra da palavra-passe antiga pode pedir ao seu administrador para recuperar os seus ficheiros. ",
diff --git a/apps/encryption/l10n/pt_PT.json b/apps/encryption/l10n/pt_PT.json
index 2dbaaaf1dbf..050c8b1710c 100644
--- a/apps/encryption/l10n/pt_PT.json
+++ b/apps/encryption/l10n/pt_PT.json
@@ -20,15 +20,21 @@
"The current log-in password was not correct, please try again." : "A palavra-passe de iniciar a sessão atual não estava correta, por favor, tente de novo.",
"Private key password successfully updated." : "A palavra-passe da chave privada foi atualizada com sucesso. ",
"You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run 'occ encryption:migrate' or contact your administrator" : "Precisa de migrar as suas chaves de encriptação da encriptação antiga (ownCloud <= 8.0) para a nova. Por favor, execute 'occ encryption:migrate' ou contacte o seu administrador",
+ "Invalid private key for encryption app. Please update your private key password in your personal settings to recover access to your encrypted files." : "Chave privada inválida para a aplicação de cifra. Por favor actualize a sua chave privada nas definições pessoais para recuperar acesso aos seus ficheiros cifrados.",
+ "Encryption App is enabled, but your keys are not initialized. Please log-out and log-in again." : "Aplicação de cifra está activa, mas as suas chaves não estão inicializaras. Por favor, faça logout e autentique-se novamente.",
+ "Please enable server side encryption in the admin settings in order to use the encryption module." : "Por favor active cifragem no servidor nas definições de administrador para usar o módulo de cifra.",
+ "Encryption app is enabled and ready" : "Aplicação de cifra activa e pronta a usar",
"Bad Signature" : "Má Assinatura",
"Missing Signature" : "Assinatura em Falta",
"one-time password for server-side-encryption" : "palavra-passe de utilização única para a encriptação do lado do servidor",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não é possível desencriptar este ficheiro, provavelmente é um ficheiro partilhado. Por favor, peça ao proprietário do ficheiro para voltar a partilhar o ficheiro consigo.",
"Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não é possível ler este ficheiro, provavelmente isto é um ficheiro compartilhado. Por favor, peça ao dono do ficheiro para voltar a partilhar o ficheiro consigo.",
+ "Default encryption module" : "Módulo de cifra padrão",
"Hey there,\n\nthe admin enabled server-side-encryption. Your files were encrypted using the password '%s'.\n\nPlease login to the web interface, go to the section 'basic encryption module' of your personal settings and update your encryption password by entering this password into the 'old log-in password' field and your current login-password.\n\n" : "Olá,\n\no administrador ativou a encriptação do lado do servidor. Os teus ficheiros foram encriptados usando a palavra-passe '%s'.\n\nPor favor, faz login via browser, vai à secção 'Módulo de encriptação básica' nas tuas definições pessoais e atualiza a tua palavra-passe de encriptação ao introduzir esta palavra-passe no campo 'palavra-passe antiga' e também a tua palavra-passe atual.\n\n",
"The share will expire on %s." : "Esta partilha irá expirar em %s.",
"Cheers!" : "Parabéns!",
"Hey there,<br><br>the admin enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>Please login to the web interface, go to the section \"basic encryption module\" of your personal settings and update your encryption password by entering this password into the \"old log-in password\" field and your current login-password.<br><br>" : "Olá,<br><br>o administrador ativou a encriptação do lado do servidor. Os teus ficheiros foram encriptados usando a palavra-passe <strong>%s</strong>.<br><br>Por favor, faz login via browser, vai à secção 'Módulo de encriptação básica' nas tuas definições pessoais e atualiza a tua palavra-passe de encriptação ao introduzir esta palavra-passe no campo 'palavra-passe antiga' e também a tua palavra-passe atual.<br><br>",
+ "Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Aplicação de cifra está activa, mas as suas chaves não estão inicializaras. Por favor, faça logout e autentique-se novamente.",
"Encrypt the home storage" : "Encriptar o armazenamento do início",
"Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Ativando esta opção todos os ficheiros armazenados no armazenamento principal serão encriptados, senão serão encriptados todos os ficheiros no armazenamento externo",
"Enable recovery key" : "Ativar a chave de recuperação",
@@ -41,6 +47,7 @@
"New recovery key password" : "Nova palavra-passe da chave de recuperação",
"Repeat new recovery key password" : "Repetir palavra-passe da chave de recuperação",
"Change Password" : "Alterar Palavra-passe",
+ "Basic encryption module" : "Módulo de cifra básica",
"Your private key password no longer matches your log-in password." : "A palavra-passe da sua chave privada já não coincide com a palavra-passe da sua sessão.",
"Set your old private key password to your current log-in password:" : "Defina a sua palavra-passe antiga da chave privada para a sua palavra-passe atual da sessão:",
" If you don't remember your old password you can ask your administrator to recover your files." : "Se não se lembra da palavra-passe antiga pode pedir ao seu administrador para recuperar os seus ficheiros. ",
diff --git a/apps/files/img/change.png b/apps/files/img/change.png
index 9f64e60d565..ca77a8844f6 100644
--- a/apps/files/img/change.png
+++ b/apps/files/img/change.png
Binary files differ
diff --git a/apps/files/img/change.svg b/apps/files/img/change.svg
index b3404d2ef84..12071422b7f 100644
--- a/apps/files/img/change.svg
+++ b/apps/files/img/change.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1"><path d="m8 0c-2.8557-3.771e-8 -5.4999 1.5269-6.9277 4l2.5976 1.5c0.8944-1.5491 2.5413-2.5 4.3301-2.5 1.5874 0 3.0628 0.74877 4 2l-2 2h6v-6l-1.875 1.875c-1.505-1.797-3.736-2.875-6.125-2.875z"/><path d="m0 9v6l1.877-1.877c1.4882 1.778 3.7559 2.857 6.123 2.877 2.8797 0.02436 5.4878-1.506 6.9277-4l-2.598-1.5c-0.902 1.562-2.5261 2.515-4.33 2.5-1.5737-0.013-3.0729-0.762-4-2l2-2z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path d="m8 2c-2.142 0-4.125 1.145-5.196 3l1.948 1.125c0.671-1.162 1.906-1.875 3.2476-1.875 1.1906 0 2.297 0.56157 3 1.5l-1.5 1.5h4.5v-4.5l-1.406 1.406c-1.129-1.348-2.802-2.1563-4.594-2.1563z"/><path d="m2 8.75v4.5l1.408-1.41c1.116 1.334 2.817 2.145 4.592 2.16 2.16 0.01827 4.116-1.132 5.196-3.002l-1.948-1.125c-0.677 1.171-1.9005 1.886-3.248 1.875-1.18-0.01-2.3047-0.572-3-1.5l1.5-1.5z"/></svg>
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 2fb7dfba29f..a6d376aa2a9 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -625,12 +625,23 @@
this.registerAction({
name: 'MoveCopy',
- displayName: t('files', 'Move or copy'),
+ displayName: function(context) {
+ var permissions = context.fileInfoModel.attributes.permissions;
+ if (permissions & OC.PERMISSION_UPDATE) {
+ return t('files', 'Move or copy');
+ }
+ return t('files', 'Copy');
+ },
mime: 'all',
order: -25,
- permissions: OC.PERMISSION_UPDATE,
+ permissions: $('#isPublic').val() ? OC.PERMISSION_UPDATE : OC.PERMISSION_READ,
iconClass: 'icon-external',
actionHandler: function (filename, context) {
+ var permissions = context.fileInfoModel.attributes.permissions;
+ var actions = OC.dialogs.FILEPICKER_TYPE_COPY;
+ if (permissions & OC.PERMISSION_UPDATE) {
+ actions = OC.dialogs.FILEPICKER_TYPE_COPY_MOVE;
+ }
OC.dialogs.filepicker(t('files', 'Target folder'), function(targetPath, type) {
if (type === OC.dialogs.FILEPICKER_TYPE_COPY) {
context.fileList.copy(filename, targetPath);
@@ -638,7 +649,7 @@
if (type === OC.dialogs.FILEPICKER_TYPE_MOVE) {
context.fileList.move(filename, targetPath);
}
- }, false, "httpd/unix-directory", true, OC.dialogs.FILEPICKER_TYPE_COPY_MOVE);
+ }, false, "httpd/unix-directory", true, actions);
}
});
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index b46db792678..4dc8a58e175 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -798,6 +798,7 @@
OCA.Files.FileActions.updateFileActionSpinner(moveFileAction, false);
};
+ var actions = this.isSelectedMovable() ? OC.dialogs.FILEPICKER_TYPE_COPY_MOVE : OC.dialogs.FILEPICKER_TYPE_COPY;
OC.dialogs.filepicker(t('files', 'Target folder'), function(targetPath, type) {
if (type === OC.dialogs.FILEPICKER_TYPE_COPY) {
self.copy(files, targetPath, disableLoadingState);
@@ -805,7 +806,7 @@
if (type === OC.dialogs.FILEPICKER_TYPE_MOVE) {
self.move(files, targetPath, disableLoadingState);
}
- }, false, "httpd/unix-directory", true, OC.dialogs.FILEPICKER_TYPE_COPY_MOVE);
+ }, false, "httpd/unix-directory", true, actions);
return false;
},
@@ -2871,18 +2872,39 @@
this.$el.find('#headerName a.name>span:first').text(selection);
this.$el.find('#modified a>span:first').text('');
this.$el.find('table').addClass('multiselect');
- this.$el.find('.selectedActions .copy-move').toggleClass('hidden', !this.isSelectedCopiableOrMovable());
this.$el.find('.selectedActions .download').toggleClass('hidden', !this.isSelectedDownloadable());
this.$el.find('.delete-selected').toggleClass('hidden', !this.isSelectedDeletable());
+
+ var $copyMove = this.$el.find('.selectedActions .copy-move');
+ if (this.isSelectedCopiable()) {
+ $copyMove.toggleClass('hidden', false);
+ if (this.isSelectedMovable()) {
+ $copyMove.find('.label').text(t('files', 'Move or copy'));
+ } else {
+ $copyMove.find('.label').text(t('files', 'Copy'));
+ }
+ } else {
+ $copyMove.toggleClass('hidden', true);
+ }
}
},
/**
- * Check whether all selected files are copiable or movable
+ * Check whether all selected files are copiable
+ */
+ isSelectedCopiable: function() {
+ return _.reduce(this.getSelectedFiles(), function(copiable, file) {
+ var requiredPermission = $('#isPublic').val() ? OC.PERMISSION_UPDATE : OC.PERMISSION_READ;
+ return copiable && (file.permissions & requiredPermission);
+ }, true);
+ },
+
+ /**
+ * Check whether all selected files are movable
*/
- isSelectedCopiableOrMovable: function() {
- return _.reduce(this.getSelectedFiles(), function(copiableOrMovable, file) {
- return copiableOrMovable && (file.permissions & OC.PERMISSION_UPDATE);
+ isSelectedMovable: function() {
+ return _.reduce(this.getSelectedFiles(), function(movable, file) {
+ return movable && (file.permissions & OC.PERMISSION_UPDATE);
}, true);
},
diff --git a/apps/files/l10n/pt_PT.js b/apps/files/l10n/pt_PT.js
index feb43aced76..ffa95f4b93c 100644
--- a/apps/files/l10n/pt_PT.js
+++ b/apps/files/l10n/pt_PT.js
@@ -17,8 +17,10 @@ OC.L10N.register(
"Target folder \"{dir}\" does not exist any more" : "A pasta de destino \"{dir}\" já não existe",
"Not enough free space" : "Espaço insuficiente",
"Uploading …" : "A carregar ...",
+ "…" : "...",
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
"Target folder does not exist any more" : "A pasta de destino já não existe",
+ "Error when assembling chunks, status code {status}" : "Erro ao agregar partições, código de estado: {estado}",
"Actions" : "Ações",
"Download" : "Transferir",
"Rename" : "Renomear",
diff --git a/apps/files/l10n/pt_PT.json b/apps/files/l10n/pt_PT.json
index 97d4308cab4..31ecc0ef67d 100644
--- a/apps/files/l10n/pt_PT.json
+++ b/apps/files/l10n/pt_PT.json
@@ -15,8 +15,10 @@
"Target folder \"{dir}\" does not exist any more" : "A pasta de destino \"{dir}\" já não existe",
"Not enough free space" : "Espaço insuficiente",
"Uploading …" : "A carregar ...",
+ "…" : "...",
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
"Target folder does not exist any more" : "A pasta de destino já não existe",
+ "Error when assembling chunks, status code {status}" : "Erro ao agregar partições, código de estado: {estado}",
"Actions" : "Ações",
"Download" : "Transferir",
"Rename" : "Renomear",
diff --git a/apps/files/templates/list.php b/apps/files/templates/list.php
index fd5423c334f..e6b1e54d389 100644
--- a/apps/files/templates/list.php
+++ b/apps/files/templates/list.php
@@ -53,7 +53,7 @@
<span id="selectedActionsList" class="selectedActions">
<a href="" class="copy-move">
<span class="icon icon-external"></span>
- <span><?php p($l->t('Move or copy'))?></span>
+ <span class="label"><?php p($l->t('Move or copy'))?></span>
</a>
<a href="" class="download">
<span class="icon icon-download"></span>
diff --git a/apps/files/tests/js/fileactionsmenuSpec.js b/apps/files/tests/js/fileactionsmenuSpec.js
index 926516b3043..c678d166153 100644
--- a/apps/files/tests/js/fileactionsmenuSpec.js
+++ b/apps/files/tests/js/fileactionsmenuSpec.js
@@ -271,6 +271,7 @@ describe('OCA.Files.FileActionsMenu tests', function() {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
+ fileInfoModel: new OCA.Files.FileInfoModel(fileData),
dir: fileList.getCurrentDirectory()
};
menu = new OCA.Files.FileActionsMenu();
@@ -304,6 +305,7 @@ describe('OCA.Files.FileActionsMenu tests', function() {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
+ fileInfoModel: new OCA.Files.FileInfoModel(fileData),
dir: '/anotherpath/there'
};
menu = new OCA.Files.FileActionsMenu();
@@ -336,6 +338,7 @@ describe('OCA.Files.FileActionsMenu tests', function() {
$file: $tr,
fileList: fileList,
fileActions: fileActions,
+ fileInfoModel: new OCA.Files.FileInfoModel(fileData),
dir: '/somepath/dir'
};
menu = new OCA.Files.FileActionsMenu();
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 08da15b8a88..1b26a468172 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -94,7 +94,7 @@ describe('OCA.Files.FileList tests', function() {
'<input type="checkbox" id="select_all_files" class="select-all checkbox">' +
'<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
'<span id="selectedActionsList" class="selectedActions hidden">' +
- '<a href class="copy-move">Move or copy</a>' +
+ '<a href class="copy-move"><span class="label">Move or copy</span></a>' +
'<a href class="download"><img src="actions/download.svg">Download</a>' +
'<a href class="delete-selected">Delete</a></span>' +
'</th>' +
@@ -2101,10 +2101,17 @@ describe('OCA.Files.FileList tests', function() {
$('#permissions').val(OC.PERMISSION_READ | OC.PERMISSION_UPDATE);
$('.select-all').click();
expect(fileList.$el.find('.selectedActions .copy-move').hasClass('hidden')).toEqual(false);
+ expect(fileList.$el.find('.selectedActions .copy-move .label').text()).toEqual('Move or copy');
testFiles[0].permissions = OC.PERMISSION_READ;
$('.select-all').click();
fileList.setFiles(testFiles);
$('.select-all').click();
+ expect(fileList.$el.find('.selectedActions .copy-move').hasClass('hidden')).toEqual(false);
+ expect(fileList.$el.find('.selectedActions .copy-move .label').text()).toEqual('Copy');
+ testFiles[0].permissions = OC.PERMISSION_NONE;
+ $('.select-all').click();
+ fileList.setFiles(testFiles);
+ $('.select-all').click();
expect(fileList.$el.find('.selectedActions .copy-move').hasClass('hidden')).toEqual(true);
});
it('show doesnt show the download action if one or more files are not downloadable', function () {
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index cb9b7ad6822..12ad285c52b 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -960,6 +960,7 @@ MountConfigListView.prototype = _.extend({
if (result.length === 0 && mainForm.attr('data-can-create') === 'false') {
mainForm.hide();
$('a[href="#external-storage"]').parent().hide();
+ $('#emptycontent').show();
}
onCompletion.resolve();
}
diff --git a/apps/files_external/l10n/pt_PT.js b/apps/files_external/l10n/pt_PT.js
index 5f119553b57..a81b857eba5 100644
--- a/apps/files_external/l10n/pt_PT.js
+++ b/apps/files_external/l10n/pt_PT.js
@@ -14,13 +14,19 @@ OC.L10N.register(
"(group)" : "(grupo)",
"Compatibility with Mac NFD encoding (slow)" : "Compatibilidade com a codificação NFD Mac (lenta)",
"Admin defined" : "Administrador definido",
+ "Are you sure you want to delete this external storage" : "De certeza que quer apagar este armazenamento externo",
+ "Delete storage?" : "Apagar armazenamento?",
"Saved" : "Guardado",
+ "Saving..." : "A guardar...",
"Save" : "Guardar",
"Empty response from the server" : "Resposta vazia a partir do servidor",
+ "Couldn't access. Please log out and in again to activate this mount point" : "Não foi possível aceder. Por favor faça logout e volte-se a autenticar para activar este ponto de montagem.",
+ "Couldn't get the information from the remote server: {code} {type}" : "Não foi possível obter informação do servidor remoto: {código}{tipo}",
"Couldn't get the list of external mount points: {type}" : "Não foi possível conseguir a lista de pontos de montagem externos: {type}",
"There was an error with message: " : "Houve um erro com a mensagem:",
"External mount error" : "Erro de montagem externa",
"external-storage" : "armazenamento externo",
+ "Couldn't fetch list of Windows network drive mount points: Empty response from server" : "Não fo possível obter lista de pontos de montagem de rede Windows: Resposta vazia do servidor",
"Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor, clique na fila vermelha para mais informação",
"Please enter the credentials for the {mount} mount" : "Por favor, introduza as credenciais para {mount}",
"Username" : "Nome de utilizador",
@@ -28,6 +34,7 @@ OC.L10N.register(
"Credentials saved" : "Credenciais guardadas",
"Credentials saving failed" : "Falha ao guardar as credenciais",
"Credentials required" : "Credenciais necessárias",
+ "Storage with ID \"%d\" not found" : "Armazenamento com ID \"%d\" não encontrado",
"Invalid backend or authentication mechanism class" : "Parâmetros do mecanismo de autenticação inválidos",
"Invalid mount point" : "Ponto de montagem inválido",
"Objectstore forbidden" : "Objectstore proibido",
@@ -38,6 +45,7 @@ OC.L10N.register(
"Unsatisfied authentication mechanism parameters" : "Parâmetros do mecanismo de autenticação inválidos",
"Insufficient data: %s" : "Dados insuficientes: %s",
"%s" : "%s",
+ "Storage with ID \"%d\" is not user editable" : "Armazenamento com ID \"%d\" não é evitável por utilizadores",
"Access key" : "Chave de acesso",
"Secret key" : "Código secreto",
"Builtin" : "Integrado",
@@ -53,8 +61,11 @@ OC.L10N.register(
"Identity endpoint URL" : "Identidade URL endpoint",
"Rackspace" : "Rackspace",
"API key" : "Chave API",
+ "Global credentials" : "Credenciais globais",
+ "Log-in credentials, save in database" : "Credenciais de Log-in, guardar na base de dados",
"Username and password" : "Nome de utilizador e palavra-passe",
"Log-in credentials, save in session" : "Credenciais de login, guardar na sessão",
+ "User entered, store in database" : "Inseridos pelo utilizador, armazenar na base de dados",
"RSA public key" : "Chave pública RSA",
"Public key" : "Chave pública",
"Amazon S3" : "Amazon S3",
@@ -64,6 +75,7 @@ OC.L10N.register(
"Region" : "Região",
"Enable SSL" : "Ativar SSL",
"Enable Path Style" : "Ativar Estilo do Caminho",
+ "Legacy (v2) authentication" : "Autenticação obsoleta (v2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Subpasta remota ",
@@ -73,6 +85,7 @@ OC.L10N.register(
"Secure ftps://" : "ftps:// Seguro",
"Local" : "Local",
"Location" : "Localização:",
+ "Nextcloud" : "Nextcloud",
"SFTP" : "SFTP",
"Root" : "Root",
"SFTP with secret key login" : "SFTP com login por chave secreta",
@@ -84,6 +97,10 @@ OC.L10N.register(
"OpenStack Object Storage" : "Armazenamento de Objetos OpenStack",
"Service name" : "Nome do serviço",
"Request timeout (seconds)" : "Pedido expira (segundos)",
+ "The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "O suporte cURL em PHP não está activo ou instalado. Não é possível montar %s. Por favor peça ao seu administrador de sistema que o instale.",
+ "The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "O suporteF TP em PHP não está activo ou instalado. Não é possível montar %s. Por favor peça ao seu administrador de sistema que o instale.",
+ "\"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "\"%s\" não está instalado. Não é possível montar %s. Por favor peça ao seu administrador que o instale.",
+ "External storage support" : "Suporte para armazenamento externo",
"No external storage configured" : "Sem armazenamentos externos configurados",
"You can add external storages in the personal settings" : "Pode adicionar armazenamentos externos nas definições pessoais",
"Name" : "Nome",
@@ -104,6 +121,14 @@ OC.L10N.register(
"Advanced settings" : "Definições avançadas",
"Delete" : "Apagar",
"Allow users to mount external storage" : "Permitir que os utilizadores montem armazenamento externo",
- "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo"
+ "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo",
+ "Fetching request tokens failed. Verify that your app key and secret are correct." : "Falhou a obter tokens de pedido. Verifique se a sua chave de aplicação e segredo estão correctos.",
+ "Fetching access tokens failed. Verify that your app key and secret are correct." : "Falhou a obter tokens de acesso. Verifique se a sua chave de aplicação e segredo estão correctos.",
+ "Step 1 failed. Exception: %s" : "Passo 1 falhou. Excepção: %s",
+ "Step 2 failed. Exception: %s" : "Passo 2 falhou. Excepção: %s",
+ "Dropbox App Configuration" : "configuração da aplicação Dropbox",
+ "Google Drive App Configuration" : "Configuração da aplicação Google Drive",
+ "Dropbox" : "Dropbox",
+ "Google Drive" : "Google Drive"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_external/l10n/pt_PT.json b/apps/files_external/l10n/pt_PT.json
index 88600ac5eaf..4efae622222 100644
--- a/apps/files_external/l10n/pt_PT.json
+++ b/apps/files_external/l10n/pt_PT.json
@@ -12,13 +12,19 @@
"(group)" : "(grupo)",
"Compatibility with Mac NFD encoding (slow)" : "Compatibilidade com a codificação NFD Mac (lenta)",
"Admin defined" : "Administrador definido",
+ "Are you sure you want to delete this external storage" : "De certeza que quer apagar este armazenamento externo",
+ "Delete storage?" : "Apagar armazenamento?",
"Saved" : "Guardado",
+ "Saving..." : "A guardar...",
"Save" : "Guardar",
"Empty response from the server" : "Resposta vazia a partir do servidor",
+ "Couldn't access. Please log out and in again to activate this mount point" : "Não foi possível aceder. Por favor faça logout e volte-se a autenticar para activar este ponto de montagem.",
+ "Couldn't get the information from the remote server: {code} {type}" : "Não foi possível obter informação do servidor remoto: {código}{tipo}",
"Couldn't get the list of external mount points: {type}" : "Não foi possível conseguir a lista de pontos de montagem externos: {type}",
"There was an error with message: " : "Houve um erro com a mensagem:",
"External mount error" : "Erro de montagem externa",
"external-storage" : "armazenamento externo",
+ "Couldn't fetch list of Windows network drive mount points: Empty response from server" : "Não fo possível obter lista de pontos de montagem de rede Windows: Resposta vazia do servidor",
"Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor, clique na fila vermelha para mais informação",
"Please enter the credentials for the {mount} mount" : "Por favor, introduza as credenciais para {mount}",
"Username" : "Nome de utilizador",
@@ -26,6 +32,7 @@
"Credentials saved" : "Credenciais guardadas",
"Credentials saving failed" : "Falha ao guardar as credenciais",
"Credentials required" : "Credenciais necessárias",
+ "Storage with ID \"%d\" not found" : "Armazenamento com ID \"%d\" não encontrado",
"Invalid backend or authentication mechanism class" : "Parâmetros do mecanismo de autenticação inválidos",
"Invalid mount point" : "Ponto de montagem inválido",
"Objectstore forbidden" : "Objectstore proibido",
@@ -36,6 +43,7 @@
"Unsatisfied authentication mechanism parameters" : "Parâmetros do mecanismo de autenticação inválidos",
"Insufficient data: %s" : "Dados insuficientes: %s",
"%s" : "%s",
+ "Storage with ID \"%d\" is not user editable" : "Armazenamento com ID \"%d\" não é evitável por utilizadores",
"Access key" : "Chave de acesso",
"Secret key" : "Código secreto",
"Builtin" : "Integrado",
@@ -51,8 +59,11 @@
"Identity endpoint URL" : "Identidade URL endpoint",
"Rackspace" : "Rackspace",
"API key" : "Chave API",
+ "Global credentials" : "Credenciais globais",
+ "Log-in credentials, save in database" : "Credenciais de Log-in, guardar na base de dados",
"Username and password" : "Nome de utilizador e palavra-passe",
"Log-in credentials, save in session" : "Credenciais de login, guardar na sessão",
+ "User entered, store in database" : "Inseridos pelo utilizador, armazenar na base de dados",
"RSA public key" : "Chave pública RSA",
"Public key" : "Chave pública",
"Amazon S3" : "Amazon S3",
@@ -62,6 +73,7 @@
"Region" : "Região",
"Enable SSL" : "Ativar SSL",
"Enable Path Style" : "Ativar Estilo do Caminho",
+ "Legacy (v2) authentication" : "Autenticação obsoleta (v2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Subpasta remota ",
@@ -71,6 +83,7 @@
"Secure ftps://" : "ftps:// Seguro",
"Local" : "Local",
"Location" : "Localização:",
+ "Nextcloud" : "Nextcloud",
"SFTP" : "SFTP",
"Root" : "Root",
"SFTP with secret key login" : "SFTP com login por chave secreta",
@@ -82,6 +95,10 @@
"OpenStack Object Storage" : "Armazenamento de Objetos OpenStack",
"Service name" : "Nome do serviço",
"Request timeout (seconds)" : "Pedido expira (segundos)",
+ "The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "O suporte cURL em PHP não está activo ou instalado. Não é possível montar %s. Por favor peça ao seu administrador de sistema que o instale.",
+ "The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "O suporteF TP em PHP não está activo ou instalado. Não é possível montar %s. Por favor peça ao seu administrador de sistema que o instale.",
+ "\"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "\"%s\" não está instalado. Não é possível montar %s. Por favor peça ao seu administrador que o instale.",
+ "External storage support" : "Suporte para armazenamento externo",
"No external storage configured" : "Sem armazenamentos externos configurados",
"You can add external storages in the personal settings" : "Pode adicionar armazenamentos externos nas definições pessoais",
"Name" : "Nome",
@@ -102,6 +119,14 @@
"Advanced settings" : "Definições avançadas",
"Delete" : "Apagar",
"Allow users to mount external storage" : "Permitir que os utilizadores montem armazenamento externo",
- "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo"
+ "Allow users to mount the following external storage" : "Permitir que os utilizadores montem o seguinte armazenamento externo",
+ "Fetching request tokens failed. Verify that your app key and secret are correct." : "Falhou a obter tokens de pedido. Verifique se a sua chave de aplicação e segredo estão correctos.",
+ "Fetching access tokens failed. Verify that your app key and secret are correct." : "Falhou a obter tokens de acesso. Verifique se a sua chave de aplicação e segredo estão correctos.",
+ "Step 1 failed. Exception: %s" : "Passo 1 falhou. Excepção: %s",
+ "Step 2 failed. Exception: %s" : "Passo 2 falhou. Excepção: %s",
+ "Dropbox App Configuration" : "configuração da aplicação Dropbox",
+ "Google Drive App Configuration" : "Configuração da aplicação Google Drive",
+ "Dropbox" : "Dropbox",
+ "Google Drive" : "Google Drive"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_external/lib/Config/ConfigAdapter.php b/apps/files_external/lib/Config/ConfigAdapter.php
index efeb3d75586..34e96df0441 100644
--- a/apps/files_external/lib/Config/ConfigAdapter.php
+++ b/apps/files_external/lib/Config/ConfigAdapter.php
@@ -168,7 +168,7 @@ class ConfigAdapter implements IMountProvider {
$storageConfig->getMountOptions()
);
} else {
- return new MountPoint(
+ return new ExternalMountPoint(
$storage,
'/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(),
null,
diff --git a/apps/files_external/lib/Lib/PersonalMount.php b/apps/files_external/lib/Lib/PersonalMount.php
index c54ed0a79f3..8c8ac0893f6 100644
--- a/apps/files_external/lib/Lib/PersonalMount.php
+++ b/apps/files_external/lib/Lib/PersonalMount.php
@@ -24,14 +24,14 @@
namespace OCA\Files_External\Lib;
-use OC\Files\Mount\MountPoint;
use OC\Files\Mount\MoveableMount;
+use OCA\Files_External\Config\ExternalMountPoint;
use OCA\Files_External\Service\UserStoragesService;
/**
* Person mount points can be moved by the user
*/
-class PersonalMount extends MountPoint implements MoveableMount {
+class PersonalMount extends ExternalMountPoint implements MoveableMount {
/** @var UserStoragesService */
protected $storagesService;
diff --git a/apps/files_external/templates/list.php b/apps/files_external/templates/list.php
index d006514bcde..ed13ed83701 100644
--- a/apps/files_external/templates/list.php
+++ b/apps/files_external/templates/list.php
@@ -6,8 +6,7 @@
<div id="emptycontent" class="hidden">
<div class="icon-external"></div>
- <h2><?php p($l->t('No external storage configured')); ?></h2>
- <p><a href="<?php p(link_to('', 'index.php/settings/personal#files_external' )); ?>"><?php p($l->t('You can add external storages in the personal settings')); ?></a></p>
+ <h2><?php p($l->t('No external storage configured or you don\'t have the permission to configure them')); ?></h2>
</div>
<input type="hidden" name="dir" value="" id="dir">
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 237985bfd0f..11b3451c32e 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -87,6 +87,11 @@
}
?>
+<div id="emptycontent" class="hidden">
+ <div class="icon-external"></div>
+ <h2><?php p($l->t('No external storage configured or you don\'t have the permission to configure them')); ?></h2>
+</div>
+
<form data-can-create="<?php echo $canCreateMounts?'true':'false' ?>" id="files_external" class="section" data-encryption-enabled="<?php echo $_['encryptionEnabled']?'true': 'false'; ?>">
<h2 data-anchor-name="external-storage"><?php p($l->t('External storages')); ?></h2>
<?php if (isset($_['dependencies']) and ($_['dependencies'] !== '') and $canCreateMounts) print_unescaped(''.$_['dependencies'].''); ?>
diff --git a/apps/files_sharing/l10n/pt_PT.js b/apps/files_sharing/l10n/pt_PT.js
index a2dd0a4708a..a1af9e5d1c8 100644
--- a/apps/files_sharing/l10n/pt_PT.js
+++ b/apps/files_sharing/l10n/pt_PT.js
@@ -79,6 +79,8 @@ OC.L10N.register(
"Public upload is only possible for publicly shared folders" : "O envio público só é possível para as pastas partilhadas publicamente",
"Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD",
"Sharing %s failed because the back end does not allow shares from type %s" : "A partilha de %s falhou porque \"back end\" não permite partilhas do tipo %s",
+ "You cannot share to a Circle if the app is not enabled" : "Não pode partilhar um Círculo se a aplicação não estiver activa",
+ "Please specify a valid circle" : "Por favor especifique um círculo válido",
"Unknown share type" : "Tipo de partilha desconhecido",
"Not a directory" : "Não é uma diretoria",
"Could not lock path" : "Não foi possível bloquear o caminho",
@@ -103,6 +105,7 @@ OC.L10N.register(
"shared by %s" : "partilhado por %s",
"Download" : "Transferir",
"Direct link" : "Hiperligação direta",
+ "Add to your Nextcloud" : "Adicionar à sua Nextcloud",
"Download %s" : "Transferir %s",
"Upload files to %s" : "Enviar ficheiros para %s",
"Select or drop files" : "Seleccione ou solte ficheiros",
diff --git a/apps/files_sharing/l10n/pt_PT.json b/apps/files_sharing/l10n/pt_PT.json
index 5c17afacf97..40d57e3ffe8 100644
--- a/apps/files_sharing/l10n/pt_PT.json
+++ b/apps/files_sharing/l10n/pt_PT.json
@@ -77,6 +77,8 @@
"Public upload is only possible for publicly shared folders" : "O envio público só é possível para as pastas partilhadas publicamente",
"Invalid date, date format must be YYYY-MM-DD" : "Data inválida, o formato da data deve ser AAAA-MM-DD",
"Sharing %s failed because the back end does not allow shares from type %s" : "A partilha de %s falhou porque \"back end\" não permite partilhas do tipo %s",
+ "You cannot share to a Circle if the app is not enabled" : "Não pode partilhar um Círculo se a aplicação não estiver activa",
+ "Please specify a valid circle" : "Por favor especifique um círculo válido",
"Unknown share type" : "Tipo de partilha desconhecido",
"Not a directory" : "Não é uma diretoria",
"Could not lock path" : "Não foi possível bloquear o caminho",
@@ -101,6 +103,7 @@
"shared by %s" : "partilhado por %s",
"Download" : "Transferir",
"Direct link" : "Hiperligação direta",
+ "Add to your Nextcloud" : "Adicionar à sua Nextcloud",
"Download %s" : "Transferir %s",
"Upload files to %s" : "Enviar ficheiros para %s",
"Select or drop files" : "Seleccione ou solte ficheiros",
diff --git a/apps/oauth2/l10n/pt_PT.js b/apps/oauth2/l10n/pt_PT.js
new file mode 100644
index 00000000000..f89a56c39d1
--- /dev/null
+++ b/apps/oauth2/l10n/pt_PT.js
@@ -0,0 +1,14 @@
+OC.L10N.register(
+ "oauth2",
+ {
+ "OAuth 2.0" : "OAuth 2.0",
+ "OAuth 2.0 clients" : "Clientes OAuth 2.0",
+ "OAuth 2.0 allows external services to request access to %s." : "OAuth2.0 permite que dispositivos externos peçam acesso a %s.",
+ "Name" : "Nome",
+ "Redirection URI" : "URI de redireccionamento",
+ "Client Identifier" : "Identificador de Cliente",
+ "Secret" : "Segredo",
+ "Add client" : "Adicionar cliente",
+ "Add" : "Adicionar"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/apps/oauth2/l10n/pt_PT.json b/apps/oauth2/l10n/pt_PT.json
new file mode 100644
index 00000000000..15f16743e78
--- /dev/null
+++ b/apps/oauth2/l10n/pt_PT.json
@@ -0,0 +1,12 @@
+{ "translations": {
+ "OAuth 2.0" : "OAuth 2.0",
+ "OAuth 2.0 clients" : "Clientes OAuth 2.0",
+ "OAuth 2.0 allows external services to request access to %s." : "OAuth2.0 permite que dispositivos externos peçam acesso a %s.",
+ "Name" : "Nome",
+ "Redirection URI" : "URI de redireccionamento",
+ "Client Identifier" : "Identificador de Cliente",
+ "Secret" : "Segredo",
+ "Add client" : "Adicionar cliente",
+ "Add" : "Adicionar"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/apps/sharebymail/lib/ShareByMailProvider.php b/apps/sharebymail/lib/ShareByMailProvider.php
index 31df8a18951..61c9c01e9ab 100644
--- a/apps/sharebymail/lib/ShareByMailProvider.php
+++ b/apps/sharebymail/lib/ShareByMailProvider.php
@@ -404,7 +404,7 @@ class ShareByMailProvider implements IShareProvider {
$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
$emailTemplate->addBodyText(
- $text . ' ' . $this->l->t('Click the button below to open it.'),
+ htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
$text
);
$emailTemplate->addBodyButton(
@@ -476,7 +476,7 @@ class ShareByMailProvider implements IShareProvider {
$emailTemplate->setSubject($this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]));
$emailTemplate->addHeader();
$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
- $emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
+ $emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
// The "From" contains the sharers name
diff --git a/apps/systemtags/lib/Activity/Listener.php b/apps/systemtags/lib/Activity/Listener.php
index b2b760ac344..7d84726d537 100644
--- a/apps/systemtags/lib/Activity/Listener.php
+++ b/apps/systemtags/lib/Activity/Listener.php
@@ -184,7 +184,7 @@ class Listener {
/** @var Node $node */
$node = array_shift($nodes);
$al = $this->shareHelper->getPathsForAccessList($node);
- $users = array_merge($users, $al['users']);
+ $users += $al['users'];
}
}
@@ -202,6 +202,7 @@ class Listener {
->setObject($event->getObjectType(), (int) $event->getObjectId());
foreach ($users as $user => $path) {
+ $user = (string)$user; // numerical ids could be ints which are not accepted everywhere
$activity->setAffectedUser($user);
foreach ($tags as $tag) {
diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php
index 6cb56941463..2e7bddb9c4d 100644
--- a/apps/user_ldap/lib/Group_LDAP.php
+++ b/apps/user_ldap/lib/Group_LDAP.php
@@ -207,6 +207,7 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface, IGroupLD
* @param string $dnGroup
* @param array|null &$seen
* @return array|mixed|null
+ * @throws \OC\ServerNotAvailableException
*/
private function _groupMembers($dnGroup, &$seen = null) {
if ($seen === null) {
@@ -220,26 +221,26 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface, IGroupLD
// used extensively in cron job, caching makes sense for nested groups
$cacheKey = '_groupMembers'.$dnGroup;
$groupMembers = $this->access->connection->getFromCache($cacheKey);
- if(!is_null($groupMembers)) {
+ if($groupMembers !== null) {
return $groupMembers;
}
$seen[$dnGroup] = 1;
$members = $this->access->readAttribute($dnGroup, $this->access->connection->ldapGroupMemberAssocAttr,
$this->access->connection->ldapGroupFilter);
if (is_array($members)) {
- foreach ($members as $memberDN) {
- $allMembers[$memberDN] = 1;
+ foreach ($members as $member) {
+ $allMembers[$member] = 1;
$nestedGroups = $this->access->connection->ldapNestedGroups;
if (!empty($nestedGroups)) {
- $subMembers = $this->_groupMembers($memberDN, $seen);
+ $subMembers = $this->_groupMembers($member, $seen);
if ($subMembers) {
- $allMembers = array_merge($allMembers, $subMembers);
+ $allMembers += $subMembers;
}
}
}
}
- $allMembers = array_merge($allMembers, $this->getDynamicGroupMembers($dnGroup));
+ $allMembers += $this->getDynamicGroupMembers($dnGroup);
$this->access->connection->writeToCache($cacheKey, $allMembers);
return $allMembers;
diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php
index 03fd73f261f..ec8d888e2a0 100644
--- a/apps/user_ldap/tests/Group_LDAPTest.php
+++ b/apps/user_ldap/tests/Group_LDAPTest.php
@@ -39,6 +39,7 @@ use OCA\User_LDAP\Connection;
use OCA\User_LDAP\Group_LDAP as GroupLDAP;
use OCA\User_LDAP\ILDAPWrapper;
use OCA\User_LDAP\User\Manager;
+use Test\TestCase;
/**
* Class GroupLDAPTest
@@ -47,7 +48,7 @@ use OCA\User_LDAP\User\Manager;
*
* @package OCA\User_LDAP\Tests
*/
-class Group_LDAPTest extends \Test\TestCase {
+class Group_LDAPTest extends TestCase {
/**
* @return \PHPUnit_Framework_MockObject_MockObject|Access
*/
@@ -965,6 +966,88 @@ class Group_LDAPTest extends \Test\TestCase {
$ldap = new GroupLDAP($access, $pluginManager);
$ldap->getGroupDetails('gid');
- }
+ }
+
+ public function groupMemberProvider() {
+ $base = 'dc=species,dc=earth';
+
+ $groups0 = [
+ 'uid=3723,' . $base,
+ 'uid=8372,' . $base,
+ 'uid=8427,' . $base,
+ 'uid=2333,' . $base,
+ 'uid=4754,' . $base,
+ ];
+ $groups1 = [
+ '3723',
+ '8372',
+ '8427',
+ '2333',
+ '4754',
+ ];
+ $groups2Nested = ['6642', '1424'];
+ $expGroups2 = array_merge($groups1, $groups2Nested);
+
+ return [
+ [ #0 – test DNs
+ 'cn=Birds,' . $base,
+ $groups0,
+ ['cn=Birds,' . $base => $groups0]
+ ],
+ [ #1 – test uids
+ 'cn=Birds,' . $base,
+ $groups1,
+ ['cn=Birds,' . $base => $groups1]
+ ],
+ [ #2 – test uids with nested groups
+ 'cn=Birds,' . $base,
+ $expGroups2,
+ [
+ 'cn=Birds,' . $base => $groups1,
+ '8427' => $groups2Nested, // simplified - nested groups would work with DNs
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * @param string $groupDN
+ * @param string[] $expectedMembers
+ * @param array $groupsInfo
+ * @dataProvider groupMemberProvider
+ */
+ public function testGroupMembers($groupDN, $expectedMembers, $groupsInfo = null) {
+ $access = $this->getAccessMock();
+ $access->expects($this->any())
+ ->method('readAttribute')
+ ->willReturnCallback(function($group) use ($groupDN, $expectedMembers, $groupsInfo) {
+ if(isset($groupsInfo[$group])) {
+ return $groupsInfo[$group];
+ }
+ return [];
+ });
+
+ $access->connection = $this->createMock(Connection::class);
+ if(count($groupsInfo) > 1) {
+ $access->connection->expects($this->any())
+ ->method('__get')
+ ->willReturnCallback(function($name) {
+ if($name === 'ldapNestedGroups') {
+ return 1;
+ }
+ return null;
+ });
+ }
+
+ /** @var GroupPluginManager $pluginManager */
+ $pluginManager = $this->createMock(GroupPluginManager::class);
+
+ $ldap = new GroupLDAP($access, $pluginManager);
+ $resultingMembers = $this->invokePrivate($ldap, '_groupMembers', [$groupDN]);
+
+ $expected = array_keys(array_flip($expectedMembers));
+
+ $this->assertEquals($expected, array_keys($resultingMembers), '', 0.0, 10, true);
+ }
}
diff --git a/build/integration/features/comments.feature b/build/integration/features/comments.feature
index 135bb016527..0ee11bc9873 100644
--- a/build/integration/features/comments.feature
+++ b/build/integration/features/comments.feature
@@ -16,21 +16,21 @@ Feature: comments
Scenario: Creating a comment on a shared file belonging to another user
Given user "user0" exists
- Given user "user1" exists
+ Given user "12345" exists
Given User "user0" uploads file "data/textfile.txt" to "/myFileToComment.txt"
Given As "user0" sending "POST" to "/apps/files_sharing/api/v1/shares" with
| path | myFileToComment.txt |
- | shareWith | user1 |
+ | shareWith | 12345 |
| shareType | 0 |
- When "user1" posts a comment with content "A comment from another user" on the file named "/myFileToComment.txt" it should return "201"
- Then As "user1" load all the comments of the file named "/myFileToComment.txt" it should return "207"
+ When "12345" posts a comment with content "A comment from another user" on the file named "/myFileToComment.txt" it should return "201"
+ Then As "12345" load all the comments of the file named "/myFileToComment.txt" it should return "207"
And the response should contain a property "oc:parentId" with value "0"
And the response should contain a property "oc:childrenCount" with value "0"
And the response should contain a property "oc:verb" with value "comment"
And the response should contain a property "oc:actorType" with value "users"
And the response should contain a property "oc:objectType" with value "files"
And the response should contain a property "oc:message" with value "A comment from another user"
- And the response should contain a property "oc:actorDisplayName" with value "user1"
+ And the response should contain a property "oc:actorDisplayName" with value "12345"
And the response should contain only "1" comments
Scenario: Creating a comment on a non-shared file belonging to another user
@@ -206,4 +206,4 @@ Feature: comments
And the response should contain a property "oc:message" with value "My first comment"
And the response should contain a property "oc:actorDisplayName" with value "user1"
And the response should contain only "1" comments
- Then As "user0" edit the last created comment and set text to "My edited comment" it should return "403" \ No newline at end of file
+ Then As "user0" edit the last created comment and set text to "My edited comment" it should return "403"
diff --git a/build/integration/features/tags.feature b/build/integration/features/tags.feature
index 0c6cd06f9f9..3ef7ccb38b0 100644
--- a/build/integration/features/tags.feature
+++ b/build/integration/features/tags.feature
@@ -114,14 +114,14 @@ Feature: tags
Scenario: Assigning a normal tag to a file shared by someone else as regular user should work
Given user "user0" exists
- Given user "user1" exists
+ Given user "12345" exists
Given "admin" creates a "normal" tag with name "MySuperAwesomeTagName"
Given user "user0" uploads file "data/textfile.txt" to "/myFileToTag.txt"
Given As "user0" sending "POST" to "/apps/files_sharing/api/v1/shares" with
| path | myFileToTag.txt |
- | shareWith | user1 |
+ | shareWith | 12345 |
| shareType | 0 |
- When "user1" adds the tag "MySuperAwesomeTagName" to "/myFileToTag.txt" shared by "user0"
+ When "12345" adds the tag "MySuperAwesomeTagName" to "/myFileToTag.txt" shared by "user0"
Then The response should have a status code "201"
And "/myFileToTag.txt" shared by "user0" has the following tags
|MySuperAwesomeTagName|
diff --git a/core/Command/App/Install.php b/core/Command/App/Install.php
index 8f530975be9..4432a1f40ac 100644
--- a/core/Command/App/Install.php
+++ b/core/Command/App/Install.php
@@ -25,6 +25,7 @@ namespace OC\Core\Command\App;
use OC\Installer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -39,6 +40,12 @@ class Install extends Command {
InputArgument::REQUIRED,
'install the specified app'
)
+ ->addOption(
+ 'keep-disabled',
+ null,
+ InputOption::VALUE_NONE,
+ 'don\'t enable the app afterwards'
+ )
;
}
@@ -66,6 +73,12 @@ class Install extends Command {
$output->writeln($appId . ' installed');
+ if (!$input->getOption('keep-disabled')) {
+ $appClass = new \OC_App();
+ $appClass->enable($appId);
+ $output->writeln($appId . ' enabled');
+ }
+
return 0;
}
}
diff --git a/core/Command/Db/ConvertFilecacheBigInt.php b/core/Command/Db/ConvertFilecacheBigInt.php
index 75d3a48a5c8..5960b7aa9dd 100644
--- a/core/Command/Db/ConvertFilecacheBigInt.php
+++ b/core/Command/Db/ConvertFilecacheBigInt.php
@@ -54,7 +54,7 @@ class ConvertFilecacheBigInt extends Command {
return [
'activity' => ['activity_id', 'object_id'],
'activity_mq' => ['mail_id'],
- 'filecache' => ['fileid', 'storage', 'parent', 'mimetype', 'mimepart'],
+ 'filecache' => ['fileid', 'storage', 'parent', 'mimetype', 'mimepart', 'mtime', 'storage_mtime'],
'mimetypes' => ['id'],
'storages' => ['numeric_id'],
];
diff --git a/core/Controller/LostController.php b/core/Controller/LostController.php
index e7462180388..90a1176ae83 100644
--- a/core/Controller/LostController.php
+++ b/core/Controller/LostController.php
@@ -321,12 +321,12 @@ class LostController extends Controller {
$emailTemplate->addHeading($this->l10n->t('Password reset'));
$emailTemplate->addBodyText(
- $this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.'),
+ htmlspecialchars($this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.')),
$this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
);
$emailTemplate->addBodyButton(
- $this->l10n->t('Reset your password'),
+ htmlspecialchars($this->l10n->t('Reset your password')),
$link,
false
);
diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js
index 30cbeff3c64..e76a25bd020 100644
--- a/core/js/sharedialogshareelistview.js
+++ b/core/js/sharedialogshareelistview.js
@@ -30,7 +30,7 @@
'<span class="sharingOptionsGroup">' +
'{{#if editPermissionPossible}}' +
'<span class="shareOption">' +
- '<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" {{#if hasEditPermission}}checked="checked"{{/if}} />' +
+ '<input id="canEdit-{{cid}}-{{shareWith}}" type="checkbox" name="edit" class="permissions checkbox" />' +
'<label for="canEdit-{{cid}}-{{shareWith}}">{{canEditLabel}}</label>' +
'</span>' +
'{{/if}}' +
@@ -232,7 +232,7 @@
return _.extend(hasPermissionOverride, {
cid: this.cid,
hasSharePermission: this.model.hasSharePermission(shareIndex),
- hasEditPermission: this.model.hasEditPermission(shareIndex),
+ editPermissionState: this.model.editPermissionState(shareIndex),
hasCreatePermission: this.model.hasCreatePermission(shareIndex),
hasUpdatePermission: this.model.hasUpdatePermission(shareIndex),
hasDeletePermission: this.model.hasDeletePermission(shareIndex),
@@ -379,16 +379,18 @@
$.extend(sharee, this.getShareProperties());
var $li = this.$('li[data-share-id=' + permissionChangeShareId + ']');
$li.find('.sharingOptionsGroup .popovermenu').replaceWith(this.popoverMenuTemplate(sharee));
-
- var checkBoxId = 'canEdit-' + this.cid + '-' + sharee.shareWith;
- checkBoxId = '#' + checkBoxId.replace( /(:|\.|\[|\]|,|=|@)/g, "\\$1");
- var $edit = $li.parent().find(checkBoxId);
- if($edit.length === 1) {
- $edit.prop('checked', sharee.hasEditPermission);
- }
}
var _this = this;
+ this.getShareeList().forEach(function(sharee) {
+ var checkBoxId = 'canEdit-' + _this.cid + '-' + sharee.shareWith;
+ checkBoxId = '#' + checkBoxId.replace( /(:|\.|\[|\]|,|=|@|\/)/g, "\\$1");
+ var $edit = _this.$(checkBoxId);
+ if($edit.length === 1) {
+ $edit.prop('checked', sharee.editPermissionState === 'checked');
+ $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate');
+ }
+ });
this.$('.popovermenu').on('afterHide', function() {
_this._menuOpen = false;
});
@@ -627,8 +629,10 @@
}
} else {
var numberChecked = $checkboxes.filter(':checked').length;
- checked = numberChecked > 0;
- $('input[name="edit"]', $li).prop('checked', checked);
+ checked = numberChecked === $checkboxes.length;
+ var $editCb = $('input[name="edit"]', $li);
+ $editCb.prop('checked', checked);
+ $editCb.prop('indeterminate', !checked && numberChecked > 0);
}
} else {
if ($element.attr('name') === 'edit' && $element.is(':checked')) {
diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js
index afe86fa464b..b699513c734 100644
--- a/core/js/shareitemmodel.js
+++ b/core/js/shareitemmodel.js
@@ -567,12 +567,26 @@
},
/**
- * @returns {boolean}
- */
- hasEditPermission: function(shareIndex) {
- return this.hasCreatePermission(shareIndex)
- || this.hasUpdatePermission(shareIndex)
- || this.hasDeletePermission(shareIndex);
+ * @returns {string}
+ * The state that the 'can edit' permission checkbox should have.
+ * Possible values:
+ * - empty string: no permission
+ * - 'checked': all applicable permissions
+ * - 'indeterminate': some but not all permissions
+ */
+ editPermissionState: function(shareIndex) {
+ var hcp = this.hasCreatePermission(shareIndex);
+ var hup = this.hasUpdatePermission(shareIndex);
+ var hdp = this.hasDeletePermission(shareIndex);
+ if (!hcp && !hup && !hdp) {
+ return '';
+ }
+ if ( (this.createPermissionPossible() && !hcp)
+ || (this.updatePermissionPossible() && !hup)
+ || (this.deletePermissionPossible() && !hdp) ) {
+ return 'indeterminate';
+ }
+ return 'checked';
},
/**
diff --git a/core/js/tests/specs/sharedialogshareelistview.js b/core/js/tests/specs/sharedialogshareelistview.js
index 8ee2c48fe39..cc0268ba580 100644
--- a/core/js/tests/specs/sharedialogshareelistview.js
+++ b/core/js/tests/specs/sharedialogshareelistview.js
@@ -89,6 +89,37 @@ describe('OC.Share.ShareDialogShareeListView', function () {
updateShareStub.restore();
});
+ describe('Sets correct initial checkbox state', function () {
+ it('marks edit box as indeterminate when only some permissions are given', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1 | OC.PERMISSION_UPDATE,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ itemType: 'folder'
+ }]);
+ shareModel.set('itemType', 'folder');
+ listView.render();
+ expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true);
+ });
+
+ it('Checks edit box when all permissions are given', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ itemType: 'folder'
+ }]);
+ shareModel.set('itemType', 'folder');
+ listView.render();
+ expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
+ });
+ });
describe('Manages checkbox events correctly', function () {
it('Checks cruds boxes when edit box checked', function () {
shareModel.set('shares', [{
@@ -106,7 +137,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
expect(updateShareStub.calledOnce).toEqual(true);
});
- it('Checks edit box when create/update/delete are checked', function () {
+ it('marks edit box as indeterminate when some of create/update/delete are checked', function () {
shareModel.set('shares', [{
id: 100,
item_source: 123,
@@ -119,6 +150,23 @@ describe('OC.Share.ShareDialogShareeListView', function () {
shareModel.set('itemType', 'folder');
listView.render();
listView.$el.find("input[name='update']").click();
+ expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true);
+ expect(updateShareStub.calledOnce).toEqual(true);
+ });
+
+ it('Checks edit box when all of create/update/delete are checked', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_DELETE,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ itemType: 'folder'
+ }]);
+ shareModel.set('itemType', 'folder');
+ listView.render();
+ listView.$el.find("input[name='update']").click();
expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
expect(updateShareStub.calledOnce).toEqual(true);
});
diff --git a/core/templates/exception.php b/core/templates/exception.php
index 0ae82b9308d..fcfa8687710 100644
--- a/core/templates/exception.php
+++ b/core/templates/exception.php
@@ -12,14 +12,14 @@ style('core', ['styles', 'header']);
<h3><?php p($l->t('Technical details')) ?></h3>
<ul>
- <li><?php p($l->t('Remote Address: %s', $_['remoteAddr'])) ?></li>
- <li><?php p($l->t('Request ID: %s', $_['requestID'])) ?></li>
+ <li><?php p($l->t('Remote Address: %s', [$_['remoteAddr']])) ?></li>
+ <li><?php p($l->t('Request ID: %s', [$_['requestID']])) ?></li>
<?php if($_['debugMode']): ?>
- <li><?php p($l->t('Type: %s', $_['errorClass'])) ?></li>
- <li><?php p($l->t('Code: %s', $_['errorCode'])) ?></li>
- <li><?php p($l->t('Message: %s', $_['errorMsg'])) ?></li>
- <li><?php p($l->t('File: %s', $_['file'])) ?></li>
- <li><?php p($l->t('Line: %s', $_['line'])) ?></li>
+ <li><?php p($l->t('Type: %s', [$_['errorClass']])) ?></li>
+ <li><?php p($l->t('Code: %s', [$_['errorCode']])) ?></li>
+ <li><?php p($l->t('Message: %s', [$_['errorMsg']])) ?></li>
+ <li><?php p($l->t('File: %s', [$_['file']])) ?></li>
+ <li><?php p($l->t('Line: %s', [$_['line']])) ?></li>
<?php endif; ?>
</ul>
diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php
index 975c4255d5a..86ba884141f 100644
--- a/lib/private/AppFramework/Http/Request.php
+++ b/lib/private/AppFramework/Http/Request.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -87,8 +88,8 @@ class Request implements \ArrayAccess, \Countable, IRequest {
protected $inputStream;
protected $content;
- protected $items = array();
- protected $allowedKeys = array(
+ protected $items = [];
+ protected $allowedKeys = [
'get',
'post',
'files',
@@ -99,7 +100,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
'parameters',
'method',
'requesttoken',
- );
+ ];
/** @var ISecureRandom */
protected $secureRandom;
/** @var IConfig */
@@ -131,13 +132,13 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $stream
* @see http://www.php.net/manual/en/reserved.variables.php
*/
- public function __construct(array $vars=array(),
+ public function __construct(array $vars= [],
ISecureRandom $secureRandom = null,
IConfig $config,
CsrfTokenManager $csrfTokenManager = null,
- $stream = 'php://input') {
+ string $stream = 'php://input') {
$this->inputStream = $stream;
- $this->items['params'] = array();
+ $this->items['params'] = [];
$this->secureRandom = $secureRandom;
$this->config = $config;
$this->csrfTokenManager = $csrfTokenManager;
@@ -149,7 +150,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
foreach($this->allowedKeys as $name) {
$this->items[$name] = isset($vars[$name])
? $vars[$name]
- : array();
+ : [];
}
$this->items['parameters'] = array_merge(
@@ -175,8 +176,8 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* Countable method
* @return int
*/
- public function count() {
- return count(array_keys($this->items['parameters']));
+ public function count(): int {
+ return \count($this->items['parameters']);
}
/**
@@ -199,13 +200,15 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $offset The key to lookup
* @return boolean
*/
- public function offsetExists($offset) {
+ public function offsetExists($offset): bool {
return isset($this->items['parameters'][$offset]);
}
/**
- * @see offsetExists
- */
+ * @see offsetExists
+ * @param string $offset
+ * @return mixed
+ */
public function offsetGet($offset) {
return isset($this->items['parameters'][$offset])
? $this->items['parameters'][$offset]
@@ -213,15 +216,18 @@ class Request implements \ArrayAccess, \Countable, IRequest {
}
/**
- * @see offsetExists
- */
+ * @see offsetExists
+ * @param string $offset
+ * @param mixed $value
+ */
public function offsetSet($offset, $value) {
throw new \RuntimeException('You cannot change the contents of the request object');
}
/**
- * @see offsetExists
- */
+ * @see offsetExists
+ * @param string $offset
+ */
public function offsetUnset($offset) {
throw new \RuntimeException('You cannot change the contents of the request object');
}
@@ -284,7 +290,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return bool
*/
public function __isset($name) {
- if (in_array($name, $this->allowedKeys, true)) {
+ if (\in_array($name, $this->allowedKeys, true)) {
return true;
}
return isset($this->items['parameters'][$name]);
@@ -305,9 +311,9 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $name
* @return string
*/
- public function getHeader($name) {
+ public function getHeader(string $name): string {
- $name = strtoupper(str_replace(array('-'),array('_'),$name));
+ $name = strtoupper(str_replace('-', '_',$name));
if (isset($this->server['HTTP_' . $name])) {
return $this->server['HTTP_' . $name];
}
@@ -340,7 +346,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param mixed $default If the key is not found, this value will be returned
* @return mixed the content of the array
*/
- public function getParam($key, $default = null) {
+ public function getParam(string $key, $default = null) {
return isset($this->parameters[$key])
? $this->parameters[$key]
: $default;
@@ -351,7 +357,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* (as GET or POST) or throuh the URL by the route
* @return array the array with all parameters
*/
- public function getParams() {
+ public function getParams(): array {
return $this->parameters;
}
@@ -359,7 +365,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* Returns the method of the request
* @return string the method of the request (POST, GET, etc)
*/
- public function getMethod() {
+ public function getMethod(): string {
return $this->method;
}
@@ -368,7 +374,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $key the key that will be taken from the $_FILES array
* @return array the file in the $_FILES element
*/
- public function getUploadedFile($key) {
+ public function getUploadedFile(string $key) {
return isset($this->files[$key]) ? $this->files[$key] : null;
}
@@ -377,7 +383,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $key the key that will be taken from the $_ENV array
* @return array the value in the $_ENV element
*/
- public function getEnv($key) {
+ public function getEnv(string $key) {
return isset($this->env[$key]) ? $this->env[$key] : null;
}
@@ -386,7 +392,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $key the key that will be taken from the $_COOKIE array
* @return string the value in the $_COOKIE element
*/
- public function getCookie($key) {
+ public function getCookie(string $key) {
return isset($this->cookies[$key]) ? $this->cookies[$key] : null;
}
@@ -435,7 +441,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
// 'application/json' must be decoded manually.
if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) {
$params = json_decode(file_get_contents($this->inputStream), true);
- if($params !== null && count($params) > 0) {
+ if($params !== null && \count($params) > 0) {
$this->items['params'] = $params;
if($this->method === 'POST') {
$this->items['post'] = $params;
@@ -449,12 +455,12 @@ class Request implements \ArrayAccess, \Countable, IRequest {
&& strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) {
parse_str(file_get_contents($this->inputStream), $params);
- if(is_array($params)) {
+ if(\is_array($params)) {
$this->items['params'] = $params;
}
}
- if (is_array($params)) {
+ if (\is_array($params)) {
$this->items['parameters'] = array_merge($this->items['parameters'], $params);
}
$this->contentDecoded = true;
@@ -465,7 +471,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* Checks if the CSRF check was correct
* @return bool true if CSRF check passed
*/
- public function passesCSRFCheck() {
+ public function passesCSRFCheck(): bool {
if($this->csrfTokenManager === null) {
return false;
}
@@ -494,7 +500,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
*
* @return bool
*/
- private function cookieCheckRequired() {
+ private function cookieCheckRequired(): bool {
if ($this->getHeader('OCS-APIREQUEST')) {
return false;
}
@@ -510,7 +516,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
*
* @return array
*/
- public function getCookieParams() {
+ public function getCookieParams(): array {
return session_get_cookie_params();
}
@@ -520,7 +526,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $name
* @return string
*/
- protected function getProtectedCookieName($name) {
+ protected function getProtectedCookieName(string $name): string {
$cookieParams = $this->getCookieParams();
$prefix = '';
if($cookieParams['secure'] === true && $cookieParams['path'] === '/') {
@@ -537,7 +543,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return bool
* @since 9.1.0
*/
- public function passesStrictCookieCheck() {
+ public function passesStrictCookieCheck(): bool {
if(!$this->cookieCheckRequired()) {
return true;
}
@@ -557,7 +563,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @return bool
* @since 9.1.0
*/
- public function passesLaxCookieCheck() {
+ public function passesLaxCookieCheck(): bool {
if(!$this->cookieCheckRequired()) {
return true;
}
@@ -575,7 +581,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* If `mod_unique_id` is installed this value will be taken.
* @return string
*/
- public function getId() {
+ public function getId(): string {
if(isset($this->server['UNIQUE_ID'])) {
return $this->server['UNIQUE_ID'];
}
@@ -595,11 +601,11 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* Do always use this instead of $_SERVER['REMOTE_ADDR']
* @return string IP address
*/
- public function getRemoteAddress() {
+ public function getRemoteAddress(): string {
$remoteAddress = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : '';
$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
- if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
+ if(\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies)) {
$forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', [
'HTTP_X_FORWARDED_FOR'
// only have one default, so we cannot ship an insecure product out of the box
@@ -625,7 +631,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param string $type
* @return bool
*/
- private function isOverwriteCondition($type = '') {
+ private function isOverwriteCondition(string $type = ''): bool {
$regex = '/' . $this->config->getSystemValue('overwritecondaddr', '') . '/';
$remoteAddr = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : '';
return $regex === '//' || preg_match($regex, $remoteAddr) === 1
@@ -637,7 +643,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* and load balancers
* @return string Server protocol (http or https)
*/
- public function getServerProtocol() {
+ public function getServerProtocol(): string {
if($this->config->getSystemValue('overwriteprotocol') !== ''
&& $this->isOverwriteCondition('protocol')) {
return $this->config->getSystemValue('overwriteprotocol');
@@ -671,8 +677,12 @@ class Request implements \ArrayAccess, \Countable, IRequest {
*
* @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
*/
- public function getHttpProtocol() {
- $claimedProtocol = strtoupper($this->server['SERVER_PROTOCOL']);
+ public function getHttpProtocol(): string {
+ $claimedProtocol = $this->server['SERVER_PROTOCOL'];
+
+ if (\is_string($claimedProtocol)) {
+ $claimedProtocol = strtoupper($claimedProtocol);
+ }
$validProtocols = [
'HTTP/1.0',
@@ -680,7 +690,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
'HTTP/2',
];
- if(in_array($claimedProtocol, $validProtocols, true)) {
+ if(\in_array($claimedProtocol, $validProtocols, true)) {
return $claimedProtocol;
}
@@ -692,10 +702,10 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* reverse proxies
* @return string
*/
- public function getRequestUri() {
+ public function getRequestUri(): string {
$uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '';
if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) {
- $uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME']));
+ $uri = $this->getScriptName() . substr($uri, \strlen($this->server['SCRIPT_NAME']));
}
return $uri;
}
@@ -705,7 +715,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @throws \Exception
* @return string Path info
*/
- public function getRawPathInfo() {
+ public function getRawPathInfo(): string {
$requestUri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '';
// remove too many leading slashes - can be caused by reverse proxy configuration
if (strpos($requestUri, '/') === 0) {
@@ -727,16 +737,20 @@ class Request implements \ArrayAccess, \Countable, IRequest {
list($path, $name) = \Sabre\Uri\split($scriptName);
if (!empty($path)) {
if($path === $pathInfo || strpos($pathInfo, $path.'/') === 0) {
- $pathInfo = substr($pathInfo, strlen($path));
+ $pathInfo = substr($pathInfo, \strlen($path));
} else {
throw new \Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')");
}
}
+ if ($name === null) {
+ $name = '';
+ }
+
if (strpos($pathInfo, '/'.$name) === 0) {
- $pathInfo = substr($pathInfo, strlen($name) + 1);
+ $pathInfo = substr($pathInfo, \strlen($name) + 1);
}
- if (strpos($pathInfo, $name) === 0) {
- $pathInfo = substr($pathInfo, strlen($name));
+ if ($name !== '' && strpos($pathInfo, $name) === 0) {
+ $pathInfo = substr($pathInfo, \strlen($name));
}
if($pathInfo === false || $pathInfo === '/'){
return '';
@@ -770,13 +784,13 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* reverse proxies
* @return string the script name
*/
- public function getScriptName() {
+ public function getScriptName(): string {
$name = $this->server['SCRIPT_NAME'];
$overwriteWebRoot = $this->config->getSystemValue('overwritewebroot');
if ($overwriteWebRoot !== '' && $this->isOverwriteCondition()) {
// FIXME: This code is untestable due to __DIR__, also that hardcoded path is really dangerous
- $serverRoot = str_replace('\\', '/', substr(__DIR__, 0, -strlen('lib/private/appframework/http/')));
- $suburi = str_replace('\\', '/', substr(realpath($this->server['SCRIPT_FILENAME']), strlen($serverRoot)));
+ $serverRoot = str_replace('\\', '/', substr(__DIR__, 0, -\strlen('lib/private/appframework/http/')));
+ $suburi = str_replace('\\', '/', substr(realpath($this->server['SCRIPT_FILENAME']), \strlen($serverRoot)));
$name = '/' . ltrim($overwriteWebRoot . $suburi, '/');
}
return $name;
@@ -787,7 +801,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* @param array $agent array of agent names
* @return bool true if at least one of the given agent matches, false otherwise
*/
- public function isUserAgent(array $agent) {
+ public function isUserAgent(array $agent): bool {
if (!isset($this->server['HTTP_USER_AGENT'])) {
return false;
}
@@ -804,7 +818,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* whether it is a trusted domain
* @return string Server host
*/
- public function getInsecureServerHost() {
+ public function getInsecureServerHost(): string {
$host = 'localhost';
if (isset($this->server['HTTP_X_FORWARDED_HOST'])) {
if (strpos($this->server['HTTP_X_FORWARDED_HOST'], ',') !== false) {
@@ -829,7 +843,7 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* trusted domain if the host isn't in the trusted list
* @return string Server host
*/
- public function getServerHost() {
+ public function getServerHost(): string {
// overwritehost is always trusted
$host = $this->getOverwriteHost();
if ($host !== null) {
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 8a8ece82077..ab0ef836fbb 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -107,7 +107,7 @@ class Installer {
if(!is_array($info)) {
throw new \Exception(
$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
- [$info['name']]
+ [$appId]
)
);
}
diff --git a/lib/private/L10N/L10N.php b/lib/private/L10N/L10N.php
index f0e37ca1a5d..a9b1b7377aa 100644
--- a/lib/private/L10N/L10N.php
+++ b/lib/private/L10N/L10N.php
@@ -78,13 +78,17 @@ class L10N implements IL10N {
/**
* Translating
* @param string $text The text we need a translation for
- * @param array $parameters default:array() Parameters for sprintf
+ * @param array|string $parameters default:array() Parameters for sprintf
* @return string Translation or the same text
*
* Returns the translation. If no translation is found, $text will be
* returned.
*/
- public function t(string $text, array $parameters = []): string {
+ public function t(string $text, $parameters = []): string {
+ if (!\is_array($parameters)) {
+ $parameters = [$parameters];
+ }
+
return (string) new L10NString($this, $text, $parameters);
}
diff --git a/lib/private/Mail/EMailTemplate.php b/lib/private/Mail/EMailTemplate.php
index 0535dabc13e..38205af366e 100644
--- a/lib/private/Mail/EMailTemplate.php
+++ b/lib/private/Mail/EMailTemplate.php
@@ -420,7 +420,7 @@ EOF;
/**
* Adds a paragraph to the body of the email
*
- * @param string $text
+ * @param string $text Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
* @param string|bool $plainText Text that is used in the plain text email
* if empty the $text is used, if false none will be used
*/
@@ -430,11 +430,12 @@ EOF;
}
if ($plainText === '') {
$plainText = $text;
+ $text = htmlspecialchars($text);
}
$this->ensureBodyIsOpened();
- $this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
+ $this->htmlBody .= vsprintf($this->bodyText, [$text]);
if ($plainText !== false) {
$this->plainBody .= $plainText . PHP_EOL . PHP_EOL;
}
@@ -443,8 +444,8 @@ EOF;
/**
* Adds a list item to the body of the email
*
- * @param string $text
- * @param string $metaInfo
+ * @param string $text Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $metaInfo Note: When $plainMetaInfo falls back to this, HTML is automatically escaped in the HTML email
* @param string $icon Absolute path, must be 16*16 pixels
* @param string $plainText Text that is used in the plain text email
* if empty the $text is used, if false none will be used
@@ -457,14 +458,16 @@ EOF;
if ($plainText === '') {
$plainText = $text;
+ $text = htmlspecialchars($text);
}
if ($plainMetaInfo === '') {
$plainMetaInfo = $metaInfo;
+ $metaInfo = htmlspecialchars($metaInfo);
}
- $htmlText = htmlspecialchars($text);
+ $htmlText = $text;
if ($metaInfo) {
- $htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
+ $htmlText = '<em style="color:#777;">' . $metaInfo . '</em><br>' . $htmlText;
}
if ($icon !== '') {
$icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
@@ -503,9 +506,9 @@ EOF;
/**
* Adds a button group of two buttons to the body of the email
*
- * @param string $textLeft Text of left button
+ * @param string $textLeft Text of left button; Note: When $plainTextLeft falls back to this, HTML is automatically escaped in the HTML email
* @param string $urlLeft URL of left button
- * @param string $textRight Text of right button
+ * @param string $textRight Text of right button; Note: When $plainTextRight falls back to this, HTML is automatically escaped in the HTML email
* @param string $urlRight URL of right button
* @param string $plainTextLeft Text of left button that is used in the plain text version - if unset the $textLeft is used
* @param string $plainTextRight Text of right button that is used in the plain text version - if unset the $textRight is used
@@ -521,10 +524,12 @@ EOF;
}
if ($plainTextLeft === '') {
$plainTextLeft = $textLeft;
+ $textLeft = htmlspecialchars($textLeft);
}
if ($plainTextRight === '') {
$plainTextRight = $textRight;
+ $textRight = htmlspecialchars($textRight);
}
$this->ensureBodyIsOpened();
@@ -533,7 +538,7 @@ EOF;
$color = $this->themingDefaults->getColorPrimary();
$textColor = $this->themingDefaults->getTextColorPrimary();
- $this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, $textColor, $textColor, htmlspecialchars($textLeft), $urlRight, htmlspecialchars($textRight)]);
+ $this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, $textColor, $textColor, $textLeft, $urlRight, $textRight]);
$this->plainBody .= $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
$this->plainBody .= $plainTextRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
@@ -542,7 +547,7 @@ EOF;
/**
* Adds a button to the body of the email
*
- * @param string $text Text of button
+ * @param string $text Text of button; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
* @param string $url URL of button
* @param string $plainText Text of button in plain text version
* if empty the $text is used, if false none will be used
@@ -559,11 +564,12 @@ EOF;
if ($plainText === '') {
$plainText = $text;
+ $text = htmlspecialchars($text);
}
$color = $this->themingDefaults->getColorPrimary();
$textColor = $this->themingDefaults->getTextColorPrimary();
- $this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, $textColor, $textColor, htmlspecialchars($text)]);
+ $this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, $textColor, $textColor, $text]);
if ($plainText !== false) {
$this->plainBody .= $plainText . ': ';
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 228f0ab5f97..d586bab15b9 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -814,7 +814,7 @@ class Server extends ServerContainer implements IServerContainer {
'cookies' => $_COOKIE,
'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
? $_SERVER['REQUEST_METHOD']
- : null,
+ : '',
'urlParams' => $urlParams,
],
$this->getSecureRandom(),
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 0ae96f29ded..cddd8c8d92b 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -735,7 +735,7 @@ class Manager implements IManager {
$text = $l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
$emailTemplate->addBodyText(
- $text . ' ' . $l->t('Click the button below to open it.'),
+ htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
$text
);
$emailTemplate->addBodyButton(
diff --git a/lib/public/IL10N.php b/lib/public/IL10N.php
index 158e0cb156c..2e55c151f62 100644
--- a/lib/public/IL10N.php
+++ b/lib/public/IL10N.php
@@ -45,14 +45,14 @@ interface IL10N {
/**
* Translating
* @param string $text The text we need a translation for
- * @param array $parameters default:array() Parameters for sprintf
+ * @param array|string $parameters default:array() Parameters for sprintf
* @return string Translation or the same text
*
* Returns the translation. If no translation is found, $text will be
* returned.
* @since 6.0.0
*/
- public function t(string $text, array $parameters = []): string;
+ public function t(string $text, $parameters = []): string;
/**
* Translating
diff --git a/lib/public/IRequest.php b/lib/public/IRequest.php
index a14b6b5f459..b3130207111 100644
--- a/lib/public/IRequest.php
+++ b/lib/public/IRequest.php
@@ -1,4 +1,5 @@
<?php
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
@@ -95,7 +96,7 @@ interface IRequest {
* @return string
* @since 6.0.0
*/
- public function getHeader($name);
+ public function getHeader(string $name): string;
/**
* Lets you access post and get parameters by the index
@@ -111,7 +112,7 @@ interface IRequest {
* @return mixed the content of the array
* @since 6.0.0
*/
- public function getParam($key, $default = null);
+ public function getParam(string $key, $default = null);
/**
@@ -122,7 +123,7 @@ interface IRequest {
* @return array the array with all parameters
* @since 6.0.0
*/
- public function getParams();
+ public function getParams(): array;
/**
* Returns the method of the request
@@ -130,7 +131,7 @@ interface IRequest {
* @return string the method of the request (POST, GET, etc)
* @since 6.0.0
*/
- public function getMethod();
+ public function getMethod(): string;
/**
* Shortcut for accessing an uploaded file through the $_FILES array
@@ -139,7 +140,7 @@ interface IRequest {
* @return array the file in the $_FILES element
* @since 6.0.0
*/
- public function getUploadedFile($key);
+ public function getUploadedFile(string $key);
/**
@@ -149,7 +150,7 @@ interface IRequest {
* @return array the value in the $_ENV element
* @since 6.0.0
*/
- public function getEnv($key);
+ public function getEnv(string $key);
/**
@@ -159,7 +160,7 @@ interface IRequest {
* @return string|null the value in the $_COOKIE element
* @since 6.0.0
*/
- public function getCookie($key);
+ public function getCookie(string $key);
/**
@@ -168,7 +169,7 @@ interface IRequest {
* @return bool true if CSRF check passed
* @since 6.0.0
*/
- public function passesCSRFCheck();
+ public function passesCSRFCheck(): bool;
/**
* Checks if the strict cookie has been sent with the request if the request
@@ -177,7 +178,7 @@ interface IRequest {
* @return bool
* @since 9.0.0
*/
- public function passesStrictCookieCheck();
+ public function passesStrictCookieCheck(): bool;
/**
* Checks if the lax cookie has been sent with the request if the request
@@ -186,7 +187,7 @@ interface IRequest {
* @return bool
* @since 9.0.0
*/
- public function passesLaxCookieCheck();
+ public function passesLaxCookieCheck(): bool;
/**
* Returns an ID for the request, value is not guaranteed to be unique and is mostly meant for logging
@@ -195,7 +196,7 @@ interface IRequest {
* @return string
* @since 8.1.0
*/
- public function getId();
+ public function getId(): string;
/**
* Returns the remote address, if the connection came from a trusted proxy
@@ -206,7 +207,7 @@ interface IRequest {
* @return string IP address
* @since 8.1.0
*/
- public function getRemoteAddress();
+ public function getRemoteAddress(): string;
/**
* Returns the server protocol. It respects reverse proxy servers and load
@@ -215,7 +216,7 @@ interface IRequest {
* @return string Server protocol (http or https)
* @since 8.1.0
*/
- public function getServerProtocol();
+ public function getServerProtocol(): string;
/**
* Returns the used HTTP protocol.
@@ -223,7 +224,7 @@ interface IRequest {
* @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
* @since 8.2.0
*/
- public function getHttpProtocol();
+ public function getHttpProtocol(): string;
/**
* Returns the request uri, even if the website uses one or more
@@ -232,7 +233,7 @@ interface IRequest {
* @return string
* @since 8.1.0
*/
- public function getRequestUri();
+ public function getRequestUri(): string;
/**
* Get raw PathInfo from request (not urldecoded)
@@ -241,7 +242,7 @@ interface IRequest {
* @return string Path info
* @since 8.1.0
*/
- public function getRawPathInfo();
+ public function getRawPathInfo(): string;
/**
* Get PathInfo from request
@@ -259,7 +260,7 @@ interface IRequest {
* @return string the script name
* @since 8.1.0
*/
- public function getScriptName();
+ public function getScriptName(): string;
/**
* Checks whether the user agent matches a given regex
@@ -268,7 +269,7 @@ interface IRequest {
* @return bool true if at least one of the given agent matches, false otherwise
* @since 8.1.0
*/
- public function isUserAgent(array $agent);
+ public function isUserAgent(array $agent): bool;
/**
* Returns the unverified server host from the headers without checking
@@ -277,7 +278,7 @@ interface IRequest {
* @return string Server host
* @since 8.1.0
*/
- public function getInsecureServerHost();
+ public function getInsecureServerHost(): string;
/**
* Returns the server host from the headers, or the first configured
@@ -286,5 +287,5 @@ interface IRequest {
* @return string Server host
* @since 8.1.0
*/
- public function getServerHost();
+ public function getServerHost(): string;
}
diff --git a/lib/public/Mail/IEMailTemplate.php b/lib/public/Mail/IEMailTemplate.php
index 3248665a7da..6d37c21ada1 100644
--- a/lib/public/Mail/IEMailTemplate.php
+++ b/lib/public/Mail/IEMailTemplate.php
@@ -85,7 +85,7 @@ interface IEMailTemplate {
/**
* Adds a paragraph to the body of the email
*
- * @param string $text
+ * @param string $text; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
* @param string|bool $plainText Text that is used in the plain text email
* if empty the $text is used, if false none will be used
*
@@ -96,8 +96,8 @@ interface IEMailTemplate {
/**
* Adds a list item to the body of the email
*
- * @param string $text
- * @param string $metaInfo
+ * @param string $text; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
+ * @param string $metaInfo; Note: When $plainMetaInfo falls back to this, HTML is automatically escaped in the HTML email
* @param string $icon Absolute path, must be 16*16 pixels
* @param string $plainText Text that is used in the plain text email
* if empty the $text is used, if false none will be used
@@ -110,9 +110,9 @@ interface IEMailTemplate {
/**
* Adds a button group of two buttons to the body of the email
*
- * @param string $textLeft Text of left button
+ * @param string $textLeft Text of left button; Note: When $plainTextLeft falls back to this, HTML is automatically escaped in the HTML email
* @param string $urlLeft URL of left button
- * @param string $textRight Text of right button
+ * @param string $textRight Text of right button; Note: When $plainTextRight falls back to this, HTML is automatically escaped in the HTML email
* @param string $urlRight URL of right button
* @param string $plainTextLeft Text of left button that is used in the plain text version - if empty the $textLeft is used
* @param string $plainTextRight Text of right button that is used in the plain text version - if empty the $textRight is used
@@ -124,7 +124,7 @@ interface IEMailTemplate {
/**
* Adds a button to the body of the email
*
- * @param string $text Text of button
+ * @param string $text Text of button; Note: When $plainText falls back to this, HTML is automatically escaped in the HTML email
* @param string $url URL of button
* @param string $plainText Text of button in plain text version
* if empty the $text is used, if false none will be used
diff --git a/settings/img/change.svg b/settings/img/change.svg
index b3404d2ef84..12071422b7f 100644
--- a/settings/img/change.svg
+++ b/settings/img/change.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1"><path d="m8 0c-2.8557-3.771e-8 -5.4999 1.5269-6.9277 4l2.5976 1.5c0.8944-1.5491 2.5413-2.5 4.3301-2.5 1.5874 0 3.0628 0.74877 4 2l-2 2h6v-6l-1.875 1.875c-1.505-1.797-3.736-2.875-6.125-2.875z"/><path d="m0 9v6l1.877-1.877c1.4882 1.778 3.7559 2.857 6.123 2.877 2.8797 0.02436 5.4878-1.506 6.9277-4l-2.598-1.5c-0.902 1.562-2.5261 2.515-4.33 2.5-1.5737-0.013-3.0729-0.762-4-2l2-2z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path d="m8 2c-2.142 0-4.125 1.145-5.196 3l1.948 1.125c0.671-1.162 1.906-1.875 3.2476-1.875 1.1906 0 2.297 0.56157 3 1.5l-1.5 1.5h4.5v-4.5l-1.406 1.406c-1.129-1.348-2.802-2.1563-4.594-2.1563z"/><path d="m2 8.75v4.5l1.408-1.41c1.116 1.334 2.817 2.145 4.592 2.16 2.16 0.01827 4.116-1.132 5.196-3.002l-1.948-1.125c-0.677 1.171-1.9005 1.886-3.248 1.875-1.18-0.01-2.3047-0.572-3-1.5l1.5-1.5z"/></svg>
diff --git a/settings/l10n/pt_PT.js b/settings/l10n/pt_PT.js
index 506408ddd33..5dc5933f566 100644
--- a/settings/l10n/pt_PT.js
+++ b/settings/l10n/pt_PT.js
@@ -120,8 +120,17 @@ OC.L10N.register(
"Allow filesystem access" : "Permitir acesso ao sistema de ficheiros",
"Disconnect" : "Desligado",
"Revoke" : "Revogar",
+ "Internet Explorer" : "Internet Explorer",
+ "Edge" : "Microsoft Edge",
+ "Firefox" : "Mozilla Firefox",
+ "Google Chrome" : "Google Chrome",
+ "Safari" : "Safari",
+ "Google Chrome for Android" : "Google Chrome para Android",
+ "iPhone iOS" : "iPhone iOS",
+ "iPad iOS" : "iPad iOS",
"iOS Client" : "Cliente iOS",
"Android Client" : "Cliente Android",
+ "Sync client - {os}" : "Sincronizar cliente - {so}",
"This session" : "Esta sessão",
"Copy" : "Copiar",
"Copied!" : "Copiado!",
@@ -244,10 +253,23 @@ OC.L10N.register(
"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." : "A configuração Só-de-Leitura foi ativada. Isto evita definir algumas configurações através da interface da Web. Além disso, o ficheiro precisa de ser definido gravável manualmente para cada atualização.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Isto é provavelmente causado por uma cache/acelerador como o Zend OPcache or eAcelerador.",
"System locale can not be set to a one which supports UTF-8." : "Não é possível definir a internacionalização do sistema para um que suporte o UTF-8.",
+ "This means that there might be problems with certain characters in filenames." : "Isto significa que podem haver problemas com alguns caracteres no nome dos ficheiros.",
+ "It is strongly proposed to install the required packages on your system to support one of the following locales: %s." : "É vivamente aconselhável que instale os pacotes necessários no seu sistema para suportar um dos nossos locais: %s.",
+ "It was not possible to execute the cron job via CLI. The following technical errors have appeared:" : "Não foi possível executar a tarefa agendada via CLI. Os seguintes erros técnicos surgiram:",
"All checks passed." : "Todas as verificações passaram.",
+ "Background jobs" : "Tarefas de segundo plano",
+ "Last job ran %s." : "Última tarefa executada: %s.",
+ "Last job execution ran %s. Something seems wrong." : "Última execução da tarefa: %s. Houve algum problema. ",
+ "Background job didn’t run yet!" : "Tarefa de segundo plano ainda não foi executada!",
+ "For optimal performance it's important to configure background jobs correctly. For bigger instances 'Cron' is the recommended setting. Please see the documentation for more information." : "Para desempenho óptimo é importante que configura as tarefas de segundo plano correctamente. Para maiores instâncias a definição recomendada é 'Cron'. Por favor veja a documentação para mais informações.",
"Execute one task with each page loaded" : "Executar uma tarefa com cada página carregada",
+ "cron.php is registered at a webcron service to call cron.php every 15 minutes over HTTP." : "cron.php está registada num serviço webcron para chamar cron.php a cada 15 minutos através de HTTP.",
+ "Use system cron service to call the cron.php file every 15 minutes." : "Use o serviço de tarefas automáticas para chamar o ficheiro cron.php a cada 15 minutos.",
+ "The cron.php needs to be executed by the system user \"%s\"." : "O cron.php precisa de ser executado pelo utilizador do sistema \"%s\".",
+ "To run this you need the PHP POSIX extension. See {linkstart}PHP documentation{linkend} for more details." : "Para esta execução precisa da extensão PHP POSIX. Veja {iniciodaligação}documentação PHP{fimdaligação} para mais mais detalhes.",
"Version" : "Versão",
"Sharing" : "Partilha",
+ "As admin you can fine-tune the sharing behavior. Please see the documentation for more information." : "Como administrador pode afinar o comportamento de partilha. Por favor veja a documentação para mais informação.",
"Allow apps to use the Share API" : "Permitir que os utilizadores usem a API de partilha",
"Allow users to share via link" : "Permitir que os utilizadores partilhem através do link",
"Allow public uploads" : "Permitir Envios Públicos",
@@ -262,15 +284,21 @@ OC.L10N.register(
"Restrict users to only share with users in their groups" : "Restringe os utilizadores só a partilhar com utilizadores do seu grupo",
"Exclude groups from sharing" : "Excluir grupos das partilhas",
"These groups will still be able to receive shares, but not to initiate them." : "Estes grupos poderão receber partilhas, mas não poderão iniciá-las.",
+ "Allow username autocompletion in share dialog. If this is disabled the full username or email address needs to be entered." : "permitir completar automáticamente nome do utilizador no diálogo de partilha. Se isto estiver inactivo é necessário introduzir o nome do utilizador ou o endereço de e-mail completo. ",
+ "Show disclaimer text on the public link upload page. (Only shown when the file list is hidden.)" : "Mostrar aviso legal na página de carregamento de ligações públicas. (Mostrar apenas quando a lista de ficheiros estiver oculta.)",
+ "This text will be shown on the public link upload page when the file list is hidden." : "Este texto será exibido na página de carregamento de ligações públicas quando a lista de ficheiros estiver oculta. ",
"Tips & tricks" : "Dicas e truques",
+ "This is particularly recommended when using the desktop client for file synchronisation." : "Isto é particularmente recomendado quando estiver a usar um cliente de desktop para sincronização de ficheiros.",
"How to do backups" : "Como fazer cópias de segurança",
"Performance tuning" : "Ajuste de desempenho",
"Improving the config.php" : "Melhorar o config.php",
"Theming" : "Temas",
+ "Check the security of your Nextcloud over our security scan" : "Verifique a segurança da sua Nextcloud através da nossa verificação de segurança",
"Hardening and security guidance" : "Orientações de proteção e segurança",
"Personal" : "Pessoal",
"Administration" : "Administração",
"You are using <strong>%s</strong> of <strong>%s</strong>" : "Está a usar <strong>%s</strong> de <strong>%s</strong>",
+ "You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)" : "Está a usar <strong>%s</strong> de <strong>%s</strong> (<strong>%s%%</strong>)",
"Profile picture" : "Foto do perfil",
"Upload new" : "Carregar novo",
"Select from Files" : "Seleccione dos Ficheiros",
@@ -289,7 +317,11 @@ OC.L10N.register(
"Your phone number" : "O seu número de telefone",
"Address" : "Morada",
"Your postal address" : "A sua morada",
+ "Website" : "Website",
"It can take up to 24 hours before the account is displayed as verified." : "Pode levar até 24 horas para que a conta seja mostrada como verificada.",
+ "Link https://…" : "Ligação https:// ...",
+ "Twitter" : "Twitter",
+ "Twitter handle @…" : "Identificador do Twitter @...",
"You are member of the following groups:" : "Você é membro dos seguintes grupos:",
"Language" : "Idioma",
"Help translate" : "Ajude a traduzir",
@@ -306,11 +338,18 @@ OC.L10N.register(
"For security reasons this password will only be shown once." : "Por motivos de segurança a sua password só será mostrada uma vez.",
"Username" : "Nome de utilizador",
"Done" : "Concluído",
+ "Follow us on Google+" : "Siga-nos no Google+",
+ "Like our Facebook page" : "Deixe um Gosto na nossa página do Facebook",
+ "Follow us on Twitter" : "Siga-nos no Twitter",
+ "Check out our blog" : "Veja o nosso blog",
+ "Subscribe to our newsletter" : "Subscreva as nossas notícias",
"Settings" : "Definições",
"Show storage location" : "Mostrar a localização do armazenamento",
"Show user backend" : "Mostrar interface do utilizador",
+ "Show last login" : "Mostrar último login",
"Show email address" : "Mostrar endereço de email",
"Send email to new user" : "Enviar email ao novo utilizador",
+ "When the password of a new user is left empty, an activation email with a link to set the password is sent." : "Quando a palavra-passe de um novo utilizador é deixada em branco, é-lhe enviado um e-mail com uma ligação para definir a nova palavra-passe.",
"E-Mail" : "Correio Eletrónico",
"Create" : "Criar",
"Admin Recovery Password" : "Recuperação da Palavra-passe de Administrador",
@@ -318,11 +357,14 @@ OC.L10N.register(
"Everyone" : "Para todos",
"Admins" : "Administrador",
"Disabled" : "Desactivado",
+ "Default quota" : "Quota padrão",
"Please enter storage quota (ex: \"512 MB\" or \"12 GB\")" : "Insira a quota de armazenamento (ex: \"512 MB\" ou \"12 GB\")",
"Unlimited" : "Ilimitado",
"Other" : "Outro",
"Group admin for" : "Administrador de grupo para",
"Quota" : "Quota",
+ "Storage location" : "Localização do armazenamento",
+ "User backend" : "Backend do utilizador",
"Last login" : "Último início de sessão",
"change full name" : "alterar nome completo",
"set new password" : "definir nova palavra-passe",
@@ -333,10 +375,33 @@ OC.L10N.register(
"Error while removing app" : "Erro ao remover a app",
"The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "A app foi activada mas necessita ser actualizada. Irá ser redireccionado para a página de actualização em 5 segundos.",
"App update" : "Actualização de app",
+ "__language_name__" : "__nome_da_linguagem__",
"Verifying" : "A verificar",
"Personal info" : "Informação pessoal",
"Sync clients" : "Sincronizar clientes",
+ "%1$s below version %2$s is installed, for stability and performance reasons we recommend updating to a newer %1$s version." : "A versão de %1$s instalada é inferior a %2$s, por motivos de estabilidade e desempenho recomendamos que actualize %1$s para uma versão mais recente.",
+ "The PHP module 'fileinfo' is missing. We strongly recommend to enable this module to get best results with MIME type detection." : "O módulo PHP 'fileinfo' está ausente. Recomendamos vivamente que active este módulo para obter melhores resultados com detecção de tipo MIME.",
+ "This means that there might be problems with certain characters in file names." : "Isto significa que podem haver problemas com alguns caracteres nos nomes dos ficheiros.",
+ "We strongly suggest installing the required packages on your system to support one of the following locales: %s." : "Recomendamos vivamente que instale os pacotes necessários no seu sistema para suportar um dos seguintes locais: %s.",
+ "It was not possible to execute the cronjob via CLI. The following technical errors have appeared:" : "Não foi possível executar a tarefa automática via CLI. Ocorreram os seguintes erros técnicos:",
+ "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>." : "Por favor confira os <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">guias de instalação ↗</a>, e procure por algum erro ou aviso nos <a href=\"%s\">logs</a>.",
+ "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php está registada num serviço webcron para chamar cron-php a cada 15 minutos através de http.",
+ "To run this you need the PHP posix extension. See {linkstart}PHP documentation{linkend} for more details." : "Para esta execução é necessária a extensão PHP posix. Veja {iniciodaligação}documentação PHP{fimdaligação} para mais detalhes.",
+ "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>." : "Para migrar para outra base de dados use a ferramenta da linha de comandos: 'occ db:convert-type', ou veja a <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentação ↗</a>.",
+ "Get the apps to sync your files" : "Tenha as aplicações a sincronizar os seus ficheiros",
"Desktop client" : "Cliente desktop",
+ "Android app" : "Aplicação Android",
+ "iOS app" : "Aplicação iOS",
+ "If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!" : "Se quiser das suporte ao nosso projecto {contributoaberto} junte-se ao desenvolvimento {linkfechado} ou {contributoaberto} espalhe a mensagem {linkfechado}!",
+ "Show First Run Wizard again" : "Mostrar Configurador de Primeira Execução novamente",
+ "Web, desktop, mobile clients and app specific passwords that currently have access to your account." : "Clientes Web, desktop e móveis, e palavras-passe específicas de aplicação que actualmente têm acesso à sua conta.",
+ "App passwords" : "Palavras-passe de aplicação",
+ "Here you can generate individual passwords for apps so you don’t have to give out your password. You can revoke them individually too." : "Aqui pode gerar palavras-passe individuais para as suas aplicações para não tenha de usar a sua palavra-passe. Também as pode revogar individualmente.",
+ "Follow us on Google+!" : "Siga-nos no Google+!",
+ "Like our facebook page!" : "Deixe um Gosto na nossa página do Facebook!",
+ "Follow us on Twitter!" : "Siga-nos no Twitter!",
+ "Check out our blog!" : "Veja o nosso blog!",
+ "Subscribe to our newsletter!" : "Subscreva as nossas notícias!",
"Group name" : "Nome do grupo"
},
"nplurals=2; plural=(n != 1);");
diff --git a/settings/l10n/pt_PT.json b/settings/l10n/pt_PT.json
index c82e604e6c5..2ce0958045d 100644
--- a/settings/l10n/pt_PT.json
+++ b/settings/l10n/pt_PT.json
@@ -118,8 +118,17 @@
"Allow filesystem access" : "Permitir acesso ao sistema de ficheiros",
"Disconnect" : "Desligado",
"Revoke" : "Revogar",
+ "Internet Explorer" : "Internet Explorer",
+ "Edge" : "Microsoft Edge",
+ "Firefox" : "Mozilla Firefox",
+ "Google Chrome" : "Google Chrome",
+ "Safari" : "Safari",
+ "Google Chrome for Android" : "Google Chrome para Android",
+ "iPhone iOS" : "iPhone iOS",
+ "iPad iOS" : "iPad iOS",
"iOS Client" : "Cliente iOS",
"Android Client" : "Cliente Android",
+ "Sync client - {os}" : "Sincronizar cliente - {so}",
"This session" : "Esta sessão",
"Copy" : "Copiar",
"Copied!" : "Copiado!",
@@ -242,10 +251,23 @@
"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." : "A configuração Só-de-Leitura foi ativada. Isto evita definir algumas configurações através da interface da Web. Além disso, o ficheiro precisa de ser definido gravável manualmente para cada atualização.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Isto é provavelmente causado por uma cache/acelerador como o Zend OPcache or eAcelerador.",
"System locale can not be set to a one which supports UTF-8." : "Não é possível definir a internacionalização do sistema para um que suporte o UTF-8.",
+ "This means that there might be problems with certain characters in filenames." : "Isto significa que podem haver problemas com alguns caracteres no nome dos ficheiros.",
+ "It is strongly proposed to install the required packages on your system to support one of the following locales: %s." : "É vivamente aconselhável que instale os pacotes necessários no seu sistema para suportar um dos nossos locais: %s.",
+ "It was not possible to execute the cron job via CLI. The following technical errors have appeared:" : "Não foi possível executar a tarefa agendada via CLI. Os seguintes erros técnicos surgiram:",
"All checks passed." : "Todas as verificações passaram.",
+ "Background jobs" : "Tarefas de segundo plano",
+ "Last job ran %s." : "Última tarefa executada: %s.",
+ "Last job execution ran %s. Something seems wrong." : "Última execução da tarefa: %s. Houve algum problema. ",
+ "Background job didn’t run yet!" : "Tarefa de segundo plano ainda não foi executada!",
+ "For optimal performance it's important to configure background jobs correctly. For bigger instances 'Cron' is the recommended setting. Please see the documentation for more information." : "Para desempenho óptimo é importante que configura as tarefas de segundo plano correctamente. Para maiores instâncias a definição recomendada é 'Cron'. Por favor veja a documentação para mais informações.",
"Execute one task with each page loaded" : "Executar uma tarefa com cada página carregada",
+ "cron.php is registered at a webcron service to call cron.php every 15 minutes over HTTP." : "cron.php está registada num serviço webcron para chamar cron.php a cada 15 minutos através de HTTP.",
+ "Use system cron service to call the cron.php file every 15 minutes." : "Use o serviço de tarefas automáticas para chamar o ficheiro cron.php a cada 15 minutos.",
+ "The cron.php needs to be executed by the system user \"%s\"." : "O cron.php precisa de ser executado pelo utilizador do sistema \"%s\".",
+ "To run this you need the PHP POSIX extension. See {linkstart}PHP documentation{linkend} for more details." : "Para esta execução precisa da extensão PHP POSIX. Veja {iniciodaligação}documentação PHP{fimdaligação} para mais mais detalhes.",
"Version" : "Versão",
"Sharing" : "Partilha",
+ "As admin you can fine-tune the sharing behavior. Please see the documentation for more information." : "Como administrador pode afinar o comportamento de partilha. Por favor veja a documentação para mais informação.",
"Allow apps to use the Share API" : "Permitir que os utilizadores usem a API de partilha",
"Allow users to share via link" : "Permitir que os utilizadores partilhem através do link",
"Allow public uploads" : "Permitir Envios Públicos",
@@ -260,15 +282,21 @@
"Restrict users to only share with users in their groups" : "Restringe os utilizadores só a partilhar com utilizadores do seu grupo",
"Exclude groups from sharing" : "Excluir grupos das partilhas",
"These groups will still be able to receive shares, but not to initiate them." : "Estes grupos poderão receber partilhas, mas não poderão iniciá-las.",
+ "Allow username autocompletion in share dialog. If this is disabled the full username or email address needs to be entered." : "permitir completar automáticamente nome do utilizador no diálogo de partilha. Se isto estiver inactivo é necessário introduzir o nome do utilizador ou o endereço de e-mail completo. ",
+ "Show disclaimer text on the public link upload page. (Only shown when the file list is hidden.)" : "Mostrar aviso legal na página de carregamento de ligações públicas. (Mostrar apenas quando a lista de ficheiros estiver oculta.)",
+ "This text will be shown on the public link upload page when the file list is hidden." : "Este texto será exibido na página de carregamento de ligações públicas quando a lista de ficheiros estiver oculta. ",
"Tips & tricks" : "Dicas e truques",
+ "This is particularly recommended when using the desktop client for file synchronisation." : "Isto é particularmente recomendado quando estiver a usar um cliente de desktop para sincronização de ficheiros.",
"How to do backups" : "Como fazer cópias de segurança",
"Performance tuning" : "Ajuste de desempenho",
"Improving the config.php" : "Melhorar o config.php",
"Theming" : "Temas",
+ "Check the security of your Nextcloud over our security scan" : "Verifique a segurança da sua Nextcloud através da nossa verificação de segurança",
"Hardening and security guidance" : "Orientações de proteção e segurança",
"Personal" : "Pessoal",
"Administration" : "Administração",
"You are using <strong>%s</strong> of <strong>%s</strong>" : "Está a usar <strong>%s</strong> de <strong>%s</strong>",
+ "You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)" : "Está a usar <strong>%s</strong> de <strong>%s</strong> (<strong>%s%%</strong>)",
"Profile picture" : "Foto do perfil",
"Upload new" : "Carregar novo",
"Select from Files" : "Seleccione dos Ficheiros",
@@ -287,7 +315,11 @@
"Your phone number" : "O seu número de telefone",
"Address" : "Morada",
"Your postal address" : "A sua morada",
+ "Website" : "Website",
"It can take up to 24 hours before the account is displayed as verified." : "Pode levar até 24 horas para que a conta seja mostrada como verificada.",
+ "Link https://…" : "Ligação https:// ...",
+ "Twitter" : "Twitter",
+ "Twitter handle @…" : "Identificador do Twitter @...",
"You are member of the following groups:" : "Você é membro dos seguintes grupos:",
"Language" : "Idioma",
"Help translate" : "Ajude a traduzir",
@@ -304,11 +336,18 @@
"For security reasons this password will only be shown once." : "Por motivos de segurança a sua password só será mostrada uma vez.",
"Username" : "Nome de utilizador",
"Done" : "Concluído",
+ "Follow us on Google+" : "Siga-nos no Google+",
+ "Like our Facebook page" : "Deixe um Gosto na nossa página do Facebook",
+ "Follow us on Twitter" : "Siga-nos no Twitter",
+ "Check out our blog" : "Veja o nosso blog",
+ "Subscribe to our newsletter" : "Subscreva as nossas notícias",
"Settings" : "Definições",
"Show storage location" : "Mostrar a localização do armazenamento",
"Show user backend" : "Mostrar interface do utilizador",
+ "Show last login" : "Mostrar último login",
"Show email address" : "Mostrar endereço de email",
"Send email to new user" : "Enviar email ao novo utilizador",
+ "When the password of a new user is left empty, an activation email with a link to set the password is sent." : "Quando a palavra-passe de um novo utilizador é deixada em branco, é-lhe enviado um e-mail com uma ligação para definir a nova palavra-passe.",
"E-Mail" : "Correio Eletrónico",
"Create" : "Criar",
"Admin Recovery Password" : "Recuperação da Palavra-passe de Administrador",
@@ -316,11 +355,14 @@
"Everyone" : "Para todos",
"Admins" : "Administrador",
"Disabled" : "Desactivado",
+ "Default quota" : "Quota padrão",
"Please enter storage quota (ex: \"512 MB\" or \"12 GB\")" : "Insira a quota de armazenamento (ex: \"512 MB\" ou \"12 GB\")",
"Unlimited" : "Ilimitado",
"Other" : "Outro",
"Group admin for" : "Administrador de grupo para",
"Quota" : "Quota",
+ "Storage location" : "Localização do armazenamento",
+ "User backend" : "Backend do utilizador",
"Last login" : "Último início de sessão",
"change full name" : "alterar nome completo",
"set new password" : "definir nova palavra-passe",
@@ -331,10 +373,33 @@
"Error while removing app" : "Erro ao remover a app",
"The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "A app foi activada mas necessita ser actualizada. Irá ser redireccionado para a página de actualização em 5 segundos.",
"App update" : "Actualização de app",
+ "__language_name__" : "__nome_da_linguagem__",
"Verifying" : "A verificar",
"Personal info" : "Informação pessoal",
"Sync clients" : "Sincronizar clientes",
+ "%1$s below version %2$s is installed, for stability and performance reasons we recommend updating to a newer %1$s version." : "A versão de %1$s instalada é inferior a %2$s, por motivos de estabilidade e desempenho recomendamos que actualize %1$s para uma versão mais recente.",
+ "The PHP module 'fileinfo' is missing. We strongly recommend to enable this module to get best results with MIME type detection." : "O módulo PHP 'fileinfo' está ausente. Recomendamos vivamente que active este módulo para obter melhores resultados com detecção de tipo MIME.",
+ "This means that there might be problems with certain characters in file names." : "Isto significa que podem haver problemas com alguns caracteres nos nomes dos ficheiros.",
+ "We strongly suggest installing the required packages on your system to support one of the following locales: %s." : "Recomendamos vivamente que instale os pacotes necessários no seu sistema para suportar um dos seguintes locais: %s.",
+ "It was not possible to execute the cronjob via CLI. The following technical errors have appeared:" : "Não foi possível executar a tarefa automática via CLI. Ocorreram os seguintes erros técnicos:",
+ "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>." : "Por favor confira os <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">guias de instalação ↗</a>, e procure por algum erro ou aviso nos <a href=\"%s\">logs</a>.",
+ "cron.php is registered at a webcron service to call cron.php every 15 minutes over http." : "cron.php está registada num serviço webcron para chamar cron-php a cada 15 minutos através de http.",
+ "To run this you need the PHP posix extension. See {linkstart}PHP documentation{linkend} for more details." : "Para esta execução é necessária a extensão PHP posix. Veja {iniciodaligação}documentação PHP{fimdaligação} para mais detalhes.",
+ "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>." : "Para migrar para outra base de dados use a ferramenta da linha de comandos: 'occ db:convert-type', ou veja a <a target=\"_blank\" rel=\"noreferrer\" href=\"%s\">documentação ↗</a>.",
+ "Get the apps to sync your files" : "Tenha as aplicações a sincronizar os seus ficheiros",
"Desktop client" : "Cliente desktop",
+ "Android app" : "Aplicação Android",
+ "iOS app" : "Aplicação iOS",
+ "If you want to support the project {contributeopen}join development{linkclose} or {contributeopen}spread the word{linkclose}!" : "Se quiser das suporte ao nosso projecto {contributoaberto} junte-se ao desenvolvimento {linkfechado} ou {contributoaberto} espalhe a mensagem {linkfechado}!",
+ "Show First Run Wizard again" : "Mostrar Configurador de Primeira Execução novamente",
+ "Web, desktop, mobile clients and app specific passwords that currently have access to your account." : "Clientes Web, desktop e móveis, e palavras-passe específicas de aplicação que actualmente têm acesso à sua conta.",
+ "App passwords" : "Palavras-passe de aplicação",
+ "Here you can generate individual passwords for apps so you don’t have to give out your password. You can revoke them individually too." : "Aqui pode gerar palavras-passe individuais para as suas aplicações para não tenha de usar a sua palavra-passe. Também as pode revogar individualmente.",
+ "Follow us on Google+!" : "Siga-nos no Google+!",
+ "Like our facebook page!" : "Deixe um Gosto na nossa página do Facebook!",
+ "Follow us on Twitter!" : "Siga-nos no Twitter!",
+ "Check out our blog!" : "Veja o nosso blog!",
+ "Subscribe to our newsletter!" : "Subscreva as nossas notícias!",
"Group name" : "Nome do grupo"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/settings/l10n/sk.js b/settings/l10n/sk.js
index 909d2ef322f..b3037f133a1 100644
--- a/settings/l10n/sk.js
+++ b/settings/l10n/sk.js
@@ -104,9 +104,14 @@ OC.L10N.register(
"Error: This app can not be enabled because it makes the server unstable" : "Chyba: aplikáciu nie je možné povoliť, lebo naruší stabilitu servera",
"Error: Could not disable broken app" : "Chyba: nebolo možné zakázať poškodenú aplikáciu",
"Error while disabling broken app" : "Nastala chyba počas zakazovania poškodenej aplikácie",
+ "App up to date" : "Aplikácia je aktuálna",
+ "Upgrading …" : "Aktualizuje sa...",
+ "Could not upgrade app" : "Aplikáciu nie je možné aktualizovať",
"Updated" : "Aktualizované",
"Removing …" : "Odstraňujem ...",
+ "Could not remove app" : "Aplikáciu nie je možné zmazať",
"Remove" : "Odstrániť",
+ "The app has been enabled but needs to be upgraded. You will be redirected to the upgrade page in 5 seconds." : "Aplikácia bola povolená, ale vyžaduje sa jej aktualizácia. Presmerovanie na stránku aktualizácie o 5 sekúnd.",
"Approved" : "Schválené",
"Experimental" : "Experimentálny",
"No apps found for {query}" : "Žiadna aplikácia nebola nájdená pre {query}",
@@ -247,6 +252,7 @@ OC.L10N.register(
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "To je pravdepodobne spôsobené cache/akcelerátorom ako napr. Zend OPcache alebo eAccelerator.",
"The PHP module 'fileinfo' is missing. It is strongly recommended to enable this module to get the best results with MIME type detection." : "Chýba PHP modul 'fileinfo'. Dôrazne doporučujeme ho povoliť pre dosiahnutie najlepších výsledkov zisťovania MIME-typu.",
"System locale can not be set to a one which supports UTF-8." : "Nie je možné nastaviť znakovú sadu, ktorá podporuje UTF-8.",
+ "This means that there might be problems with certain characters in filenames." : "To znamená, že problémom môžu byť niektoré znaky v názvoch súborov.",
"It is strongly proposed to install the required packages on your system to support one of the following locales: %s." : "Dôrazne doporučujeme nainštalovať na váš systém požadované balíčky podporujúce jednu z nasledovných znakových sád: %s.",
"If your installation is not installed at 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\")" : "Inštalácia mimo koreňový priečinok domény a používanie systémového príkazu cron môže spôsobiť problém s generovaním správnej URL. Pre zabránenie týmto chybám nastavte prosím správnu cestu v svojom config.php súbore pre hodnotu \"overwrite.cli.url\" (Doporučujeme: \"%s\")",
"It was not possible to execute the cron job via CLI. The following technical errors have appeared:" : "Nebolo možné spustiť úlohu na pozadí pomocou CLI. Toto sú chyby:",
@@ -362,6 +368,21 @@ OC.L10N.register(
"change full name" : "zmeniť meno a priezvisko",
"set new password" : "nastaviť nové heslo",
"change email address" : "zmeniť emailovú adresu",
- "Default" : "Predvolené"
+ "Default" : "Predvolené",
+ "Updating...." : "Aktualizuje sa...",
+ "Error while updating app" : "Chyba pri aktualizácii aplikácie",
+ "Error while removing app" : "Chyba pri odstraňovaní aplikácie",
+ "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "Aplikácia bola povolená, ale vyžaduje sa aktualizácia. Presmerovanie na stránku aktualizácie o 5 sekúnd.",
+ "App update" : "Aktualizácia aplikácie",
+ "Verifying" : "Overovanie",
+ "Personal info" : "Osobné informácie",
+ "It's important for the security and performance of your instance that everything is configured correctly. To help you with that we are doing some automatic checks. Please see the Tips & Ticks section and the documentation for more information." : "Z hľadiska bezpečnosti a výkonu Vašej inštalácie je dôležité, že všetko je správne nastavené. Robíme automatickú kontrolu, ktorá Vám s tým pomáha. Pre ďalšie informácie nahliadnite do sekcie Tipy a triky a do dokumentácie.",
+ "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "PHP nie je správne nastavené pre zobrazovanie systémových premenných. Príkaz getenv(\"PATH\") vracia iba prázdnu odpoveď.",
+ "Android app" : "Android aplikácia",
+ "iOS app" : "iOS aplikácia",
+ "Show First Run Wizard again" : "Znova zobraz Sprievodcu prvým spustením",
+ "App passwords" : "Heslá aplikácie",
+ "Follow us on Google+!" : "Sledujte nás na Google+!",
+ "Follow us on Twitter!" : "Sledujte nás na Twitteri!"
},
"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");
diff --git a/settings/l10n/sk.json b/settings/l10n/sk.json
index 25b902d9ac3..f9b15bdfd7d 100644
--- a/settings/l10n/sk.json
+++ b/settings/l10n/sk.json
@@ -102,9 +102,14 @@
"Error: This app can not be enabled because it makes the server unstable" : "Chyba: aplikáciu nie je možné povoliť, lebo naruší stabilitu servera",
"Error: Could not disable broken app" : "Chyba: nebolo možné zakázať poškodenú aplikáciu",
"Error while disabling broken app" : "Nastala chyba počas zakazovania poškodenej aplikácie",
+ "App up to date" : "Aplikácia je aktuálna",
+ "Upgrading …" : "Aktualizuje sa...",
+ "Could not upgrade app" : "Aplikáciu nie je možné aktualizovať",
"Updated" : "Aktualizované",
"Removing …" : "Odstraňujem ...",
+ "Could not remove app" : "Aplikáciu nie je možné zmazať",
"Remove" : "Odstrániť",
+ "The app has been enabled but needs to be upgraded. You will be redirected to the upgrade page in 5 seconds." : "Aplikácia bola povolená, ale vyžaduje sa jej aktualizácia. Presmerovanie na stránku aktualizácie o 5 sekúnd.",
"Approved" : "Schválené",
"Experimental" : "Experimentálny",
"No apps found for {query}" : "Žiadna aplikácia nebola nájdená pre {query}",
@@ -245,6 +250,7 @@
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "To je pravdepodobne spôsobené cache/akcelerátorom ako napr. Zend OPcache alebo eAccelerator.",
"The PHP module 'fileinfo' is missing. It is strongly recommended to enable this module to get the best results with MIME type detection." : "Chýba PHP modul 'fileinfo'. Dôrazne doporučujeme ho povoliť pre dosiahnutie najlepších výsledkov zisťovania MIME-typu.",
"System locale can not be set to a one which supports UTF-8." : "Nie je možné nastaviť znakovú sadu, ktorá podporuje UTF-8.",
+ "This means that there might be problems with certain characters in filenames." : "To znamená, že problémom môžu byť niektoré znaky v názvoch súborov.",
"It is strongly proposed to install the required packages on your system to support one of the following locales: %s." : "Dôrazne doporučujeme nainštalovať na váš systém požadované balíčky podporujúce jednu z nasledovných znakových sád: %s.",
"If your installation is not installed at 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\")" : "Inštalácia mimo koreňový priečinok domény a používanie systémového príkazu cron môže spôsobiť problém s generovaním správnej URL. Pre zabránenie týmto chybám nastavte prosím správnu cestu v svojom config.php súbore pre hodnotu \"overwrite.cli.url\" (Doporučujeme: \"%s\")",
"It was not possible to execute the cron job via CLI. The following technical errors have appeared:" : "Nebolo možné spustiť úlohu na pozadí pomocou CLI. Toto sú chyby:",
@@ -360,6 +366,21 @@
"change full name" : "zmeniť meno a priezvisko",
"set new password" : "nastaviť nové heslo",
"change email address" : "zmeniť emailovú adresu",
- "Default" : "Predvolené"
+ "Default" : "Predvolené",
+ "Updating...." : "Aktualizuje sa...",
+ "Error while updating app" : "Chyba pri aktualizácii aplikácie",
+ "Error while removing app" : "Chyba pri odstraňovaní aplikácie",
+ "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "Aplikácia bola povolená, ale vyžaduje sa aktualizácia. Presmerovanie na stránku aktualizácie o 5 sekúnd.",
+ "App update" : "Aktualizácia aplikácie",
+ "Verifying" : "Overovanie",
+ "Personal info" : "Osobné informácie",
+ "It's important for the security and performance of your instance that everything is configured correctly. To help you with that we are doing some automatic checks. Please see the Tips & Ticks section and the documentation for more information." : "Z hľadiska bezpečnosti a výkonu Vašej inštalácie je dôležité, že všetko je správne nastavené. Robíme automatickú kontrolu, ktorá Vám s tým pomáha. Pre ďalšie informácie nahliadnite do sekcie Tipy a triky a do dokumentácie.",
+ "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "PHP nie je správne nastavené pre zobrazovanie systémových premenných. Príkaz getenv(\"PATH\") vracia iba prázdnu odpoveď.",
+ "Android app" : "Android aplikácia",
+ "iOS app" : "iOS aplikácia",
+ "Show First Run Wizard again" : "Znova zobraz Sprievodcu prvým spustením",
+ "App passwords" : "Heslá aplikácie",
+ "Follow us on Google+!" : "Sledujte nás na Google+!",
+ "Follow us on Twitter!" : "Sledujte nás na Twitteri!"
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
} \ No newline at end of file
diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php
index cc55e33f354..c6b9719b32a 100644
--- a/tests/lib/AppFramework/Http/RequestTest.php
+++ b/tests/lib/AppFramework/Http/RequestTest.php
@@ -307,7 +307,7 @@ class RequestTest extends \Test\TestCase {
'method' => 'PUT',
'server' => [
'CONTENT_TYPE' => 'image/png',
- 'CONTENT_LENGTH' => strlen($data)
+ 'CONTENT_LENGTH' => (string)strlen($data)
],
);