summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/dav/lib/connector/sabre/file.php10
-rw-r--r--apps/dav/lib/connector/sabre/objecttree.php3
-rw-r--r--apps/encryption/l10n/es.js1
-rw-r--r--apps/encryption/l10n/es.json1
-rw-r--r--apps/files/l10n/es.js3
-rw-r--r--apps/files/l10n/es.json3
-rw-r--r--apps/files_external/appinfo/app.php7
-rw-r--r--apps/files_external/appinfo/application.php13
-rw-r--r--apps/files_external/l10n/es.js11
-rw-r--r--apps/files_external/l10n/es.json11
-rw-r--r--apps/files_sharing/l10n/es.js1
-rw-r--r--apps/files_sharing/l10n/es.json1
-rw-r--r--apps/files_sharing/lib/cache.php13
-rw-r--r--apps/files_sharing/lib/helper.php10
-rw-r--r--apps/files_sharing/lib/scanner.php2
-rw-r--r--apps/files_sharing/lib/watcher.php3
-rw-r--r--apps/files_sharing/tests/backend.php6
-rw-r--r--apps/files_sharing/tests/external/cache.php4
-rw-r--r--apps/files_sharing/tests/sharedmount.php6
-rw-r--r--apps/files_sharing/tests/updater.php6
-rw-r--r--apps/files_sharing/tests/watcher.php12
-rw-r--r--apps/files_trashbin/lib/helper.php3
-rw-r--r--apps/files_trashbin/lib/trashbin.php19
-rw-r--r--apps/files_versions/lib/storage.php38
-rw-r--r--apps/files_versions/tests/versions.php10
-rw-r--r--apps/provisioning_api/appinfo/info.xml5
-rw-r--r--core/command/security/importcertificate.php67
-rw-r--r--core/command/security/listcertificates.php96
-rw-r--r--core/command/security/removecertificate.php59
-rw-r--r--core/l10n/es.js13
-rw-r--r--core/l10n/es.json13
-rw-r--r--core/l10n/th_TH.js4
-rw-r--r--core/l10n/th_TH.json4
-rw-r--r--core/register_command.php4
-rw-r--r--lib/l10n/cs_CZ.js1
-rw-r--r--lib/l10n/cs_CZ.json1
-rw-r--r--lib/l10n/es.js9
-rw-r--r--lib/l10n/es.json9
-rw-r--r--lib/l10n/fr.js1
-rw-r--r--lib/l10n/fr.json1
-rw-r--r--lib/l10n/it.js1
-rw-r--r--lib/l10n/it.json1
-rw-r--r--lib/l10n/pt_BR.js1
-rw-r--r--lib/l10n/pt_BR.json1
-rw-r--r--lib/l10n/sq.js1
-rw-r--r--lib/l10n/sq.json1
-rw-r--r--lib/l10n/th_TH.js1
-rw-r--r--lib/l10n/th_TH.json1
-rw-r--r--lib/private/app/appmanager.php21
-rw-r--r--lib/private/cache/cappedmemorycache.php4
-rw-r--r--lib/private/files/cache/cache.php67
-rw-r--r--lib/private/files/cache/cacheentry.php114
-rw-r--r--lib/private/files/cache/homecache.php4
-rw-r--r--lib/private/files/cache/propagator.php6
-rw-r--r--lib/private/files/cache/scanner.php63
-rw-r--r--lib/private/files/cache/updater.php16
-rw-r--r--lib/private/files/cache/watcher.php13
-rw-r--r--lib/private/files/cache/wrapper/cachewrapper.php15
-rw-r--r--lib/private/files/fileinfo.php3
-rw-r--r--lib/private/files/objectstore/objectstorestorage.php8
-rw-r--r--lib/private/files/storage/common.php3
-rw-r--r--lib/private/files/storage/wrapper/encryption.php4
-rw-r--r--lib/private/files/storage/wrapper/quota.php4
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php15
-rw-r--r--lib/private/files/view.php81
-rw-r--r--lib/private/group/backend.php4
-rw-r--r--lib/private/group/manager.php5
-rw-r--r--lib/private/tempmanager.php11
-rw-r--r--lib/public/files/cache/icache.php249
-rw-r--r--lib/public/files/cache/icacheentry.php132
-rw-r--r--lib/public/files/cache/ipropagator.php37
-rw-r--r--lib/public/files/cache/iscanner.php81
-rw-r--r--lib/public/files/cache/iupdater.php75
-rw-r--r--lib/public/files/cache/iwatcher.php82
-rw-r--r--lib/public/files/storage.php13
-rw-r--r--lib/public/files/storage/ilockingstorage.php60
-rw-r--r--lib/public/files/storage/istorage.php482
-rw-r--r--lib/public/igroupmanager.php2
-rw-r--r--settings/js/apps.js3
-rw-r--r--settings/l10n/es.js13
-rw-r--r--settings/l10n/es.json13
-rw-r--r--settings/users.php2
-rw-r--r--tests/lib/app/manager.php93
-rw-r--r--tests/lib/cache/cappedmemorycache.php12
-rw-r--r--tests/lib/files/cache/cache.php2
-rw-r--r--tests/lib/files/cache/scanner.php4
-rw-r--r--tests/lib/files/storage/wrapper/quota.php4
87 files changed, 2093 insertions, 219 deletions
diff --git a/apps/dav/lib/connector/sabre/file.php b/apps/dav/lib/connector/sabre/file.php
index 4075c565f43..b925a670405 100644
--- a/apps/dav/lib/connector/sabre/file.php
+++ b/apps/dav/lib/connector/sabre/file.php
@@ -130,9 +130,17 @@ class File extends Node implements IFile {
// because we have no clue about the cause we can only throw back a 500/Internal Server Error
throw new Exception('Could not write file contents');
}
- list($count,) = \OC_Helper::streamCopy($data, $target);
+ list($count, $result) = \OC_Helper::streamCopy($data, $target);
fclose($target);
+ if($result === false) {
+ $expected = -1;
+ if (isset($_SERVER['CONTENT_LENGTH'])) {
+ $expected = $_SERVER['CONTENT_LENGTH'];
+ }
+ throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: '. $expected .' )');
+ }
+
// if content length is sent by client:
// double check if the file was fully received
// compare expected and actual size
diff --git a/apps/dav/lib/connector/sabre/objecttree.php b/apps/dav/lib/connector/sabre/objecttree.php
index ba4c855f58a..55b310a4405 100644
--- a/apps/dav/lib/connector/sabre/objecttree.php
+++ b/apps/dav/lib/connector/sabre/objecttree.php
@@ -135,9 +135,8 @@ class ObjectTree extends \Sabre\DAV\Tree {
/**
* @var \OC\Files\Storage\Storage $storage
*/
- $scanner = $storage->getScanner($internalPath);
// get data directly
- $data = $scanner->getData($internalPath);
+ $data = $storage->getMetaData($internalPath);
$info = new FileInfo($absPath, $storage, $internalPath, $data, $mount);
} else {
$info = null;
diff --git a/apps/encryption/l10n/es.js b/apps/encryption/l10n/es.js
index 1dadb88064a..bdaeabb68cb 100644
--- a/apps/encryption/l10n/es.js
+++ b/apps/encryption/l10n/es.js
@@ -33,6 +33,7 @@ OC.L10N.register(
"Cheers!" : "¡Saludos!",
"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 \"ownCloud 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>" : "Hola,\n<br><br>\nEl administrador ha habilitado el cifrado del lado servidor. Sus archivos serán cifrados usando como contraseña: <strong>%s</strong>\n<br><br>\nPor favor, identifíquese en la interfaz web, vaya a la sección 'Modulo básico de cifrado' de sus opciones personales y actualice su contraseña tecleando esta contraseña en el campo 'contraseña antigua' e introduciendo la nueva en su correspondiente campo.<br><br>",
"Encrypt the home storage" : "Encriptar el almacenamiento personal",
+ "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Al activar esta opción se encriptarán todos los archivos almacenados en la memoria principal, de lo contrario serán cifrados sólo los archivos de almacenamiento externo",
"Enable recovery key" : "Activa la clave de recuperación",
"Disable recovery key" : "Desactiva la clave de recuperación",
"The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "La clave de recuperación es una clave de cifrado extra que se usa para cifrar ficheros. Permite la recuperación de los ficheros de un usuario si él o ella olvida su contraseña.",
diff --git a/apps/encryption/l10n/es.json b/apps/encryption/l10n/es.json
index 5cf2b12ce5f..3eb7994eb9d 100644
--- a/apps/encryption/l10n/es.json
+++ b/apps/encryption/l10n/es.json
@@ -31,6 +31,7 @@
"Cheers!" : "¡Saludos!",
"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 \"ownCloud 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>" : "Hola,\n<br><br>\nEl administrador ha habilitado el cifrado del lado servidor. Sus archivos serán cifrados usando como contraseña: <strong>%s</strong>\n<br><br>\nPor favor, identifíquese en la interfaz web, vaya a la sección 'Modulo básico de cifrado' de sus opciones personales y actualice su contraseña tecleando esta contraseña en el campo 'contraseña antigua' e introduciendo la nueva en su correspondiente campo.<br><br>",
"Encrypt the home storage" : "Encriptar el almacenamiento personal",
+ "Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Al activar esta opción se encriptarán todos los archivos almacenados en la memoria principal, de lo contrario serán cifrados sólo los archivos de almacenamiento externo",
"Enable recovery key" : "Activa la clave de recuperación",
"Disable recovery key" : "Desactiva la clave de recuperación",
"The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "La clave de recuperación es una clave de cifrado extra que se usa para cifrar ficheros. Permite la recuperación de los ficheros de un usuario si él o ella olvida su contraseña.",
diff --git a/apps/files/l10n/es.js b/apps/files/l10n/es.js
index 92e3b530d28..449334e7cc5 100644
--- a/apps/files/l10n/es.js
+++ b/apps/files/l10n/es.js
@@ -45,6 +45,8 @@ OC.L10N.register(
"Could not move \"{file}\", target exists" : "No se pudo mover \"{file}\", destino ya existe",
"Could not move \"{file}\"" : "No se pudo mover \"{file}\"",
"{newName} already exists" : "{newName} ya existe",
+ "Could not rename \"{fileName}\", it does not exist any more" : "No se pudo renombrar \"{fileName}\", ya no existe",
+ "The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "El nombre \"{targetName}\" ya se utiliza en la carpeta \"{dir}\". Por favor elija un nombre diferente.",
"Could not rename \"{fileName}\"" : "No se pudo renombrar \"{fileName}\"",
"Could not create file \"{file}\"" : "No se pudo crear archivo \"{file}\"",
"Could not create file \"{file}\" because it already exists" : "No se pudo crear archivo \"{file}\" porque ya existe",
@@ -99,6 +101,7 @@ OC.L10N.register(
"Maximum upload size" : "Tamaño máximo de subida",
"max. possible: " : "máx. posible:",
"Save" : "Guardar",
+ "With PHP-FPM it might take 5 minutes for changes to be applied." : "Con PHP-FPM podría tomar 5 minutos para que los cambios se apliquen.",
"Missing permissions to edit from here." : "Faltan permisos para poder editar desde aquí.",
"Settings" : "Ajustes",
"WebDAV" : "WebDAV",
diff --git a/apps/files/l10n/es.json b/apps/files/l10n/es.json
index cb65f8c1d87..7d0d2be207c 100644
--- a/apps/files/l10n/es.json
+++ b/apps/files/l10n/es.json
@@ -43,6 +43,8 @@
"Could not move \"{file}\", target exists" : "No se pudo mover \"{file}\", destino ya existe",
"Could not move \"{file}\"" : "No se pudo mover \"{file}\"",
"{newName} already exists" : "{newName} ya existe",
+ "Could not rename \"{fileName}\", it does not exist any more" : "No se pudo renombrar \"{fileName}\", ya no existe",
+ "The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "El nombre \"{targetName}\" ya se utiliza en la carpeta \"{dir}\". Por favor elija un nombre diferente.",
"Could not rename \"{fileName}\"" : "No se pudo renombrar \"{fileName}\"",
"Could not create file \"{file}\"" : "No se pudo crear archivo \"{file}\"",
"Could not create file \"{file}\" because it already exists" : "No se pudo crear archivo \"{file}\" porque ya existe",
@@ -97,6 +99,7 @@
"Maximum upload size" : "Tamaño máximo de subida",
"max. possible: " : "máx. posible:",
"Save" : "Guardar",
+ "With PHP-FPM it might take 5 minutes for changes to be applied." : "Con PHP-FPM podría tomar 5 minutos para que los cambios se apliquen.",
"Missing permissions to edit from here." : "Faltan permisos para poder editar desde aquí.",
"Settings" : "Ajustes",
"WebDAV" : "WebDAV",
diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php
index 9a2ec7286ca..c8d90f02f29 100644
--- a/apps/files_external/appinfo/app.php
+++ b/apps/files_external/appinfo/app.php
@@ -45,12 +45,9 @@ require_once __DIR__ . '/../3rdparty/autoload.php';
\OC_Mount_Config::$app = new \OCA\Files_external\Appinfo\Application();
$appContainer = \OC_Mount_Config::$app->getContainer();
-$l = \OC::$server->getL10N('files_external');
+\OC_Mount_Config::$app->registerSettings();
-OCP\App::registerAdmin('files_external', 'settings');
-if (OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes') == 'yes') {
- OCP\App::registerPersonal('files_external', 'personal');
-}
+$l = \OC::$server->getL10N('files_external');
\OCA\Files\App::getNavigationManager()->add([
"id" => 'extstoragemounts',
diff --git a/apps/files_external/appinfo/application.php b/apps/files_external/appinfo/application.php
index b750734bf34..0c8b90935d3 100644
--- a/apps/files_external/appinfo/application.php
+++ b/apps/files_external/appinfo/application.php
@@ -46,6 +46,19 @@ class Application extends App {
}
/**
+ * Register settings templates
+ */
+ public function registerSettings() {
+ $container = $this->getContainer();
+ $backendService = $container->query('OCA\\Files_External\\Service\\BackendService');
+
+ \OCP\App::registerAdmin('files_external', 'settings');
+ if ($backendService->isUserMountingAllowed()) {
+ \OCP\App::registerPersonal('files_external', 'personal');
+ }
+ }
+
+ /**
* Load storage backends provided by this app
*/
protected function loadBackends() {
diff --git a/apps/files_external/l10n/es.js b/apps/files_external/l10n/es.js
index c39653acb53..6db3afd6441 100644
--- a/apps/files_external/l10n/es.js
+++ b/apps/files_external/l10n/es.js
@@ -35,9 +35,17 @@ OC.L10N.register(
"(group)" : "(grupo)",
"Admin defined" : "Admin definido",
"Saved" : "Guardado",
+ "Empty response from the server" : "Respuesta vacía desde el servidor",
+ "Couldn't access. Please logout and login to activate this mount point" : "No se puede acceder. Por favor cierra sesión e iníciala de nuevo para activar este punto de montaje",
+ "Couldn't get the information from the ownCloud server: {code} {type}" : "No se puede obtener información acerca del servidor de OwnCloud: {code} {type}",
+ "Couldn't get the list of external mount points: {type}" : "No se puede obtener la lista de los puntos de montaje externos: {type}",
"There was an error with message: " : "Hubo un error con el mensaje:",
+ "External mount error" : "Error de montaje externo",
+ "Couldn't get the list of Windows network drive mount points: empty response from the server" : "No se puede obtener la lista de unidades de red y sus puntos de montaje de Windows: respuesta vacía desde el servidor",
+ "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Algunos de los puntos de montaje externos configurados no están conectados. Por favor, haga clic en la fila roja (s) para obtener más información",
"Access key" : "Clave de acceso",
"Secret key" : "Clave secreta",
+ "Builtin" : "Incorporado",
"None" : "Ninguno",
"OAuth1" : "OAuth1",
"App key" : "App principal",
@@ -49,6 +57,8 @@ OC.L10N.register(
"Username" : "Nombre de usuario",
"Password" : "Contraseña",
"Tenant name" : "Nombre del inquilino",
+ "Identity endpoint URL" : "Identidad de punto final URL",
+ "Rackspace" : "Espacio de Rack",
"API key" : "Clave API",
"Username and password" : "Nombre de usuario y contraseña",
"Session credentials" : "Credenciales de la sesión",
@@ -83,6 +93,7 @@ OC.L10N.register(
"Username as share" : "Nombre de usuario como compartir",
"OpenStack Object Storage" : "Almacenamiento de objeto OpenStack",
"Service name" : "Nombre del servicio",
+ "Request timeout (seconds)" : "Tiempo agotado para petición (segundos)",
"<b>Note:</b> " : "<b>Nota:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> El soporte de cURL en PHP no está activado o instalado. No se puede montar %s. Pídale al administrador del sistema que lo instale.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> El soporte de FTP en PHP no está activado o instalado. No se puede montar %s. Pídale al administrador del sistema que lo instale.",
diff --git a/apps/files_external/l10n/es.json b/apps/files_external/l10n/es.json
index 761aaad5a13..e9a3e317679 100644
--- a/apps/files_external/l10n/es.json
+++ b/apps/files_external/l10n/es.json
@@ -33,9 +33,17 @@
"(group)" : "(grupo)",
"Admin defined" : "Admin definido",
"Saved" : "Guardado",
+ "Empty response from the server" : "Respuesta vacía desde el servidor",
+ "Couldn't access. Please logout and login to activate this mount point" : "No se puede acceder. Por favor cierra sesión e iníciala de nuevo para activar este punto de montaje",
+ "Couldn't get the information from the ownCloud server: {code} {type}" : "No se puede obtener información acerca del servidor de OwnCloud: {code} {type}",
+ "Couldn't get the list of external mount points: {type}" : "No se puede obtener la lista de los puntos de montaje externos: {type}",
"There was an error with message: " : "Hubo un error con el mensaje:",
+ "External mount error" : "Error de montaje externo",
+ "Couldn't get the list of Windows network drive mount points: empty response from the server" : "No se puede obtener la lista de unidades de red y sus puntos de montaje de Windows: respuesta vacía desde el servidor",
+ "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Algunos de los puntos de montaje externos configurados no están conectados. Por favor, haga clic en la fila roja (s) para obtener más información",
"Access key" : "Clave de acceso",
"Secret key" : "Clave secreta",
+ "Builtin" : "Incorporado",
"None" : "Ninguno",
"OAuth1" : "OAuth1",
"App key" : "App principal",
@@ -47,6 +55,8 @@
"Username" : "Nombre de usuario",
"Password" : "Contraseña",
"Tenant name" : "Nombre del inquilino",
+ "Identity endpoint URL" : "Identidad de punto final URL",
+ "Rackspace" : "Espacio de Rack",
"API key" : "Clave API",
"Username and password" : "Nombre de usuario y contraseña",
"Session credentials" : "Credenciales de la sesión",
@@ -81,6 +91,7 @@
"Username as share" : "Nombre de usuario como compartir",
"OpenStack Object Storage" : "Almacenamiento de objeto OpenStack",
"Service name" : "Nombre del servicio",
+ "Request timeout (seconds)" : "Tiempo agotado para petición (segundos)",
"<b>Note:</b> " : "<b>Nota:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> El soporte de cURL en PHP no está activado o instalado. No se puede montar %s. Pídale al administrador del sistema que lo instale.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> El soporte de FTP en PHP no está activado o instalado. No se puede montar %s. Pídale al administrador del sistema que lo instale.",
diff --git a/apps/files_sharing/l10n/es.js b/apps/files_sharing/l10n/es.js
index e77c4b974f7..da479f40975 100644
--- a/apps/files_sharing/l10n/es.js
+++ b/apps/files_sharing/l10n/es.js
@@ -3,6 +3,7 @@ OC.L10N.register(
{
"Server to server sharing is not enabled on this server" : "Compartir entre servidores no está habilitado en este servidor",
"The mountpoint name contains invalid characters." : "El punto de montaje contiene caracteres inválidos.",
+ "Not allowed to create a federated share with the same user server" : "No se permite crear un recurso compartido federado con el mismo servidor de usuario",
"Invalid or untrusted SSL certificate" : "Certificado SSL inválido o no confiable",
"Could not authenticate to remote share, password might be wrong" : "No se ha podido autenticar para compartir remotamente, quizás esté mal la contraseña",
"Storage not valid" : "Almacenamiento inválido",
diff --git a/apps/files_sharing/l10n/es.json b/apps/files_sharing/l10n/es.json
index 96fb368f76b..3b6f828b79a 100644
--- a/apps/files_sharing/l10n/es.json
+++ b/apps/files_sharing/l10n/es.json
@@ -1,6 +1,7 @@
{ "translations": {
"Server to server sharing is not enabled on this server" : "Compartir entre servidores no está habilitado en este servidor",
"The mountpoint name contains invalid characters." : "El punto de montaje contiene caracteres inválidos.",
+ "Not allowed to create a federated share with the same user server" : "No se permite crear un recurso compartido federado con el mismo servidor de usuario",
"Invalid or untrusted SSL certificate" : "Certificado SSL inválido o no confiable",
"Could not authenticate to remote share, password might be wrong" : "No se ha podido autenticar para compartir remotamente, quizás esté mal la contraseña",
"Storage not valid" : "Almacenamiento inválido",
diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php
index 714cc144c0b..10d1e787922 100644
--- a/apps/files_sharing/lib/cache.php
+++ b/apps/files_sharing/lib/cache.php
@@ -33,6 +33,7 @@
namespace OC\Files\Cache;
use OC\User\NoUserException;
+use OCP\Files\Cache\ICacheEntry;
use OCP\Share_Backend_Collection;
/**
@@ -98,8 +99,8 @@ class Shared_Cache extends Cache {
/**
* get the stored metadata of a file or folder
*
- * @param string $file
- * @return array|false
+ * @param string|int $file
+ * @return ICacheEntry|false
*/
public function get($file) {
$mimetypeLoader = \OC::$server->getMimeTypeLoader();
@@ -161,7 +162,7 @@ class Shared_Cache extends Cache {
* get the metadata of all files stored in $folder
*
* @param string $folderId
- * @return array|false
+ * @return ICacheEntry[]|false
*/
public function getFolderContentsById($folderId) {
$cache = $this->getSourceCache('');
@@ -281,7 +282,7 @@ class Shared_Cache extends Cache {
* search for files matching $pattern
*
* @param string $pattern
- * @return array of file data
+ * @return ICacheEntry[] of file data
*/
public function search($pattern) {
@@ -320,7 +321,7 @@ class Shared_Cache extends Cache {
* search for files by mimetype
*
* @param string $mimetype
- * @return array
+ * @return ICacheEntry[]
*/
public function searchByMime($mimetype) {
$mimepart = null;
@@ -373,7 +374,7 @@ class Shared_Cache extends Cache {
*
* @param string|int $tag tag to search for
* @param string $userId owner of the tags
- * @return array file data
+ * @return ICacheEntry[] file data
*/
public function searchByTag($tag, $userId) {
// TODO: inject this
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index ca60f622844..cffdc8887ec 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -28,6 +28,7 @@
*/
namespace OCA\Files_Sharing;
+use OC\Files\Filesystem;
use OCP\Files\NotFoundException;
class Helper {
@@ -205,14 +206,7 @@ class Helper {
}
public static function getUidAndFilename($filename) {
- $uid = \OC\Files\Filesystem::getOwner($filename);
- \OC\Files\Filesystem::initMountPoints($uid);
- if ( $uid != \OCP\User::getUser() ) {
- $info = \OC\Files\Filesystem::getFileInfo($filename);
- $ownerView = new \OC\Files\View('/'.$uid.'/files');
- $filename = $ownerView->getPath($info['fileid']);
- }
- return array($uid, $filename);
+ return Filesystem::getView()->getUidAndFilename($filename);
}
/**
diff --git a/apps/files_sharing/lib/scanner.php b/apps/files_sharing/lib/scanner.php
index 1152c49755a..bd6a28a4934 100644
--- a/apps/files_sharing/lib/scanner.php
+++ b/apps/files_sharing/lib/scanner.php
@@ -35,7 +35,7 @@ class SharedScanner extends Scanner {
*
* @return array an array of metadata of the file
*/
- public function getData($path){
+ protected function getData($path){
$data = parent::getData($path);
$sourcePath = $this->storage->getSourcePath($path);
list($sourceStorage, $internalPath) = \OC\Files\Filesystem::resolvePath($sourcePath);
diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php
index 9a8968f2265..5b4736c21e1 100644
--- a/apps/files_sharing/lib/watcher.php
+++ b/apps/files_sharing/lib/watcher.php
@@ -24,6 +24,7 @@
*/
namespace OC\Files\Cache;
+use OCP\Files\Cache\ICacheEntry;
/**
* check the storage backends for updates and change the cache accordingly
@@ -38,7 +39,7 @@ class Shared_Watcher extends Watcher {
* Update the cache for changes to $path
*
* @param string $path
- * @param array $cachedData
+ * @param ICacheEntry $cachedData
*/
public function update($path, $cachedData) {
parent::update($path, $cachedData);
diff --git a/apps/files_sharing/tests/backend.php b/apps/files_sharing/tests/backend.php
index 0e151d9e76a..acb59855394 100644
--- a/apps/files_sharing/tests/backend.php
+++ b/apps/files_sharing/tests/backend.php
@@ -58,8 +58,10 @@ class Test_Files_Sharing_Backend extends TestCase {
}
protected function tearDown() {
- $this->view->unlink($this->filename);
- $this->view->deleteAll($this->folder);
+ if ($this->view) {
+ $this->view->unlink($this->filename);
+ $this->view->deleteAll($this->folder);
+ }
parent::tearDown();
}
diff --git a/apps/files_sharing/tests/external/cache.php b/apps/files_sharing/tests/external/cache.php
index 52e01677fa3..3e078bf3722 100644
--- a/apps/files_sharing/tests/external/cache.php
+++ b/apps/files_sharing/tests/external/cache.php
@@ -75,7 +75,9 @@ class Cache extends TestCase {
}
protected function tearDown() {
- $this->cache->clear();
+ if ($this->cache) {
+ $this->cache->clear();
+ }
parent::tearDown();
}
diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php
index 347ec0d2a7b..e01deeb60f4 100644
--- a/apps/files_sharing/tests/sharedmount.php
+++ b/apps/files_sharing/tests/sharedmount.php
@@ -48,8 +48,10 @@ class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase {
}
protected function tearDown() {
- $this->view->unlink($this->folder);
- $this->view->unlink($this->filename);
+ if ($this->view) {
+ $this->view->unlink($this->folder);
+ $this->view->unlink($this->filename);
+ }
parent::tearDown();
}
diff --git a/apps/files_sharing/tests/updater.php b/apps/files_sharing/tests/updater.php
index 02c5f487e0a..dd1f83c99a8 100644
--- a/apps/files_sharing/tests/updater.php
+++ b/apps/files_sharing/tests/updater.php
@@ -52,8 +52,10 @@ class Test_Files_Sharing_Updater extends OCA\Files_Sharing\Tests\TestCase {
}
protected function tearDown() {
- $this->view->unlink($this->filename);
- $this->view->deleteAll($this->folder);
+ if ($this->view) {
+ $this->view->unlink($this->filename);
+ $this->view->deleteAll($this->folder);
+ }
parent::tearDown();
}
diff --git a/apps/files_sharing/tests/watcher.php b/apps/files_sharing/tests/watcher.php
index 021f10bacca..247fb59f351 100644
--- a/apps/files_sharing/tests/watcher.php
+++ b/apps/files_sharing/tests/watcher.php
@@ -88,13 +88,15 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
+ if ($this->view) {
+ $fileinfo = $this->view->getFileInfo('container/shareddir');
+ \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
+ self::TEST_FILES_SHARING_API_USER2);
- $this->view->deleteAll('container');
+ $this->view->deleteAll('container');
- $this->ownerCache->clear();
+ $this->ownerCache->clear();
+ }
parent::tearDown();
}
diff --git a/apps/files_trashbin/lib/helper.php b/apps/files_trashbin/lib/helper.php
index 4d8b8b448ef..f56bbb12a91 100644
--- a/apps/files_trashbin/lib/helper.php
+++ b/apps/files_trashbin/lib/helper.php
@@ -27,6 +27,7 @@
namespace OCA\Files_Trashbin;
use OC\Files\FileInfo;
+use OCP\Constants;
class Helper
{
@@ -91,6 +92,8 @@ class Helper
'type' => $view->is_dir($dir . '/' . $entryName) ? 'dir' : 'file',
'directory' => ($dir === '/') ? '' : $dir,
'size' => $size,
+ 'etag' => '',
+ 'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE
);
if ($originalPath) {
$i['extraData'] = $originalPath.'/'.$id;
diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php
index fdca25ff457..ca3a8b178a2 100644
--- a/apps/files_trashbin/lib/trashbin.php
+++ b/apps/files_trashbin/lib/trashbin.php
@@ -63,7 +63,11 @@ class Trashbin {
* @param array $params
*/
public static function ensureFileScannedHook($params) {
- self::getUidAndFilename($params['path']);
+ try {
+ self::getUidAndFilename($params['path']);
+ } catch (NotFoundException $e) {
+ // nothing to scan for non existing files
+ }
}
/**
@@ -72,18 +76,7 @@ class Trashbin {
* @throws \OC\User\NoUserException
*/
public static function getUidAndFilename($filename) {
- $uid = \OC\Files\Filesystem::getOwner($filename);
- \OC\Files\Filesystem::initMountPoints($uid);
- if ($uid != \OCP\User::getUser()) {
- $info = \OC\Files\Filesystem::getFileInfo($filename);
- $ownerView = new \OC\Files\View('/' . $uid . '/files');
- try {
- $filename = $ownerView->getPath($info['fileid']);
- } catch (NotFoundException $e) {
- $filename = null;
- }
- }
- return [$uid, $filename];
+ return Filesystem::getView()->getUidAndFilename($filename);
}
/**
diff --git a/apps/files_versions/lib/storage.php b/apps/files_versions/lib/storage.php
index 74bf8fea49d..35b3110928b 100644
--- a/apps/files_versions/lib/storage.php
+++ b/apps/files_versions/lib/storage.php
@@ -41,10 +41,10 @@
namespace OCA\Files_Versions;
+use OC\Files\Filesystem;
use OCA\Files_Versions\AppInfo\Application;
use OCA\Files_Versions\Command\Expire;
use OCP\Lock\ILockingProvider;
-use OCP\Files\NotFoundException;
class Storage {
@@ -81,18 +81,7 @@ class Storage {
* @throws \OC\User\NoUserException
*/
public static function getUidAndFilename($filename) {
- $uid = \OC\Files\Filesystem::getOwner($filename);
- \OC\Files\Filesystem::initMountPoints($uid);
- if ( $uid != \OCP\User::getUser() ) {
- $info = \OC\Files\Filesystem::getFileInfo($filename);
- $ownerView = new \OC\Files\View('/'.$uid.'/files');
- try {
- $filename = $ownerView->getPath($info['fileid']);
- } catch (NotFoundException $e) {
- $filename = null;
- }
- }
- return [$uid, $filename];
+ return Filesystem::getView()->getUidAndFilename($filename);
}
/**
@@ -145,7 +134,12 @@ class Storage {
// to get the right target
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if ($ext === 'part') {
- $filename = substr($filename, 0, strlen($filename)-5);
+ $filename = substr($filename, 0, strlen($filename) - 5);
+ }
+
+ // we only handle existing files
+ if (! Filesystem::file_exists($filename) || Filesystem::is_dir($filename)) {
+ return false;
}
list($uid, $filename) = self::getUidAndFilename($filename);
@@ -153,15 +147,8 @@ class Storage {
$files_view = new \OC\Files\View('/'.$uid .'/files');
$users_view = new \OC\Files\View('/'.$uid);
- // check if filename is a directory
- if($files_view->is_dir($filename)) {
- return false;
- }
-
- // we should have a source file to work with, and the file shouldn't
- // be empty
- $fileExists = $files_view->file_exists($filename);
- if (!($fileExists && $files_view->filesize($filename) > 0)) {
+ // no use making versions for empty files
+ if ($files_view->filesize($filename) === 0) {
return false;
}
@@ -648,6 +635,11 @@ class Storage {
$expiration = self::getExpiration();
if($config->getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' && $expiration->isEnabled()) {
+
+ if (!Filesystem::file_exists($filename)) {
+ return false;
+ }
+
list($uid, $filename) = self::getUidAndFilename($filename);
if (empty($filename)) {
// file maybe renamed or deleted
diff --git a/apps/files_versions/tests/versions.php b/apps/files_versions/tests/versions.php
index 74d6006cfd9..ac922b74b9f 100644
--- a/apps/files_versions/tests/versions.php
+++ b/apps/files_versions/tests/versions.php
@@ -86,10 +86,12 @@ class Test_Files_Versioning extends \Test\TestCase {
}
protected function tearDown() {
- $this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files/');
- $this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files/');
- $this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files_versions/');
- $this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files_versions/');
+ if ($this->rootView) {
+ $this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files/');
+ $this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files/');
+ $this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files_versions/');
+ $this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files_versions/');
+ }
\OC_Hook::clear();
diff --git a/apps/provisioning_api/appinfo/info.xml b/apps/provisioning_api/appinfo/info.xml
index a8702aaf1ef..e75f032008c 100644
--- a/apps/provisioning_api/appinfo/info.xml
+++ b/apps/provisioning_api/appinfo/info.xml
@@ -17,10 +17,9 @@
<documentation>
<admin>admin-provisioning-api</admin>
</documentation>
- <version>0.4.0</version>
+ <version>0.4.1</version>
<types>
- <!-- this is used to disable the feature of enabling an app for specific groups only because this would break this app -->
- <filesystem/>
+ <prevent_group_restriction/>
</types>
<dependencies>
<owncloud min-version="9.0" max-version="9.0" />
diff --git a/core/command/security/importcertificate.php b/core/command/security/importcertificate.php
new file mode 100644
index 00000000000..a280eee6505
--- /dev/null
+++ b/core/command/security/importcertificate.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\Security;
+
+use OC\Core\Command\Base;
+use OCP\ICertificateManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class ImportCertificate extends Base {
+
+ /** @var ICertificateManager */
+ protected $certificateManager;
+
+ public function __construct(ICertificateManager $certificateManager) {
+ $this->certificateManager = $certificateManager;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('security:certificates:import')
+ ->setDescription('import trusted certificate')
+ ->addArgument(
+ 'path',
+ InputArgument::REQUIRED,
+ 'path to the certificate to import'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $path = $input->getArgument('path');
+
+ if (!file_exists($path)) {
+ $output->writeln('<error>certificate not found</error>');
+ return;
+ }
+
+ $certData = file_get_contents($path);
+ $name = basename($path);
+
+ $this->certificateManager->addCertificate($certData, $name);
+ }
+}
diff --git a/core/command/security/listcertificates.php b/core/command/security/listcertificates.php
new file mode 100644
index 00000000000..eb25de172bd
--- /dev/null
+++ b/core/command/security/listcertificates.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\Security;
+
+use OC\Core\Command\Base;
+use OCP\ICertificate;
+use OCP\ICertificateManager;
+use OCP\IL10N;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class ListCertificates extends Base {
+
+ /** @var ICertificateManager */
+ protected $certificateManager;
+ /** @var IL10N */
+ protected $l;
+
+ public function __construct(ICertificateManager $certificateManager, IL10N $l) {
+ $this->certificateManager = $certificateManager;
+ $this->l = $l;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('security:certificates')
+ ->setDescription('list trusted certificates');
+ parent::configure();
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $outputType = $input->getOption('output');
+ if ($outputType === self::OUTPUT_FORMAT_JSON || $outputType === self::OUTPUT_FORMAT_JSON_PRETTY) {
+ $certificates = array_map(function (ICertificate $certificate) {
+ return [
+ 'name' => $certificate->getName(),
+ 'common_name' => $certificate->getCommonName(),
+ 'organization' => $certificate->getOrganization(),
+ 'expire' => $certificate->getExpireDate()->format(\DateTime::ATOM),
+ 'issuer' => $certificate->getIssuerName(),
+ 'issuer_organization' => $certificate->getIssuerOrganization(),
+ 'issue_date' => $certificate->getIssueDate()->format(\DateTime::ATOM)
+ ];
+ }, $this->certificateManager->listCertificates());
+ if ($outputType === self::OUTPUT_FORMAT_JSON) {
+ $output->writeln(json_encode(array_values($certificates)));
+ } else {
+ $output->writeln(json_encode(array_values($certificates), JSON_PRETTY_PRINT));
+ }
+ } else {
+ $table = new Table($output);
+ $table->setHeaders([
+ 'File Name',
+ 'Common Name',
+ 'Organization',
+ 'Valid Until',
+ 'Issued By'
+ ]);
+
+ $rows = array_map(function (ICertificate $certificate) {
+ return [
+ $certificate->getName(),
+ $certificate->getCommonName(),
+ $certificate->getOrganization(),
+ $this->l->l('date', $certificate->getExpireDate()),
+ $certificate->getIssuerName()
+ ];
+ }, $this->certificateManager->listCertificates());
+ $table->setRows($rows);
+ $table->render();
+ }
+ }
+}
diff --git a/core/command/security/removecertificate.php b/core/command/security/removecertificate.php
new file mode 100644
index 00000000000..64078adab9c
--- /dev/null
+++ b/core/command/security/removecertificate.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\Security;
+
+use OC\Core\Command\Base;
+use OCP\ICertificateManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class RemoveCertificate extends Base {
+
+ /** @var ICertificateManager */
+ protected $certificateManager;
+
+ public function __construct(ICertificateManager $certificateManager) {
+ $this->certificateManager = $certificateManager;
+ parent::__construct();
+ }
+
+ protected function configure() {
+ $this
+ ->setName('security:certificates:remove')
+ ->setDescription('import trusted certificate')
+ ->addArgument(
+ 'name',
+ InputArgument::REQUIRED,
+ 'the file name of the certificate to remove'
+ );
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $name = $input->getArgument('name');
+
+ $this->certificateManager->removeCertificate($name);
+ }
+}
diff --git a/core/l10n/es.js b/core/l10n/es.js
index 070369bfb41..c3dc85bca9b 100644
--- a/core/l10n/es.js
+++ b/core/l10n/es.js
@@ -16,12 +16,15 @@ OC.L10N.register(
"Updated \"%s\" to %s" : "Se ha actualizado \"%s\" a %s",
"Repair warning: " : "Advertencia de reparación:",
"Repair error: " : "Error que reparar:",
+ "Set log level to debug" : "Establecer el nivel de registro a depuración",
+ "Reset log level" : "Restablecer el nivel de registro",
"Starting code integrity check" : "Comenzando comprobación de integridad de código",
"Finished code integrity check" : "Terminando comprobación de integridad de código",
"%s (3rdparty)" : "%s (tercer parte)",
"%s (incompatible)" : "%s (incompatible)",
"Following apps have been disabled: %s" : "Siguiendo aplicaciones ha sido deshabilitado: %s",
"Already up to date" : "Ya actualizado",
+ "Please select a file." : "Por favor, seleccione un archivo",
"File is too big" : "El archivo es demasiado grande",
"Invalid file provided" : "Archivo inválido",
"No image or file provided" : "No se especificó ningún archivo o imagen",
@@ -110,8 +113,15 @@ OC.L10N.register(
"Good password" : "Contraseña buena",
"Strong password" : "Contraseña muy buena",
"Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "Su servidor web aún no está configurado adecuadamente para permitir sincronización de archivos ya que la interfaz WebDAV parece no estar funcionando.",
+ "Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "Su servidor web no está configurado correctamente para resolver \"{url}\". Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
"This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Este servidor no tiene una conexión a Internet. Esto significa que algunas de las características como el montaje de almacenamiento externo, las notificaciones sobre actualizaciones o instalación de aplicaciones de terceros no funcionan. Podría no funcionar el acceso a los archivos de forma remota y el envío de correos electrónicos de notificación. Sugerimos habilitar la conexión a Internet de este servidor, si quiere tener todas las funciones.",
"Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Su directorio de datos y sus archivos probablemente sean accesibles desde Internet. El archivo .htaccess no está funcionando. Le sugerimos encarecidamente que configure su servidor web de modo que el directorio de datos ya no sea accesible o que mueva el directorio de datos fuera de la raíz de documentos del servidor web.",
+ "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "La memoria caché no ha sido configurada. Para aumentar su rendimiento por favor configure memcache si está disponible. Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
+ "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "/dev/urandom no es legible por PHP el mismo es altamente desalentado por razones de seguridad. Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
+ "Your PHP version ({version}) is no longer <a target=\"_blank\" href=\"{phpLink}\">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP." : "Su versión PHP ({version}) ya no es <a target=\"_blank\" href=\"{phpLink}\">respaldada por PHP</a>. Recomendamos actualizar su versión de PHP para aprovechar las actualizaciones de rendimiento y seguridad proporcionadas por PHP.",
+ "The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "La configuración de las cabeceras inversas del proxy son incorrectas, o está accediendo a ownCloud desde un proxy confiable. Si no está accediendo a ownCloud desde un proxy certificado y confiable, este es un problema de seguridad y puede permitirle a un hacker camuflar su dirección IP a ownCloud. Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
+ "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "memcached es un sistema de cache distribuido. pero ha sido instalado por error el modulo PHP memcache.\nConsulte <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki acerca de ambos modulos</a>",
+ "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Algunos archivos no han superado la comprobación de integridad. Para más información sobre cómo resolver este inconveniente consulte nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">Lista de archivos inválidos…</a> / <a href=\"{rescanEndpoint}\">Reescanear…</a>)",
"Error occurred while checking server setup" : "Ha ocurrido un error al revisar la configuración del servidor",
"The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "La \"{header}\" cabecera HTTP no está configurado para ser igual a \"{expected}\". Esto puede suponer un riesgo para la seguridad o la privacidad, por lo que se recomienda ajustar esta opción.",
"The \"Strict-Transport-Security\" HTTP header is not configured to least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\">security tips</a>." : "La cabecera HTTP \"Strict-Transport-Security\" no está configurada en al menos \"{segundos}\" segundos. Para una mejor seguridad recomendamos que habilite HSTS como es descripta en nuestros <a href=\"{docUrl}\">consejos de seguridad</a>.",
@@ -173,6 +183,7 @@ OC.L10N.register(
"Hello {name}" : "Hola {name}",
"_download %n file_::_download %n files_" : ["descargar %n ficheros","descargar %n archivos"],
"{version} is available. Get more information on how to update." : "Una nueva {version} está disponible. Obtenga más información sobre cómo actualizar.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "La actualización está en curso, salir de esta página podrían interrumpir el proceso en algunos entornos.",
"Updating {productName} to version {version}, this may take a while." : "Actualizando {productName} a la versión {version}. Esto puede tardar un poco.",
"An error occurred." : "Ocurrió un error.",
"Please reload the page." : "Recargue/Actualice la página",
@@ -182,6 +193,7 @@ OC.L10N.register(
"Couldn't reset password because the token is invalid" : "No se puede restablecer la contraseña porque el vale de identificación es inválido.",
"Couldn't reset password because the token is expired" : "No se puede restablecer la contraseña porque el vale de identificación ha caducado.",
"Couldn't send reset email. Please make sure your username is correct." : "No se pudo enviar el correo electrónico para el restablecimiento. Por favor, asegúrese de que su nombre de usuario es el correcto.",
+ "Could not send reset email because there is no email address for this username. Please contact your administrator." : "No se pudo enviar el correo electrónico de restablecimiento porque no hay una dirección de correo electrónico para este nombre de usuario. Póngase en contacto con un administrador.",
"%s password reset" : "%s restablecer contraseña",
"Use the following link to reset your password: {link}" : "Utilice el siguiente enlace para restablecer su contraseña: {link}",
"New password" : "Nueva contraseña",
@@ -264,6 +276,7 @@ OC.L10N.register(
"Contact your system administrator if this message persists or appeared unexpectedly." : "Contacte con su administrador de sistemas si este mensaje persiste o aparece de forma inesperada.",
"Thank you for your patience." : "Gracias por su paciencia.",
"You are accessing the server from an untrusted domain." : "Está accediendo al servidor desde un dominio inseguro.",
+ "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Contacte con su administrador. Si usted es el administrador, configure \"trusted_domains\" en config/config.php. En config/config.sample.php se encuentra un ejemplo para la configuración.",
"Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "Dependiendo de su configuración, como administrador, debería poder usar el botón de abajo para confiar en este dominio.",
"Add \"%s\" as trusted domain" : "Agregar \"%s\" como dominio de confianza",
"App update required" : "Es necesaria una actualización en la aplicación",
diff --git a/core/l10n/es.json b/core/l10n/es.json
index 12e45a828dd..ea75547aa64 100644
--- a/core/l10n/es.json
+++ b/core/l10n/es.json
@@ -14,12 +14,15 @@
"Updated \"%s\" to %s" : "Se ha actualizado \"%s\" a %s",
"Repair warning: " : "Advertencia de reparación:",
"Repair error: " : "Error que reparar:",
+ "Set log level to debug" : "Establecer el nivel de registro a depuración",
+ "Reset log level" : "Restablecer el nivel de registro",
"Starting code integrity check" : "Comenzando comprobación de integridad de código",
"Finished code integrity check" : "Terminando comprobación de integridad de código",
"%s (3rdparty)" : "%s (tercer parte)",
"%s (incompatible)" : "%s (incompatible)",
"Following apps have been disabled: %s" : "Siguiendo aplicaciones ha sido deshabilitado: %s",
"Already up to date" : "Ya actualizado",
+ "Please select a file." : "Por favor, seleccione un archivo",
"File is too big" : "El archivo es demasiado grande",
"Invalid file provided" : "Archivo inválido",
"No image or file provided" : "No se especificó ningún archivo o imagen",
@@ -108,8 +111,15 @@
"Good password" : "Contraseña buena",
"Strong password" : "Contraseña muy buena",
"Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "Su servidor web aún no está configurado adecuadamente para permitir sincronización de archivos ya que la interfaz WebDAV parece no estar funcionando.",
+ "Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "Su servidor web no está configurado correctamente para resolver \"{url}\". Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
"This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Este servidor no tiene una conexión a Internet. Esto significa que algunas de las características como el montaje de almacenamiento externo, las notificaciones sobre actualizaciones o instalación de aplicaciones de terceros no funcionan. Podría no funcionar el acceso a los archivos de forma remota y el envío de correos electrónicos de notificación. Sugerimos habilitar la conexión a Internet de este servidor, si quiere tener todas las funciones.",
"Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Su directorio de datos y sus archivos probablemente sean accesibles desde Internet. El archivo .htaccess no está funcionando. Le sugerimos encarecidamente que configure su servidor web de modo que el directorio de datos ya no sea accesible o que mueva el directorio de datos fuera de la raíz de documentos del servidor web.",
+ "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "La memoria caché no ha sido configurada. Para aumentar su rendimiento por favor configure memcache si está disponible. Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
+ "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "/dev/urandom no es legible por PHP el mismo es altamente desalentado por razones de seguridad. Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
+ "Your PHP version ({version}) is no longer <a target=\"_blank\" href=\"{phpLink}\">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP." : "Su versión PHP ({version}) ya no es <a target=\"_blank\" href=\"{phpLink}\">respaldada por PHP</a>. Recomendamos actualizar su versión de PHP para aprovechar las actualizaciones de rendimiento y seguridad proporcionadas por PHP.",
+ "The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "La configuración de las cabeceras inversas del proxy son incorrectas, o está accediendo a ownCloud desde un proxy confiable. Si no está accediendo a ownCloud desde un proxy certificado y confiable, este es un problema de seguridad y puede permitirle a un hacker camuflar su dirección IP a ownCloud. Más información puede ser encontrada en nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>.",
+ "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "memcached es un sistema de cache distribuido. pero ha sido instalado por error el modulo PHP memcache.\nConsulte <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki acerca de ambos modulos</a>",
+ "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Algunos archivos no han superado la comprobación de integridad. Para más información sobre cómo resolver este inconveniente consulte nuestra <a target=\"_blank\" href=\"{docLink}\">documentación</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">Lista de archivos inválidos…</a> / <a href=\"{rescanEndpoint}\">Reescanear…</a>)",
"Error occurred while checking server setup" : "Ha ocurrido un error al revisar la configuración del servidor",
"The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "La \"{header}\" cabecera HTTP no está configurado para ser igual a \"{expected}\". Esto puede suponer un riesgo para la seguridad o la privacidad, por lo que se recomienda ajustar esta opción.",
"The \"Strict-Transport-Security\" HTTP header is not configured to least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\">security tips</a>." : "La cabecera HTTP \"Strict-Transport-Security\" no está configurada en al menos \"{segundos}\" segundos. Para una mejor seguridad recomendamos que habilite HSTS como es descripta en nuestros <a href=\"{docUrl}\">consejos de seguridad</a>.",
@@ -171,6 +181,7 @@
"Hello {name}" : "Hola {name}",
"_download %n file_::_download %n files_" : ["descargar %n ficheros","descargar %n archivos"],
"{version} is available. Get more information on how to update." : "Una nueva {version} está disponible. Obtenga más información sobre cómo actualizar.",
+ "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "La actualización está en curso, salir de esta página podrían interrumpir el proceso en algunos entornos.",
"Updating {productName} to version {version}, this may take a while." : "Actualizando {productName} a la versión {version}. Esto puede tardar un poco.",
"An error occurred." : "Ocurrió un error.",
"Please reload the page." : "Recargue/Actualice la página",
@@ -180,6 +191,7 @@
"Couldn't reset password because the token is invalid" : "No se puede restablecer la contraseña porque el vale de identificación es inválido.",
"Couldn't reset password because the token is expired" : "No se puede restablecer la contraseña porque el vale de identificación ha caducado.",
"Couldn't send reset email. Please make sure your username is correct." : "No se pudo enviar el correo electrónico para el restablecimiento. Por favor, asegúrese de que su nombre de usuario es el correcto.",
+ "Could not send reset email because there is no email address for this username. Please contact your administrator." : "No se pudo enviar el correo electrónico de restablecimiento porque no hay una dirección de correo electrónico para este nombre de usuario. Póngase en contacto con un administrador.",
"%s password reset" : "%s restablecer contraseña",
"Use the following link to reset your password: {link}" : "Utilice el siguiente enlace para restablecer su contraseña: {link}",
"New password" : "Nueva contraseña",
@@ -262,6 +274,7 @@
"Contact your system administrator if this message persists or appeared unexpectedly." : "Contacte con su administrador de sistemas si este mensaje persiste o aparece de forma inesperada.",
"Thank you for your patience." : "Gracias por su paciencia.",
"You are accessing the server from an untrusted domain." : "Está accediendo al servidor desde un dominio inseguro.",
+ "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Contacte con su administrador. Si usted es el administrador, configure \"trusted_domains\" en config/config.php. En config/config.sample.php se encuentra un ejemplo para la configuración.",
"Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "Dependiendo de su configuración, como administrador, debería poder usar el botón de abajo para confiar en este dominio.",
"Add \"%s\" as trusted domain" : "Agregar \"%s\" como dominio de confianza",
"App update required" : "Es necesaria una actualización en la aplicación",
diff --git a/core/l10n/th_TH.js b/core/l10n/th_TH.js
index 6f01ab9f5f5..21421278ba1 100644
--- a/core/l10n/th_TH.js
+++ b/core/l10n/th_TH.js
@@ -116,8 +116,12 @@ OC.L10N.register(
"Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "เว็บเซิร์ฟเวอร์ของคุณไม่ได้ติดตั้งอย่างถูกต้องเพื่อที่จะแก้ไข \"{url}\" สามารถข้อมูลเพิ่มเติมได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
"This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "เซิร์ฟเวอร์นี้ไม่มีการเชื่อมต่ออินเทอร์เน็ตซึ่งหมายความว่าบางส่วนของคุณสมบัติ เช่น การจัดเก็บข้อมูลภายนอก การแจ้งเตือนเกี่ยวกับการปรับปรุงหรือการติดตั้งแอพพลิเคชันของบุคคลที่สามจะไม่ทำงาน การเข้าถึงไฟล์จากระยะไกลและการส่งอีเมล์แจ้งเตือนอาจจะไม่ทำงาน เราขอแนะนำให้เปิดใช้งานการเชื่อมต่ออินเทอร์เน็ตสำหรับเซิร์ฟเวอร์นี้ถ้าคุณต้องการใช้งานคุณสมบัติทั้งหมด",
"Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "ข้อมูลไดเรกทอรีและไฟล์ของคุณอาจจะสามารถเข้าถึงได้จากอินเทอร์เน็ต ขณะที่ htaccess ไฟล์ไม่ทำงาน เราขอแนะนำให้คุณกำหนดค่าเว็บเซิร์ฟเวอร์ของคุณในทางที่ข้อมูลไดเรกทอรีไม่สามารถเข้าถึงได้หรือคุณย้ายข้อมูลไดเรกทอรีไปยังนอกเว็บเซิร์ฟเวอร์หรือเอกสาร",
+ "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "ไม่ได้กำหนดค่าหน่วยความจำแคช เพื่อเพิ่มประสิทธิภาพของคุณโปรดกำหนดค่า memcache หากต้องการข้อมูลเพิ่มเติมสามารถอ่านได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
"/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "ไม่สามารถอ่าน /dev/urandom โดย PHP ซึ่งมีผลอย่างมากสำหรับเหตุผลด้านความปลอดภัย สามารถข้อมูลเพิ่มเติมได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
"Your PHP version ({version}) is no longer <a target=\"_blank\" href=\"{phpLink}\">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP." : "PHP ของคุณรุ่น ({version}) <a target=\"_blank\" href=\"{phpLink}\">ไม่สนับสนุน PHP</a> เราขอแนะนำให้อัพเกรดรุ่น PHP ของคุณ เพื่อปรับปรุงประสิทธิภาพการทำงานและเนื้อหาด้านความปลอดภัย",
+ "The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "การกำหนดค่าส่วนหัวของรีเวิร์สพร็อกซี่ไม่ถูกต้องหรือคุณกำลังเข้าถึง ownCloud จากพร็อกซี่ที่เชื่อถือได้ ถ้าคุณไม่ได้เข้าถึง ownCloud จากพร็อกซี่ที่เชื่อถือได้นี้เป็นปัญหาด้านความปลอดภัยและมันจะอณุญาตทำให้แฮกเกอร์ปลอมที่อยู่ IP ของพวกเขา ข้อมูลเพิ่มเติมสามารถอ่านได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
+ "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "การกำหนดค่า memcach ผิดพลาดเนื่องจากมีโมดูล PHP ของ memcache ได้ถูกติดตั้งไปแล้ว มีการติดตั้ง \\OC\\Memcache\\Memcached สนับสนุนเฉพาะ \"memcached\" แต่ไม่สนับสนุน \"memcache\" คุณสามารถดู <a target=\"_blank\" href=\"{wikiLink}\">ข้อมูลเกี่ยวกับทั้ง 2 โมดูล</a>",
+ "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "บางไฟล์ยังไม่ผ่านการตรวจสอบความสมบูรณ์ ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการแก้ไขปัญหาเหล่านี้สามารถอ่านได้จาก <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา (<a href=\"{codeIntegrityDownloadEndpoint}\">รายชื่อของไฟล์ที่ไม่ถูกต้อง…</a> / <a href=\"{rescanEndpoint}\">ค้นหาใหม่…</a>)",
"Error occurred while checking server setup" : "เกิดข้อผิดพลาดขณะที่ทำการตรวจสอบการติดตั้งเซิร์ฟเวอร์",
"The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "\"{header}\" ไม่ได้กำหนดค่าส่วนหัว Http ให้เท่ากับ \"{expected}\" นี่คือระบบการรักษาความปลอดภัยที่มีศักยภาพหรือลดความเสี่ยงที่จะเกิดขึ้นเราขอแนะนำให้ปรับการตั้งค่านี้",
"The \"Strict-Transport-Security\" HTTP header is not configured to least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\">security tips</a>." : "\"Strict-Transport-Security\" ส่วนหัว HTTP ไม่ได้กำหนดค่าให้น้อยกว่า \"{seconds}\" วินาที เพื่อความปลอดภัยที่เพิ่มขึ้นเราขอแนะนำให้เปิดใช้งาน HSTS ที่อธิบายไว้ใน <a href=\"{docUrl}\">เคล็ดลับการรักษาความปลอดภัย</a> ของเรา",
diff --git a/core/l10n/th_TH.json b/core/l10n/th_TH.json
index 0332736817f..d276bea4332 100644
--- a/core/l10n/th_TH.json
+++ b/core/l10n/th_TH.json
@@ -114,8 +114,12 @@
"Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "เว็บเซิร์ฟเวอร์ของคุณไม่ได้ติดตั้งอย่างถูกต้องเพื่อที่จะแก้ไข \"{url}\" สามารถข้อมูลเพิ่มเติมได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
"This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "เซิร์ฟเวอร์นี้ไม่มีการเชื่อมต่ออินเทอร์เน็ตซึ่งหมายความว่าบางส่วนของคุณสมบัติ เช่น การจัดเก็บข้อมูลภายนอก การแจ้งเตือนเกี่ยวกับการปรับปรุงหรือการติดตั้งแอพพลิเคชันของบุคคลที่สามจะไม่ทำงาน การเข้าถึงไฟล์จากระยะไกลและการส่งอีเมล์แจ้งเตือนอาจจะไม่ทำงาน เราขอแนะนำให้เปิดใช้งานการเชื่อมต่ออินเทอร์เน็ตสำหรับเซิร์ฟเวอร์นี้ถ้าคุณต้องการใช้งานคุณสมบัติทั้งหมด",
"Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "ข้อมูลไดเรกทอรีและไฟล์ของคุณอาจจะสามารถเข้าถึงได้จากอินเทอร์เน็ต ขณะที่ htaccess ไฟล์ไม่ทำงาน เราขอแนะนำให้คุณกำหนดค่าเว็บเซิร์ฟเวอร์ของคุณในทางที่ข้อมูลไดเรกทอรีไม่สามารถเข้าถึงได้หรือคุณย้ายข้อมูลไดเรกทอรีไปยังนอกเว็บเซิร์ฟเวอร์หรือเอกสาร",
+ "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "ไม่ได้กำหนดค่าหน่วยความจำแคช เพื่อเพิ่มประสิทธิภาพของคุณโปรดกำหนดค่า memcache หากต้องการข้อมูลเพิ่มเติมสามารถอ่านได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
"/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "ไม่สามารถอ่าน /dev/urandom โดย PHP ซึ่งมีผลอย่างมากสำหรับเหตุผลด้านความปลอดภัย สามารถข้อมูลเพิ่มเติมได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
"Your PHP version ({version}) is no longer <a target=\"_blank\" href=\"{phpLink}\">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP." : "PHP ของคุณรุ่น ({version}) <a target=\"_blank\" href=\"{phpLink}\">ไม่สนับสนุน PHP</a> เราขอแนะนำให้อัพเกรดรุ่น PHP ของคุณ เพื่อปรับปรุงประสิทธิภาพการทำงานและเนื้อหาด้านความปลอดภัย",
+ "The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>." : "การกำหนดค่าส่วนหัวของรีเวิร์สพร็อกซี่ไม่ถูกต้องหรือคุณกำลังเข้าถึง ownCloud จากพร็อกซี่ที่เชื่อถือได้ ถ้าคุณไม่ได้เข้าถึง ownCloud จากพร็อกซี่ที่เชื่อถือได้นี้เป็นปัญหาด้านความปลอดภัยและมันจะอณุญาตทำให้แฮกเกอร์ปลอมที่อยู่ IP ของพวกเขา ข้อมูลเพิ่มเติมสามารถอ่านได้ใน <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา",
+ "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "การกำหนดค่า memcach ผิดพลาดเนื่องจากมีโมดูล PHP ของ memcache ได้ถูกติดตั้งไปแล้ว มีการติดตั้ง \\OC\\Memcache\\Memcached สนับสนุนเฉพาะ \"memcached\" แต่ไม่สนับสนุน \"memcache\" คุณสามารถดู <a target=\"_blank\" href=\"{wikiLink}\">ข้อมูลเกี่ยวกับทั้ง 2 โมดูล</a>",
+ "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "บางไฟล์ยังไม่ผ่านการตรวจสอบความสมบูรณ์ ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการแก้ไขปัญหาเหล่านี้สามารถอ่านได้จาก <a target=\"_blank\" href=\"{docLink}\">เอกสาร</a> ของเรา (<a href=\"{codeIntegrityDownloadEndpoint}\">รายชื่อของไฟล์ที่ไม่ถูกต้อง…</a> / <a href=\"{rescanEndpoint}\">ค้นหาใหม่…</a>)",
"Error occurred while checking server setup" : "เกิดข้อผิดพลาดขณะที่ทำการตรวจสอบการติดตั้งเซิร์ฟเวอร์",
"The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "\"{header}\" ไม่ได้กำหนดค่าส่วนหัว Http ให้เท่ากับ \"{expected}\" นี่คือระบบการรักษาความปลอดภัยที่มีศักยภาพหรือลดความเสี่ยงที่จะเกิดขึ้นเราขอแนะนำให้ปรับการตั้งค่านี้",
"The \"Strict-Transport-Security\" HTTP header is not configured to least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\">security tips</a>." : "\"Strict-Transport-Security\" ส่วนหัว HTTP ไม่ได้กำหนดค่าให้น้อยกว่า \"{seconds}\" วินาที เพื่อความปลอดภัยที่เพิ่มขึ้นเราขอแนะนำให้เปิดใช้งาน HSTS ที่อธิบายไว้ใน <a href=\"{docUrl}\">เคล็ดลับการรักษาความปลอดภัย</a> ของเรา",
diff --git a/core/register_command.php b/core/register_command.php
index 2875af15caf..a7dd7414790 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -112,6 +112,10 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
$application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
+
+ $application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
+ $application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
+ $application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
} else {
$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getConfig()));
}
diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js
index 5b17429465a..fdbabd0ce70 100644
--- a/lib/l10n/cs_CZ.js
+++ b/lib/l10n/cs_CZ.js
@@ -56,6 +56,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "Archivy typu %s nejsou podporovány",
"Failed to open archive when installing app" : "Chyba při otevírání archivu během instalace aplikace",
"App does not provide an info.xml file" : "Aplikace neposkytuje soubor info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "Podpis nelze ověřit. Kontaktujte prosím vývojáře aplikace a zkontrolujte obrazovku administrace.",
"App can't be installed because of not allowed code in the App" : "Aplikace nemůže být nainstalována, protože obsahuje nepovolený kód",
"App can't be installed because it is not compatible with this version of ownCloud" : "Aplikace nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "Aplikace nemůže být nainstalována, protože obsahuje značku\n<shipped>\n\ntrue\n</shipped>\n\ncož není povoleno pro nedodávané aplikace",
diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json
index e1788a6bfe5..1ef95bfacb6 100644
--- a/lib/l10n/cs_CZ.json
+++ b/lib/l10n/cs_CZ.json
@@ -54,6 +54,7 @@
"Archives of type %s are not supported" : "Archivy typu %s nejsou podporovány",
"Failed to open archive when installing app" : "Chyba při otevírání archivu během instalace aplikace",
"App does not provide an info.xml file" : "Aplikace neposkytuje soubor info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "Podpis nelze ověřit. Kontaktujte prosím vývojáře aplikace a zkontrolujte obrazovku administrace.",
"App can't be installed because of not allowed code in the App" : "Aplikace nemůže být nainstalována, protože obsahuje nepovolený kód",
"App can't be installed because it is not compatible with this version of ownCloud" : "Aplikace nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "Aplikace nemůže být nainstalována, protože obsahuje značku\n<shipped>\n\ntrue\n</shipped>\n\ncož není povoleno pro nedodávané aplikace",
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index b37631114a0..67d08d8a3e3 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -56,6 +56,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "Los ficheros de tipo %s no son soportados",
"Failed to open archive when installing app" : "Falló la apertura ded fichero mientras se instalaba la aplicación",
"App does not provide an info.xml file" : "La aplicación no suministra un fichero info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "La firma no pudo ser evaluada. Por favor, contacte con el desarrollador de la aplicación y compruebe su pantalla de administración.",
"App can't be installed because of not allowed code in the App" : "La aplicación no puede ser instalada por tener código no autorizado en la aplicación",
"App can't be installed because it is not compatible with this version of ownCloud" : "La aplicación no se puede instalar porque no es compatible con esta versión de ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "La aplicación no se puede instalar porque contiene la etiqueta\n<shipped>\ntrue\n</shipped>\nque no está permitida para aplicaciones no distribuidas",
@@ -96,6 +97,7 @@ OC.L10N.register(
"Sharing %s failed, because %s is not a member of the group %s" : "Se falló al compartir %s, ya que %s no es miembro del grupo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Es necesario definir una contraseña para crear un enlace publico. Solo los enlaces protegidos están permitidos",
"Sharing %s failed, because sharing with links is not allowed" : "Se falló al compartir %s, ya que no está permitida la compartición con enlaces",
+ "Not allowed to create a federated share with the same user" : "No se permite crear un recurso compartido federado con el mismo usuario",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Se falló al compartir %s. No se pudo hallar %s, quizás haya un problema de conexión con el servidor.",
"Share type %s is not valid for %s" : "Compartir tipo %s no es válido para %s",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "La configuración de permisos para %s ha fallado, ya que los permisos superan los permisos dados a %s",
@@ -111,6 +113,9 @@ OC.L10N.register(
"Sharing %s failed, because resharing is not allowed" : "Se ha fallado al compartir %s, ya que volver a compartir no está permitido",
"Sharing %s failed, because the sharing backend for %s could not find its source" : "Se ha fallado al compartir %s porque el motor compartido para %s podría no encontrar su origen",
"Sharing %s failed, because the file could not be found in the file cache" : "Se ha fallado al compartir %s, ya que el archivo no pudo ser encontrado en el cache de archivo",
+ "Cannot increase permissions of %s" : "No se pueden incrementar los permisos de %s",
+ "Expiration date is in the past" : "Ha pasado la fecha de caducidad",
+ "Cannot set expiration date more than %s days in the future" : "No se puede fijar la fecha de caducidad más de %s días en el futuro.",
"Could not find category \"%s\"" : "No puede encontrar la categoría \"%s\"",
"Apps" : "Aplicaciones",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Solo los siguientes caracteres están permitidos en un nombre de usuario: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"",
@@ -149,6 +154,8 @@ OC.L10N.register(
"Could not obtain lock type %d on \"%s\"." : "No se pudo realizar el bloqueo %d en \"%s\".",
"Storage unauthorized. %s" : "Almacenamiento no autorizado. %s",
"Storage incomplete configuration. %s" : "Configuración de almacenamiento incompleta. %s",
- "Storage not available" : "Almacenamiento no disponible"
+ "Storage connection error. %s" : "Error de conexión de almacenamiento. %s",
+ "Storage not available" : "Almacenamiento no disponible",
+ "Storage connection timeout. %s" : "Tiempo de conexión de almacenamiento agotado. %s"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 9be893bbb60..73d3ac59512 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -54,6 +54,7 @@
"Archives of type %s are not supported" : "Los ficheros de tipo %s no son soportados",
"Failed to open archive when installing app" : "Falló la apertura ded fichero mientras se instalaba la aplicación",
"App does not provide an info.xml file" : "La aplicación no suministra un fichero info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "La firma no pudo ser evaluada. Por favor, contacte con el desarrollador de la aplicación y compruebe su pantalla de administración.",
"App can't be installed because of not allowed code in the App" : "La aplicación no puede ser instalada por tener código no autorizado en la aplicación",
"App can't be installed because it is not compatible with this version of ownCloud" : "La aplicación no se puede instalar porque no es compatible con esta versión de ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "La aplicación no se puede instalar porque contiene la etiqueta\n<shipped>\ntrue\n</shipped>\nque no está permitida para aplicaciones no distribuidas",
@@ -94,6 +95,7 @@
"Sharing %s failed, because %s is not a member of the group %s" : "Se falló al compartir %s, ya que %s no es miembro del grupo %s",
"You need to provide a password to create a public link, only protected links are allowed" : "Es necesario definir una contraseña para crear un enlace publico. Solo los enlaces protegidos están permitidos",
"Sharing %s failed, because sharing with links is not allowed" : "Se falló al compartir %s, ya que no está permitida la compartición con enlaces",
+ "Not allowed to create a federated share with the same user" : "No se permite crear un recurso compartido federado con el mismo usuario",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Se falló al compartir %s. No se pudo hallar %s, quizás haya un problema de conexión con el servidor.",
"Share type %s is not valid for %s" : "Compartir tipo %s no es válido para %s",
"Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "La configuración de permisos para %s ha fallado, ya que los permisos superan los permisos dados a %s",
@@ -109,6 +111,9 @@
"Sharing %s failed, because resharing is not allowed" : "Se ha fallado al compartir %s, ya que volver a compartir no está permitido",
"Sharing %s failed, because the sharing backend for %s could not find its source" : "Se ha fallado al compartir %s porque el motor compartido para %s podría no encontrar su origen",
"Sharing %s failed, because the file could not be found in the file cache" : "Se ha fallado al compartir %s, ya que el archivo no pudo ser encontrado en el cache de archivo",
+ "Cannot increase permissions of %s" : "No se pueden incrementar los permisos de %s",
+ "Expiration date is in the past" : "Ha pasado la fecha de caducidad",
+ "Cannot set expiration date more than %s days in the future" : "No se puede fijar la fecha de caducidad más de %s días en el futuro.",
"Could not find category \"%s\"" : "No puede encontrar la categoría \"%s\"",
"Apps" : "Aplicaciones",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Solo los siguientes caracteres están permitidos en un nombre de usuario: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"",
@@ -147,6 +152,8 @@
"Could not obtain lock type %d on \"%s\"." : "No se pudo realizar el bloqueo %d en \"%s\".",
"Storage unauthorized. %s" : "Almacenamiento no autorizado. %s",
"Storage incomplete configuration. %s" : "Configuración de almacenamiento incompleta. %s",
- "Storage not available" : "Almacenamiento no disponible"
+ "Storage connection error. %s" : "Error de conexión de almacenamiento. %s",
+ "Storage not available" : "Almacenamiento no disponible",
+ "Storage connection timeout. %s" : "Tiempo de conexión de almacenamiento agotado. %s"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js
index 1465d9efd4a..9a8d68412de 100644
--- a/lib/l10n/fr.js
+++ b/lib/l10n/fr.js
@@ -55,6 +55,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "Les archives de type %s ne sont pas prises en charge",
"Failed to open archive when installing app" : "Échec de l'ouverture de l'archive lors de l'installation de l'application",
"App does not provide an info.xml file" : "L'application ne fournit pas de fichier info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "La signature n'a pas pu être vérifiée. Merci de contacter le développeur de l'application et de vérifier votre écran admin.",
"App can't be installed because of not allowed code in the App" : "L'application ne peut être installée car elle contient du code non-autorisé",
"App can't be installed because it is not compatible with this version of ownCloud" : "L'application ne peut être installée car elle n'est pas compatible avec cette version de ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "L'application ne peut être installée car elle contient la balise <shipped>true</shipped> qui n'est pas autorisée pour les applications non incluses par défaut",
diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json
index 217d9f54724..0b0cd925822 100644
--- a/lib/l10n/fr.json
+++ b/lib/l10n/fr.json
@@ -53,6 +53,7 @@
"Archives of type %s are not supported" : "Les archives de type %s ne sont pas prises en charge",
"Failed to open archive when installing app" : "Échec de l'ouverture de l'archive lors de l'installation de l'application",
"App does not provide an info.xml file" : "L'application ne fournit pas de fichier info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "La signature n'a pas pu être vérifiée. Merci de contacter le développeur de l'application et de vérifier votre écran admin.",
"App can't be installed because of not allowed code in the App" : "L'application ne peut être installée car elle contient du code non-autorisé",
"App can't be installed because it is not compatible with this version of ownCloud" : "L'application ne peut être installée car elle n'est pas compatible avec cette version de ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "L'application ne peut être installée car elle contient la balise <shipped>true</shipped> qui n'est pas autorisée pour les applications non incluses par défaut",
diff --git a/lib/l10n/it.js b/lib/l10n/it.js
index 1be68c0d847..e12e621f61f 100644
--- a/lib/l10n/it.js
+++ b/lib/l10n/it.js
@@ -56,6 +56,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "Gli archivi di tipo %s non sono supportati",
"Failed to open archive when installing app" : "Apertura archivio non riuscita durante l'installazione dell'applicazione",
"App does not provide an info.xml file" : "L'applicazione non fornisce un file info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "La firma non può essere verificata. Contatta lo sviluppatore dell'applicazione e controlla la schermata di amministrazione.",
"App can't be installed because of not allowed code in the App" : "L'applicazione non può essere installata a causa di codice non consentito al suo interno",
"App can't be installed because it is not compatible with this version of ownCloud" : "L'applicazione non può essere installata poiché non è compatibile con questa versione di ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "L'applicazione non può essere installata poiché contiene il tag <shipped>true<shipped> che è consentito per le applicazioni native",
diff --git a/lib/l10n/it.json b/lib/l10n/it.json
index d9d9c6b3240..a76e19d46f5 100644
--- a/lib/l10n/it.json
+++ b/lib/l10n/it.json
@@ -54,6 +54,7 @@
"Archives of type %s are not supported" : "Gli archivi di tipo %s non sono supportati",
"Failed to open archive when installing app" : "Apertura archivio non riuscita durante l'installazione dell'applicazione",
"App does not provide an info.xml file" : "L'applicazione non fornisce un file info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "La firma non può essere verificata. Contatta lo sviluppatore dell'applicazione e controlla la schermata di amministrazione.",
"App can't be installed because of not allowed code in the App" : "L'applicazione non può essere installata a causa di codice non consentito al suo interno",
"App can't be installed because it is not compatible with this version of ownCloud" : "L'applicazione non può essere installata poiché non è compatibile con questa versione di ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "L'applicazione non può essere installata poiché contiene il tag <shipped>true<shipped> che è consentito per le applicazioni native",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index 435aee8e6f2..0c11cf36101 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -56,6 +56,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "Arquivos do tipo %s não são suportados",
"Failed to open archive when installing app" : "Falha para abrir o arquivo enquanto instalava o aplicativo",
"App does not provide an info.xml file" : "O aplicativo não fornece um arquivo info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "A assinatura não pode ser verificada. Por favor entre em contato com o desenvolvedor do aplicativo e verificar sua tela de administração.",
"App can't be installed because of not allowed code in the App" : "O aplicativo não pode ser instalado por causa do código não permitido no Aplivativo",
"App can't be installed because it is not compatible with this version of ownCloud" : "O aplicativo não pode ser instalado porque não é compatível com esta versão do ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "O aplicativo não pode ser instalado porque ele contém a marca <shipped>verdadeiro</shipped> que não é permitido para aplicações não embarcadas",
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index d3a7f463841..e75cb070f0e 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -54,6 +54,7 @@
"Archives of type %s are not supported" : "Arquivos do tipo %s não são suportados",
"Failed to open archive when installing app" : "Falha para abrir o arquivo enquanto instalava o aplicativo",
"App does not provide an info.xml file" : "O aplicativo não fornece um arquivo info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "A assinatura não pode ser verificada. Por favor entre em contato com o desenvolvedor do aplicativo e verificar sua tela de administração.",
"App can't be installed because of not allowed code in the App" : "O aplicativo não pode ser instalado por causa do código não permitido no Aplivativo",
"App can't be installed because it is not compatible with this version of ownCloud" : "O aplicativo não pode ser instalado porque não é compatível com esta versão do ownCloud",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "O aplicativo não pode ser instalado porque ele contém a marca <shipped>verdadeiro</shipped> que não é permitido para aplicações não embarcadas",
diff --git a/lib/l10n/sq.js b/lib/l10n/sq.js
index a6f377529e1..e8fd3d09327 100644
--- a/lib/l10n/sq.js
+++ b/lib/l10n/sq.js
@@ -56,6 +56,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "Nuk mbulohen arkivat e llojit %s",
"Failed to open archive when installing app" : "Dështoi në hapje arkivi teksa instalohej aplikacioni",
"App does not provide an info.xml file" : "Aplikacioni s’ofron kartele të vlefshme .xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "Nënshkrimi s’u kontrollua dot. Ju lutemi, lidhuni me zhvilluesin e aplikacionit dhe kontrolloni te skena juaj e përgjegjësit.",
"App can't be installed because of not allowed code in the App" : "Aplikacioni s’mund të instalohet, për shkak kodi të palejuar te Aplikacioni",
"App can't be installed because it is not compatible with this version of ownCloud" : "Aplikacioni s’mund të instalohet, ngaqë s’është i përputhshëm me këtë version të ownCloud-it",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "Aplikacioni s’mund të instalohet, ngaqë përmban etiketën <shipped>true</shipped> e cila nuk lejohet për aplikacione që s’janë hedhur në qarkullim",
diff --git a/lib/l10n/sq.json b/lib/l10n/sq.json
index c173372f1bc..8c20c179813 100644
--- a/lib/l10n/sq.json
+++ b/lib/l10n/sq.json
@@ -54,6 +54,7 @@
"Archives of type %s are not supported" : "Nuk mbulohen arkivat e llojit %s",
"Failed to open archive when installing app" : "Dështoi në hapje arkivi teksa instalohej aplikacioni",
"App does not provide an info.xml file" : "Aplikacioni s’ofron kartele të vlefshme .xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "Nënshkrimi s’u kontrollua dot. Ju lutemi, lidhuni me zhvilluesin e aplikacionit dhe kontrolloni te skena juaj e përgjegjësit.",
"App can't be installed because of not allowed code in the App" : "Aplikacioni s’mund të instalohet, për shkak kodi të palejuar te Aplikacioni",
"App can't be installed because it is not compatible with this version of ownCloud" : "Aplikacioni s’mund të instalohet, ngaqë s’është i përputhshëm me këtë version të ownCloud-it",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "Aplikacioni s’mund të instalohet, ngaqë përmban etiketën <shipped>true</shipped> e cila nuk lejohet për aplikacione që s’janë hedhur në qarkullim",
diff --git a/lib/l10n/th_TH.js b/lib/l10n/th_TH.js
index 64adbdc8b66..c49d194b517 100644
--- a/lib/l10n/th_TH.js
+++ b/lib/l10n/th_TH.js
@@ -56,6 +56,7 @@ OC.L10N.register(
"Archives of type %s are not supported" : "ประเภทข้อมูลที่เก็บของ %s ไม่ได้รับการสนับสนุน",
"Failed to open archive when installing app" : "ไม่สามารถเปิดที่เก็บข้อมูลเมื่อกำลังติดตั้งแอพพลิเคชั่น",
"App does not provide an info.xml file" : "แอพฯ ไม่ได้ระบุไฟล์ info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "ไม่สามารถตรวจสอบลายเซ็น โปรดติดต่อนักพัฒนาแอพพลิเคชันและตรวจสอบหน้าจอแผงควบคุมระบบของคุณ",
"App can't be installed because of not allowed code in the App" : "ไม่สามารถติดตั้งแอพพลิเคชันเพราะไม่ได้อนุญาตรหัสในแอพพลิเคชัน",
"App can't be installed because it is not compatible with this version of ownCloud" : "ไม่สามารถติดตั้งแอพพลิเคชันเพราะมันเข้ากันไม่ได้กับรุ่นของ ownCloud นี้",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "ไม่สามารถติดตั้งแอพพลิเคชันเพราะมันมี <shipped>จริง</shipped> แท็กที่ไม่ได้รับอนุญาต",
diff --git a/lib/l10n/th_TH.json b/lib/l10n/th_TH.json
index a502baa6cf0..4da887a615c 100644
--- a/lib/l10n/th_TH.json
+++ b/lib/l10n/th_TH.json
@@ -54,6 +54,7 @@
"Archives of type %s are not supported" : "ประเภทข้อมูลที่เก็บของ %s ไม่ได้รับการสนับสนุน",
"Failed to open archive when installing app" : "ไม่สามารถเปิดที่เก็บข้อมูลเมื่อกำลังติดตั้งแอพพลิเคชั่น",
"App does not provide an info.xml file" : "แอพฯ ไม่ได้ระบุไฟล์ info.xml",
+ "Signature could not get checked. Please contact the app developer and check your admin screen." : "ไม่สามารถตรวจสอบลายเซ็น โปรดติดต่อนักพัฒนาแอพพลิเคชันและตรวจสอบหน้าจอแผงควบคุมระบบของคุณ",
"App can't be installed because of not allowed code in the App" : "ไม่สามารถติดตั้งแอพพลิเคชันเพราะไม่ได้อนุญาตรหัสในแอพพลิเคชัน",
"App can't be installed because it is not compatible with this version of ownCloud" : "ไม่สามารถติดตั้งแอพพลิเคชันเพราะมันเข้ากันไม่ได้กับรุ่นของ ownCloud นี้",
"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" : "ไม่สามารถติดตั้งแอพพลิเคชันเพราะมันมี <shipped>จริง</shipped> แท็กที่ไม่ได้รับอนุญาต",
diff --git a/lib/private/app/appmanager.php b/lib/private/app/appmanager.php
index 7cb945784bc..bf07a2ef548 100644
--- a/lib/private/app/appmanager.php
+++ b/lib/private/app/appmanager.php
@@ -35,6 +35,18 @@ use OCP\IUserSession;
class AppManager implements IAppManager {
+ /**
+ * Apps with these types can not be enabled for certain groups only
+ * @var string[]
+ */
+ protected $protectedAppTypes = [
+ 'filesystem',
+ 'prelogin',
+ 'authentication',
+ 'logging',
+ 'prevent_group_restriction',
+ ];
+
/** @var \OCP\IUserSession */
private $userSession;
@@ -197,8 +209,17 @@ class AppManager implements IAppManager {
*
* @param string $appId
* @param \OCP\IGroup[] $groups
+ * @throws \Exception if app can't be enabled for groups
*/
public function enableAppForGroups($appId, $groups) {
+ $info = $this->getAppInfo($appId);
+ if (!empty($info['types'])) {
+ $protectedTypes = array_intersect($this->protectedAppTypes, $info['types']);
+ if (!empty($protectedTypes)) {
+ throw new \Exception("$appId can't be enabled for groups.");
+ }
+ }
+
$groupIds = array_map(function ($group) {
/** @var \OCP\IGroup $group */
return $group->getGID();
diff --git a/lib/private/cache/cappedmemorycache.php b/lib/private/cache/cappedmemorycache.php
index cfaf78c51df..e3efbf76a23 100644
--- a/lib/private/cache/cappedmemorycache.php
+++ b/lib/private/cache/cappedmemorycache.php
@@ -64,8 +64,8 @@ class CappedMemoryCache implements ICache, \ArrayAccess {
return $this->hasKey($offset);
}
- public function offsetGet($offset) {
- return $this->get($offset);
+ public function &offsetGet($offset) {
+ return $this->cache[$offset];
}
public function offsetSet($offset, $value) {
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
index 7a976e18888..527c8b76e52 100644
--- a/lib/private/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -33,6 +33,8 @@
namespace OC\Files\Cache;
+use OCP\Files\Cache\ICache;
+use OCP\Files\Cache\ICacheEntry;
use \OCP\Files\IMimeTypeLoader;
use OCP\IDBConnection;
@@ -46,12 +48,7 @@ use OCP\IDBConnection;
* - Updater: listens to changes made to the filesystem inside of the ownCloud instance and updates the cache where needed
* - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
*/
-class Cache {
- const NOT_FOUND = 0;
- const PARTIAL = 1; //only partial data available, file not cached in the database
- const SHALLOW = 2; //folder in cache, but not all child files are completely scanned
- const COMPLETE = 3;
-
+class Cache implements ICache {
/**
* @var array partial data for the cache
*/
@@ -105,28 +102,8 @@ class Cache {
/**
* get the stored metadata of a file or folder
*
- * the returned cache entry contains at least the following values:
- * [
- * 'fileid' => int, the numeric id of a file (see getId)
- * 'storage' => int, the numeric id of the storage the file is stored on
- * 'path' => string, the path of the file within the storage ('foo/bar.txt')
- * 'name' => string, the basename of a file ('bar.txt)
- * 'mimetype' => string, the full mimetype of the file ('text/plain')
- * 'mimepart' => string, the first half of the mimetype ('text')
- * 'size' => int, the size of the file or folder in bytes
- * 'mtime' => int, the last modified date of the file as unix timestamp as shown in the ui
- * 'storage_mtime' => int, the last modified date of the file as unix timestamp as stored on the storage
- * Note that when a file is updated we also update the mtime of all parent folders to make it visible to the user which folder has had updates most recently
- * This can differ from the mtime on the underlying storage which usually only changes when a direct child is added, removed or renamed
- * 'etag' => string, the etag for the file
- * An etag is used for change detection of files and folders, an etag of a file changes whenever the content of the file changes
- * Etag for folders change whenever a file in the folder has changed
- * 'permissions' int, the permissions for the file stored as bitwise combination of \OCP\PERMISSION_READ, \OCP\PERMISSION_CREATE
- * \OCP\PERMISSION_UPDATE, \OCP\PERMISSION_DELETE and \OCP\PERMISSION_SHARE
- * ]
- *
* @param string | int $file either the path of a file or folder or the file id for a file or folder
- * @return array|false the cache entry as array of false if the file is not found in the cache
+ * @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
*/
public function get($file) {
if (is_string($file) or $file == '') {
@@ -156,6 +133,7 @@ class Cache {
if (isset($this->partial[$file])) {
$data = $this->partial[$file];
}
+ return $data;
} else {
//fix types
$data['fileid'] = (int)$data['fileid'];
@@ -171,16 +149,15 @@ class Cache {
$data['storage_mtime'] = $data['mtime'];
}
$data['permissions'] = (int)$data['permissions'];
+ return new CacheEntry($data);
}
-
- return $data;
}
/**
* get the metadata of all files stored in $folder
*
* @param string $folder
- * @return array
+ * @return ICacheEntry[]
*/
public function getFolderContents($folder) {
$fileId = $this->getId($folder);
@@ -191,7 +168,7 @@ class Cache {
* get the metadata of all files stored in $folder
*
* @param int $fileId the file id of the folder
- * @return array
+ * @return ICacheEntry[]
*/
public function getFolderContentsById($fileId) {
if ($fileId > -1) {
@@ -211,7 +188,9 @@ class Cache {
$file['storage_mtime'] = (int)$file['storage_mtime'];
$file['size'] = 0 + $file['size'];
}
- return $files;
+ return array_map(function (array $data) {
+ return new CacheEntry($data);
+ }, $files);
} else {
return array();
}
@@ -392,7 +371,7 @@ class Cache {
return -1;
} else {
$parent = $this->getParentPath($file);
- return (int) $this->getId($parent);
+ return (int)$this->getId($parent);
}
}
@@ -481,12 +460,12 @@ class Cache {
/**
* Move a file or folder in the cache
*
- * @param \OC\Files\Cache\Cache $sourceCache
+ * @param \OCP\Files\Cache\ICache $sourceCache
* @param string $sourcePath
* @param string $targetPath
* @throws \OC\DatabaseException
*/
- public function moveFromCache(Cache $sourceCache, $sourcePath, $targetPath) {
+ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
// normalize source and target
$sourcePath = $this->normalize($sourcePath);
$targetPath = $this->normalize($targetPath);
@@ -571,7 +550,7 @@ class Cache {
* search for files matching $pattern
*
* @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
- * @return array an array of cache entries where the name matches the search pattern
+ * @return ICacheEntry[] an array of cache entries where the name matches the search pattern
*/
public function search($pattern) {
// normalize pattern
@@ -594,7 +573,9 @@ class Cache {
$row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
$files[] = $row;
}
- return $files;
+ return array_map(function(array $data) {
+ return new CacheEntry($data);
+ }, $files);
}
/**
@@ -602,7 +583,7 @@ class Cache {
*
* @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
* where it will search for all mimetypes in the group ('image/*')
- * @return array an array of cache entries where the mimetype matches the search
+ * @return ICacheEntry[] an array of cache entries where the mimetype matches the search
*/
public function searchByMime($mimetype) {
if (strpos($mimetype, '/')) {
@@ -620,7 +601,9 @@ class Cache {
$row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
$files[] = $row;
}
- return $files;
+ return array_map(function (array $data) {
+ return new CacheEntry($data);
+ }, $files);
}
/**
@@ -630,7 +613,7 @@ class Cache {
*
* @param string|int $tag name or tag id
* @param string $userId owner of the tags
- * @return array file data
+ * @return ICacheEntry[] file data
*/
public function searchByTag($tag, $userId) {
$sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, ' .
@@ -665,7 +648,9 @@ class Cache {
while ($row = $result->fetch()) {
$files[] = $row;
}
- return $files;
+ return array_map(function (array $data) {
+ return new CacheEntry($data);
+ }, $files);
}
/**
diff --git a/lib/private/files/cache/cacheentry.php b/lib/private/files/cache/cacheentry.php
new file mode 100644
index 00000000000..3db3b3f8aa0
--- /dev/null
+++ b/lib/private/files/cache/cacheentry.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Cache;
+
+use OCP\Files\Cache\ICacheEntry;
+
+/**
+ * meta data for a file or folder
+ */
+class CacheEntry implements ICacheEntry, \ArrayAccess {
+ /**
+ * @var array
+ */
+ private $data;
+
+ public function __construct(array $data) {
+ $this->data = $data;
+ }
+
+ public function offsetSet($offset, $value) {
+ $this->data[$offset] = $value;
+ }
+
+ public function offsetExists($offset) {
+ return isset($this->data[$offset]);
+ }
+
+ public function offsetUnset($offset) {
+ unset($this->data[$offset]);
+ }
+
+ public function offsetGet($offset) {
+ if (isset($this->data[$offset])) {
+ return $this->data[$offset];
+ } else {
+ return null;
+ }
+ }
+
+ public function getId() {
+ return (int)$this->data['fileid'];
+ }
+
+ public function getStorageId() {
+ return $this->data['storage'];
+ }
+
+
+ public function getPath() {
+ return $this->data['path'];
+ }
+
+
+ public function getName() {
+ return $this->data['name'];
+ }
+
+
+ public function getMimeType() {
+ return $this->data['mimetype'];
+ }
+
+
+ public function getMimePart() {
+ return $this->data['mimepart'];
+ }
+
+ public function getSize() {
+ return $this->data['size'];
+ }
+
+ public function getMTime() {
+ return $this->data['mtime'];
+ }
+
+ public function getStorageMTime() {
+ return $this->data['storage_mtime'];
+ }
+
+ public function getEtag() {
+ return $this->data['etag'];
+ }
+
+ public function getPermissions() {
+ return $this->data['permissions'];
+ }
+
+ public function isEncrypted() {
+ return isset($this->data['encrypted']) && $this->data['encrypted'];
+ }
+
+ public function getData() {
+ return $this->data;
+ }
+}
diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php
index 693896fccfb..ae92504ddd6 100644
--- a/lib/private/files/cache/homecache.php
+++ b/lib/private/files/cache/homecache.php
@@ -26,6 +26,8 @@
namespace OC\Files\Cache;
+use OCP\Files\Cache\ICacheEntry;
+
class HomeCache extends Cache {
/**
* get the size of a folder and set it in the cache
@@ -67,7 +69,7 @@ class HomeCache extends Cache {
/**
* @param string $path
- * @return array
+ * @return ICacheEntry
*/
public function get($path) {
$data = parent::get($path);
diff --git a/lib/private/files/cache/propagator.php b/lib/private/files/cache/propagator.php
index 56abcdadee2..1e85a2ecc8b 100644
--- a/lib/private/files/cache/propagator.php
+++ b/lib/private/files/cache/propagator.php
@@ -21,10 +21,12 @@
namespace OC\Files\Cache;
+use OCP\Files\Cache\IPropagator;
+
/**
* Propagate etags and mtimes within the storage
*/
-class Propagator {
+class Propagator implements IPropagator {
/**
* @var \OC\Files\Storage\Storage
*/
@@ -41,7 +43,7 @@ class Propagator {
/**
* @param string $internalPath
* @param int $time
- * @return array[] all propagated entries
+ * @return array[] all propagated cache entries
*/
public function propagateChange($internalPath, $time) {
$cache = $this->storage->getCache($internalPath);
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index 79f749394f1..1c50978a2e5 100644
--- a/lib/private/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -37,6 +37,8 @@ namespace OC\Files\Cache;
use OC\Files\Filesystem;
use OC\Hooks\BasicEmitter;
use OCP\Config;
+use OCP\Files\Cache\IScanner;
+use OCP\Files\Storage\ILockingStorage;
use OCP\Lock\ILockingProvider;
/**
@@ -50,7 +52,7 @@ use OCP\Lock\ILockingProvider;
*
* @package OC\Files\Cache
*/
-class Scanner extends BasicEmitter {
+class Scanner extends BasicEmitter implements IScanner {
/**
* @var \OC\Files\Storage\Storage $storage
*/
@@ -81,12 +83,6 @@ class Scanner extends BasicEmitter {
*/
protected $lockingProvider;
- const SCAN_RECURSIVE = true;
- const SCAN_SHALLOW = false;
-
- const REUSE_ETAG = 1;
- const REUSE_SIZE = 2;
-
public function __construct(\OC\Files\Storage\Storage $storage) {
$this->storage = $storage;
$this->storageId = $this->storage->getId();
@@ -112,7 +108,7 @@ class Scanner extends BasicEmitter {
* @param string $path
* @return array an array of metadata of the file
*/
- public function getData($path) {
+ protected function getData($path) {
$data = $this->storage->getMetaData($path);
if (is_null($data)) {
\OCP\Util::writeLog('OC\Files\Cache\Scanner', "!!! Path '$path' is not accessible or present !!!", \OCP\Util::DEBUG);
@@ -133,16 +129,27 @@ class Scanner extends BasicEmitter {
* @throws \OCP\Lock\LockedException
*/
public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) {
- if (!self::isPartialFile($file)
- and !Filesystem::isFileBlacklisted($file)
- ) {
+
+ // only proceed if $file is not a partial file nor a blacklisted file
+ if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
+
+ //acquire a lock
if ($lock) {
- $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
}
- $this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId));
- \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
+
$data = $this->getData($file);
+
if ($data) {
+
+ // pre-emit only if it was a file. By that we avoid counting/treating folders as files
+ if ($data['mimetype'] !== 'httpd/unix-directory') {
+ $this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId));
+ \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
+ }
+
$parent = dirname($file);
if ($parent === '.' or $parent === '/') {
$parent = '';
@@ -160,6 +167,7 @@ class Scanner extends BasicEmitter {
$data['parent'] = $parentId;
}
if (is_null($cacheData)) {
+ /** @var CacheEntry $cacheData */
$cacheData = $this->cache->get($file);
}
if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) {
@@ -182,7 +190,7 @@ class Scanner extends BasicEmitter {
}
}
// Only update metadata that has changed
- $newData = array_diff_assoc($data, $cacheData);
+ $newData = array_diff_assoc($data, $cacheData->getData());
} else {
$newData = $data;
$fileId = -1;
@@ -190,16 +198,27 @@ class Scanner extends BasicEmitter {
if (!empty($newData)) {
$data['fileid'] = $this->addToCache($file, $newData, $fileId);
}
- $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId));
- \OC_Hook::emit('\OC\Files\Cache\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
+
+ // post-emit only if it was a file. By that we avoid counting/treating folders as files
+ if ($data['mimetype'] !== 'httpd/unix-directory') {
+ $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId));
+ \OC_Hook::emit('\OC\Files\Cache\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
+ }
+
} else {
$this->removeFromCache($file);
}
+
+ //release the acquired lock
if ($lock) {
- $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
}
+
return $data;
}
+
return null;
}
@@ -263,7 +282,9 @@ class Scanner extends BasicEmitter {
$reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
}
if ($lock) {
- $this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
}
$data = $this->scanFile($path, $reuse, -1, null, $lock);
if ($data and $data['mimetype'] === 'httpd/unix-directory') {
@@ -271,7 +292,9 @@ class Scanner extends BasicEmitter {
$data['size'] = $size;
}
if ($lock) {
- $this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
+ }
}
return $data;
}
diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php
index c5b1e7de32e..58d8e53cfd1 100644
--- a/lib/private/files/cache/updater.php
+++ b/lib/private/files/cache/updater.php
@@ -24,12 +24,14 @@
*/
namespace OC\Files\Cache;
+use OCP\Files\Cache\IUpdater;
+use OCP\Files\Storage\IStorage;
/**
* Update the cache and propagate changes
*
*/
-class Updater {
+class Updater implements IUpdater {
/**
* @var bool
*/
@@ -145,18 +147,18 @@ class Updater {
/**
* Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
*
- * @param \OC\Files\Storage\Storage $sourceStorage
+ * @param IStorage $sourceStorage
* @param string $source
* @param string $target
*/
- public function renameFromStorage(\OC\Files\Storage\Storage $sourceStorage, $source, $target) {
+ public function renameFromStorage(IStorage $sourceStorage, $source, $target) {
if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) {
return;
}
$time = time();
- $sourceCache = $sourceStorage->getCache($source);
+ $sourceCache = $sourceStorage->getCache();
$sourceUpdater = $sourceStorage->getUpdater();
$sourcePropagator = $sourceStorage->getPropagator();
@@ -181,7 +183,9 @@ class Updater {
$sourceCache->correctFolderSize($source);
$this->cache->correctFolderSize($target);
- $sourceUpdater->correctParentStorageMtime($source);
+ if ($sourceUpdater instanceof Updater) {
+ $sourceUpdater->correctParentStorageMtime($source);
+ }
$this->correctParentStorageMtime($target);
$this->updateStorageMTimeOnly($target);
$sourcePropagator->propagateChange($source, $time);
@@ -205,7 +209,7 @@ class Updater {
*
* @param string $internalPath
*/
- public function correctParentStorageMtime($internalPath) {
+ private function correctParentStorageMtime($internalPath) {
$parentId = $this->cache->getParentId($internalPath);
$parent = dirname($internalPath);
if ($parentId != -1) {
diff --git a/lib/private/files/cache/watcher.php b/lib/private/files/cache/watcher.php
index bb80dcbd80c..a00e875a2d4 100644
--- a/lib/private/files/cache/watcher.php
+++ b/lib/private/files/cache/watcher.php
@@ -22,14 +22,13 @@
*/
namespace OC\Files\Cache;
+use OCP\Files\Cache\ICacheEntry;
+use OCP\Files\Cache\IWatcher;
/**
* check the storage backends for updates and change the cache accordingly
*/
-class Watcher {
- const CHECK_NEVER = 0; // never check the underlying filesystem for updates
- const CHECK_ONCE = 1; // check the underlying filesystem for updates once every request for each file
- const CHECK_ALWAYS = 2; // always check the underlying filesystem for updates
+class Watcher implements IWatcher {
protected $watchPolicy = self::CHECK_ONCE;
@@ -77,7 +76,7 @@ class Watcher {
* check $path for updates and update if needed
*
* @param string $path
- * @param array $cachedEntry
+ * @param ICacheEntry|null $cachedEntry
* @return boolean true if path was updated
*/
public function checkUpdate($path, $cachedEntry = null) {
@@ -96,7 +95,7 @@ class Watcher {
* Update the cache for changes to $path
*
* @param string $path
- * @param array $cachedData
+ * @param ICacheEntry $cachedData
*/
public function update($path, $cachedData) {
if ($this->storage->is_dir($path)) {
@@ -114,7 +113,7 @@ class Watcher {
* Check if the cache for $path needs to be updated
*
* @param string $path
- * @param array $cachedData
+ * @param ICacheEntry $cachedData
* @return bool
*/
public function needsUpdate($path, $cachedData) {
diff --git a/lib/private/files/cache/wrapper/cachewrapper.php b/lib/private/files/cache/wrapper/cachewrapper.php
index f401b7482eb..39a6b63205b 100644
--- a/lib/private/files/cache/wrapper/cachewrapper.php
+++ b/lib/private/files/cache/wrapper/cachewrapper.php
@@ -25,6 +25,7 @@
namespace OC\Files\Cache\Wrapper;
use OC\Files\Cache\Cache;
+use OCP\Files\Cache\ICacheEntry;
class CacheWrapper extends Cache {
/**
@@ -42,8 +43,8 @@ class CacheWrapper extends Cache {
/**
* Make it easy for wrappers to modify every returned cache entry
*
- * @param array $entry
- * @return array
+ * @param ICacheEntry $entry
+ * @return ICacheEntry
*/
protected function formatCacheEntry($entry) {
return $entry;
@@ -53,7 +54,7 @@ class CacheWrapper extends Cache {
* get the stored metadata of a file or folder
*
* @param string /int $file
- * @return array|false
+ * @return ICacheEntry|false
*/
public function get($file) {
$result = $this->cache->get($file);
@@ -67,7 +68,7 @@ class CacheWrapper extends Cache {
* get the metadata of all files stored in $folder
*
* @param string $folder
- * @return array
+ * @return ICacheEntry[]
*/
public function getFolderContents($folder) {
// cant do a simple $this->cache->.... call here since getFolderContentsById needs to be called on this
@@ -178,7 +179,7 @@ class CacheWrapper extends Cache {
* search for files matching $pattern
*
* @param string $pattern
- * @return array an array of file data
+ * @return ICacheEntry[] an array of file data
*/
public function search($pattern) {
$results = $this->cache->search($pattern);
@@ -189,7 +190,7 @@ class CacheWrapper extends Cache {
* search for files by mimetype
*
* @param string $mimetype
- * @return array
+ * @return ICacheEntry[]
*/
public function searchByMime($mimetype) {
$results = $this->cache->searchByMime($mimetype);
@@ -201,7 +202,7 @@ class CacheWrapper extends Cache {
*
* @param string|int $tag name or tag id
* @param string $userId owner of the tags
- * @return array file data
+ * @return ICacheEntry[] file data
*/
public function searchByTag($tag, $userId) {
$results = $this->cache->searchByTag($tag, $userId);
diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php
index 3e5e894eed4..1e6fe474f7b 100644
--- a/lib/private/files/fileinfo.php
+++ b/lib/private/files/fileinfo.php
@@ -29,6 +29,7 @@
namespace OC\Files;
+use OCP\Files\Cache\ICacheEntry;
use OCP\IUser;
class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
@@ -71,7 +72,7 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
* @param string|boolean $path
* @param Storage\Storage $storage
* @param string $internalPath
- * @param array $data
+ * @param array|ICacheEntry $data
* @param \OCP\Files\Mount\IMountPoint $mount
* @param \OCP\IUser|null $owner
*/
diff --git a/lib/private/files/objectstore/objectstorestorage.php b/lib/private/files/objectstore/objectstorestorage.php
index 9cea07b7f69..35c2c19c75b 100644
--- a/lib/private/files/objectstore/objectstorestorage.php
+++ b/lib/private/files/objectstore/objectstorestorage.php
@@ -25,6 +25,7 @@
namespace OC\Files\ObjectStore;
use Icewind\Streams\IteratorDirectory;
+use OC\Files\Cache\CacheEntry;
use OCP\Files\ObjectStore\IObjectStore;
class ObjectStoreStorage extends \OC\Files\Storage\Common {
@@ -192,7 +193,12 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
public function stat($path) {
$path = $this->normalizePath($path);
- return $this->getCache()->get($path);
+ $cacheEntry = $this->getCache()->get($path);
+ if ($cacheEntry instanceof CacheEntry) {
+ return $cacheEntry->getData();
+ } else {
+ return false;
+ }
}
/**
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
index c27f9d759f1..95bb3f74ba7 100644
--- a/lib/private/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -46,6 +46,7 @@ use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
use OCP\Files\InvalidPathException;
use OCP\Files\ReservedWordException;
+use OCP\Files\Storage\ILockingStorage;
use OCP\Lock\ILockingProvider;
/**
@@ -59,7 +60,7 @@ use OCP\Lock\ILockingProvider;
* Some \OC\Files\Storage\Common methods call functions which are first defined
* in classes which extend it, e.g. $this->stat() .
*/
-abstract class Common implements Storage {
+abstract class Common implements Storage, ILockingStorage {
use LocalTempFileTrait;
diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php
index fda28079d0f..69438ef0c7c 100644
--- a/lib/private/files/storage/wrapper/encryption.php
+++ b/lib/private/files/storage/wrapper/encryption.php
@@ -28,6 +28,7 @@ namespace OC\Files\Storage\Wrapper;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
use OC\Encryption\Update;
use OC\Encryption\Util;
+use OC\Files\Cache\CacheEntry;
use OC\Files\Filesystem;
use OC\Files\Mount\Manager;
use OC\Files\Storage\LocalTempFileTrait;
@@ -123,13 +124,14 @@ class Encryption extends Wrapper {
public function filesize($path) {
$fullPath = $this->getFullPath($path);
+ /** @var CacheEntry $info */
$info = $this->getCache()->get($path);
if (isset($this->unencryptedSize[$fullPath])) {
$size = $this->unencryptedSize[$fullPath];
// update file cache
$info['encrypted'] = true;
$info['size'] = $size;
- $this->getCache()->put($path, $info);
+ $this->getCache()->put($path, $info->getData());
return $size;
}
diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
index 55c826092c1..844505679df 100644
--- a/lib/private/files/storage/wrapper/quota.php
+++ b/lib/private/files/storage/wrapper/quota.php
@@ -25,6 +25,8 @@
namespace OC\Files\Storage\Wrapper;
+use OCP\Files\Cache\ICacheEntry;
+
class Quota extends Wrapper {
/**
@@ -64,7 +66,7 @@ class Quota extends Wrapper {
$cache = $storage->getCache();
}
$data = $cache->get($path);
- if (is_array($data) and isset($data['size'])) {
+ if ($data instanceof ICacheEntry and isset($data['size'])) {
return $data['size'];
} else {
return \OCP\Files\FileInfo::SPACE_NOT_COMPUTED;
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index 472c60b5faa..c632aa399e1 100644
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
@@ -26,9 +26,10 @@
namespace OC\Files\Storage\Wrapper;
use OCP\Files\InvalidPathException;
+use OCP\Files\Storage\ILockingStorage;
use OCP\Lock\ILockingProvider;
-class Wrapper implements \OC\Files\Storage\Storage {
+class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage {
/**
* @var \OC\Files\Storage\Storage $storage
*/
@@ -583,7 +584,9 @@ class Wrapper implements \OC\Files\Storage\Storage {
* @throws \OCP\Lock\LockedException
*/
public function acquireLock($path, $type, ILockingProvider $provider) {
- $this->storage->acquireLock($path, $type, $provider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->acquireLock($path, $type, $provider);
+ }
}
/**
@@ -592,7 +595,9 @@ class Wrapper implements \OC\Files\Storage\Storage {
* @param \OCP\Lock\ILockingProvider $provider
*/
public function releaseLock($path, $type, ILockingProvider $provider) {
- $this->storage->releaseLock($path, $type, $provider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->releaseLock($path, $type, $provider);
+ }
}
/**
@@ -601,6 +606,8 @@ class Wrapper implements \OC\Files\Storage\Storage {
* @param \OCP\Lock\ILockingProvider $provider
*/
public function changeLock($path, $type, ILockingProvider $provider) {
- $this->storage->changeLock($path, $type, $provider);
+ if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $this->storage->changeLock($path, $type, $provider);
+ }
}
}
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 7b0f1d37255..d4cc24ae0f5 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -43,15 +43,16 @@
namespace OC\Files;
use Icewind\Streams\CallbackWrapper;
-use OC\Files\Cache\Updater;
use OC\Files\Mount\MoveableMount;
use OC\Files\Storage\Storage;
use OC\User\User;
+use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileNameTooLongException;
use OCP\Files\InvalidCharacterInPathException;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Files\ReservedWordException;
+use OCP\Files\Storage\ILockingStorage;
use OCP\IUser;
use OCP\Lock\ILockingProvider;
use OCP\Lock\LockedException;
@@ -1274,7 +1275,7 @@ class View {
if ($storage) {
$data = $this->getCacheEntry($storage, $internalPath, $relativePath);
- if (!is_array($data)) {
+ if (!$data instanceof ICacheEntry) {
return false;
}
@@ -1334,7 +1335,7 @@ class View {
$data = $this->getCacheEntry($storage, $internalPath, $directory);
- if (!is_array($data) || !isset($data['fileid'])) {
+ if (!$data instanceof ICacheEntry || !isset($data['fileid'])) {
return [];
}
@@ -1345,7 +1346,7 @@ class View {
/**
* @var \OC\Files\FileInfo[] $files
*/
- $files = array_map(function (array $content) use ($path, $storage, $mount, $sharingDisabled) {
+ $files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
if ($sharingDisabled) {
$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
}
@@ -1572,10 +1573,15 @@ class View {
* Get the owner for a file or folder
*
* @param string $path
- * @return string
+ * @return string the user id of the owner
+ * @throws NotFoundException
*/
public function getOwner($path) {
- return $this->basicOperation('getOwner', $path);
+ $info = $this->getFileInfo($path);
+ if (!$info) {
+ throw new NotFoundException($path . ' not found while trying to get owner');
+ }
+ return $info->getOwner()->getUID();
}
/**
@@ -1834,11 +1840,14 @@ class View {
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
if ($mount) {
try {
- $mount->getStorage()->acquireLock(
- $mount->getInternalPath($absolutePath),
- $type,
- $this->lockingProvider
- );
+ $storage = $mount->getStorage();
+ if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $storage->acquireLock(
+ $mount->getInternalPath($absolutePath),
+ $type,
+ $this->lockingProvider
+ );
+ }
} catch (\OCP\Lock\LockedException $e) {
// rethrow with the a human-readable path
throw new \OCP\Lock\LockedException(
@@ -1872,11 +1881,14 @@ class View {
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
if ($mount) {
try {
- $mount->getStorage()->changeLock(
- $mount->getInternalPath($absolutePath),
- $type,
- $this->lockingProvider
- );
+ $storage = $mount->getStorage();
+ if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $storage->changeLock(
+ $mount->getInternalPath($absolutePath),
+ $type,
+ $this->lockingProvider
+ );
+ }
} catch (\OCP\Lock\LockedException $e) {
// rethrow with the a human-readable path
throw new \OCP\Lock\LockedException(
@@ -1907,11 +1919,14 @@ class View {
$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
if ($mount) {
- $mount->getStorage()->releaseLock(
- $mount->getInternalPath($absolutePath),
- $type,
- $this->lockingProvider
- );
+ $storage = $mount->getStorage();
+ if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
+ $storage->releaseLock(
+ $mount->getInternalPath($absolutePath),
+ $type,
+ $this->lockingProvider
+ );
+ }
}
return true;
@@ -2011,4 +2026,28 @@ class View {
}
return '';
}
+
+ /**
+ * @param string $filename
+ * @return array
+ * @throws \OC\User\NoUserException
+ * @throws NotFoundException
+ */
+ public function getUidAndFilename($filename) {
+ $info = $this->getFileInfo($filename);
+ if (!$info instanceof \OCP\Files\FileInfo) {
+ throw new NotFoundException($this->getAbsolutePath($filename) . ' not found');
+ }
+ $uid = $info->getOwner()->getUID();
+ if ($uid != \OCP\User::getUser()) {
+ Filesystem::initMountPoints($uid);
+ $ownerView = new View('/' . $uid . '/files');
+ try {
+ $filename = $ownerView->getPath($info['fileid']);
+ } catch (NotFoundException $e) {
+ throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid);
+ }
+ }
+ return [$uid, $filename];
+ }
}
diff --git a/lib/private/group/backend.php b/lib/private/group/backend.php
index ed059f63aaf..ed2a2f4bb68 100644
--- a/lib/private/group/backend.php
+++ b/lib/private/group/backend.php
@@ -82,7 +82,7 @@ abstract class OC_Group_Backend implements \OCP\GroupInterface {
* @return int bitwise-or'ed actions
*
* Returns the supported actions as int to be
- * compared with OC_USER_BACKEND_CREATE_USER etc.
+ * compared with \OC_Group_Backend::CREATE_GROUP etc.
*/
public function getSupportedActions() {
$actions = 0;
@@ -101,7 +101,7 @@ abstract class OC_Group_Backend implements \OCP\GroupInterface {
* @return bool
*
* Returns the supported actions as int to be
- * compared with OC_GROUP_BACKEND_CREATE_GROUP etc.
+ * compared with \OC_Group_Backend::CREATE_GROUP etc.
*/
public function implementsActions($actions) {
return (bool)($this->getSupportedActions() & $actions);
diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php
index 8a21c77b58b..2c28f3b0e7f 100644
--- a/lib/private/group/manager.php
+++ b/lib/private/group/manager.php
@@ -33,6 +33,7 @@
namespace OC\Group;
use OC\Hooks\PublicEmitter;
+use OCP\GroupInterface;
use OCP\IGroupManager;
/**
@@ -52,7 +53,7 @@ use OCP\IGroupManager;
*/
class Manager extends PublicEmitter implements IGroupManager {
/**
- * @var \OC_Group_Backend[]|\OC_Group_Database[] $backends
+ * @var GroupInterface[] $backends
*/
private $backends = array();
@@ -121,7 +122,7 @@ class Manager extends PublicEmitter implements IGroupManager {
}
/**
- * @param \OC_Group_Backend $backend
+ * @param \OCP\GroupInterface $backend
*/
public function addBackend($backend) {
$this->backends[] = $backend;
diff --git a/lib/private/tempmanager.php b/lib/private/tempmanager.php
index 378da91e226..19bbaf6e78e 100644
--- a/lib/private/tempmanager.php
+++ b/lib/private/tempmanager.php
@@ -225,11 +225,6 @@ class TempManager implements ITempManager {
if ($temp = getenv('TMPDIR')) {
$directories[] = $temp;
}
- $temp = tempnam(__FILE__, '');
- if (file_exists($temp)) {
- unlink($temp);
- $directories[] = dirname($temp);
- }
if ($temp = sys_get_temp_dir()) {
$directories[] = $temp;
}
@@ -239,6 +234,12 @@ class TempManager implements ITempManager {
return $dir;
}
}
+
+ $temp = tempnam(dirname(__FILE__), '');
+ if (file_exists($temp)) {
+ unlink($temp);
+ return dirname($temp);
+ }
throw new \UnexpectedValueException('Unable to detect system temporary directory');
}
diff --git a/lib/public/files/cache/icache.php b/lib/public/files/cache/icache.php
new file mode 100644
index 00000000000..07396db4588
--- /dev/null
+++ b/lib/public/files/cache/icache.php
@@ -0,0 +1,249 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Cache;
+
+/**
+ * Metadata cache for a storage
+ *
+ * The cache stores the metadata for all files and folders in a storage and is kept up to date trough the following mechanisms:
+ *
+ * - Scanner: scans the storage and updates the cache where needed
+ * - Watcher: checks for changes made to the filesystem outside of the ownCloud instance and rescans files and folder when a change is detected
+ * - Updater: listens to changes made to the filesystem inside of the ownCloud instance and updates the cache where needed
+ * - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
+ *
+ * @since 9.0.0
+ */
+interface ICache {
+ const NOT_FOUND = 0;
+ const PARTIAL = 1; //only partial data available, file not cached in the database
+ const SHALLOW = 2; //folder in cache, but not all child files are completely scanned
+ const COMPLETE = 3;
+
+ /**
+ * Get the numeric storage id for this cache's storage
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getNumericStorageId();
+
+ /**
+ * get the stored metadata of a file or folder
+ *
+ * @param string | int $file either the path of a file or folder or the file id for a file or folder
+ * @return ICacheEntry[]|false the cache entry or false if the file is not found in the cache
+ * @since 9.0.0
+ */
+ public function get($file);
+
+ /**
+ * get the metadata of all files stored in $folder
+ *
+ * @param string $folder
+ * @return ICacheEntry[]
+ * @since 9.0.0
+ */
+ public function getFolderContents($folder);
+
+ /**
+ * get the metadata of all files stored in $folder
+ *
+ * @param int $fileId the file id of the folder
+ * @return ICacheEntry[]
+ * @since 9.0.0
+ */
+ public function getFolderContentsById($fileId);
+
+ /**
+ * store meta data for a file or folder
+ *
+ * @param string $file
+ * @param array $data
+ *
+ * @return int file id
+ * @throws \RuntimeException
+ * @since 9.0.0
+ */
+ public function put($file, array $data);
+
+ /**
+ * update the metadata of an existing file or folder in the cache
+ *
+ * @param int $id the fileid of the existing file or folder
+ * @param array $data [$key => $value] the metadata to update, only the fields provided in the array will be updated, non-provided values will remain unchanged
+ * @since 9.0.0
+ */
+ public function update($id, array $data);
+
+ /**
+ * get the file id for a file
+ *
+ * A file id is a numeric id for a file or folder that's unique within an owncloud instance which stays the same for the lifetime of a file
+ *
+ * File ids are easiest way for apps to store references to a file since unlike paths they are not affected by renames or sharing
+ *
+ * @param string $file
+ * @return int
+ * @since 9.0.0
+ */
+ public function getId($file);
+
+ /**
+ * get the id of the parent folder of a file
+ *
+ * @param string $file
+ * @return int
+ * @since 9.0.0
+ */
+ public function getParentId($file);
+
+ /**
+ * check if a file is available in the cache
+ *
+ * @param string $file
+ * @return bool
+ * @since 9.0.0
+ */
+ public function inCache($file);
+
+ /**
+ * remove a file or folder from the cache
+ *
+ * when removing a folder from the cache all files and folders inside the folder will be removed as well
+ *
+ * @param string $file
+ * @since 9.0.0
+ */
+ public function remove($file);
+
+ /**
+ * Move a file or folder in the cache
+ *
+ * @param string $source
+ * @param string $target
+ * @since 9.0.0
+ */
+ public function move($source, $target);
+
+ /**
+ * Move a file or folder in the cache
+ *
+ * @param \OCP\Files\Cache\ICache $sourceCache
+ * @param string $sourcePath
+ * @param string $targetPath
+ * @throws \OC\DatabaseException
+ * @since 9.0.0
+ */
+ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath);
+
+ /**
+ * remove all entries for files that are stored on the storage from the cache
+ *
+ * @since 9.0.0
+ */
+ public function clear();
+
+ /**
+ * Get the scan status of a file
+ *
+ * - ICache::NOT_FOUND: File is not in the cache
+ * - ICache::PARTIAL: File is not stored in the cache but some incomplete data is known
+ * - ICache::SHALLOW: The folder and it's direct children are in the cache but not all sub folders are fully scanned
+ * - ICache::COMPLETE: The file or folder, with all it's children) are fully scanned
+ *
+ * @param string $file
+ *
+ * @return int ICache::NOT_FOUND, ICache::PARTIAL, ICache::SHALLOW or ICache::COMPLETE
+ * @since 9.0.0
+ */
+ public function getStatus($file);
+
+ /**
+ * search for files matching $pattern
+ *
+ * @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
+ * @return ICacheEntry[] an array of cache entries where the name matches the search pattern
+ * @since 9.0.0
+ */
+ public function search($pattern);
+
+ /**
+ * search for files by mimetype
+ *
+ * @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
+ * where it will search for all mimetypes in the group ('image/*')
+ * @return ICacheEntry[] an array of cache entries where the mimetype matches the search
+ * @since 9.0.0
+ */
+ public function searchByMime($mimetype);
+
+ /**
+ * Search for files by tag of a given users.
+ *
+ * Note that every user can tag files differently.
+ *
+ * @param string|int $tag name or tag id
+ * @param string $userId owner of the tags
+ * @return ICacheEntry[] file data
+ * @since 9.0.0
+ */
+ public function searchByTag($tag, $userId);
+
+ /**
+ * get all file ids on the files on the storage
+ *
+ * @return int[]
+ * @since 9.0.0
+ */
+ public function getAll();
+
+ /**
+ * find a folder in the cache which has not been fully scanned
+ *
+ * If multiple incomplete folders are in the cache, the one with the highest id will be returned,
+ * use the one with the highest id gives the best result with the background scanner, since that is most
+ * likely the folder where we stopped scanning previously
+ *
+ * @return string|bool the path of the folder or false when no folder matched
+ * @since 9.0.0
+ */
+ public function getIncomplete();
+
+ /**
+ * get the path of a file on this storage by it's file id
+ *
+ * @param int $id the file id of the file or folder to search
+ * @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
+ * @since 9.0.0
+ */
+ public function getPathById($id);
+
+ /**
+ * normalize the given path for usage in the cache
+ *
+ * @param string $path
+ * @return string
+ * @since 9.0.0
+ */
+ public function normalize($path);
+}
diff --git a/lib/public/files/cache/icacheentry.php b/lib/public/files/cache/icacheentry.php
new file mode 100644
index 00000000000..8d14bd2c555
--- /dev/null
+++ b/lib/public/files/cache/icacheentry.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Cache;
+
+/**
+ * meta data for a file or folder
+ *
+ * @since 9.0.0
+ */
+interface ICacheEntry {
+ /**
+ * Get the numeric id of a file
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getId();
+
+ /**
+ * Get the numeric id for the storage
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getStorageId();
+
+ /**
+ * Get the path of the file relative to the storage root
+ *
+ * @return string
+ * @since 9.0.0
+ */
+ public function getPath();
+
+ /**
+ * Get the file name
+ *
+ * @return string
+ * @since 9.0.0
+ */
+ public function getName();
+
+ /**
+ * Get the full mimetype
+ *
+ * @return string
+ * @since 9.0.0
+ */
+ public function getMimeType();
+
+ /**
+ * Get the first part of the mimetype
+ *
+ * @return string
+ * @since 9.0.0
+ */
+ public function getMimePart();
+
+ /**
+ * Get the file size in bytes
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getSize();
+
+ /**
+ * Get the last modified date as unix timestamp
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getMTime();
+
+ /**
+ * Get the last modified date on the storage as unix timestamp
+ *
+ * Note that when a file is updated we also update the mtime of all parent folders to make it visible to the user which folder has had updates most recently
+ * This can differ from the mtime on the underlying storage which usually only changes when a direct child is added, removed or renamed
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getStorageMTime();
+
+ /**
+ * Get the etag for the file
+ *
+ * An etag is used for change detection of files and folders, an etag of a file changes whenever the content of the file changes
+ * Etag for folders change whenever a file in the folder has changed
+ *
+ * @return string
+ * @since 9.0.0
+ */
+ public function getEtag();
+
+ /**
+ * Get the permissions for the file stored as bitwise combination of \OCP\PERMISSION_READ, \OCP\PERMISSION_CREATE
+ * \OCP\PERMISSION_UPDATE, \OCP\PERMISSION_DELETE and \OCP\PERMISSION_SHARE
+ *
+ * @return int
+ * @since 9.0.0
+ */
+ public function getPermissions();
+
+ /**
+ * Check if the file is encrypted
+ *
+ * @return bool
+ * @since 9.0.0
+ */
+ public function isEncrypted();
+}
diff --git a/lib/public/files/cache/ipropagator.php b/lib/public/files/cache/ipropagator.php
new file mode 100644
index 00000000000..7f7dbada532
--- /dev/null
+++ b/lib/public/files/cache/ipropagator.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Cache;
+
+/**
+ * Propagate etags and mtimes within the storage
+ *
+ * @since 9.0.0
+ */
+interface IPropagator {
+ /**
+ * @param string $internalPath
+ * @param int $time
+ * @return array[] all propagated cache entries
+ * @since 9.0.0
+ */
+ public function propagateChange($internalPath, $time);
+}
diff --git a/lib/public/files/cache/iscanner.php b/lib/public/files/cache/iscanner.php
new file mode 100644
index 00000000000..47e33a98bae
--- /dev/null
+++ b/lib/public/files/cache/iscanner.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Cache;
+
+/**
+ * Scan files from the storage and save to the cache
+ *
+ * @since 9.0.0
+ */
+interface IScanner {
+ const SCAN_RECURSIVE = true;
+ const SCAN_SHALLOW = false;
+
+ const REUSE_ETAG = 1;
+ const REUSE_SIZE = 2;
+
+ /**
+ * scan a single file and store it in the cache
+ *
+ * @param string $file
+ * @param int $reuseExisting
+ * @param int $parentId
+ * @param array | null $cacheData existing data in the cache for the file to be scanned
+ * @param bool $lock set to false to disable getting an additional read lock during scanning
+ * @return array an array of metadata of the scanned file
+ * @throws \OC\ServerNotAvailableException
+ * @throws \OCP\Lock\LockedException
+ * @since 9.0.0
+ */
+ public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true);
+
+ /**
+ * scan a folder and all its children
+ *
+ * @param string $path
+ * @param bool $recursive
+ * @param int $reuse
+ * @param bool $lock set to false to disable getting an additional read lock during scanning
+ * @return array an array of the meta data of the scanned file or folder
+ * @since 9.0.0
+ */
+ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true);
+
+ /**
+ * check if the file should be ignored when scanning
+ * NOTE: files with a '.part' extension are ignored as well!
+ * prevents unfinished put requests to be scanned
+ *
+ * @param string $file
+ * @return boolean
+ * @since 9.0.0
+ */
+ public static function isPartialFile($file);
+
+ /**
+ * walk over any folders that are not fully scanned yet and scan them
+ *
+ * @since 9.0.0
+ */
+ public function backgroundScan();
+}
+
diff --git a/lib/public/files/cache/iupdater.php b/lib/public/files/cache/iupdater.php
new file mode 100644
index 00000000000..241cd8636a1
--- /dev/null
+++ b/lib/public/files/cache/iupdater.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Cache;
+
+use OCP\Files\Storage\IStorage;
+
+/**
+ * Update the cache and propagate changes
+ *
+ * @since 9.0.0
+ */
+interface IUpdater {
+ /**
+ * Get the propagator for etags and mtime for the view the updater works on
+ *
+ * @return IPropagator
+ * @since 9.0.0
+ */
+ public function getPropagator();
+
+ /**
+ * Propagate etag and mtime changes for the parent folders of $path up to the root of the filesystem
+ *
+ * @param string $path the path of the file to propagate the changes for
+ * @param int|null $time the timestamp to set as mtime for the parent folders, if left out the current time is used
+ * @since 9.0.0
+ */
+ public function propagate($path, $time = null);
+
+ /**
+ * Update the cache for $path and update the size, etag and mtime of the parent folders
+ *
+ * @param string $path
+ * @param int $time
+ * @since 9.0.0
+ */
+ public function update($path, $time = null);
+
+ /**
+ * Remove $path from the cache and update the size, etag and mtime of the parent folders
+ *
+ * @param string $path
+ * @since 9.0.0
+ */
+ public function remove($path);
+
+ /**
+ * Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
+ *
+ * @param IStorage $sourceStorage
+ * @param string $source
+ * @param string $target
+ * @since 9.0.0
+ */
+ public function renameFromStorage(IStorage $sourceStorage, $source, $target);
+}
diff --git a/lib/public/files/cache/iwatcher.php b/lib/public/files/cache/iwatcher.php
new file mode 100644
index 00000000000..a61975036f8
--- /dev/null
+++ b/lib/public/files/cache/iwatcher.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Cache;
+
+/**
+ * check the storage backends for updates and change the cache accordingly
+ *
+ * @since 9.0.0
+ */
+interface IWatcher {
+ const CHECK_NEVER = 0; // never check the underlying filesystem for updates
+ const CHECK_ONCE = 1; // check the underlying filesystem for updates once every request for each file
+ const CHECK_ALWAYS = 2; // always check the underlying filesystem for updates
+
+ /**
+ * @param int $policy either IWatcher::CHECK_NEVER, IWatcher::CHECK_ONCE, IWatcher::CHECK_ALWAYS
+ * @since 9.0.0
+ */
+ public function setPolicy($policy);
+
+ /**
+ * @return int either IWatcher::CHECK_NEVER, IWatcher::CHECK_ONCE, IWatcher::CHECK_ALWAYS
+ * @since 9.0.0
+ */
+ public function getPolicy();
+
+ /**
+ * check $path for updates and update if needed
+ *
+ * @param string $path
+ * @param ICacheEntry|null $cachedEntry
+ * @return boolean true if path was updated
+ * @since 9.0.0
+ */
+ public function checkUpdate($path, $cachedEntry = null);
+
+ /**
+ * Update the cache for changes to $path
+ *
+ * @param string $path
+ * @param ICacheEntry $cachedData
+ * @since 9.0.0
+ */
+ public function update($path, $cachedData);
+
+ /**
+ * Check if the cache for $path needs to be updated
+ *
+ * @param string $path
+ * @param ICacheEntry $cachedData
+ * @return bool
+ * @since 9.0.0
+ */
+ public function needsUpdate($path, $cachedData);
+
+ /**
+ * remove deleted files in $path from the cache
+ *
+ * @param string $path
+ * @since 9.0.0
+ */
+ public function cleanFolder($path);
+}
diff --git a/lib/public/files/storage.php b/lib/public/files/storage.php
index f6f5081abaa..1c125221449 100644
--- a/lib/public/files/storage.php
+++ b/lib/public/files/storage.php
@@ -33,16 +33,19 @@
// use OCP namespace for all classes that are considered public.
// This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP\Files;
-use OCP\Files\InvalidPathException;
+
+use OCP\Files\Storage\IStorage;
use OCP\Lock\ILockingProvider;
/**
* Provide a common interface to all different storage options
*
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
+ *
* @since 6.0.0
+ * @deprecated 9.0.0 use \OCP\Files\Storage\IStorage instead
*/
-interface Storage {
+interface Storage extends IStorage {
/**
* $parameters is a free form array with the configuration options needed to construct the storage
*
@@ -462,10 +465,4 @@ interface Storage {
* @param bool $isAvailable
*/
public function setAvailability($isAvailable);
-
- /**
- * @param $path path for which to retrieve the owner
- * @since 9.0.0
- */
- public function getOwner($path);
}
diff --git a/lib/public/files/storage/ilockingstorage.php b/lib/public/files/storage/ilockingstorage.php
new file mode 100644
index 00000000000..32cc32ffb05
--- /dev/null
+++ b/lib/public/files/storage/ilockingstorage.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @author Robin Appelman <icewind@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCP\Files\Storage;
+
+use OCP\Lock\ILockingProvider;
+
+/**
+ * Storage backends that require explicit locking
+ *
+ * Storage backends implementing this interface do not need to implement their own locking implementation but should use the provided lockingprovider instead
+ * The implementation of the locking methods only need to map internal storage paths to "lock keys"
+ *
+ * @since 9.0.0
+ */
+interface ILockingStorage {
+ /**
+ * @param string $path The path of the file to acquire the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ * @since 9.0.0
+ */
+ public function acquireLock($path, $type, ILockingProvider $provider);
+
+ /**
+ * @param string $path The path of the file to acquire the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @since 9.0.0
+ */
+ public function releaseLock($path, $type, ILockingProvider $provider);
+
+ /**
+ * @param string $path The path of the file to change the lock for
+ * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
+ * @param \OCP\Lock\ILockingProvider $provider
+ * @throws \OCP\Lock\LockedException
+ * @since 9.0.0
+ */
+ public function changeLock($path, $type, ILockingProvider $provider);
+}
diff --git a/lib/public/files/storage/istorage.php b/lib/public/files/storage/istorage.php
new file mode 100644
index 00000000000..4bc5e3536dc
--- /dev/null
+++ b/lib/public/files/storage/istorage.php
@@ -0,0 +1,482 @@
+<?php
+/**
+ * @author Jörn Friedrich Dreyer <jfd@butonic.de>
+ * @author Michael Roth <michael.roth@rz.uni-augsburg.de>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Files/Storage interface
+ */
+
+// use OCP namespace for all classes that are considered public.
+// This means that they should be used by apps instead of the internal ownCloud classes
+namespace OCP\Files\Storage;
+
+use OCP\Files\Cache\ICache;
+use OCP\Files\Cache\IPropagator;
+use OCP\Files\Cache\IScanner;
+use OCP\Files\Cache\IUpdater;
+use OCP\Files\Cache\IWatcher;
+use OCP\Files\InvalidPathException;
+
+/**
+ * Provide a common interface to all different storage options
+ *
+ * All paths passed to the storage are relative to the storage and should NOT have a leading slash.
+ *
+ * @since 9.0.0
+ */
+interface IStorage {
+ /**
+ * $parameters is a free form array with the configuration options needed to construct the storage
+ *
+ * @param array $parameters
+ * @since 9.0.0
+ */
+ public function __construct($parameters);
+
+ /**
+ * Get the identifier for the storage,
+ * the returned id should be the same for every storage object that is created with the same parameters
+ * and two storage objects with the same id should refer to two storages that display the same files.
+ *
+ * @return string
+ * @since 9.0.0
+ */
+ public function getId();
+
+ /**
+ * see http://php.net/manual/en/function.mkdir.php
+ * implementations need to implement a recursive mkdir
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function mkdir($path);
+
+ /**
+ * see http://php.net/manual/en/function.rmdir.php
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function rmdir($path);
+
+ /**
+ * see http://php.net/manual/en/function.opendir.php
+ *
+ * @param string $path
+ * @return resource|false
+ * @since 9.0.0
+ */
+ public function opendir($path);
+
+ /**
+ * see http://php.net/manual/en/function.is-dir.php
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function is_dir($path);
+
+ /**
+ * see http://php.net/manual/en/function.is-file.php
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function is_file($path);
+
+ /**
+ * see http://php.net/manual/en/function.stat.php
+ * only the following keys are required in the result: size and mtime
+ *
+ * @param string $path
+ * @return array|false
+ * @since 9.0.0
+ */
+ public function stat($path);
+
+ /**
+ * see http://php.net/manual/en/function.filetype.php
+ *
+ * @param string $path
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function filetype($path);
+
+ /**
+ * see http://php.net/manual/en/function.filesize.php
+ * The result for filesize when called on a folder is required to be 0
+ *
+ * @param string $path
+ * @return int|false
+ * @since 9.0.0
+ */
+ public function filesize($path);
+
+ /**
+ * check if a file can be created in $path
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function isCreatable($path);
+
+ /**
+ * check if a file can be read
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function isReadable($path);
+
+ /**
+ * check if a file can be written to
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function isUpdatable($path);
+
+ /**
+ * check if a file can be deleted
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function isDeletable($path);
+
+ /**
+ * check if a file can be shared
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function isSharable($path);
+
+ /**
+ * get the full permissions of a path.
+ * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
+ *
+ * @param string $path
+ * @return int
+ * @since 9.0.0
+ */
+ public function getPermissions($path);
+
+ /**
+ * see http://php.net/manual/en/function.file_exists.php
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function file_exists($path);
+
+ /**
+ * see http://php.net/manual/en/function.filemtime.php
+ *
+ * @param string $path
+ * @return int|false
+ * @since 9.0.0
+ */
+ public function filemtime($path);
+
+ /**
+ * see http://php.net/manual/en/function.file_get_contents.php
+ *
+ * @param string $path
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function file_get_contents($path);
+
+ /**
+ * see http://php.net/manual/en/function.file_put_contents.php
+ *
+ * @param string $path
+ * @param string $data
+ * @return bool
+ * @since 9.0.0
+ */
+ public function file_put_contents($path, $data);
+
+ /**
+ * see http://php.net/manual/en/function.unlink.php
+ *
+ * @param string $path
+ * @return bool
+ * @since 9.0.0
+ */
+ public function unlink($path);
+
+ /**
+ * see http://php.net/manual/en/function.rename.php
+ *
+ * @param string $path1
+ * @param string $path2
+ * @return bool
+ * @since 9.0.0
+ */
+ public function rename($path1, $path2);
+
+ /**
+ * see http://php.net/manual/en/function.copy.php
+ *
+ * @param string $path1
+ * @param string $path2
+ * @return bool
+ * @since 9.0.0
+ */
+ public function copy($path1, $path2);
+
+ /**
+ * see http://php.net/manual/en/function.fopen.php
+ *
+ * @param string $path
+ * @param string $mode
+ * @return resource|false
+ * @since 9.0.0
+ */
+ public function fopen($path, $mode);
+
+ /**
+ * get the mimetype for a file or folder
+ * The mimetype for a folder is required to be "httpd/unix-directory"
+ *
+ * @param string $path
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function getMimeType($path);
+
+ /**
+ * see http://php.net/manual/en/function.hash-file.php
+ *
+ * @param string $type
+ * @param string $path
+ * @param bool $raw
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function hash($type, $path, $raw = false);
+
+ /**
+ * see http://php.net/manual/en/function.free_space.php
+ *
+ * @param string $path
+ * @return int|false
+ * @since 9.0.0
+ */
+ public function free_space($path);
+
+ /**
+ * search for occurrences of $query in file names
+ *
+ * @param string $query
+ * @return array|false
+ * @since 9.0.0
+ */
+ public function search($query);
+
+ /**
+ * see http://php.net/manual/en/function.touch.php
+ * If the backend does not support the operation, false should be returned
+ *
+ * @param string $path
+ * @param int $mtime
+ * @return bool
+ * @since 9.0.0
+ */
+ public function touch($path, $mtime = null);
+
+ /**
+ * get the path to a local version of the file.
+ * The local version of the file can be temporary and doesn't have to be persistent across requests
+ *
+ * @param string $path
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function getLocalFile($path);
+
+ /**
+ * get the path to a local version of the folder.
+ * The local version of the folder can be temporary and doesn't have to be persistent across requests
+ *
+ * @param string $path
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function getLocalFolder($path);
+
+ /**
+ * check if a file or folder has been updated since $time
+ *
+ * @param string $path
+ * @param int $time
+ * @return bool
+ * @since 9.0.0
+ *
+ * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
+ * returning true for other changes in the folder is optional
+ */
+ public function hasUpdated($path, $time);
+
+ /**
+ * get the ETag for a file or folder
+ *
+ * @param string $path
+ * @return string|false
+ * @since 9.0.0
+ */
+ public function getETag($path);
+
+ /**
+ * Returns whether the storage is local, which means that files
+ * are stored on the local filesystem instead of remotely.
+ * Calling getLocalFile() for local storages should always
+ * return the local files, whereas for non-local storages
+ * it might return a temporary file.
+ *
+ * @return bool true if the files are stored locally, false otherwise
+ * @since 9.0.0
+ */
+ public function isLocal();
+
+ /**
+ * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
+ *
+ * @param string $class
+ * @return bool
+ * @since 9.0.0
+ */
+ public function instanceOfStorage($class);
+
+ /**
+ * A custom storage implementation can return an url for direct download of a give file.
+ *
+ * For now the returned array can hold the parameter url - in future more attributes might follow.
+ *
+ * @param string $path
+ * @return array|false
+ * @since 9.0.0
+ */
+ public function getDirectDownload($path);
+
+ /**
+ * @param string $path the path of the target folder
+ * @param string $fileName the name of the file itself
+ * @return void
+ * @throws InvalidPathException
+ * @since 9.0.0
+ */
+ public function verifyPath($path, $fileName);
+
+ /**
+ * @param \OCP\Files\Storage $sourceStorage
+ * @param string $sourceInternalPath
+ * @param string $targetInternalPath
+ * @return bool
+ * @since 9.0.0
+ */
+ public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
+
+ /**
+ * @param \OCP\Files\Storage $sourceStorage
+ * @param string $sourceInternalPath
+ * @param string $targetInternalPath
+ * @return bool
+ * @since 9.0.0
+ */
+ public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath);
+
+ /**
+ * Test a storage for availability
+ *
+ * @since 9.0.0
+ * @return bool
+ */
+ public function test();
+
+ /**
+ * @since 9.0.0
+ * @return array [ available, last_checked ]
+ */
+ public function getAvailability();
+
+ /**
+ * @since 9.0.0
+ * @param bool $isAvailable
+ */
+ public function setAvailability($isAvailable);
+
+ /**
+ * @param string $path path for which to retrieve the owner
+ * @since 9.0.0
+ */
+ public function getOwner($path);
+
+ /**
+ * @return ICache
+ * @since 9.0.0
+ */
+ public function getCache();
+
+ /**
+ * @return IPropagator
+ * @since 9.0.0
+ */
+ public function getPropagator();
+
+ /**
+ * @return IScanner
+ * @since 9.0.0
+ */
+ public function getScanner();
+
+ /**
+ * @return IUpdater
+ * @since 9.0.0
+ */
+ public function getUpdater();
+
+ /**
+ * @return IWatcher
+ * @since 9.0.0
+ */
+ public function getWatcher();
+}
diff --git a/lib/public/igroupmanager.php b/lib/public/igroupmanager.php
index 5ec780e4471..7eabc8a59b0 100644
--- a/lib/public/igroupmanager.php
+++ b/lib/public/igroupmanager.php
@@ -53,7 +53,7 @@ interface IGroupManager {
public function isBackendUsed($backendClass);
/**
- * @param \OCP\UserInterface $backend
+ * @param \OCP\GroupInterface $backend
* @since 8.0.0
*/
public function addBackend($backend);
diff --git a/settings/js/apps.js b/settings/js/apps.js
index 85627e613c6..3078e4fda33 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -176,7 +176,8 @@ OC.Settings.Apps = OC.Settings.Apps || {
// set group select properly
if(OC.Settings.Apps.isType(app, 'filesystem') || OC.Settings.Apps.isType(app, 'prelogin') ||
- OC.Settings.Apps.isType(app, 'authentication') || OC.Settings.Apps.isType(app, 'logging')) {
+ OC.Settings.Apps.isType(app, 'authentication') || OC.Settings.Apps.isType(app, 'logging') ||
+ OC.Settings.Apps.isType(app, 'prevent_group_restriction')) {
page.find(".groups-enable").hide();
page.find(".groups-enable__checkbox").attr('checked', null);
} else {
diff --git a/settings/l10n/es.js b/settings/l10n/es.js
index 43880e037c1..d6dfc0385ef 100644
--- a/settings/l10n/es.js
+++ b/settings/l10n/es.js
@@ -160,7 +160,10 @@ OC.L10N.register(
"Use system's cron service to call the cron.php file every 15 minutes." : "Usar el servicio cron del sistema para llamar al archivo cron.php cada 15 minutos.",
"Enable server-side encryption" : "Habilitar cifrado en el servidor",
"Please read carefully before activating server-side encryption: " : "Por favor lea cuidadosamente antes de activar el cifrado del lado del servidor.",
+ "Once encryption is enabled, all files uploaded to the server from that point forward will be encrypted at rest on the server. It will only be possible to disable encryption at a later date if the active encryption module supports that function, and all pre-conditions (e.g. setting a recover key) are met." : "Una vez que el cifrado está habilitado, todos los archivos subidos al servidor desde ese punto en adelante se cifrarán en reposo en el servidor. Sólo será posible desactivar el cifrado en una fecha posterior si el módulo de cifrado activado soporta esa función, y todas las condiciones previas (por ejemplo, el establecimiento de una clave de recuperación) se cumplan.",
+ "Encryption alone does not guarantee security of the system. Please see ownCloud documentation for more information about how the encryption app works, and the supported use cases." : "El cifrado en sí solo no garantiza la seguridad del sistema. Por favor, consulte la documentación de ownCloud para obtener más información acerca de cómo funciona la aplicación de cifrado, y los casos de uso compatibles.",
"Be aware that encryption always increases the file size." : "Tenga presente que la encripción siempre incrementa el tamaño del archivo.",
+ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Es siempre bueno crear copias de seguridad de sus datos, en el caso del cifrado, asegúrese de tener una copia de seguridad de las claves de cifrado junto con sus datos.",
"This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final. ¿Realmente quiere activar el cifrado?",
"Enable encryption" : "Habilitar cifrado",
"No encryption module loaded, please enable an encryption module in the app menu." : "No se ha cargado el modulo de cifrado. Por favor habilite un modulo de cifrado en el menú de aplicaciones.",
@@ -187,6 +190,7 @@ OC.L10N.register(
"More" : "Más",
"Less" : "Menos",
"The logfile is bigger than 100 MB. Downloading it may take some time!" : "El archivo de registro es mayor de 100 MB. Descargarlo puede tardar.",
+ "What to log" : "Que registrar",
"SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "Se utiliza SQLite como base de datos. Para instalaciones mas grandes se recomiende cambiar a otro sistema de base de datos. ",
"Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "El uso de SQLite está desaconsejado especialmente cuando se usa el cliente de escritorio para sincronizar los ficheros.",
"To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" href=\"%s\">documentation ↗</a>." : "Para migrar a otra base de datos use la herramienta de línea de comandos: 'occ db:convert-type', o consulte la <a target=\"_blank\" href=\"%s\">documentación ↗</a>.",
@@ -207,10 +211,13 @@ OC.L10N.register(
"Admin documentation" : "Documentación de administrador",
"Show description …" : "Mostrar descripción…",
"Hide description …" : "Ocultar descripción…",
+ "This app has no minimum ownCloud version assigned. This will be an error in ownCloud 11 and later." : "Esta aplicación no tiene ninguna versión mínima de ownCloud asignada. Este será un error en ownCloud 11 y posteriores.",
+ "This app has no maximum ownCloud version assigned. This will be an error in ownCloud 11 and later." : "Esta aplicación no tiene ninguna versión máxima de ownCloud asignada. Este será un error en ownCloud 11 y posteriores.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Esta aplicación no puede instalarse porque las siguientes dependencias no están cumplimentadas:",
"Enable only for specific groups" : "Activar solamente para grupos específicos",
"Uninstall App" : "Desinstalar aplicación",
"Enable experimental apps" : "Habilitar aplicaciones experimentales",
+ "SSL Root Certificates" : "Raíz de certificados SSL ",
"Common Name" : "Nombre común",
"Valid until" : "Válido hasta",
"Issued By" : "Emitido por",
@@ -224,14 +231,20 @@ OC.L10N.register(
"Forum" : "Foro",
"Issue tracker" : "Seguidor de problemas:",
"Commercial support" : "Soporte Comercial",
+ "You are using <strong>%s</strong> of <strong>%s</strong>" : "Estas usando <strong>%s</strong> de <strong>%s</strong> ",
"Profile picture" : "Foto de perfil",
"Upload new" : "Subir otra",
+ "Select from Files" : "Seleccionar desde Archivos",
"Remove image" : "Borrar imagen",
+ "png or jpg, max. 20 MB" : "png o jpg, max. 20 MB",
+ "Picture provided by original account" : "Imagen provista por cuenta original",
"Cancel" : "Cancelar",
+ "Choose as profile picture" : "Seleccionar como imagen de perfil",
"Full name" : "Nombre completo",
"No display name set" : "No se ha establecido ningún nombre para mostrar",
"Email" : "Correo electrónico",
"Your email address" : "Su dirección de correo",
+ "For password recovery and notifications" : "Para la recuperación de contraseña y notificaciones",
"No email address set" : "Ninguna dirección de correo establecida",
"You are member of the following groups:" : "Es miembro de los siguientes grupos:",
"Password" : "Contraseña",
diff --git a/settings/l10n/es.json b/settings/l10n/es.json
index d3d94db46b8..c4078970f72 100644
--- a/settings/l10n/es.json
+++ b/settings/l10n/es.json
@@ -158,7 +158,10 @@
"Use system's cron service to call the cron.php file every 15 minutes." : "Usar el servicio cron del sistema para llamar al archivo cron.php cada 15 minutos.",
"Enable server-side encryption" : "Habilitar cifrado en el servidor",
"Please read carefully before activating server-side encryption: " : "Por favor lea cuidadosamente antes de activar el cifrado del lado del servidor.",
+ "Once encryption is enabled, all files uploaded to the server from that point forward will be encrypted at rest on the server. It will only be possible to disable encryption at a later date if the active encryption module supports that function, and all pre-conditions (e.g. setting a recover key) are met." : "Una vez que el cifrado está habilitado, todos los archivos subidos al servidor desde ese punto en adelante se cifrarán en reposo en el servidor. Sólo será posible desactivar el cifrado en una fecha posterior si el módulo de cifrado activado soporta esa función, y todas las condiciones previas (por ejemplo, el establecimiento de una clave de recuperación) se cumplan.",
+ "Encryption alone does not guarantee security of the system. Please see ownCloud documentation for more information about how the encryption app works, and the supported use cases." : "El cifrado en sí solo no garantiza la seguridad del sistema. Por favor, consulte la documentación de ownCloud para obtener más información acerca de cómo funciona la aplicación de cifrado, y los casos de uso compatibles.",
"Be aware that encryption always increases the file size." : "Tenga presente que la encripción siempre incrementa el tamaño del archivo.",
+ "It is always good to create regular backups of your data, in case of encryption make sure to backup the encryption keys along with your data." : "Es siempre bueno crear copias de seguridad de sus datos, en el caso del cifrado, asegúrese de tener una copia de seguridad de las claves de cifrado junto con sus datos.",
"This is the final warning: Do you really want to enable encryption?" : "Esta es la advertencia final. ¿Realmente quiere activar el cifrado?",
"Enable encryption" : "Habilitar cifrado",
"No encryption module loaded, please enable an encryption module in the app menu." : "No se ha cargado el modulo de cifrado. Por favor habilite un modulo de cifrado en el menú de aplicaciones.",
@@ -185,6 +188,7 @@
"More" : "Más",
"Less" : "Menos",
"The logfile is bigger than 100 MB. Downloading it may take some time!" : "El archivo de registro es mayor de 100 MB. Descargarlo puede tardar.",
+ "What to log" : "Que registrar",
"SQLite is used as database. For larger installations we recommend to switch to a different database backend." : "Se utiliza SQLite como base de datos. Para instalaciones mas grandes se recomiende cambiar a otro sistema de base de datos. ",
"Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "El uso de SQLite está desaconsejado especialmente cuando se usa el cliente de escritorio para sincronizar los ficheros.",
"To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" href=\"%s\">documentation ↗</a>." : "Para migrar a otra base de datos use la herramienta de línea de comandos: 'occ db:convert-type', o consulte la <a target=\"_blank\" href=\"%s\">documentación ↗</a>.",
@@ -205,10 +209,13 @@
"Admin documentation" : "Documentación de administrador",
"Show description …" : "Mostrar descripción…",
"Hide description …" : "Ocultar descripción…",
+ "This app has no minimum ownCloud version assigned. This will be an error in ownCloud 11 and later." : "Esta aplicación no tiene ninguna versión mínima de ownCloud asignada. Este será un error en ownCloud 11 y posteriores.",
+ "This app has no maximum ownCloud version assigned. This will be an error in ownCloud 11 and later." : "Esta aplicación no tiene ninguna versión máxima de ownCloud asignada. Este será un error en ownCloud 11 y posteriores.",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Esta aplicación no puede instalarse porque las siguientes dependencias no están cumplimentadas:",
"Enable only for specific groups" : "Activar solamente para grupos específicos",
"Uninstall App" : "Desinstalar aplicación",
"Enable experimental apps" : "Habilitar aplicaciones experimentales",
+ "SSL Root Certificates" : "Raíz de certificados SSL ",
"Common Name" : "Nombre común",
"Valid until" : "Válido hasta",
"Issued By" : "Emitido por",
@@ -222,14 +229,20 @@
"Forum" : "Foro",
"Issue tracker" : "Seguidor de problemas:",
"Commercial support" : "Soporte Comercial",
+ "You are using <strong>%s</strong> of <strong>%s</strong>" : "Estas usando <strong>%s</strong> de <strong>%s</strong> ",
"Profile picture" : "Foto de perfil",
"Upload new" : "Subir otra",
+ "Select from Files" : "Seleccionar desde Archivos",
"Remove image" : "Borrar imagen",
+ "png or jpg, max. 20 MB" : "png o jpg, max. 20 MB",
+ "Picture provided by original account" : "Imagen provista por cuenta original",
"Cancel" : "Cancelar",
+ "Choose as profile picture" : "Seleccionar como imagen de perfil",
"Full name" : "Nombre completo",
"No display name set" : "No se ha establecido ningún nombre para mostrar",
"Email" : "Correo electrónico",
"Your email address" : "Su dirección de correo",
+ "For password recovery and notifications" : "Para la recuperación de contraseña y notificaciones",
"No email address set" : "Ninguna dirección de correo establecida",
"You are member of the following groups:" : "Es miembro de los siguientes grupos:",
"Password" : "Contraseña",
diff --git a/settings/users.php b/settings/users.php
index 81f6ed4335c..9d89ff65b4a 100644
--- a/settings/users.php
+++ b/settings/users.php
@@ -103,6 +103,8 @@ $defaultQuota=$config->getAppValue('files', 'default_quota', 'none');
$defaultQuotaIsUserDefined=array_search($defaultQuota, $quotaPreset)===false
&& array_search($defaultQuota, array('none', 'default'))===false;
+\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
+
$tmpl = new OC_Template("settings", "users/main", "user");
$tmpl->assign('groups', $groups);
$tmpl->assign('sortGroups', $sortGroupsBy);
diff --git a/tests/lib/app/manager.php b/tests/lib/app/manager.php
index a3e55c6b890..f82f1049ce3 100644
--- a/tests/lib/app/manager.php
+++ b/tests/lib/app/manager.php
@@ -13,6 +13,12 @@ use OC\Group\Group;
use OC\User\User;
use Test\TestCase;
+/**
+ * Class Manager
+ *
+ * @package Test\App
+ * @group DB
+ */
class Manager extends TestCase {
/**
* @return \OCP\IAppConfig | \PHPUnit_Framework_MockObject_MockObject
@@ -116,6 +122,93 @@ class Manager extends TestCase {
$this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no'));
}
+ public function dataEnableAppForGroupsAllowedTypes() {
+ return [
+ [[]],
+ [[
+ 'types' => [],
+ ]],
+ [[
+ 'types' => ['nickvergessen'],
+ ]],
+ ];
+ }
+
+ /**
+ * @dataProvider dataEnableAppForGroupsAllowedTypes
+ *
+ * @param array $appInfo
+ */
+ public function testEnableAppForGroupsAllowedTypes(array $appInfo) {
+ $groups = array(
+ new Group('group1', array(), null),
+ new Group('group2', array(), null)
+ );
+ $this->expectClearCache();
+
+ /** @var \OC\App\AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
+ $manager = $this->getMockBuilder('OC\App\AppManager')
+ ->setConstructorArgs([
+ $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory
+ ])
+ ->setMethods([
+ 'getAppInfo'
+ ])
+ ->getMock();
+
+ $manager->expects($this->once())
+ ->method('getAppInfo')
+ ->with('test')
+ ->willReturn($appInfo);
+
+ $manager->enableAppForGroups('test', $groups);
+ $this->assertEquals('["group1","group2"]', $this->appConfig->getValue('test', 'enabled', 'no'));
+ }
+
+ public function dataEnableAppForGroupsForbiddenTypes() {
+ return [
+ ['filesystem'],
+ ['prelogin'],
+ ['authentication'],
+ ['logging'],
+ ['prevent_group_restriction'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataEnableAppForGroupsForbiddenTypes
+ *
+ * @param string $type
+ *
+ * @expectedException \Exception
+ * @expectedExceptionMessage test can't be enabled for groups.
+ */
+ public function testEnableAppForGroupsForbiddenTypes($type) {
+ $groups = array(
+ new Group('group1', array(), null),
+ new Group('group2', array(), null)
+ );
+
+ /** @var \OC\App\AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
+ $manager = $this->getMockBuilder('OC\App\AppManager')
+ ->setConstructorArgs([
+ $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory
+ ])
+ ->setMethods([
+ 'getAppInfo'
+ ])
+ ->getMock();
+
+ $manager->expects($this->once())
+ ->method('getAppInfo')
+ ->with('test')
+ ->willReturn([
+ 'types' => [$type],
+ ]);
+
+ $manager->enableAppForGroups('test', $groups);
+ }
+
public function testIsInstalledEnabled() {
$this->appConfig->setValue('test', 'enabled', 'yes');
$this->assertTrue($this->manager->isInstalled('test'));
diff --git a/tests/lib/cache/cappedmemorycache.php b/tests/lib/cache/cappedmemorycache.php
index 5444d928421..a8fb273b80a 100644
--- a/tests/lib/cache/cappedmemorycache.php
+++ b/tests/lib/cache/cappedmemorycache.php
@@ -64,4 +64,16 @@ class CappedMemoryCache extends \Test_Cache {
$this->assertFalse($this->instance->hasKey('2_value1'));
$this->assertFalse($this->instance->hasKey('3_value1'));
}
+
+ function testIndirectSet() {
+ $this->instance->set('array', []);
+
+ $this->instance['array'][] = 'foo';
+
+ $this->assertEquals(['foo'], $this->instance->get('array'));
+
+ $this->instance['array']['bar'] = 'qwerty';
+
+ $this->assertEquals(['foo', 'bar' => 'qwerty'], $this->instance->get('array'));
+ }
}
diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php
index d674ac27fa1..de4ae9cd8e9 100644
--- a/tests/lib/files/cache/cache.php
+++ b/tests/lib/files/cache/cache.php
@@ -556,7 +556,7 @@ class Cache extends \Test\TestCase {
$this->assertEquals($folderWith00F6, $unNormalizedFolderName['name']);
// put normalized folder
- $this->assertTrue(is_array($this->cache->get('folder/' . $folderWith00F6)));
+ $this->assertInstanceOf('\OCP\Files\Cache\ICacheEntry', $this->cache->get('folder/' . $folderWith00F6));
$this->assertGreaterThan(0, $this->cache->put('folder/' . $folderWith00F6, $data));
// at this point we should have only one folder named "Schön"
diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php
index 8186fe29493..b1eb3f589e8 100644
--- a/tests/lib/files/cache/scanner.php
+++ b/tests/lib/files/cache/scanner.php
@@ -7,6 +7,7 @@
*/
namespace Test\Files\Cache;
+use OC\Files\Cache\CacheEntry;
/**
* Class Scanner
@@ -226,6 +227,7 @@ class Scanner extends \Test\TestCase {
// manipulate etag to simulate an empty etag
$this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
+ /** @var CacheEntry $data0 */
$data0 = $this->cache->get('folder/bar.txt');
$this->assertInternalType('string', $data0['etag']);
$data1 = $this->cache->get('folder');
@@ -233,7 +235,7 @@ class Scanner extends \Test\TestCase {
$data2 = $this->cache->get('');
$this->assertInternalType('string', $data2['etag']);
$data0['etag'] = '';
- $this->cache->put('folder/bar.txt', $data0);
+ $this->cache->put('folder/bar.txt', $data0->getData());
// rescan
$this->scanner->scan('folder/bar.txt', \OC\Files\Cache\Scanner::SCAN_SHALLOW, \OC\Files\Cache\Scanner::REUSE_ETAG);
diff --git a/tests/lib/files/storage/wrapper/quota.php b/tests/lib/files/storage/wrapper/quota.php
index 95bc2ff7a1a..d087a3eef33 100644
--- a/tests/lib/files/storage/wrapper/quota.php
+++ b/tests/lib/files/storage/wrapper/quota.php
@@ -9,6 +9,8 @@
namespace Test\Files\Storage\Wrapper;
//ensure the constants are loaded
+use OC\Files\Cache\CacheEntry;
+
\OC::$loader->load('\OC\Files\Filesystem');
/**
@@ -194,7 +196,7 @@ class Quota extends \Test\Files\Storage\Storage {
$cache->expects($this->once())
->method('get')
->with('files')
- ->will($this->returnValue(array('size' => 50)));
+ ->will($this->returnValue(new CacheEntry(['size' => 50])));
$instance = new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => 1024, 'root' => 'files'));