diff options
author | Robin McCorkell <rmccorkell@owncloud.com> | 2015-09-14 19:50:52 +0100 |
---|---|---|
committer | Robin McCorkell <rmccorkell@owncloud.com> | 2015-09-14 19:50:52 +0100 |
commit | 35d4851af2733515a1c81d4c0b78c4c14bf570e6 (patch) | |
tree | 7adde58609d8de5d7b64774f4339cdc4dd0c7449 /lib | |
parent | 227868fe168529a638dcf2dbff4ff8f44cadc519 (diff) | |
parent | fb9e75edb6d01729a27c84f6f11399a1b0fde9f3 (diff) | |
download | nextcloud-server-35d4851af2733515a1c81d4c0b78c4c14bf570e6.tar.gz nextcloud-server-35d4851af2733515a1c81d4c0b78c4c14bf570e6.zip |
Merge branch 'master' into fix-app-disable-route
Diffstat (limited to 'lib')
64 files changed, 2022 insertions, 290 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php index d7649781ea1..41a040b3f54 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -27,6 +27,8 @@ namespace OC; +use \OCP\AutoloadNotAllowedException; + class Autoloader { private $useGlobalClassPath = true; @@ -58,7 +60,7 @@ class Autoloader { * @param string $root */ public function addValidRoot($root) { - $this->validRoots[] = $root; + $this->validRoots[] = stream_resolve_include_path($root); } /** @@ -129,7 +131,7 @@ class Autoloader { return true; } } - throw new \Exception('Path not allowed: '. $fullPath); + throw new AutoloadNotAllowedException($fullPath); } /** diff --git a/lib/base.php b/lib/base.php index 63aad4518ab..5f8a7ed0f19 100644 --- a/lib/base.php +++ b/lib/base.php @@ -552,10 +552,6 @@ class OC { exit(); } - foreach(OC::$APPSROOTS as $appRoot) { - self::$loader->addValidRoot($appRoot['path']); - } - // setup the basic server self::$server = new \OC\Server(\OC::$WEBROOT); \OC::$server->getEventLogger()->log('autoloader', 'Autoloader', $loaderStart, $loaderEnd); @@ -1119,27 +1115,16 @@ class OC { } return true; } -} -if (!function_exists('get_temp_dir')) { /** * Get the temporary dir to store uploaded data * @return null|string Path to the temporary directory or null */ function get_temp_dir() { - if ($temp = ini_get('upload_tmp_dir')) return $temp; - if ($temp = getenv('TMP')) return $temp; - if ($temp = getenv('TEMP')) return $temp; - if ($temp = getenv('TMPDIR')) return $temp; - $temp = tempnam(__FILE__, ''); - if (file_exists($temp)) { - unlink($temp); - return dirname($temp); - } - if ($temp = sys_get_temp_dir()) return $temp; - - return null; + return \OC::$server->getTempManager()->t_get_temp_dir(); } + } + OC::init(); diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js index 715b834d2bf..65ff43b4f23 100644 --- a/lib/l10n/cs_CZ.js +++ b/lib/l10n/cs_CZ.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Sdílení položky %s selhalo, protože uživatel %s neexistuje", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Sdílení položky %s selhalo, protože uživatel %s není členem žádné skupiny společné s uživatelem %s", "Sharing %s failed, because this item is already shared with %s" : "Sdílení položky %s selhalo, protože položka již je s uživatelem %s sdílena", + "Sharing %s failed, because this item is already shared with user %s" : "Sdílení položky %s selhalo, protože ta je již s uživatelem %s sdílena", "Sharing %s failed, because the group %s does not exist" : "Sdílení položky %s selhalo, protože skupina %s neexistuje", "Sharing %s failed, because %s is not a member of the group %s" : "Sdílení položky %s selhalo, protože uživatel %s není členem skupiny %s", "You need to provide a password to create a public link, only protected links are allowed" : "Pro vytvoření veřejného odkazu je nutné zadat heslo, jsou povoleny pouze chráněné odkazy", diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json index 891b30850ab..501210dd0f8 100644 --- a/lib/l10n/cs_CZ.json +++ b/lib/l10n/cs_CZ.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Sdílení položky %s selhalo, protože uživatel %s neexistuje", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Sdílení položky %s selhalo, protože uživatel %s není členem žádné skupiny společné s uživatelem %s", "Sharing %s failed, because this item is already shared with %s" : "Sdílení položky %s selhalo, protože položka již je s uživatelem %s sdílena", + "Sharing %s failed, because this item is already shared with user %s" : "Sdílení položky %s selhalo, protože ta je již s uživatelem %s sdílena", "Sharing %s failed, because the group %s does not exist" : "Sdílení položky %s selhalo, protože skupina %s neexistuje", "Sharing %s failed, because %s is not a member of the group %s" : "Sdílení položky %s selhalo, protože uživatel %s není členem skupiny %s", "You need to provide a password to create a public link, only protected links are allowed" : "Pro vytvoření veřejného odkazu je nutné zadat heslo, jsou povoleny pouze chráněné odkazy", diff --git a/lib/l10n/da.js b/lib/l10n/da.js index 42f367d21c2..285e9ac55d1 100644 --- a/lib/l10n/da.js +++ b/lib/l10n/da.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Der skete en fejl ved deling af %s, brugeren %s eksistere ikke", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Der skete en fejl ved deling af %s, brugeren %s er ikke medlem af nogle grupper som %s er medlem af", "Sharing %s failed, because this item is already shared with %s" : "Der skete en fejl ved deling af %s, objektet er allerede delt med %s", + "Sharing %s failed, because this item is already shared with user %s" : "Deling af %s mislykkedes, fordi dette element allerede er delt med brugeren %s", "Sharing %s failed, because the group %s does not exist" : "Der skete en fejl ved deling af %s, gruppen %s eksistere ikke", "Sharing %s failed, because %s is not a member of the group %s" : "Der skete en fejl ved deling af %s, fordi %s ikke er medlem af gruppen %s", "You need to provide a password to create a public link, only protected links are allowed" : "Du skal angive et kodeord for at oprette et offentligt link - kun beskyttede links er tilladt", @@ -131,7 +132,7 @@ OC.L10N.register( "PHP setting \"%s\" is not set to \"%s\"." : "PHP-indstillingen \"%s\" er ikke angivet til \"%s\".", "Adjusting this setting in php.ini will make ownCloud run again" : "Justeres denne indstilling i php.ini, så vil ownCloud kunne køre igen", "mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload er angivet til \"%s\", i stedet for den forventede værdi \"0\"", - "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, så angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini", + "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini", "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP er tilsyneladende sat op til at fjerne indlejrede doc-blokke. Dette vil gøre adskillige kerneprogrammer utilgængelige.", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dette er sansynligvis forårsaget af et accelerator eller cache som Zend OPcache eller eAccelerator", "PHP modules have been installed, but they are still listed as missing?" : "Der er installeret PHP-moduler, men de fremstår stadig som fraværende?", diff --git a/lib/l10n/da.json b/lib/l10n/da.json index 0e20adc31bf..1b9ed304596 100644 --- a/lib/l10n/da.json +++ b/lib/l10n/da.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Der skete en fejl ved deling af %s, brugeren %s eksistere ikke", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Der skete en fejl ved deling af %s, brugeren %s er ikke medlem af nogle grupper som %s er medlem af", "Sharing %s failed, because this item is already shared with %s" : "Der skete en fejl ved deling af %s, objektet er allerede delt med %s", + "Sharing %s failed, because this item is already shared with user %s" : "Deling af %s mislykkedes, fordi dette element allerede er delt med brugeren %s", "Sharing %s failed, because the group %s does not exist" : "Der skete en fejl ved deling af %s, gruppen %s eksistere ikke", "Sharing %s failed, because %s is not a member of the group %s" : "Der skete en fejl ved deling af %s, fordi %s ikke er medlem af gruppen %s", "You need to provide a password to create a public link, only protected links are allowed" : "Du skal angive et kodeord for at oprette et offentligt link - kun beskyttede links er tilladt", @@ -129,7 +130,7 @@ "PHP setting \"%s\" is not set to \"%s\"." : "PHP-indstillingen \"%s\" er ikke angivet til \"%s\".", "Adjusting this setting in php.ini will make ownCloud run again" : "Justeres denne indstilling i php.ini, så vil ownCloud kunne køre igen", "mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload er angivet til \"%s\", i stedet for den forventede værdi \"0\"", - "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, så angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini", + "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "For at rette dette problem, angiv\n<code>mbstring.func_overload</code> til <code>0</code> i din php.ini", "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP er tilsyneladende sat op til at fjerne indlejrede doc-blokke. Dette vil gøre adskillige kerneprogrammer utilgængelige.", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Dette er sansynligvis forårsaget af et accelerator eller cache som Zend OPcache eller eAccelerator", "PHP modules have been installed, but they are still listed as missing?" : "Der er installeret PHP-moduler, men de fremstår stadig som fraværende?", diff --git a/lib/l10n/el.js b/lib/l10n/el.js index b47cc7e36d2..ee9ad8efd42 100644 --- a/lib/l10n/el.js +++ b/lib/l10n/el.js @@ -88,6 +88,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν υπάρχει", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος καμίας ομάδας στην οποία ο χρήστης %s είναι μέλος", "Sharing %s failed, because this item is already shared with %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί το αντικείμενο είναι διαμοιρασμένο ήδη με τον χρήστη %s", + "Sharing %s failed, because this item is already shared with user %s" : "Αποτυχία διαμοιρασμού με %s, διότι αυτό το αντικείμενο διαμοιράζεται ήδη με τον χρήστη %s", "Sharing %s failed, because the group %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί η ομάδα χρηστών %s δεν υπάρχει", "Sharing %s failed, because %s is not a member of the group %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος της ομάδας %s", "You need to provide a password to create a public link, only protected links are allowed" : "Πρέπει να εισάγετε έναν κωδικό για να δημιουργήσετε έναν δημόσιο σύνδεσμο. Μόνο προστατευμένοι σύνδεσμοι επιτρέπονται", diff --git a/lib/l10n/el.json b/lib/l10n/el.json index d82aec00129..d0235598f7e 100644 --- a/lib/l10n/el.json +++ b/lib/l10n/el.json @@ -86,6 +86,7 @@ "Sharing %s failed, because the user %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν υπάρχει", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος καμίας ομάδας στην οποία ο χρήστης %s είναι μέλος", "Sharing %s failed, because this item is already shared with %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί το αντικείμενο είναι διαμοιρασμένο ήδη με τον χρήστη %s", + "Sharing %s failed, because this item is already shared with user %s" : "Αποτυχία διαμοιρασμού με %s, διότι αυτό το αντικείμενο διαμοιράζεται ήδη με τον χρήστη %s", "Sharing %s failed, because the group %s does not exist" : "Ο διαμοιρασμός του %s απέτυχε, γιατί η ομάδα χρηστών %s δεν υπάρχει", "Sharing %s failed, because %s is not a member of the group %s" : "Ο διαμοιρασμός του %s απέτυχε, γιατί ο χρήστης %s δεν είναι μέλος της ομάδας %s", "You need to provide a password to create a public link, only protected links are allowed" : "Πρέπει να εισάγετε έναν κωδικό για να δημιουργήσετε έναν δημόσιο σύνδεσμο. Μόνο προστατευμένοι σύνδεσμοι επιτρέπονται", diff --git a/lib/l10n/es.js b/lib/l10n/es.js index e08ed66f1b5..3f1d751fc1e 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Se ha fallado al compartir %s, ya que el usuario %s no existe", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Se ha fallado al compartir %s, ya que el usuario %s no es miembro de ningún grupo del que %s sea miembro", "Sharing %s failed, because this item is already shared with %s" : "Se falló al compartir %s, ya que este elemento ya está compartido con %s", + "Sharing %s failed, because this item is already shared with user %s" : "Compartiendo %s falló, porque este objeto ya se comparte con el usuario %s", "Sharing %s failed, because the group %s does not exist" : "Se falló al compartir %s, ya que el grupo %s no existe", "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", diff --git a/lib/l10n/es.json b/lib/l10n/es.json index f9bca103231..75b8060b819 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Se ha fallado al compartir %s, ya que el usuario %s no existe", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Se ha fallado al compartir %s, ya que el usuario %s no es miembro de ningún grupo del que %s sea miembro", "Sharing %s failed, because this item is already shared with %s" : "Se falló al compartir %s, ya que este elemento ya está compartido con %s", + "Sharing %s failed, because this item is already shared with user %s" : "Compartiendo %s falló, porque este objeto ya se comparte con el usuario %s", "Sharing %s failed, because the group %s does not exist" : "Se falló al compartir %s, ya que el grupo %s no existe", "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", diff --git a/lib/l10n/fi_FI.js b/lib/l10n/fi_FI.js index d82d26645db..6960162e0ab 100644 --- a/lib/l10n/fi_FI.js +++ b/lib/l10n/fi_FI.js @@ -82,6 +82,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s is the item owner" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s on kohteen omistaja", "Sharing %s failed, because the user %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska käyttäjää %s ei ole olemassa", "Sharing %s failed, because this item is already shared with %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa", + "Sharing %s failed, because this item is already shared with user %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa", "Sharing %s failed, because the group %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska ryhmää %s ei ole olemassa", "Sharing %s failed, because %s is not a member of the group %s" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s ei ole ryhmän %s jäsen", "You need to provide a password to create a public link, only protected links are allowed" : "Anna salasana luodaksesi julkisen linkin. Vain suojatut linkit ovat sallittuja", diff --git a/lib/l10n/fi_FI.json b/lib/l10n/fi_FI.json index de6d474e467..7d23189b358 100644 --- a/lib/l10n/fi_FI.json +++ b/lib/l10n/fi_FI.json @@ -80,6 +80,7 @@ "Sharing %s failed, because the user %s is the item owner" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s on kohteen omistaja", "Sharing %s failed, because the user %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska käyttäjää %s ei ole olemassa", "Sharing %s failed, because this item is already shared with %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa", + "Sharing %s failed, because this item is already shared with user %s" : "Kohteen %s jakaminen epäonnistui, koska kohde on jo jaettu käyttäjän %s kanssa", "Sharing %s failed, because the group %s does not exist" : "Kohteen %s jakaminen epäonnistui, koska ryhmää %s ei ole olemassa", "Sharing %s failed, because %s is not a member of the group %s" : "Kohteen %s jakaminen epäonnistui, koska käyttäjä %s ei ole ryhmän %s jäsen", "You need to provide a password to create a public link, only protected links are allowed" : "Anna salasana luodaksesi julkisen linkin. Vain suojatut linkit ovat sallittuja", diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js index 873abd44ad0..d0abd693e0c 100644 --- a/lib/l10n/fr.js +++ b/lib/l10n/fr.js @@ -90,6 +90,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Le partage de %s a échoué car l'utilisateur %s n'existe pas", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Le partage de %s a échoué car l'utilisateur %s n'est membre d'aucun groupe auquel %s appartient", "Sharing %s failed, because this item is already shared with %s" : "Le partage de %s a échoué car cet objet est déjà partagé avec %s", + "Sharing %s failed, because this item is already shared with user %s" : "Le partage de %s a échoué car cet élément est déjà partagé avec l'utilisateur %s", "Sharing %s failed, because the group %s does not exist" : "Le partage de %s a échoué car le groupe %s n'existe pas", "Sharing %s failed, because %s is not a member of the group %s" : "Le partage de %s a échoué car %s n'est pas membre du groupe %s", "You need to provide a password to create a public link, only protected links are allowed" : "Vous devez fournir un mot de passe pour créer un lien public, seuls les liens protégés sont autorisées.", diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json index 440f2ddd84d..d0a90797df9 100644 --- a/lib/l10n/fr.json +++ b/lib/l10n/fr.json @@ -88,6 +88,7 @@ "Sharing %s failed, because the user %s does not exist" : "Le partage de %s a échoué car l'utilisateur %s n'existe pas", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Le partage de %s a échoué car l'utilisateur %s n'est membre d'aucun groupe auquel %s appartient", "Sharing %s failed, because this item is already shared with %s" : "Le partage de %s a échoué car cet objet est déjà partagé avec %s", + "Sharing %s failed, because this item is already shared with user %s" : "Le partage de %s a échoué car cet élément est déjà partagé avec l'utilisateur %s", "Sharing %s failed, because the group %s does not exist" : "Le partage de %s a échoué car le groupe %s n'existe pas", "Sharing %s failed, because %s is not a member of the group %s" : "Le partage de %s a échoué car %s n'est pas membre du groupe %s", "You need to provide a password to create a public link, only protected links are allowed" : "Vous devez fournir un mot de passe pour créer un lien public, seuls les liens protégés sont autorisées.", diff --git a/lib/l10n/id.js b/lib/l10n/id.js index 2114b34eddd..0de6a4124fb 100644 --- a/lib/l10n/id.js +++ b/lib/l10n/id.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Gagal membagikan %s, karena pengguna %s tidak ada", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Gagal membagikan %s, karena pengguna %s bukan merupakan anggota dari grup yang %s ikuti", "Sharing %s failed, because this item is already shared with %s" : "Gagal membagkan %s, karena item ini sudah dibagikan dengan %s", + "Sharing %s failed, because this item is already shared with user %s" : "Berbagi %s gagal karena item ini sudah dibagikan dengan pengguna %s", "Sharing %s failed, because the group %s does not exist" : "Gagal membagikan %s, karena grup %s tidak ada", "Sharing %s failed, because %s is not a member of the group %s" : "Gagal membagikan %s, karena %s bukan anggota dari grup %s", "You need to provide a password to create a public link, only protected links are allowed" : "Anda perlu memberikan sandi untuk membuat tautan publik, hanya tautan yang terlindungi yang diizinkan", diff --git a/lib/l10n/id.json b/lib/l10n/id.json index cdc17b6ce8e..e1b3a9f93b0 100644 --- a/lib/l10n/id.json +++ b/lib/l10n/id.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Gagal membagikan %s, karena pengguna %s tidak ada", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Gagal membagikan %s, karena pengguna %s bukan merupakan anggota dari grup yang %s ikuti", "Sharing %s failed, because this item is already shared with %s" : "Gagal membagkan %s, karena item ini sudah dibagikan dengan %s", + "Sharing %s failed, because this item is already shared with user %s" : "Berbagi %s gagal karena item ini sudah dibagikan dengan pengguna %s", "Sharing %s failed, because the group %s does not exist" : "Gagal membagikan %s, karena grup %s tidak ada", "Sharing %s failed, because %s is not a member of the group %s" : "Gagal membagikan %s, karena %s bukan anggota dari grup %s", "You need to provide a password to create a public link, only protected links are allowed" : "Anda perlu memberikan sandi untuk membuat tautan publik, hanya tautan yang terlindungi yang diizinkan", diff --git a/lib/l10n/it.js b/lib/l10n/it.js index d0c0022fd06..d0cf725013b 100644 --- a/lib/l10n/it.js +++ b/lib/l10n/it.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Condivisione di %s non riuscita, poiché l'utente %s non esiste", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Condivisione di %s non riuscita, poiché l'utente %s non appartiene ad alcun gruppo di cui %s è membro", "Sharing %s failed, because this item is already shared with %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con %s", + "Sharing %s failed, because this item is already shared with user %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con l'utente %s", "Sharing %s failed, because the group %s does not exist" : "Condivisione di %s non riuscita, poiché il gruppo %s non esiste", "Sharing %s failed, because %s is not a member of the group %s" : "Condivisione di %s non riuscita, poiché %s non appartiene al gruppo %s", "You need to provide a password to create a public link, only protected links are allowed" : "Devi fornire una password per creare un collegamento pubblico, sono consentiti solo i collegamenti protetti", diff --git a/lib/l10n/it.json b/lib/l10n/it.json index 1183b588eb2..81038c0e425 100644 --- a/lib/l10n/it.json +++ b/lib/l10n/it.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Condivisione di %s non riuscita, poiché l'utente %s non esiste", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Condivisione di %s non riuscita, poiché l'utente %s non appartiene ad alcun gruppo di cui %s è membro", "Sharing %s failed, because this item is already shared with %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con %s", + "Sharing %s failed, because this item is already shared with user %s" : "Condivisione di %s non riuscita, poiché l'oggetto è già condiviso con l'utente %s", "Sharing %s failed, because the group %s does not exist" : "Condivisione di %s non riuscita, poiché il gruppo %s non esiste", "Sharing %s failed, because %s is not a member of the group %s" : "Condivisione di %s non riuscita, poiché %s non appartiene al gruppo %s", "You need to provide a password to create a public link, only protected links are allowed" : "Devi fornire una password per creare un collegamento pubblico, sono consentiti solo i collegamenti protetti", diff --git a/lib/l10n/ko.js b/lib/l10n/ko.js index a2ec230d59f..bb143bdd527 100644 --- a/lib/l10n/ko.js +++ b/lib/l10n/ko.js @@ -49,6 +49,7 @@ OC.L10N.register( "Can't read file" : "파일을 읽을 수 없음", "App directory already exists" : "앱 디렉터리가 이미 존재합니다.", "Can't create app folder. Please fix permissions. %s" : "앱 폴더를 만들 수 없습니다. 권한을 수정하십시오. %s", + "Archive does not contain a directory named %s" : "압축 파일에 디렉터리 %s이(가) 없습니다", "No source specified when installing app" : "앱을 설치할 때 소스가 지정되지 않았습니다.", "No href specified when installing app from http" : "http에서 앱을 설치할 때 href가 지정되지 않았습니다.", "No path specified when installing app from local file" : "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.", @@ -90,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "%s을(를) 공유할 수 없습니다. 사용자 %s이(가) 존재하지 않습니다", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "%s을(를) 공유할 수 없습니다. 사용자 %s 님은 %s 님이 회원인 어떠한 그룹에도 속해 있지 않습니다", "Sharing %s failed, because this item is already shared with %s" : "%s을(를) 공유할 수 없습니다. 이미 %s 님과 공유되어 있습니다", + "Sharing %s failed, because this item is already shared with user %s" : "%s을(를) 공유할 수 없습니다. 이 항목을 이미 %s 님과 공유하고 있습니다", "Sharing %s failed, because the group %s does not exist" : "%s을(를) 공유할 수 없습니다. 그룹 %s이(가) 존재하지 않습니다", "Sharing %s failed, because %s is not a member of the group %s" : "%s을(를) 공유할 수 없습니다. %s 님이 그룹 %s의 구성원이 아닙니다", "You need to provide a password to create a public link, only protected links are allowed" : "공개 링크를 만들려면 암호를 입력해야 합니다. 보호된 링크만 사용 가능합니다", diff --git a/lib/l10n/ko.json b/lib/l10n/ko.json index fa52b9a8f05..8fea07402ca 100644 --- a/lib/l10n/ko.json +++ b/lib/l10n/ko.json @@ -47,6 +47,7 @@ "Can't read file" : "파일을 읽을 수 없음", "App directory already exists" : "앱 디렉터리가 이미 존재합니다.", "Can't create app folder. Please fix permissions. %s" : "앱 폴더를 만들 수 없습니다. 권한을 수정하십시오. %s", + "Archive does not contain a directory named %s" : "압축 파일에 디렉터리 %s이(가) 없습니다", "No source specified when installing app" : "앱을 설치할 때 소스가 지정되지 않았습니다.", "No href specified when installing app from http" : "http에서 앱을 설치할 때 href가 지정되지 않았습니다.", "No path specified when installing app from local file" : "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.", @@ -88,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "%s을(를) 공유할 수 없습니다. 사용자 %s이(가) 존재하지 않습니다", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "%s을(를) 공유할 수 없습니다. 사용자 %s 님은 %s 님이 회원인 어떠한 그룹에도 속해 있지 않습니다", "Sharing %s failed, because this item is already shared with %s" : "%s을(를) 공유할 수 없습니다. 이미 %s 님과 공유되어 있습니다", + "Sharing %s failed, because this item is already shared with user %s" : "%s을(를) 공유할 수 없습니다. 이 항목을 이미 %s 님과 공유하고 있습니다", "Sharing %s failed, because the group %s does not exist" : "%s을(를) 공유할 수 없습니다. 그룹 %s이(가) 존재하지 않습니다", "Sharing %s failed, because %s is not a member of the group %s" : "%s을(를) 공유할 수 없습니다. %s 님이 그룹 %s의 구성원이 아닙니다", "You need to provide a password to create a public link, only protected links are allowed" : "공개 링크를 만들려면 암호를 입력해야 합니다. 보호된 링크만 사용 가능합니다", diff --git a/lib/l10n/nb_NO.js b/lib/l10n/nb_NO.js index d09fa5ca6e8..af629c5ef34 100644 --- a/lib/l10n/nb_NO.js +++ b/lib/l10n/nb_NO.js @@ -49,6 +49,7 @@ OC.L10N.register( "Can't read file" : "Kan ikke lese fil", "App directory already exists" : "App-mappe finnes allerede", "Can't create app folder. Please fix permissions. %s" : "Kan ikke opprette app-mappe. Vennligst ordne opp i tillatelser. %s", + "Archive does not contain a directory named %s" : "Arkivet inneholder ikke en mappe med navn %s", "No source specified when installing app" : "Ingen kilde spesifisert ved installering av app", "No href specified when installing app from http" : "Ingen href spesifisert ved installering av app fra http", "No path specified when installing app from local file" : "Ingen sti spesifisert ved installering av app fra lokal fil", @@ -90,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Deling av %s feilet, fordi brukeren %s ikke finnes", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Deling av %s feilet, fordi brukeren %s ikke er medlem av noen grupper som %s er medlem av", "Sharing %s failed, because this item is already shared with %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med %s", + "Sharing %s failed, because this item is already shared with user %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med bruker %s", "Sharing %s failed, because the group %s does not exist" : "Deling av %s feilet, fordi gruppen %s ikke finnes", "Sharing %s failed, because %s is not a member of the group %s" : "Deling av %s feilet, fordi %s ikke er medlem av gruppen %s", "You need to provide a password to create a public link, only protected links are allowed" : "Du må oppgi et passord for å lage en offentlig lenke. Bare beskyttede lenker er tillatt", diff --git a/lib/l10n/nb_NO.json b/lib/l10n/nb_NO.json index 665ae866969..29f9e7f1365 100644 --- a/lib/l10n/nb_NO.json +++ b/lib/l10n/nb_NO.json @@ -47,6 +47,7 @@ "Can't read file" : "Kan ikke lese fil", "App directory already exists" : "App-mappe finnes allerede", "Can't create app folder. Please fix permissions. %s" : "Kan ikke opprette app-mappe. Vennligst ordne opp i tillatelser. %s", + "Archive does not contain a directory named %s" : "Arkivet inneholder ikke en mappe med navn %s", "No source specified when installing app" : "Ingen kilde spesifisert ved installering av app", "No href specified when installing app from http" : "Ingen href spesifisert ved installering av app fra http", "No path specified when installing app from local file" : "Ingen sti spesifisert ved installering av app fra lokal fil", @@ -88,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Deling av %s feilet, fordi brukeren %s ikke finnes", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Deling av %s feilet, fordi brukeren %s ikke er medlem av noen grupper som %s er medlem av", "Sharing %s failed, because this item is already shared with %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med %s", + "Sharing %s failed, because this item is already shared with user %s" : "Deling av %s feilet, fordi dette elementet allerede er delt med bruker %s", "Sharing %s failed, because the group %s does not exist" : "Deling av %s feilet, fordi gruppen %s ikke finnes", "Sharing %s failed, because %s is not a member of the group %s" : "Deling av %s feilet, fordi %s ikke er medlem av gruppen %s", "You need to provide a password to create a public link, only protected links are allowed" : "Du må oppgi et passord for å lage en offentlig lenke. Bare beskyttede lenker er tillatt", diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js index d08e8294dfb..5abae786d34 100644 --- a/lib/l10n/nl.js +++ b/lib/l10n/nl.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Delen van %s is mislukt, omdat gebruiker %s niet bestaat", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Delen van %s is mislukt, omdat gebruiker %s geen lid is van een groep waar %s lid van is", "Sharing %s failed, because this item is already shared with %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met %s", + "Sharing %s failed, because this item is already shared with user %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met gebruiker %s", "Sharing %s failed, because the group %s does not exist" : "Delen van %s is mislukt, omdat groep %s niet bestaat", "Sharing %s failed, because %s is not a member of the group %s" : "Delen van %s is mislukt, omdat %s geen lid is van groep %s", "You need to provide a password to create a public link, only protected links are allowed" : "U moet een wachtwoord verstrekken om een openbare koppeling te maken, alleen beschermde links zijn toegestaan", diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json index 8d0b5dc7169..4e4eaf8b52a 100644 --- a/lib/l10n/nl.json +++ b/lib/l10n/nl.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Delen van %s is mislukt, omdat gebruiker %s niet bestaat", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Delen van %s is mislukt, omdat gebruiker %s geen lid is van een groep waar %s lid van is", "Sharing %s failed, because this item is already shared with %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met %s", + "Sharing %s failed, because this item is already shared with user %s" : "Delen van %s is mislukt, omdat het object al wordt gedeeld met gebruiker %s", "Sharing %s failed, because the group %s does not exist" : "Delen van %s is mislukt, omdat groep %s niet bestaat", "Sharing %s failed, because %s is not a member of the group %s" : "Delen van %s is mislukt, omdat %s geen lid is van groep %s", "You need to provide a password to create a public link, only protected links are allowed" : "U moet een wachtwoord verstrekken om een openbare koppeling te maken, alleen beschermde links zijn toegestaan", diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js index a53e5f01a16..402a7cbc51a 100644 --- a/lib/l10n/pt_BR.js +++ b/lib/l10n/pt_BR.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "Compartilhamento %s falhou, porque o usuário %s não existe", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Compartilhamento %s falhou, porque o usuário %s não é membro de nenhum grupo que o usuário %s pertença", "Sharing %s failed, because this item is already shared with %s" : "Compartilhamento %s falhou, porque este ítem já está compartilhado com %s", + "Sharing %s failed, because this item is already shared with user %s" : "Compartilhamento de %s falhou, porque esse item já é compartilhada com o usuário %s", "Sharing %s failed, because the group %s does not exist" : "Compartilhamento %s falhou, porque o grupo %s não existe", "Sharing %s failed, because %s is not a member of the group %s" : "Compartilhamento %s falhou, porque %s não é membro do grupo %s", "You need to provide a password to create a public link, only protected links are allowed" : "Você precisa fornecer uma senha para criar um link público, apenas links protegidos são permitidos", diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json index cef167c2098..255272b8cb8 100644 --- a/lib/l10n/pt_BR.json +++ b/lib/l10n/pt_BR.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "Compartilhamento %s falhou, porque o usuário %s não existe", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Compartilhamento %s falhou, porque o usuário %s não é membro de nenhum grupo que o usuário %s pertença", "Sharing %s failed, because this item is already shared with %s" : "Compartilhamento %s falhou, porque este ítem já está compartilhado com %s", + "Sharing %s failed, because this item is already shared with user %s" : "Compartilhamento de %s falhou, porque esse item já é compartilhada com o usuário %s", "Sharing %s failed, because the group %s does not exist" : "Compartilhamento %s falhou, porque o grupo %s não existe", "Sharing %s failed, because %s is not a member of the group %s" : "Compartilhamento %s falhou, porque %s não é membro do grupo %s", "You need to provide a password to create a public link, only protected links are allowed" : "Você precisa fornecer uma senha para criar um link público, apenas links protegidos são permitidos", diff --git a/lib/l10n/th_TH.js b/lib/l10n/th_TH.js index 2ff86f599e9..6092f348cb5 100644 --- a/lib/l10n/th_TH.js +++ b/lib/l10n/th_TH.js @@ -91,6 +91,7 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "การแชร์ %s ล้มเหลวเนื่องจากไม่ได้มีผู้ใช้ %s อยู่", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "การแชร์ %s ล้มเหลวเนื่องจากผู้ใช้ %s ไม่ได้เป็นสมาชิกของกลุ่มใดๆ %s เป็นสมาชิกของ", "Sharing %s failed, because this item is already shared with %s" : "การแชร์ %s ล้มเหลวเพราะรายการนี้ถูกแชร์กับ %s", + "Sharing %s failed, because this item is already shared with user %s" : "%s ที่กำลังแชร์ล้มเหลว เพราะรายการนี้ได้ถูกแชร์กับผู้ใช้ %s", "Sharing %s failed, because the group %s does not exist" : "การแชร์ %s ล้มเหลวเพราะไม่มีกลุ่ม %s อยู่", "Sharing %s failed, because %s is not a member of the group %s" : "การแชร์ %s ล้มเหลวเพราะ %s ไม่ได้เป็นสมาชิกของกลุ่ม %s", "You need to provide a password to create a public link, only protected links are allowed" : "คุณจำเป็นต้องระบุรหัสผ่านเพื่อสร้างลิงค์สาธารณะ, ลิงค์ที่มีการป้องกันเท่านั้นที่ได้รับอนุญาต", diff --git a/lib/l10n/th_TH.json b/lib/l10n/th_TH.json index a215b67a180..a872236a70d 100644 --- a/lib/l10n/th_TH.json +++ b/lib/l10n/th_TH.json @@ -89,6 +89,7 @@ "Sharing %s failed, because the user %s does not exist" : "การแชร์ %s ล้มเหลวเนื่องจากไม่ได้มีผู้ใช้ %s อยู่", "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "การแชร์ %s ล้มเหลวเนื่องจากผู้ใช้ %s ไม่ได้เป็นสมาชิกของกลุ่มใดๆ %s เป็นสมาชิกของ", "Sharing %s failed, because this item is already shared with %s" : "การแชร์ %s ล้มเหลวเพราะรายการนี้ถูกแชร์กับ %s", + "Sharing %s failed, because this item is already shared with user %s" : "%s ที่กำลังแชร์ล้มเหลว เพราะรายการนี้ได้ถูกแชร์กับผู้ใช้ %s", "Sharing %s failed, because the group %s does not exist" : "การแชร์ %s ล้มเหลวเพราะไม่มีกลุ่ม %s อยู่", "Sharing %s failed, because %s is not a member of the group %s" : "การแชร์ %s ล้มเหลวเพราะ %s ไม่ได้เป็นสมาชิกของกลุ่ม %s", "You need to provide a password to create a public link, only protected links are allowed" : "คุณจำเป็นต้องระบุรหัสผ่านเพื่อสร้างลิงค์สาธารณะ, ลิงค์ที่มีการป้องกันเท่านั้นที่ได้รับอนุญาต", diff --git a/lib/private/app.php b/lib/private/app.php index d5415834fa4..6eba215ee27 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -105,7 +105,6 @@ class OC_App { ob_start(); foreach ($apps as $app) { if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) { - self::$loadedApps[] = $app; self::loadApp($app); } } @@ -122,6 +121,8 @@ class OC_App { * @throws \OC\NeedsUpdateException */ public static function loadApp($app, $checkUpgrade = true) { + self::$loadedApps[] = $app; + \OC::$loader->addValidRoot(self::getAppPath($app)); if (is_file(self::getAppPath($app) . '/appinfo/app.php')) { \OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app); if ($checkUpgrade and self::shouldUpgrade($app)) { diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php index 7ee64980fd0..cf2a057f224 100644 --- a/lib/private/appconfig.php +++ b/lib/private/appconfig.php @@ -175,11 +175,21 @@ class AppConfig implements IAppConfig { ->set('configvalue', $sql->createParameter('configvalue')) ->where($sql->expr()->eq('appid', $sql->createParameter('app'))) ->andWhere($sql->expr()->eq('configkey', $sql->createParameter('configkey'))) - ->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue'))) ->setParameter('configvalue', $value) ->setParameter('app', $app) - ->setParameter('configkey', $key) - ->setParameter('configvalue', $value); + ->setParameter('configkey', $key); + + /* + * Only limit to the existing value for non-Oracle DBs: + * http://docs.oracle.com/cd/E11882_01/server.112/e26088/conditions002.htm#i1033286 + * > Large objects (LOBs) are not supported in comparison conditions. + */ + if (!($this->conn instanceof \OC\DB\OracleConnection)) { + // Only update the value when it is not the same + $sql->andWhere($sql->expr()->neq('configvalue', $sql->createParameter('configvalue'))) + ->setParameter('configvalue', $value); + } + $changedRow = (bool) $sql->execute(); $this->cache[$app][$key] = $value; diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php index 83a08acde26..5d7ea48752b 100644 --- a/lib/private/appframework/utility/simplecontainer.php +++ b/lib/private/appframework/utility/simplecontainer.php @@ -77,7 +77,7 @@ class SimpleContainer extends Container implements IContainer { * @return stdClass * @throws QueryException if the class could not be found or instantiated */ - private function resolve($name) { + public function resolve($name) { $baseMsg = 'Could not resolve ' . $name . '!'; try { $class = new ReflectionClass($name); diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index f297bccbc7d..deadadfb77e 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -26,6 +26,7 @@ namespace OC\BackgroundJob; use OCP\BackgroundJob\IJobList; +use OCP\AutoloadNotAllowedException; class JobList implements IJobList { /** @@ -185,15 +186,20 @@ class JobList implements IJobList { /** * @var Job $job */ - if (!class_exists($class)) { - // job from disabled app or old version of an app, no need to do anything - return null; + try { + if (!class_exists($class)) { + // job from disabled app or old version of an app, no need to do anything + return null; + } + $job = new $class(); + $job->setId($row['id']); + $job->setLastRun($row['last_run']); + $job->setArgument(json_decode($row['argument'], true)); + return $job; + } catch (AutoloadNotAllowedException $e) { + // job is from a disabled app, ignore } - $job = new $class(); - $job->setId($row['id']); - $job->setLastRun($row['last_run']); - $job->setArgument(json_decode($row['argument'], true)); - return $job; + return null; } /** diff --git a/lib/private/eventsource.php b/lib/private/eventsource.php index c69671c1a75..e2be808e726 100644 --- a/lib/private/eventsource.php +++ b/lib/private/eventsource.php @@ -59,6 +59,17 @@ class OC_EventSource implements \OCP\IEventSource { $this->fallback = isset($_GET['fallback']) and $_GET['fallback'] == 'true'; if ($this->fallback) { $this->fallBackId = (int)$_GET['fallback_id']; + /** + * FIXME: The default content-security-policy of ownCloud forbids inline + * JavaScript for security reasons. IE starting on Windows 10 will + * however also obey the CSP which will break the event source fallback. + * + * As a workaround thus we set a custom policy which allows the execution + * of inline JavaScript. + * + * @link https://github.com/owncloud/core/issues/14286 + */ + header("Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline'"); header("Content-Type: text/html"); echo str_repeat('<span></span>' . PHP_EOL, 10); //dummy data to keep IE happy } else { diff --git a/lib/private/files.php b/lib/private/files.php index 6268bf8a129..0172f1ca6af 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -86,15 +86,6 @@ class OC_Files { */ public static function get($dir, $files, $only_header = false) { $view = \OC\Files\Filesystem::getView(); - $xsendfile = false; - if (\OC::$server->getLockingProvider() instanceof NoopLockingProvider) { - if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) || - isset($_SERVER['MOD_X_SENDFILE2_ENABLED']) || - isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED']) - ) { - $xsendfile = true; - } - } if (is_array($files) && count($files) === 1) { $files = $files[0]; @@ -129,9 +120,6 @@ class OC_Files { if ($get_type === self::FILE) { $zip = false; - if ($xsendfile && \OC::$server->getEncryptionManager()->isEnabled()) { - $xsendfile = false; - } } else { $zip = new ZipStreamer(false); } @@ -176,17 +164,7 @@ class OC_Files { $zip->finalize(); set_time_limit($executionTime); } else { - if ($xsendfile) { - /** @var $storage \OC\Files\Storage\Storage */ - list($storage) = $view->resolvePath($filename); - if ($storage->isLocal()) { - self::addSendfileHeader($filename); - } else { - \OC\Files\Filesystem::readfile($filename); - } - } else { - \OC\Files\Filesystem::readfile($filename); - } + \OC\Files\Filesystem::readfile($filename); } if ($get_type === self::FILE) { $view->unlockFile($filename, ILockingProvider::LOCK_SHARED); @@ -203,40 +181,6 @@ class OC_Files { } /** - * @param false|string $filename - */ - private static function addSendfileHeader($filename) { - if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) { - $filename = \OC\Files\Filesystem::getLocalFile($filename); - header("X-Sendfile: " . $filename); - } - if (isset($_SERVER['MOD_X_SENDFILE2_ENABLED'])) { - $filename = \OC\Files\Filesystem::getLocalFile($filename); - if (isset($_SERVER['HTTP_RANGE']) && - preg_match("/^bytes=([0-9]+)-([0-9]*)$/", $_SERVER['HTTP_RANGE'], $range)) { - $filelength = filesize($filename); - if ($range[2] === "") { - $range[2] = $filelength - 1; - } - header("Content-Range: bytes $range[1]-$range[2]/" . $filelength); - header("HTTP/1.1 206 Partial content"); - header("X-Sendfile2: " . str_replace(",", "%2c", rawurlencode($filename)) . " $range[1]-$range[2]"); - } else { - header("X-Sendfile: " . $filename); - } - } - - if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) { - if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_PREFIX'])) { - $filename = $_SERVER['MOD_X_ACCEL_REDIRECT_PREFIX'] . \OC\Files\Filesystem::getLocalFile($filename); - } else { - $filename = \OC::$WEBROOT . '/data' . \OC\Files\Filesystem::getRoot() . $filename; - } - header("X-Accel-Redirect: " . $filename); - } - } - - /** * @param string $dir * @param ZipStreamer $zip * @param string $internalDir diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 8cf097421d4..5c04da1f0d5 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -35,6 +35,8 @@ namespace OC\Files\Cache; +use \OCP\Files\IMimeTypeLoader; + /** * Metadata cache for a storage * @@ -66,8 +68,8 @@ class Cache { */ protected $storageCache; - protected static $mimetypeIds = array(); - protected static $mimetypes = array(); + /** @var IMimeTypeLoader */ + protected $mimetypeLoader; /** * @param \OC\Files\Storage\Storage|string $storage @@ -83,6 +85,7 @@ class Cache { } $this->storageCache = new Storage($storage); + $this->mimetypeLoader = \OC::$server->getMimeTypeLoader(); } /** @@ -95,72 +98,6 @@ class Cache { } /** - * Get the numeric id for a mimetype - * - * Mimetypes are stored as integers in the cache to prevent duplicated data of the (usually) fairly limited amount of unique mimetypes - * If the supplied mimetype does not yet have a numeric id a new one will be generated - * - * @param string $mime - * @return int - */ - public function getMimetypeId($mime) { - if (empty($mime)) { - // Can not insert empty string into Oracle NOT NULL column. - $mime = 'application/octet-stream'; - } - if (empty(self::$mimetypeIds)) { - $this->loadMimetypes(); - } - - if (!isset(self::$mimetypeIds[$mime])) { - try { - $connection = \OC_DB::getConnection(); - $connection->insertIfNotExist('*PREFIX*mimetypes', [ - 'mimetype' => $mime, - ]); - $this->loadMimetypes(); - } catch (\Doctrine\DBAL\DBALException $e) { - \OCP\Util::writeLog('core', 'Exception during mimetype insertion: ' . $e->getmessage(), \OCP\Util::DEBUG); - return -1; - } - } - - return self::$mimetypeIds[$mime]; - } - - - /** - * Get the mimetype (as string) from a mimetype id - * - * @param int $id - * @return string | null the mimetype for the id or null if the id is not known - */ - public function getMimetype($id) { - if (empty(self::$mimetypes)) { - $this->loadMimetypes(); - } - - return isset(self::$mimetypes[$id]) ? self::$mimetypes[$id] : null; - } - - /** - * Load all known mimetypes and mimetype ids from the database - * - * @throws \OC\DatabaseException - */ - public function loadMimetypes() { - self::$mimetypeIds = self::$mimetypes = array(); - - $result = \OC_DB::executeAudited('SELECT `id`, `mimetype` FROM `*PREFIX*mimetypes`', array()); - if ($result) { - while ($row = $result->fetchRow()) { - self::$mimetypeIds[$row['mimetype']] = $row['id']; - self::$mimetypes[$row['id']] = $row['mimetype']; - } - } - } - - /** * get the stored metadata of a file or folder * * the returned cache entry contains at least the following values: @@ -222,8 +159,8 @@ class Cache { $data['storage_mtime'] = (int)$data['storage_mtime']; $data['encrypted'] = (bool)$data['encrypted']; $data['storage'] = $this->storageId; - $data['mimetype'] = $this->getMimetype($data['mimetype']); - $data['mimepart'] = $this->getMimetype($data['mimepart']); + $data['mimetype'] = $this->mimetypeLoader->getMimetypeById($data['mimetype']); + $data['mimepart'] = $this->mimetypeLoader->getMimetypeById($data['mimepart']); if ($data['storage_mtime'] == 0) { $data['storage_mtime'] = $data['mtime']; } @@ -258,8 +195,8 @@ class Cache { $result = \OC_DB::executeAudited($sql, array($fileId)); $files = $result->fetchAll(); foreach ($files as &$file) { - $file['mimetype'] = $this->getMimetype($file['mimetype']); - $file['mimepart'] = $this->getMimetype($file['mimepart']); + $file['mimetype'] = $this->mimetypeLoader->getMimetypeById($file['mimetype']); + $file['mimepart'] = $this->mimetypeLoader->getMimetypeById($file['mimepart']); if ($file['storage_mtime'] == 0) { $file['storage_mtime'] = $file['mtime']; } @@ -385,9 +322,9 @@ class Cache { $params[] = md5($value); $queryParts[] = '`path_hash`'; } elseif ($name === 'mimetype') { - $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/'))); + $params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/'))); $queryParts[] = '`mimepart`'; - $value = $this->getMimetypeId($value); + $value = $this->mimetypeLoader->getId($value); } elseif ($name === 'storage_mtime') { if (!isset($data['mtime'])) { $params[] = $value; @@ -613,7 +550,6 @@ class Cache { * @return array an array of cache entries where the name matches the search pattern */ public function search($pattern) { - // normalize pattern $pattern = $this->normalize($pattern); @@ -630,8 +566,8 @@ class Cache { $files = array(); while ($row = $result->fetchRow()) { - $row['mimetype'] = $this->getMimetype($row['mimetype']); - $row['mimepart'] = $this->getMimetype($row['mimepart']); + $row['mimetype'] = $this->mimetypeLoader->getMimetypeById($row['mimetype']); + $row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']); $files[] = $row; } return $files; @@ -652,12 +588,12 @@ class Cache { } $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'; - $mimetype = $this->getMimetypeId($mimetype); + $mimetype = $this->mimetypeLoader->getId($mimetype); $result = \OC_DB::executeAudited($sql, array($mimetype, $this->getNumericStorageId())); $files = array(); while ($row = $result->fetchRow()) { - $row['mimetype'] = $this->getMimetype($row['mimetype']); - $row['mimepart'] = $this->getMimetype($row['mimepart']); + $row['mimetype'] = $this->mimetypeLoader->getMimetypeById($row['mimetype']); + $row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']); $files[] = $row; } return $files; diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index f76ef5ba0dd..fb60ee5aa53 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -377,7 +377,7 @@ class Scanner extends BasicEmitter { // inserted mimetypes but those weren't available yet inside the transaction // To make sure to have the updated mime types in such cases, // we reload them here - $this->cache->loadMimetypes(); + \OC::$server->getMimeTypeLoader()->reset(); } foreach ($childQueue as $child => $childData) { diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php index 6e89dcccbcd..c1cf17abdee 100644 --- a/lib/private/files/storage/dav.php +++ b/lib/private/files/storage/dav.php @@ -40,6 +40,7 @@ use OC\Files\Filesystem; use OC\Files\Stream\Close; use Icewind\Streams\IteratorDirectory; use OC\MemCache\ArrayCache; +use OCP\AppFramework\Http; use OCP\Constants; use OCP\Files; use OCP\Files\FileInfo; @@ -77,6 +78,8 @@ class DAV extends Common { private $statCache; /** @var array */ private static $tempFiles = []; + /** @var \OCP\Http\Client\IClientService */ + private $httpClientService; /** * @param array $params @@ -84,6 +87,7 @@ class DAV extends Common { */ public function __construct($params) { $this->statCache = new ArrayCache(); + $this->httpClientService = \OC::$server->getHTTPClientService(); if (isset($params['host']) && isset($params['user']) && isset($params['password'])) { $host = $params['host']; //remove leading http[s], will be generated in createBaseUri() @@ -232,7 +236,7 @@ class DAV extends Common { * If not, request it from the server then store to cache. * * @param string $path path to propfind - * + * * @return array propfind response * * @throws NotFound @@ -337,38 +341,22 @@ class DAV extends Common { if (!$this->file_exists($path)) { return false; } - //straight up curl instead of sabredav here, sabredav put's the entire get result in memory - $curl = curl_init(); - $fp = fopen('php://temp', 'r+'); - curl_setopt($curl, CURLOPT_USERPWD, $this->user . ':' . $this->password); - curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . $this->encodePath($path)); - curl_setopt($curl, CURLOPT_FILE, $fp); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - if(defined('CURLOPT_PROTOCOLS')) { - curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); - } - if(defined('CURLOPT_REDIR_PROTOCOLS')) { - curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); - } - if ($this->secure === true) { - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); - if ($this->certPath) { - curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); - } - } - - curl_exec($curl); - $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); - if ($statusCode !== 200) { - Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, Util::ERROR); - if ($statusCode === 423) { + $response = $this->httpClientService + ->newClient() + ->get($this->createBaseUri() . $this->encodePath($path), [ + 'auth' => [$this->user, $this->password], + 'stream' => true + ]); + + if ($response->getStatusCode() !== Http::STATUS_OK) { + if ($response->getStatusCode() === Http::STATUS_LOCKED) { throw new \OCP\Lock\LockedException($path); + } else { + Util::writeLog("webdav client", 'Guzzle get returned status code ' . $response->getStatusCode(), Util::ERROR); } } - curl_close($curl); - rewind($fp); - return $fp; + + return $response->getBody(); case 'w': case 'wb': case 'a': @@ -478,38 +466,19 @@ class DAV extends Common { */ protected function uploadFile($path, $target) { $this->init(); + // invalidate $target = $this->cleanPath($target); $this->statCache->remove($target); $source = fopen($path, 'r'); - $curl = curl_init(); - curl_setopt($curl, CURLOPT_USERPWD, $this->user . ':' . $this->password); - curl_setopt($curl, CURLOPT_URL, $this->createBaseUri() . $this->encodePath($target)); - curl_setopt($curl, CURLOPT_BINARYTRANSFER, true); - curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer - curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path)); - curl_setopt($curl, CURLOPT_PUT, true); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); - curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); - if ($this->secure === true) { - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); - if ($this->certPath) { - curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); - } - } - curl_exec($curl); - $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); - if ($statusCode !== 200) { - Util::writeLog("webdav client", 'curl GET ' . curl_getinfo($curl, CURLINFO_EFFECTIVE_URL) . ' returned status code ' . $statusCode, Util::ERROR); - if ($statusCode === 423) { - throw new \OCP\Lock\LockedException($path); - } - } - curl_close($curl); - fclose($source); + $this->httpClientService + ->newClient() + ->put($this->createBaseUri() . $this->encodePath($target), [ + 'body' => $source, + 'auth' => [$this->user, $this->password] + ]); + $this->removeCachedFile($target); } @@ -768,7 +737,7 @@ class DAV extends Common { if ($e->getHttpStatus() === 404 || $e->getHttpStatus() === 405) { if ($path === '') { // if root is gone it means the storage is not available - throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage()); + throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage()); } return false; } @@ -802,19 +771,19 @@ class DAV extends Common { } if ($e->getHttpStatus() === 401) { // either password was changed or was invalid all along - throw new StorageInvalidException(get_class($e).': '.$e->getMessage()); + throw new StorageInvalidException(get_class($e) . ': ' . $e->getMessage()); } else if ($e->getHttpStatus() === 405) { // ignore exception for MethodNotAllowed, false will be returned return; } - throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage()); + throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage()); } else if ($e instanceof ClientException) { // connection timeout or refused, server could be temporarily down - throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage()); + throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage()); } else if ($e instanceof \InvalidArgumentException) { // parse error because the server returned HTML instead of XML, // possibly temporarily down - throw new StorageNotAvailableException(get_class($e).': '.$e->getMessage()); + throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage()); } else if (($e instanceof StorageNotAvailableException) || ($e instanceof StorageInvalidException)) { // rethrow throw $e; diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php index ba286637df3..3dc3975fb2a 100644 --- a/lib/private/files/type/detection.php +++ b/lib/private/files/type/detection.php @@ -6,6 +6,7 @@ * @author Robin Appelman <icewind@owncloud.com> * @author Roeland Jago Douma <roeland@famdouma.nl> * @author Thomas Tanghus <thomas@tanghus.net> + * @author Robin McCorkell <rmccorkell@owncloud.com> * * @copyright Copyright (c) 2015, ownCloud, Inc. * @license AGPL-3.0 @@ -101,16 +102,23 @@ class Detection implements IMimeTypeDetector { return; } - $file = file_get_contents($this->configDir . '/mimetypealiases.dist.json'); - $this->mimeTypeAlias = get_object_vars(json_decode($file)); + $this->mimeTypeAlias = json_decode(file_get_contents($this->configDir . '/mimetypealiases.dist.json'), true); if (file_exists($this->configDir . '/mimetypealiases.json')) { - $custom = get_object_vars(json_decode(file_get_contents($this->configDir . '/mimetypealiases.json'))); + $custom = json_decode(file_get_contents($this->configDir . '/mimetypealiases.json'), true); $this->mimeTypeAlias = array_merge($this->mimeTypeAlias, $custom); } } /** + * @return array + */ + public function getAllAliases() { + $this->loadAliases(); + return $this->mimeTypeAlias; + } + + /** * Add mimetype mappings if they are not yet present */ private function loadMappings() { @@ -118,20 +126,26 @@ class Detection implements IMimeTypeDetector { return; } - $dist = file_get_contents($this->configDir . '/mimetypemapping.dist.json'); - $mimetypemapping = get_object_vars(json_decode($dist)); + $mimetypemapping = json_decode(file_get_contents($this->configDir . '/mimetypemapping.dist.json'), true); //Check if need to load custom mappings if (file_exists($this->configDir . '/mimetypemapping.json')) { - $custom = file_get_contents($this->configDir . '/mimetypemapping.json'); - $custom_mapping = get_object_vars(json_decode($custom)); - $mimetypemapping = array_merge($mimetypemapping, $custom_mapping); + $custom = json_decode(file_get_contents($this->configDir . '/mimetypemapping.json'), true); + $mimetypemapping = array_merge($mimetypemapping, $custom); } $this->registerTypeArray($mimetypemapping); } /** + * @return array + */ + public function getAllMappings() { + $this->loadMappings(); + return $this->mimetypes; + } + + /** * detect mimetype only based on filename, content of file is not used * * @param string $path diff --git a/lib/private/files/type/loader.php b/lib/private/files/type/loader.php new file mode 100644 index 00000000000..78bfcf60bff --- /dev/null +++ b/lib/private/files/type/loader.php @@ -0,0 +1,173 @@ +<?php +/** + * @author Robin McCorkell <rmccorkell@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\Type; + +use OCP\Files\IMimeTypeLoader; +use OCP\IDBConnection; + +use Doctrine\DBAL\Exception\UniqueConstraintViolationException; + +/** + * Mimetype database loader + * + * @package OC\Files\Type + */ +class Loader implements IMimeTypeLoader { + + /** @var IDBConnection */ + private $dbConnection; + + /** @var array [id => mimetype] */ + protected $mimetypes; + + /** @var array [mimetype => id] */ + protected $mimetypeIds; + + /** + * @param IDBConnection $dbConnection + */ + public function __construct(IDBConnection $dbConnection) { + $this->dbConnection = $dbConnection; + $this->mimetypes = []; + $this->mimetypeIds = []; + } + + /** + * Get a mimetype from its ID + * + * @param int $id + * @return string|null + */ + public function getMimetypeById($id) { + if (!$this->mimetypes) { + $this->loadMimetypes(); + } + if (isset($this->mimetypes[$id])) { + return $this->mimetypes[$id]; + } + return null; + } + + /** + * Get a mimetype ID, adding the mimetype to the DB if it does not exist + * + * @param string $mimetype + * @return int + */ + public function getId($mimetype) { + if (!$this->mimetypeIds) { + $this->loadMimetypes(); + } + if (isset($this->mimetypeIds[$mimetype])) { + return $this->mimetypeIds[$mimetype]; + } + return $this->store($mimetype); + } + + /** + * Test if a mimetype exists in the database + * + * @param string $mimetype + * @return bool + */ + public function exists($mimetype) { + if (!$this->mimetypeIds) { + $this->loadMimetypes(); + } + return isset($this->mimetypeIds[$mimetype]); + } + + /** + * Clear all loaded mimetypes, allow for re-loading + */ + public function reset() { + $this->mimetypes = []; + $this->mimetypeIds = []; + } + + /** + * Store a mimetype in the DB + * + * @param string $mimetype + * @param int inserted ID + */ + protected function store($mimetype) { + try { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert('mimetypes') + ->values([ + 'mimetype' => $qb->createNamedParameter($mimetype) + ]); + $qb->execute(); + } catch (UniqueConstraintViolationException $e) { + // something inserted it before us + } + + $fetch = $this->dbConnection->getQueryBuilder(); + $fetch->select('id') + ->from('mimetypes') + ->where( + $fetch->expr()->eq('mimetype', $fetch->createNamedParameter($mimetype) + )); + $row = $fetch->execute()->fetch(); + + $this->mimetypes[$row['id']] = $mimetype; + $this->mimetypeIds[$mimetype] = $row['id']; + return $row['id']; + } + + /** + * Load all mimetypes from DB + */ + private function loadMimetypes() { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('id', 'mimetype') + ->from('mimetypes'); + $results = $qb->execute()->fetchAll(); + + foreach ($results as $row) { + $this->mimetypes[$row['id']] = $row['mimetype']; + $this->mimetypeIds[$row['mimetype']] = $row['id']; + } + } + + /** + * Update filecache mimetype based on file extension + * + * @param string $ext file extension + * @param int $mimetypeId + * @return int number of changed rows + */ + public function updateFilecache($ext, $mimetypeId) { + $update = $this->dbConnection->getQueryBuilder(); + $update->update('filecache') + ->set('mimetype', $update->createNamedParameter($mimetypeId)) + ->where($update->expr()->neq( + 'mimetype', $update->createNamedParameter($mimetypeId) + )) + ->andWhere($update->expr()->like( + $update->createFunction('LOWER(`name`)'), $update->createNamedParameter($ext) + )); + return $update->execute(); + } + +} diff --git a/lib/private/http/client/client.php b/lib/private/http/client/client.php index 323fc0d324f..b0aff10a413 100644 --- a/lib/private/http/client/client.php +++ b/lib/private/http/client/client.php @@ -120,7 +120,8 @@ class Client implements IClient { */ public function get($uri, array $options = []) { $response = $this->client->get($uri, $options); - return new Response($response); + $isStream = isset($options['stream']) && $options['stream']; + return new Response($response, $isStream); } /** diff --git a/lib/private/http/client/response.php b/lib/private/http/client/response.php index 4e9df51d77f..558482491d1 100644 --- a/lib/private/http/client/response.php +++ b/lib/private/http/client/response.php @@ -34,17 +34,26 @@ class Response implements IResponse { private $response; /** + * @var bool + */ + private $stream; + + /** * @param GuzzleResponse $response + * @param bool $stream */ - public function __construct(GuzzleResponse $response) { + public function __construct(GuzzleResponse $response, $stream = false) { $this->response = $response; + $this->stream = $stream; } /** - * @return string + * @return string|resource */ public function getBody() { - return $this->response->getBody()->getContents(); + return $this->stream ? + $this->response->getBody()->detach(): + $this->response->getBody()->getContents(); } /** diff --git a/lib/private/memcache/memcached.php b/lib/private/memcache/memcached.php index 1503851fd73..e99303ecc15 100644 --- a/lib/private/memcache/memcached.php +++ b/lib/private/memcache/memcached.php @@ -89,6 +89,11 @@ class Memcached extends Cache implements IMemcache { public function clear($prefix = '') { $prefix = $this->getNamespace() . $prefix; $allKeys = self::$cache->getAllKeys(); + if ($allKeys === false) { + // newer Memcached doesn't like getAllKeys(), flush everything + self::$cache->flush(); + return true; + } $keys = array(); $prefixLength = strlen($prefix); foreach ($allKeys as $key) { diff --git a/lib/private/notification/action.php b/lib/private/notification/action.php new file mode 100644 index 00000000000..6de8a1a4bbc --- /dev/null +++ b/lib/private/notification/action.php @@ -0,0 +1,167 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + + +class Action implements IAction { + + /** @var string */ + protected $label; + + /** @var string */ + protected $labelParsed; + + /** @var string */ + protected $link; + + /** @var string */ + protected $requestType; + + /** @var string */ + protected $icon; + + /** + * Constructor + */ + public function __construct() { + $this->label = ''; + $this->labelParsed = ''; + $this->link = ''; + $this->requestType = ''; + $this->icon = ''; + } + + /** + * @param string $label + * @return $this + * @throws \InvalidArgumentException if the label is invalid + * @since 8.2.0 + */ + public function setLabel($label) { + if (!is_string($label) || $label === '' || isset($label[32])) { + throw new \InvalidArgumentException('The given label is invalid'); + } + $this->label = $label; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getLabel() { + return $this->label; + } + + /** + * @param string $label + * @return $this + * @throws \InvalidArgumentException if the label is invalid + * @since 8.2.0 + */ + public function setParsedLabel($label) { + if (!is_string($label) || $label === '') { + throw new \InvalidArgumentException('The given parsed label is invalid'); + } + $this->labelParsed = $label; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getParsedLabel() { + return $this->labelParsed; + } + + /** + * @param string $link + * @param string $requestType + * @return $this + * @throws \InvalidArgumentException if the link is invalid + * @since 8.2.0 + */ + public function setLink($link, $requestType) { + if (!is_string($link) || $link === '' || isset($link[256])) { + throw new \InvalidArgumentException('The given link is invalid'); + } + if (!in_array($requestType, ['GET', 'POST', 'PUT', 'DELETE'], true)) { + throw new \InvalidArgumentException('The given request type is invalid'); + } + $this->link = $link; + $this->requestType = $requestType; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getLink() { + return $this->link; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getRequestType() { + return $this->requestType; + } + + /** + * @param string $icon + * @return $this + * @throws \InvalidArgumentException if the icon is invalid + * @since 8.2.0 + */ + public function setIcon($icon) { + if (!is_string($icon) || $icon === '' || isset($icon[64])) { + throw new \InvalidArgumentException('The given icon is invalid'); + } + $this->icon = $icon; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getIcon() { + return $this->icon; + } + + /** + * @return bool + */ + public function isValid() { + return $this->label !== '' && $this->link !== ''; + } + + /** + * @return bool + */ + public function isValidParsed() { + return $this->labelParsed !== '' && $this->link !== ''; + } +} diff --git a/lib/private/notification/iaction.php b/lib/private/notification/iaction.php new file mode 100644 index 00000000000..da6728f5c52 --- /dev/null +++ b/lib/private/notification/iaction.php @@ -0,0 +1,109 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + +/** + * Interface IAction + * + * @package OC\Notification + * @since 8.2.0 + * + * DEVELOPER NOTE: + * The notification api is experimental only in 8.2.0! Do not start using it, + * if you can not prepare an update for the next version afterwards. + */ +interface IAction { + /** + * @param string $label + * @return $this + * @throws \InvalidArgumentException if the label is invalid + * @since 8.2.0 + */ + public function setLabel($label); + + /** + * @return string + * @since 8.2.0 + */ + public function getLabel(); + + /** + * @param string $label + * @return $this + * @throws \InvalidArgumentException if the label is invalid + * @since 8.2.0 + */ + public function setParsedLabel($label); + + /** + * @return string + * @since 8.2.0 + */ + public function getParsedLabel(); + + /** + * @param string $link + * @param string $requestType + * @return $this + * @throws \InvalidArgumentException if the link is invalid + * @since 8.2.0 + */ + public function setLink($link, $requestType); + + /** + * @return string + * @since 8.2.0 + */ + public function getLink(); + + /** + * @return string + * @since 8.2.0 + */ + public function getRequestType(); + + /** + * @param string $icon + * @return $this + * @throws \InvalidArgumentException if the icon is invalid + * @since 8.2.0 + */ + public function setIcon($icon); + + /** + * @return string + * @since 8.2.0 + */ + public function getIcon(); + + /** + * @return bool + * @since 8.2.0 + */ + public function isValid(); + + /** + * @return bool + * @since 8.2.0 + */ + public function isValidParsed(); +} diff --git a/lib/private/notification/iapp.php b/lib/private/notification/iapp.php new file mode 100644 index 00000000000..eda66423f3a --- /dev/null +++ b/lib/private/notification/iapp.php @@ -0,0 +1,56 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + +/** + * Interface IApp + * + * @package OC\Notification + * @since 8.2.0 + * + * DEVELOPER NOTE: + * The notification api is experimental only in 8.2.0! Do not start using it, + * if you can not prepare an update for the next version afterwards. + */ +interface IApp { + /** + * @param INotification $notification + * @return null + * @throws \InvalidArgumentException When the notification is not valid + * @since 8.2.0 + */ + public function notify(INotification $notification); + + /** + * @param INotification $notification + * @return null + * @since 8.2.0 + */ + public function markProcessed(INotification $notification); + + /** + * @param INotification $notification + * @return int + * @since 8.2.0 + */ + public function getCount(INotification $notification); +} diff --git a/lib/private/notification/imanager.php b/lib/private/notification/imanager.php new file mode 100644 index 00000000000..0cd92b33251 --- /dev/null +++ b/lib/private/notification/imanager.php @@ -0,0 +1,56 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + +/** + * Interface IManager + * + * @package OC\Notification + * @since 8.2.0 + * + * DEVELOPER NOTE: + * The notification api is experimental only in 8.2.0! Do not start using it, + * if you can not prepare an update for the next version afterwards. + */ +interface IManager extends IApp, INotifier { + /** + * @param \Closure $service The service must implement IApp, otherwise a + * \InvalidArgumentException is thrown later + * @return null + * @since 8.2.0 + */ + public function registerApp(\Closure $service); + + /** + * @param \Closure $service The service must implement INotifier, otherwise a + * \InvalidArgumentException is thrown later + * @return null + * @since 8.2.0 + */ + public function registerNotifier(\Closure $service); + + /** + * @return INotification + * @since 8.2.0 + */ + public function createNotification(); +} diff --git a/lib/private/notification/inotification.php b/lib/private/notification/inotification.php new file mode 100644 index 00000000000..faf5db1d24c --- /dev/null +++ b/lib/private/notification/inotification.php @@ -0,0 +1,241 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + +/** + * Interface INotification + * + * @package OC\Notification + * @since 8.2.0 + * + * DEVELOPER NOTE: + * The notification api is experimental only in 8.2.0! Do not start using it, + * if you can not prepare an update for the next version afterwards. + */ +interface INotification { + /** + * @param string $app + * @return $this + * @throws \InvalidArgumentException if the app id are invalid + * @since 8.2.0 + */ + public function setApp($app); + + /** + * @return string + * @since 8.2.0 + */ + public function getApp(); + + /** + * @param string $user + * @return $this + * @throws \InvalidArgumentException if the user id are invalid + * @since 8.2.0 + */ + public function setUser($user); + + /** + * @return string + * @since 8.2.0 + */ + public function getUser(); + + /** + * @param int $timestamp + * @return $this + * @throws \InvalidArgumentException if the timestamp are invalid + * @since 8.2.0 + */ + public function setTimestamp($timestamp); + + /** + * @return int + * @since 8.2.0 + */ + public function getTimestamp(); + + /** + * @param string $type + * @param int $id + * @return $this + * @throws \InvalidArgumentException if the object type or id are invalid + * @since 8.2.0 + */ + public function setObject($type, $id); + + /** + * @return string + * @since 8.2.0 + */ + public function getObjectType(); + + /** + * @return int + * @since 8.2.0 + */ + public function getObjectId(); + + /** + * @param string $subject + * @param array $parameters + * @return $this + * @throws \InvalidArgumentException if the subject or parameters are invalid + * @since 8.2.0 + */ + public function setSubject($subject, array $parameters = []); + + /** + * @return string + * @since 8.2.0 + */ + public function getSubject(); + + /** + * @return string[] + * @since 8.2.0 + */ + public function getSubjectParameters(); + + /** + * @param string $subject + * @return $this + * @throws \InvalidArgumentException if the subject are invalid + * @since 8.2.0 + */ + public function setParsedSubject($subject); + + /** + * @return string + * @since 8.2.0 + */ + public function getParsedSubject(); + + /** + * @param string $message + * @param array $parameters + * @return $this + * @throws \InvalidArgumentException if the message or parameters are invalid + * @since 8.2.0 + */ + public function setMessage($message, array $parameters = []); + + /** + * @return string + * @since 8.2.0 + */ + public function getMessage(); + + /** + * @return string[] + * @since 8.2.0 + */ + public function getMessageParameters(); + + /** + * @param string $message + * @return $this + * @throws \InvalidArgumentException if the message are invalid + * @since 8.2.0 + */ + public function setParsedMessage($message); + + /** + * @return string + * @since 8.2.0 + */ + public function getParsedMessage(); + + /** + * @param string $link + * @return $this + * @throws \InvalidArgumentException if the link are invalid + * @since 8.2.0 + */ + public function setLink($link); + + /** + * @return string + * @since 8.2.0 + */ + public function getLink(); + + /** + * @param string $icon + * @return $this + * @throws \InvalidArgumentException if the icon are invalid + * @since 8.2.0 + */ + public function setIcon($icon); + + /** + * @return string + * @since 8.2.0 + */ + public function getIcon(); + + /** + * @return IAction + * @since 8.2.0 + */ + public function createAction(); + + /** + * @param IAction $action + * @return $this + * @throws \InvalidArgumentException if the action are invalid + * @since 8.2.0 + */ + public function addAction(IAction $action); + + /** + * @return IAction[] + * @since 8.2.0 + */ + public function getActions(); + + /** + * @param IAction $action + * @return $this + * @throws \InvalidArgumentException if the action are invalid + * @since 8.2.0 + */ + public function addParsedAction(IAction $action); + + /** + * @return IAction[] + * @since 8.2.0 + */ + public function getParsedActions(); + + /** + * @return bool + * @since 8.2.0 + */ + public function isValid(); + + /** + * @return bool + * @since 8.2.0 + */ + public function isValidParsed(); +} diff --git a/lib/private/notification/inotifier.php b/lib/private/notification/inotifier.php new file mode 100644 index 00000000000..22531229e3f --- /dev/null +++ b/lib/private/notification/inotifier.php @@ -0,0 +1,43 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + +/** + * Interface INotifier + * + * @package OC\Notification + * @since 8.2.0 + * + * DEVELOPER NOTE: + * The notification api is experimental only in 8.2.0! Do not start using it, + * if you can not prepare an update for the next version afterwards. + */ +interface INotifier { + /** + * @param INotification $notification + * @param string $languageCode The code of the language that should be used to prepare the notification + * @return INotification + * @throws \InvalidArgumentException When the notification was not prepared by a notifier + * @since 8.2.0 + */ + public function prepare(INotification $notification, $languageCode); +} diff --git a/lib/private/notification/manager.php b/lib/private/notification/manager.php new file mode 100644 index 00000000000..9635925e38e --- /dev/null +++ b/lib/private/notification/manager.php @@ -0,0 +1,191 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + + +class Manager implements IManager { + /** @var IApp */ + protected $apps; + + /** @var INotifier */ + protected $notifiers; + + /** @var \Closure */ + protected $appsClosures; + + /** @var \Closure */ + protected $notifiersClosures; + + public function __construct() { + $this->apps = []; + $this->notifiers = []; + $this->appsClosures = []; + $this->notifiersClosures = []; + } + + /** + * @param \Closure $service The service must implement IApp, otherwise a + * \InvalidArgumentException is thrown later + * @return null + * @since 8.2.0 + */ + public function registerApp(\Closure $service) { + $this->appsClosures[] = $service; + $this->apps = []; + } + + /** + * @param \Closure $service The service must implement INotifier, otherwise a + * \InvalidArgumentException is thrown later + * @return null + * @since 8.2.0 + */ + public function registerNotifier(\Closure $service) { + $this->notifiersClosures[] = $service; + $this->notifiers = []; + } + + /** + * @return IApp[] + */ + protected function getApps() { + if (!empty($this->apps)) { + return $this->apps; + } + + $this->apps = []; + foreach ($this->appsClosures as $closure) { + $app = $closure(); + if (!($app instanceof IApp)) { + throw new \InvalidArgumentException('The given notification app does not implement the IApp interface'); + } + $this->apps[] = $app; + } + + return $this->apps; + } + + /** + * @return INotifier[] + */ + protected function getNotifiers() { + if (!empty($this->notifiers)) { + return $this->notifiers; + } + + $this->notifiers = []; + foreach ($this->notifiersClosures as $closure) { + $notifier = $closure(); + if (!($notifier instanceof INotifier)) { + throw new \InvalidArgumentException('The given notification app does not implement the INotifier interface'); + } + $this->notifiers[] = $notifier; + } + + return $this->notifiers; + } + + /** + * @return INotification + * @since 8.2.0 + */ + public function createNotification() { + return new Notification(); + } + + /** + * @param INotification $notification + * @return null + * @throws \InvalidArgumentException When the notification is not valid + * @since 8.2.0 + */ + public function notify(INotification $notification) { + if (!$notification->isValid()) { + throw new \InvalidArgumentException('The given notification is invalid'); + } + + $apps = $this->getApps(); + + foreach ($apps as $app) { + try { + $app->notify($notification); + } catch (\InvalidArgumentException $e) { + } + } + } + + /** + * @param INotification $notification + * @param string $languageCode The code of the language that should be used to prepare the notification + * @return INotification + * @throws \InvalidArgumentException When the notification was not prepared by a notifier + * @since 8.2.0 + */ + public function prepare(INotification $notification, $languageCode) { + $notifiers = $this->getNotifiers(); + + foreach ($notifiers as $notifier) { + try { + $notification = $notifier->prepare($notification, $languageCode); + } catch (\InvalidArgumentException $e) { + continue; + } + + if (!($notification instanceof INotification) || !$notification->isValidParsed()) { + throw new \InvalidArgumentException('The given notification has not been handled'); + } + } + + if (!($notification instanceof INotification) || !$notification->isValidParsed()) { + throw new \InvalidArgumentException('The given notification has not been handled'); + } + + return $notification; + } + + /** + * @param INotification $notification + * @return null + */ + public function markProcessed(INotification $notification) { + $apps = $this->getApps(); + + foreach ($apps as $app) { + $app->markProcessed($notification); + } + } + + /** + * @param INotification $notification + * @return int + */ + public function getCount(INotification $notification) { + $apps = $this->getApps(); + + $count = 0; + foreach ($apps as $app) { + $count += $app->getCount($notification); + } + + return $count; + } +} diff --git a/lib/private/notification/notification.php b/lib/private/notification/notification.php new file mode 100644 index 00000000000..40fe39a956e --- /dev/null +++ b/lib/private/notification/notification.php @@ -0,0 +1,446 @@ +<?php +/** + * @author Joas Schilling <nickvergessen@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\Notification; + + +class Notification implements INotification { + /** @var string */ + protected $app; + + /** @var string */ + protected $user; + + /** @var int */ + protected $timestamp; + + /** @var string */ + protected $objectType; + + /** @var int */ + protected $objectId; + + /** @var string */ + protected $subject; + + /** @var array */ + protected $subjectParameters; + + /** @var string */ + protected $subjectParsed; + + /** @var string */ + protected $message; + + /** @var array */ + protected $messageParameters; + + /** @var string */ + protected $messageParsed; + + /** @var string */ + protected $link; + + /** @var string */ + protected $icon; + + /** @var array */ + protected $actions; + + /** @var array */ + protected $actionsParsed; + + /** + * Constructor + */ + public function __construct() { + $this->app = ''; + $this->user = ''; + $this->timestamp = 0; + $this->objectType = ''; + $this->objectId = 0; + $this->subject = ''; + $this->subjectParameters = []; + $this->subjectParsed = ''; + $this->message = ''; + $this->messageParameters = []; + $this->messageParsed = ''; + $this->link = ''; + $this->icon = ''; + $this->actions = []; + $this->actionsParsed = []; + } + + /** + * @param string $app + * @return $this + * @throws \InvalidArgumentException if the app id is invalid + * @since 8.2.0 + */ + public function setApp($app) { + if (!is_string($app) || $app === '' || isset($app[32])) { + throw new \InvalidArgumentException('The given app name is invalid'); + } + $this->app = $app; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getApp() { + return $this->app; + } + + /** + * @param string $user + * @return $this + * @throws \InvalidArgumentException if the user id is invalid + * @since 8.2.0 + */ + public function setUser($user) { + if (!is_string($user) || $user === '' || isset($user[64])) { + throw new \InvalidArgumentException('The given user id is invalid'); + } + $this->user = $user; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getUser() { + return $this->user; + } + + /** + * @param int $timestamp + * @return $this + * @throws \InvalidArgumentException if the timestamp is invalid + * @since 8.2.0 + */ + public function setTimestamp($timestamp) { + if (!is_int($timestamp)) { + throw new \InvalidArgumentException('The given timestamp is invalid'); + } + $this->timestamp = $timestamp; + return $this; + } + + /** + * @return int + * @since 8.2.0 + */ + public function getTimestamp() { + return $this->timestamp; + } + + /** + * @param string $type + * @param int $id + * @return $this + * @throws \InvalidArgumentException if the object type or id is invalid + * @since 8.2.0 + */ + public function setObject($type, $id) { + if (!is_string($type) || $type === '' || isset($type[64])) { + throw new \InvalidArgumentException('The given object type is invalid'); + } + $this->objectType = $type; + + if (!is_int($id)) { + throw new \InvalidArgumentException('The given object id is invalid'); + } + $this->objectId = $id; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getObjectType() { + return $this->objectType; + } + + /** + * @return int + * @since 8.2.0 + */ + public function getObjectId() { + return $this->objectId; + } + + /** + * @param string $subject + * @param array $parameters + * @return $this + * @throws \InvalidArgumentException if the subject or parameters are invalid + * @since 8.2.0 + */ + public function setSubject($subject, array $parameters = []) { + if (!is_string($subject) || $subject === '' || isset($subject[64])) { + throw new \InvalidArgumentException('The given subject is invalid'); + } + $this->subject = $subject; + + if (!is_array($parameters)) { + throw new \InvalidArgumentException('The given subject parameters are invalid'); + } + $this->subjectParameters = $parameters; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getSubject() { + return $this->subject; + } + + /** + * @return string[] + * @since 8.2.0 + */ + public function getSubjectParameters() { + return $this->subjectParameters; + } + + /** + * @param string $subject + * @return $this + * @throws \InvalidArgumentException if the subject are invalid + * @since 8.2.0 + */ + public function setParsedSubject($subject) { + if (!is_string($subject) || $subject === '') { + throw new \InvalidArgumentException('The given parsed subject is invalid'); + } + $this->subjectParsed = $subject; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getParsedSubject() { + return $this->subjectParsed; + } + + /** + * @param string $message + * @param array $parameters + * @return $this + * @throws \InvalidArgumentException if the message or parameters are invalid + * @since 8.2.0 + */ + public function setMessage($message, array $parameters = []) { + if (!is_string($message) || $message === '' || isset($message[64])) { + throw new \InvalidArgumentException('The given message is invalid'); + } + $this->message = $message; + + if (!is_array($parameters)) { + throw new \InvalidArgumentException('The given message parameters are invalid'); + } + $this->messageParameters = $parameters; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getMessage() { + return $this->message; + } + + /** + * @return string[] + * @since 8.2.0 + */ + public function getMessageParameters() { + return $this->messageParameters; + } + + /** + * @param string $message + * @return $this + * @throws \InvalidArgumentException if the message are invalid + * @since 8.2.0 + */ + public function setParsedMessage($message) { + if (!is_string($message) || $message === '') { + throw new \InvalidArgumentException('The given parsed message is invalid'); + } + $this->messageParsed = $message; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getParsedMessage() { + return $this->messageParsed; + } + + /** + * @param string $link + * @return $this + * @throws \InvalidArgumentException if the link are invalid + * @since 8.2.0 + */ + public function setLink($link) { + if (!is_string($link) || $link === '' || isset($link[4000])) { + throw new \InvalidArgumentException('The given link is invalid'); + } + $this->link = $link; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getLink() { + return $this->link; + } + + /** + * @param string $icon + * @return $this + * @throws \InvalidArgumentException if the icon are invalid + * @since 8.2.0 + */ + public function setIcon($icon) { + if (!is_string($icon) || $icon === '' || isset($icon[64])) { + throw new \InvalidArgumentException('The given icon is invalid'); + } + $this->icon = $icon; + return $this; + } + + /** + * @return string + * @since 8.2.0 + */ + public function getIcon() { + return $this->icon; + } + + /** + * @return IAction + * @since 8.2.0 + */ + public function createAction() { + return new Action(); + } + + /** + * @param IAction $action + * @return $this + * @throws \InvalidArgumentException if the action are invalid + * @since 8.2.0 + */ + public function addAction(IAction $action) { + if (!$action->isValid()) { + throw new \InvalidArgumentException('The given action is invalid'); + } + $this->actions[] = $action; + return $this; + } + + /** + * @return IAction[] + * @since 8.2.0 + */ + public function getActions() { + return $this->actions; + } + + /** + * @param IAction $action + * @return $this + * @throws \InvalidArgumentException if the action are invalid + * @since 8.2.0 + */ + public function addParsedAction(IAction $action) { + if (!$action->isValidParsed()) { + throw new \InvalidArgumentException('The given parsed action is invalid'); + } + $this->actionsParsed[] = $action; + return $this; + } + + /** + * @return IAction[] + * @since 8.2.0 + */ + public function getParsedActions() { + return $this->actionsParsed; + } + + /** + * @return bool + * @since 8.2.0 + */ + public function isValid() { + return + $this->isValidCommon() + && + $this->getSubject() !== '' + ; + } + + /** + * @return bool + * @since 8.2.0 + */ + public function isValidParsed() { + return + $this->isValidCommon() + && + $this->getParsedSubject() !== '' + ; + } + + /** + * @return bool + */ + protected function isValidCommon() { + return + $this->getApp() !== '' + && + $this->getUser() !== '' + && + $this->getTimestamp() !== 0 + && + $this->getObjectType() !== '' + && + $this->getObjectId() !== 0 + ; + } +} diff --git a/lib/private/server.php b/lib/private/server.php index 24674d2e3c7..9657afbdaec 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -53,6 +53,7 @@ use OC\Lock\DBLockingProvider; use OC\Lock\MemcacheLockingProvider; use OC\Lock\NoopLockingProvider; use OC\Mail\Mailer; +use OC\Notification\Manager; use OC\Security\CertificateManager; use OC\Security\Crypto; use OC\Security\Hasher; @@ -177,8 +178,6 @@ class Server extends SimpleContainer implements IServerContainer { $manager = $c->getUserManager(); $session = new \OC\Session\Memory(''); - $cryptoWrapper = $c->getSessionCryptoWrapper(); - $session = $cryptoWrapper->wrapSession($session); $userSession = new \OC\User\Session($manager, $session); $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) { @@ -252,7 +251,7 @@ class Server extends SimpleContainer implements IServerContainer { if($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) { $v = \OC_App::getAppVersions(); - $v['core'] = implode('.', \OC_Util::getVersion()); + $v['core'] = md5(file_get_contents(\OC::$SERVERROOT . '/version.php')); $version = implode(',', $v); $instanceId = \OC_Util::getInstanceId(); $path = \OC::$SERVERROOT; @@ -357,7 +356,10 @@ class Server extends SimpleContainer implements IServerContainer { } }); $this->registerService('TempManager', function (Server $c) { - return new TempManager(get_temp_dir(), $c->getLogger()); + return new TempManager( + $c->getLogger(), + $c->getConfig() + ); }); $this->registerService('AppManager', function(Server $c) { return new \OC\App\AppManager( @@ -470,6 +472,14 @@ class Server extends SimpleContainer implements IServerContainer { $c->getURLGenerator(), \OC::$configDir); }); + $this->registerService('MimeTypeLoader', function(Server $c) { + return new \OC\Files\Type\Loader( + $c->getDatabaseConnection() + ); + }); + $this->registerService('NotificationManager', function() { + return new Manager(); + }); $this->registerService('CapabilitiesManager', function (Server $c) { $manager = new \OC\CapabilitiesManager(); $manager->registerCapability(function() use ($c) { @@ -1011,6 +1021,15 @@ class Server extends SimpleContainer implements IServerContainer { } /** + * Get the MimeTypeLoader + * + * @return \OCP\Files\IMimeTypeLoader + */ + public function getMimeTypeLoader() { + return $this->query('MimeTypeLoader'); + } + + /** * Get the manager of all the capabilities * * @return \OC\CapabilitiesManager @@ -1030,9 +1049,51 @@ class Server extends SimpleContainer implements IServerContainer { } /** + * Get the Notification Manager + * + * @return \OC\Notification\IManager + * @since 8.2.0 + */ + public function getNotificationManager() { + return $this->query('NotificationManager'); + } + + /** * @return \OC\Session\CryptoWrapper */ public function getSessionCryptoWrapper() { return $this->query('CryptoWrapper'); } + + /** + * Not a public API as of 8.2, wait for 9.0 + * @return \OCA\Files_External\Service\BackendService + */ + public function getStoragesBackendService() { + return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\BackendService'); + } + + /** + * Not a public API as of 8.2, wait for 9.0 + * @return \OCA\Files_External\Service\GlobalStoragesService + */ + public function getGlobalStoragesService() { + return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\GlobalStoragesService'); + } + + /** + * Not a public API as of 8.2, wait for 9.0 + * @return \OCA\Files_External\Service\UserGlobalStoragesService + */ + public function getUserGlobalStoragesService() { + return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserGlobalStoragesService'); + } + + /** + * Not a public API as of 8.2, wait for 9.0 + * @return \OCA\Files_External\Service\UserStoragesService + */ + public function getUserStoragesService() { + return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserStoragesService'); + } } diff --git a/lib/private/session/cryptosessiondata.php b/lib/private/session/cryptosessiondata.php index 60d22b25e97..6826ede5e33 100644 --- a/lib/private/session/cryptosessiondata.php +++ b/lib/private/session/cryptosessiondata.php @@ -32,22 +32,47 @@ use OCP\Security\ICrypto; class CryptoSessionData implements \ArrayAccess, ISession { /** @var ISession */ protected $session; - /** @var \OCP\Security\ICrypto */ protected $crypto; - /** @var string */ protected $passphrase; + /** @var array */ + protected $sessionValues; + /** @var bool */ + protected $isModified = false; + CONST encryptedSessionName = 'encrypted_session_data'; /** * @param ISession $session * @param ICrypto $crypto * @param string $passphrase */ - public function __construct(ISession $session, ICrypto $crypto, $passphrase) { + public function __construct(ISession $session, + ICrypto $crypto, + $passphrase) { $this->crypto = $crypto; $this->session = $session; $this->passphrase = $passphrase; + $this->initializeSession(); + } + + /** + * Close session if class gets destructed + */ + public function __destruct() { + $this->close(); + } + + protected function initializeSession() { + $encryptedSessionData = $this->session->get(self::encryptedSessionName); + try { + $this->sessionValues = json_decode( + $this->crypto->decrypt($encryptedSessionData, $this->passphrase), + true + ); + } catch (\Exception $e) { + $this->sessionValues = []; + } } /** @@ -57,8 +82,8 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @param mixed $value */ public function set($key, $value) { - $encryptedValue = $this->crypto->encrypt(json_encode($value), $this->passphrase); - $this->session->set($key, $encryptedValue); + $this->sessionValues[$key] = $value; + $this->isModified = true; } /** @@ -68,17 +93,11 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @return string|null Either the value or null */ public function get($key) { - $encryptedValue = $this->session->get($key); - if ($encryptedValue === null) { - return null; + if(isset($this->sessionValues[$key])) { + return $this->sessionValues[$key]; } - try { - $value = $this->crypto->decrypt($encryptedValue, $this->passphrase); - return json_decode($value); - } catch (\Exception $e) { - return null; - } + return null; } /** @@ -88,7 +107,7 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @return bool */ public function exists($key) { - return $this->session->exists($key); + return isset($this->sessionValues[$key]); } /** @@ -97,20 +116,29 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @param string $key */ public function remove($key) { - $this->session->remove($key); + $this->isModified = true; + unset($this->sessionValues[$key]); + $this->session->remove(self::encryptedSessionName); } /** * Reset and recreate the session */ public function clear() { + $this->sessionValues = []; + $this->isModified = true; $this->session->clear(); } /** - * Close the session and release the lock + * Close the session and release the lock, also writes all changed data in batch */ public function close() { + if($this->isModified) { + $encryptedValue = $this->crypto->encrypt(json_encode($this->sessionValues), $this->passphrase); + $this->session->set(self::encryptedSessionName, $encryptedValue); + $this->isModified = false; + } $this->session->close(); } diff --git a/lib/private/session/cryptowrapper.php b/lib/private/session/cryptowrapper.php index 62bdcbfb719..261514d683e 100644 --- a/lib/private/session/cryptowrapper.php +++ b/lib/private/session/cryptowrapper.php @@ -77,7 +77,11 @@ class CryptoWrapper { $secureCookie = $request->getServerProtocol() === 'https'; // FIXME: Required for CI if (!defined('PHPUNIT_RUN')) { - setcookie(self::COOKIE_NAME, $this->passphrase, 0, \OC::$WEBROOT, '', $secureCookie, true); + $webRoot = \OC::$WEBROOT; + if($webRoot === '') { + $webRoot = '/'; + } + setcookie(self::COOKIE_NAME, $this->passphrase, 0, $webRoot, '', $secureCookie, true); } } } diff --git a/lib/private/session/internal.php b/lib/private/session/internal.php index 77197887754..8ee21272104 100644 --- a/lib/private/session/internal.php +++ b/lib/private/session/internal.php @@ -32,6 +32,10 @@ namespace OC\Session; * @package OC\Session */ class Internal extends Session { + /** + * @param string $name + * @throws \Exception + */ public function __construct($name) { session_name($name); set_error_handler(array($this, 'trapError')); @@ -42,10 +46,6 @@ class Internal extends Session { } } - public function __destruct() { - $this->close(); - } - /** * @param string $key * @param integer $value diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 70ed26c0b27..6ad36d60fe8 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -765,7 +765,7 @@ class Share extends Constants { } // Generate hash of password - same method as user passwords - if (!empty($shareWith)) { + if (is_string($shareWith) && $shareWith !== '') { self::verifyPassword($shareWith); $shareWith = \OC::$server->getHasher()->hash($shareWith); } else { diff --git a/lib/private/tempmanager.php b/lib/private/tempmanager.php index b8cef8e036e..cc7c51d8568 100644 --- a/lib/private/tempmanager.php +++ b/lib/private/tempmanager.php @@ -25,6 +25,7 @@ namespace OC; use OCP\ILogger; +use OCP\IConfig; use OCP\ITempManager; class TempManager implements ITempManager { @@ -34,16 +35,20 @@ class TempManager implements ITempManager { protected $tmpBaseDir; /** @var ILogger */ protected $log; + /** @var IConfig */ + protected $config; + /** Prefix */ const TMP_PREFIX = 'oc_tmp_'; /** - * @param string $baseDir * @param \OCP\ILogger $logger + * @param \OCP\IConfig $config */ - public function __construct($baseDir, ILogger $logger) { - $this->tmpBaseDir = $baseDir; + public function __construct(ILogger $logger, IConfig $config) { $this->log = $logger; + $this->config = $config; + $this->tmpBaseDir = $this->getTempBaseDir(); } /** @@ -190,4 +195,79 @@ class TempManager implements ITempManager { } return $files; } + + /** + * Get the temporary base directory configured on the server + * + * @return string Path to the temporary directory or null + * @throws \UnexpectedValueException + */ + public function getTempBaseDir() { + if ($this->tmpBaseDir) { + return $this->tmpBaseDir; + } + + $directories = []; + if ($temp = $this->config->getSystemValue('tempdirectory', null)) { + $directories[] = $temp; + } + if ($temp = ini_get('upload_tmp_dir')) { + $directories[] = $temp; + } + if ($temp = getenv('TMP')) { + $directories[] = $temp; + } + if ($temp = getenv('TEMP')) { + $directories[] = $temp; + } + 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; + } + + foreach ($directories as $dir) { + if ($this->checkTemporaryDirectory($dir)) { + return $dir; + } + } + throw new \UnexpectedValueException('Unable to detect system temporary directory'); + } + + /** + * Check if a temporary directory is ready for use + * + * @param mixed $directory + * @return bool + */ + private function checkTemporaryDirectory($directory) { + // surpress any possible errors caused by is_writable + // checks missing or invalid path or characters, wrong permissions ect + try { + if (is_writeable($directory)) { + return true; + } + } catch (Exception $e) { + } + $this->log->warning('Temporary directory {dir} is not present or writable', + ['dir' => $directory] + ); + return false; + } + + /** + * Override the temporary base directory + * + * @param string $directory + */ + public function overrideTempBaseDir($directory) { + $this->tmpBaseDir = $directory; + } + } diff --git a/lib/private/updater.php b/lib/private/updater.php index f73fa8ff655..71e9732c307 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -212,19 +212,26 @@ class Updater extends BasicEmitter { } /** + * Return version from which this version is allowed to upgrade from + * + * @return string allowed previous version + */ + private function getAllowedPreviousVersion() { + // this should really be a JSON file + require \OC::$SERVERROOT . '/version.php'; + return implode('.', $OC_VersionCanBeUpgradedFrom); + } + + /** * Whether an upgrade to a specified version is possible * @param string $oldVersion * @param string $newVersion + * @param string $allowedPreviousVersion * @return bool */ - public function isUpgradePossible($oldVersion, $newVersion) { - $oldVersion = explode('.', $oldVersion); - $newVersion = explode('.', $newVersion); - - if($newVersion[0] > ($oldVersion[0] + 1) || $oldVersion[0] > $newVersion[0]) { - return false; - } - return true; + public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVersion) { + return (version_compare($allowedPreviousVersion, $oldVersion, '<=') + && version_compare($oldVersion, $newVersion, '<=')); } /** @@ -259,8 +266,9 @@ class Updater extends BasicEmitter { */ private function doUpgrade($currentVersion, $installedVersion) { // Stop update if the update is over several major versions - if (!self::isUpgradePossible($installedVersion, $currentVersion)) { - throw new \Exception('Updates between multiple major versions are unsupported.'); + $allowedPreviousVersion = $this->getAllowedPreviousVersion(); + if (!self::isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersion)) { + throw new \Exception('Updates between multiple major versions and downgrades are unsupported.'); } // Update .htaccess files diff --git a/lib/private/util.php b/lib/private/util.php index 0fda55496dc..eb1de5be5a4 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1054,6 +1054,7 @@ class OC_Util { return $id; } + protected static $encryptedToken; /** * Register an get/post call. Important to prevent CSRF attacks. * @@ -1066,6 +1067,11 @@ class OC_Util { * @see OC_Util::isCallRegistered() */ public static function callRegister() { + // Use existing token if function has already been called + if(isset(self::$encryptedToken)) { + return self::$encryptedToken; + } + // Check if a token exists if (!\OC::$server->getSession()->exists('requesttoken')) { // No valid token found, generate a new one. @@ -1078,7 +1084,8 @@ class OC_Util { // Encrypt the token to mitigate breach-like attacks $sharedSecret = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(10); - return \OC::$server->getCrypto()->encrypt($requestToken, $sharedSecret) . ':' . $sharedSecret; + self::$encryptedToken = \OC::$server->getCrypto()->encrypt($requestToken, $sharedSecret) . ':' . $sharedSecret; + return self::$encryptedToken; } /** @@ -1449,8 +1456,12 @@ class OC_Util { if ($config->getSystemValue('installed', false)) { $installedVersion = $config->getSystemValue('version', '0.0.0'); $currentVersion = implode('.', OC_Util::getVersion()); - if (version_compare($currentVersion, $installedVersion, '>')) { + $versionDiff = version_compare($currentVersion, $installedVersion); + if ($versionDiff > 0) { return true; + } else if ($versionDiff < 0) { + // downgrade attempt, throw exception + throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')'); } // also check for upgrades for apps (independently from the user) diff --git a/lib/public/autoloadnotallowedexception.php b/lib/public/autoloadnotallowedexception.php new file mode 100644 index 00000000000..edb7121c065 --- /dev/null +++ b/lib/public/autoloadnotallowedexception.php @@ -0,0 +1,36 @@ +<?php +/** + * @author Robin McCorkell <rmccorkell@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; + +/** + * Exception for when a not allowed path is attempted to be autoloaded + * @since 8.2.0 + */ +class AutoloadNotAllowedException extends \DomainException { + /** + * @param string $path + * @since 8.2.0 + */ + public function __construct($path) { + parent::__construct('Autoload path not allowed: '.$path); + } +} + diff --git a/lib/public/files/imimetypeloader.php b/lib/public/files/imimetypeloader.php new file mode 100644 index 00000000000..6d00c4a0b31 --- /dev/null +++ b/lib/public/files/imimetypeloader.php @@ -0,0 +1,66 @@ +<?php +/** + * @author Robin McCorkell <rmccorkell@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; + +/** + * Interface IMimeTypeLoader + * @package OCP\Files + * @since 8.2.0 + * + * Interface to load mimetypes + **/ +interface IMimeTypeLoader { + + /** + * Get a mimetype from its ID + * + * @param int $id + * @return string|null + * @since 8.2.0 + */ + public function getMimetypeById($id); + + /** + * Get a mimetype ID, adding the mimetype to the DB if it does not exist + * + * @param string $mimetype + * @return int + * @since 8.2.0 + */ + public function getId($mimetype); + + /** + * Test if a mimetype exists in the database + * + * @param string $mimetype + * @return bool + * @since 8.2.0 + */ + public function exists($mimetype); + + /** + * Clear all loaded mimetypes, allow for re-loading + * + * @since 8.2.0 + */ + public function reset(); +} diff --git a/lib/public/http/client/iresponse.php b/lib/public/http/client/iresponse.php index 0e0ef4c5014..92bb7af82dd 100644 --- a/lib/public/http/client/iresponse.php +++ b/lib/public/http/client/iresponse.php @@ -30,7 +30,7 @@ namespace OCP\Http\Client; */ interface IResponse { /** - * @return string + * @return string|resource * @since 8.1.0 */ public function getBody(); diff --git a/lib/public/icontainer.php b/lib/public/icontainer.php index 75ff5e97b69..ffd1d16c97e 100644 --- a/lib/public/icontainer.php +++ b/lib/public/icontainer.php @@ -44,6 +44,16 @@ use Closure; interface IContainer { /** + * If a parameter is not registered in the container try to instantiate it + * by using reflection to find out how to build the class + * @param string $name the class name to resolve + * @return \stdClass + * @since 8.2.0 + * @throws QueryException if the class could not be found or instantiated + */ + public function resolve($name); + + /** * Look up a service for a given name in the container. * * @param string $name diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index a6d83156de3..8be23dff214 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -440,6 +440,13 @@ interface IServerContainer { */ public function getMimeTypeDetector(); + /** + * Get the MimeTypeLoader + * + * @return \OCP\Files\IMimeTypeLoader + * @since 8.2.0 + */ + public function getMimeTypeLoader(); /** * Get the EventDispatcher @@ -448,4 +455,12 @@ interface IServerContainer { * @since 8.2.0 */ public function getEventDispatcher(); + + /** + * Get the Notification Manager + * + * @return \OC\Notification\IManager + * @since 8.2.0 + */ + public function getNotificationManager(); } diff --git a/lib/public/itempmanager.php b/lib/public/itempmanager.php index 7ba5b1e7bff..6364fa71913 100644 --- a/lib/public/itempmanager.php +++ b/lib/public/itempmanager.php @@ -58,4 +58,12 @@ interface ITempManager { * @since 8.0.0 */ public function cleanOld(); + + /** + * Get the temporary base directory + * + * @return string + * @since 8.2.0 + */ + public function getTempBaseDir(); } |