diff options
author | Georg Ehrke <developer@georgehrke.com> | 2014-06-05 22:54:27 +0200 |
---|---|---|
committer | Georg Ehrke <developer@georgehrke.com> | 2014-06-05 22:54:27 +0200 |
commit | 0fe8f77c1748d167e115680346ae98bba78da38d (patch) | |
tree | a456ff35bb2da1a2778f18ccab1ade63e9aaddda /lib | |
parent | fad3bd7fc0c094bd16e07708557cd1a7676889cd (diff) | |
parent | e1beb8c6c38d48eb923ed323dea25110e4bbacfd (diff) | |
download | nextcloud-server-0fe8f77c1748d167e115680346ae98bba78da38d.tar.gz nextcloud-server-0fe8f77c1748d167e115680346ae98bba78da38d.zip |
Merge branch 'master' into update_shipped_apps_from_appstore
Conflicts:
lib/private/app.php
settings/templates/apps.php
Diffstat (limited to 'lib')
117 files changed, 1518 insertions, 1213 deletions
diff --git a/lib/base.php b/lib/base.php index 882b587a6fd..7c58619a556 100644 --- a/lib/base.php +++ b/lib/base.php @@ -320,8 +320,7 @@ class OC { OC_Util::addScript("jquery-migrate-1.2.1.min"); OC_Util::addScript("jquery-ui-1.10.0.custom"); OC_Util::addScript("jquery-showpassword"); - OC_Util::addScript("jquery.infieldlabel"); - OC_Util::addScript("jquery.placeholder"); + OC_Util::addScript("placeholders"); OC_Util::addScript("jquery-tipsy"); OC_Util::addScript("compatibility"); OC_Util::addScript("underscore"); @@ -334,6 +333,7 @@ class OC { //OC_Util::addScript( "multiselect" ); OC_Util::addScript('search', 'result'); OC_Util::addScript("oc-requesttoken"); + OC_Util::addScript("apps"); // avatars if (\OC_Config::getValue('enable_avatars', true) === true) { @@ -344,8 +344,10 @@ class OC { } OC_Util::addStyle("styles"); + OC_Util::addStyle("header"); OC_Util::addStyle("mobile"); OC_Util::addStyle("icons"); + OC_Util::addStyle("fonts"); OC_Util::addStyle("apps"); OC_Util::addStyle("fixes"); OC_Util::addStyle("multiselect"); @@ -434,6 +436,9 @@ class OC { self::$loader->registerPrefix('Pimple', '3rdparty/Pimple'); spl_autoload_register(array(self::$loader, 'load')); + // make a dummy session available as early as possible since error pages need it + self::$session = new \OC\Session\Memory(''); + // set some stuff //ob_start(); error_reporting(E_ALL | E_STRICT); @@ -726,7 +731,7 @@ class OC { if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) { try { - if (!OC_Config::getValue('maintenance', false)) { + if (!OC_Config::getValue('maintenance', false) && !self::needUpgrade()) { OC_App::loadApps(); } self::checkSingleUserMode(); @@ -765,11 +770,20 @@ class OC { return; } + // Redirect to index if the logout link is accessed without valid session + // this is needed to prevent "Token expired" messages while login if a session is expired + // @see https://github.com/owncloud/core/pull/8443#issuecomment-42425583 + if(isset($_GET['logout']) && !OC_User::isLoggedIn()) { + header("Location: " . OC::$WEBROOT.(empty(OC::$WEBROOT) ? '/' : '')); + return; + } + // Someone is logged in : if (OC_User::isLoggedIn()) { OC_App::loadApps(); OC_User::setupBackends(); if (isset($_GET["logout"]) and ($_GET["logout"])) { + OC_JSON::callCheck(); if (isset($_COOKIE['oc_token'])) { OC_Preferences::deleteKey(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']); } @@ -930,6 +944,7 @@ class OC { return false; } + OC_JSON::callCheck(); OC_App::loadApps(); //setup extra user backends diff --git a/lib/l10n/ar.php b/lib/l10n/ar.php index c8b51a3bb7e..45a6ccf6eb0 100644 --- a/lib/l10n/ar.php +++ b/lib/l10n/ar.php @@ -11,10 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "نوع الملف غير معروف", "Invalid image" => "الصورة غير صالحة", "web services under your control" => "خدمات الشبكة تحت سيطرتك", -"ZIP download is turned off." => "تحميل ملفات ZIP متوقف", -"Files need to be downloaded one by one." => "الملفات بحاجة الى ان يتم تحميلها واحد تلو الاخر", -"Back to Files" => "العودة الى الملفات", -"Selected files too large to generate zip file." => "الملفات المحددة كبيرة جدا ليتم ضغطها في ملف zip", "No source specified when installing app" => "لم يتم تحديد المصدر عن تثبيت البرنامج", "Archives of type %s are not supported" => "الأرشيفات من نوع %s غير مدعومة", "App does not provide an info.xml file" => "التطبيق لا يتوفر على ملف info.xml", diff --git a/lib/l10n/ast.php b/lib/l10n/ast.php index 5819cf25639..f5ea4504908 100644 --- a/lib/l10n/ast.php +++ b/lib/l10n/ast.php @@ -11,9 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Triba de ficheru desconocida", "Invalid image" => "Imaxe inválida", "web services under your control" => "servicios web baxo'l to control", -"ZIP download is turned off." => "Tan deshabilitaes les descargues de ZIP.", -"Files need to be downloaded one by one." => "Los ficheros necesiten descargase ún a ún", -"Selected files too large to generate zip file." => "Los ficheros esbillaos son milenta grandes pa xenerar un ficheru zip.", "App does not provide an info.xml file" => "L'aplicación nun apurre un ficheru info.xml", "App can't be installed because it is not compatible with this version of ownCloud" => "Nun pue instalase l'aplicación porque nun ye compatible con esta versión d'ownCloud.", "Can't create app folder. Please fix permissions. %s" => "Nun pue crease la carpeta de l'aplicación. Por favor, igua los permisos. %s", diff --git a/lib/l10n/bg_BG.php b/lib/l10n/bg_BG.php index f29120e60e9..ca771f06bbf 100644 --- a/lib/l10n/bg_BG.php +++ b/lib/l10n/bg_BG.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "Потребители", "Admin" => "Админ", "web services under your control" => "уеб услуги под Ваш контрол", -"ZIP download is turned off." => "Изтеглянето като ZIP е изключено.", -"Files need to be downloaded one by one." => "Файловете трябва да се изтеглят един по един.", -"Back to Files" => "Назад към файловете", -"Selected files too large to generate zip file." => "Избраните файлове са прекалено големи за генерирането на ZIP архив.", "Application is not enabled" => "Приложението не е включено.", "Authentication error" => "Възникна проблем с идентификацията", "Token expired. Please reload page." => "Ключът е изтекъл, моля презаредете страницата", diff --git a/lib/l10n/bn_BD.php b/lib/l10n/bn_BD.php index a42435a2a47..a2bdfe5efa7 100644 --- a/lib/l10n/bn_BD.php +++ b/lib/l10n/bn_BD.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "ব্যবহারকারী", "Admin" => "প্রশাসন", "web services under your control" => "ওয়েব সার্ভিস আপনার হাতের মুঠোয়", -"ZIP download is turned off." => "ZIP ডাউনলোড বন্ধ করা আছে।", -"Files need to be downloaded one by one." => "ফাইলগুলো একে একে ডাউনলোড করা আবশ্যক।", -"Back to Files" => "ফাইলে ফিরে চল", -"Selected files too large to generate zip file." => "নির্বাচিত ফাইলগুলো এতই বৃহৎ যে জিপ ফাইল তৈরী করা সম্ভব নয়।", "Application is not enabled" => "অ্যাপ্লিকেসনটি সক্রিয় নয়", "Authentication error" => "অনুমোদন ঘটিত সমস্যা", "Token expired. Please reload page." => "টোকেন মেয়াদোত্তীর্ণ। দয়া করে পৃষ্ঠাটি পূনরায় লোড করুন।", diff --git a/lib/l10n/ca.php b/lib/l10n/ca.php index 22d8c457f5e..582e6462b3a 100644 --- a/lib/l10n/ca.php +++ b/lib/l10n/ca.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipus de fitxer desconegut", "Invalid image" => "Imatge no vàlida", "web services under your control" => "controleu els vostres serveis web", -"ZIP download is turned off." => "La baixada en ZIP està desactivada.", -"Files need to be downloaded one by one." => "Els fitxers s'han de baixar d'un en un.", -"Back to Files" => "Torna a Fitxers", -"Selected files too large to generate zip file." => "Els fitxers seleccionats son massa grans per generar un fitxer zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Baixeu els fitxers separadament en petits trossos o pregunteu a l'administrador.", "No source specified when installing app" => "No heu especificat la font en instal·lar l'aplicació", "No href specified when installing app from http" => "No heu especificat href en instal·lar l'aplicació des de http", "No path specified when installing app from local file" => "No heu seleccionat el camí en instal·lar una aplicació des d'un fitxer local", diff --git a/lib/l10n/cs_CZ.php b/lib/l10n/cs_CZ.php index 94d0fbe0697..f65328e2bf3 100644 --- a/lib/l10n/cs_CZ.php +++ b/lib/l10n/cs_CZ.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Neznámý typ souboru", "Invalid image" => "Chybný obrázek", "web services under your control" => "webové služby pod Vaší kontrolou", -"ZIP download is turned off." => "Stahování v ZIPu je vypnuto.", -"Files need to be downloaded one by one." => "Soubory musí být stahovány jednotlivě.", -"Back to Files" => "Zpět k souborům", -"Selected files too large to generate zip file." => "Vybrané soubory jsou příliš velké pro vytvoření ZIP souboru.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Prosím stáhněte soubory odděleně po menších množstvích nebo požádejte vašeho správce.", "No source specified when installing app" => "Nebyl zadán zdroj při instalaci aplikace", "No href specified when installing app from http" => "Nebyl zadán odkaz pro instalaci aplikace z HTTP", "No path specified when installing app from local file" => "Nebyla zadána cesta pro instalaci aplikace z místního souboru", diff --git a/lib/l10n/cy_GB.php b/lib/l10n/cy_GB.php index 57cb02653f5..92cb1a09e4b 100644 --- a/lib/l10n/cy_GB.php +++ b/lib/l10n/cy_GB.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "Defnyddwyr", "Admin" => "Gweinyddu", "web services under your control" => "gwasanaethau gwe a reolir gennych", -"ZIP download is turned off." => "Mae llwytho ZIP wedi ei ddiffodd.", -"Files need to be downloaded one by one." => "Mae angen llwytho ffeiliau i lawr fesul un.", -"Back to Files" => "Nôl i Ffeiliau", -"Selected files too large to generate zip file." => "Mae'r ffeiliau ddewiswyd yn rhy fawr i gynhyrchu ffeil zip.", "Application is not enabled" => "Nid yw'r pecyn wedi'i alluogi", "Authentication error" => "Gwall dilysu", "Token expired. Please reload page." => "Tocyn wedi dod i ben. Ail-lwythwch y dudalen.", diff --git a/lib/l10n/da.php b/lib/l10n/da.php index 3be45001030..2550b60da29 100644 --- a/lib/l10n/da.php +++ b/lib/l10n/da.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Ukendt filtype", "Invalid image" => "Ugyldigt billede", "web services under your control" => "Webtjenester under din kontrol", -"ZIP download is turned off." => "ZIP-download er slået fra.", -"Files need to be downloaded one by one." => "Filer skal downloades en for en.", -"Back to Files" => "Tilbage til Filer", -"Selected files too large to generate zip file." => "De markerede filer er for store til at generere en ZIP-fil.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Hent venligst filerne hver for sig i mindre dele eller spørg din administrator.", "No source specified when installing app" => "Ingen kilde angivet under installation af app", "No href specified when installing app from http" => "Ingen href angivet under installation af app via http", "No path specified when installing app from local file" => "Ingen sti angivet under installation af app fra lokal fil", diff --git a/lib/l10n/de.php b/lib/l10n/de.php index 1c12d95501e..a62d6b2aa75 100644 --- a/lib/l10n/de.php +++ b/lib/l10n/de.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Unbekannter Dateityp", "Invalid image" => "Ungültiges Bild", "web services under your control" => "Web-Services unter Deiner Kontrolle", -"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.", -"Files need to be downloaded one by one." => "Die Dateien müssen einzeln heruntergeladen werden.", -"Back to Files" => "Zurück zu \"Dateien\"", -"Selected files too large to generate zip file." => "Die gewählten Dateien sind zu groß, um eine ZIP-Datei zu erstellen.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Bitte lade die Dateien einzeln in kleineren Teilen herunter oder bitte Deinen Administrator.", "No source specified when installing app" => "Für die Installation der Applikation wurde keine Quelle angegeben", "No href specified when installing app from http" => "Für die Installation der Applikation über http wurde keine Quelle (href) angegeben", "No path specified when installing app from local file" => "Bei der Installation der Applikation aus einer lokalen Datei wurde kein Pfad angegeben", diff --git a/lib/l10n/de_CH.php b/lib/l10n/de_CH.php index e034cc3c209..64dd02a7278 100644 --- a/lib/l10n/de_CH.php +++ b/lib/l10n/de_CH.php @@ -9,10 +9,6 @@ $TRANSLATIONS = array( "Admin" => "Administrator", "Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.", "web services under your control" => "Web-Services unter Ihrer Kontrolle", -"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.", -"Files need to be downloaded one by one." => "Die Dateien müssen einzeln heruntergeladen werden.", -"Back to Files" => "Zurück zu \"Dateien\"", -"Selected files too large to generate zip file." => "Die gewählten Dateien sind zu gross, um eine ZIP-Datei zu erstellen.", "App can't be installed because of not allowed code in the App" => "Anwendung kann wegen nicht erlaubten Codes nicht installiert werden", "App directory already exists" => "Anwendungsverzeichnis existiert bereits", "Application is not enabled" => "Die Anwendung ist nicht aktiviert", diff --git a/lib/l10n/de_DE.php b/lib/l10n/de_DE.php index 7010cc29fbf..da3280ce05c 100644 --- a/lib/l10n/de_DE.php +++ b/lib/l10n/de_DE.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Unbekannter Dateityp", "Invalid image" => "Ungültiges Bild", "web services under your control" => "Web-Services unter Ihrer Kontrolle", -"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.", -"Files need to be downloaded one by one." => "Die Dateien müssen einzeln heruntergeladen werden.", -"Back to Files" => "Zurück zu \"Dateien\"", -"Selected files too large to generate zip file." => "Die gewählten Dateien sind zu groß, um eine ZIP-Datei zu erstellen.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Bitte laden Sie die Dateien einzeln in kleineren Teilen herunter oder bitten Sie Ihren Administrator.", "No source specified when installing app" => "Für die Installation der Applikation wurde keine Quelle angegeben", "No href specified when installing app from http" => "Der Link (href) wurde nicht angegeben um die Applikation per http zu installieren", "No path specified when installing app from local file" => "Bei der Installation der Applikation aus einer lokalen Datei wurde kein Pfad angegeben", diff --git a/lib/l10n/el.php b/lib/l10n/el.php index 546fb6347b5..3cfe796b1ee 100644 --- a/lib/l10n/el.php +++ b/lib/l10n/el.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Άγνωστος τύπος αρχείου", "Invalid image" => "Μη έγκυρη εικόνα", "web services under your control" => "υπηρεσίες δικτύου υπό τον έλεγχό σας", -"ZIP download is turned off." => "Η λήψη ZIP απενεργοποιήθηκε.", -"Files need to be downloaded one by one." => "Τα αρχεία πρέπει να ληφθούν ένα-ένα.", -"Back to Files" => "Πίσω στα Αρχεία", -"Selected files too large to generate zip file." => "Τα επιλεγμένα αρχεία είναι μεγάλα ώστε να δημιουργηθεί αρχείο zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Παρακαλώ κάντε λήψη των αρχείων σε μικρότερα κομμάτια ή ζητήστε το από το διαχειριστή σας.", "No source specified when installing app" => "Δεν προσδιορίστηκε πηγή κατά την εγκατάσταση της εφαρμογής", "No href specified when installing app from http" => "Δεν προσδιορίστηκε href κατά την εγκατάσταση της εφαρμογής μέσω http ", "No path specified when installing app from local file" => "Δεν προσδιορίστηκε μονοπάτι κατά την εγκατάσταση εφαρμογής από τοπικό αρχείο", diff --git a/lib/l10n/en_GB.php b/lib/l10n/en_GB.php index 9a5e9bb831f..0d0be27fe62 100644 --- a/lib/l10n/en_GB.php +++ b/lib/l10n/en_GB.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Unknown filetype", "Invalid image" => "Invalid image", "web services under your control" => "web services under your control", -"ZIP download is turned off." => "ZIP download is turned off.", -"Files need to be downloaded one by one." => "Files need to be downloaded one by one.", -"Back to Files" => "Back to Files", -"Selected files too large to generate zip file." => "Selected files too large to generate zip file.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Please download the files separately in smaller chunks or kindly ask your administrator.", "No source specified when installing app" => "No source specified when installing app", "No href specified when installing app from http" => "No href specified when installing app from http", "No path specified when installing app from local file" => "No path specified when installing app from local file", diff --git a/lib/l10n/eo.php b/lib/l10n/eo.php index b8ccfee3f2e..74b3ecef701 100644 --- a/lib/l10n/eo.php +++ b/lib/l10n/eo.php @@ -8,10 +8,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Ne konatas dosiertipo", "Invalid image" => "Ne validas bildo", "web services under your control" => "TTT-servoj regataj de vi", -"ZIP download is turned off." => "ZIP-elŝuto estas malkapabligita.", -"Files need to be downloaded one by one." => "Dosieroj devas elŝutiĝi unuope.", -"Back to Files" => "Reen al la dosieroj", -"Selected files too large to generate zip file." => "La elektitaj dosieroj tro grandas por genero de ZIP-dosiero.", "Application is not enabled" => "La aplikaĵo ne estas kapabligita", "Authentication error" => "Aŭtentiga eraro", "Token expired. Please reload page." => "Ĵetono eksvalidiĝis. Bonvolu reŝargi la paĝon.", diff --git a/lib/l10n/es.php b/lib/l10n/es.php index 11baff86587..9e30f78f9d6 100644 --- a/lib/l10n/es.php +++ b/lib/l10n/es.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipo de archivo desconocido", "Invalid image" => "Imagen inválida", "web services under your control" => "Servicios web bajo su control", -"ZIP download is turned off." => "La descarga en ZIP está desactivada.", -"Files need to be downloaded one by one." => "Los archivos deben ser descargados uno por uno.", -"Back to Files" => "Volver a Archivos", -"Selected files too large to generate zip file." => "Los archivos seleccionados son demasiado grandes para generar el archivo zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Descargue los archivos en trozos más pequeños, por separado o solicítelos amablemente su administrador.", "No source specified when installing app" => "No se ha especificado origen cuando se ha instalado la aplicación", "No href specified when installing app from http" => "No href especificado cuando se ha instalado la aplicación", "No path specified when installing app from local file" => "Sin path especificado cuando se ha instalado la aplicación desde el fichero local", diff --git a/lib/l10n/es_AR.php b/lib/l10n/es_AR.php index 34775b16b22..6b5e1961186 100644 --- a/lib/l10n/es_AR.php +++ b/lib/l10n/es_AR.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipo de archivo desconocido", "Invalid image" => "Imagen inválida", "web services under your control" => "servicios web sobre los que tenés control", -"ZIP download is turned off." => "La descarga en ZIP está desactivada.", -"Files need to be downloaded one by one." => "Los archivos deben ser descargados de a uno.", -"Back to Files" => "Volver a Archivos", -"Selected files too large to generate zip file." => "Los archivos seleccionados son demasiado grandes para generar el archivo zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Por favor, descargue estos archivos de forma separada en pequeñas partes o pídalo amablemente a su administrador.", "No source specified when installing app" => "No se especificó el origen al instalar la app", "No href specified when installing app from http" => "No se especificó href al instalar la app", "No path specified when installing app from local file" => "No se especificó PATH al instalar la app desde el archivo local", diff --git a/lib/l10n/es_MX.php b/lib/l10n/es_MX.php index befb076b7de..82a2594058c 100644 --- a/lib/l10n/es_MX.php +++ b/lib/l10n/es_MX.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipo de archivo desconocido", "Invalid image" => "Imagen inválida", "web services under your control" => "Servicios web bajo su control", -"ZIP download is turned off." => "La descarga en ZIP está desactivada.", -"Files need to be downloaded one by one." => "Los archivos deben ser descargados uno por uno.", -"Back to Files" => "Volver a Archivos", -"Selected files too large to generate zip file." => "Los archivos seleccionados son demasiado grandes para generar el archivo zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Descargue los archivos en trozos más pequeños, por separado o solicítelos amablemente a su administrador.", "No source specified when installing app" => "No se ha especificado origen cuando se ha instalado la aplicación", "No href specified when installing app from http" => "No href especificado cuando se ha instalado la aplicación", "No path specified when installing app from local file" => "Sin path especificado cuando se ha instalado la aplicación desde el archivo local", diff --git a/lib/l10n/et_EE.php b/lib/l10n/et_EE.php index 4c18742345c..128d0fc8317 100644 --- a/lib/l10n/et_EE.php +++ b/lib/l10n/et_EE.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tundmatu failitüüp", "Invalid image" => "Vigane pilt", "web services under your control" => "veebitenused sinu kontrolli all", -"ZIP download is turned off." => "ZIP-ina allalaadimine on välja lülitatud.", -"Files need to be downloaded one by one." => "Failid tuleb alla laadida ükshaaval.", -"Back to Files" => "Tagasi failide juurde", -"Selected files too large to generate zip file." => "Valitud failid on ZIP-faili loomiseks liiga suured.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Palun laadi failid alla eraldi väiksemate osadena või palu abi oma süsteemihaldurilt.", "No source specified when installing app" => "Ühegi lähteallikat pole rakendi paigalduseks määratletud", "No href specified when installing app from http" => "Ühtegi aadressi pole määratletud rakendi paigalduseks veebist", "No path specified when installing app from local file" => "Ühtegi teed pole määratletud paigaldamaks rakendit kohalikust failist", diff --git a/lib/l10n/eu.php b/lib/l10n/eu.php index 7a8a11f5b32..f6a5306b358 100644 --- a/lib/l10n/eu.php +++ b/lib/l10n/eu.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Fitxategi mota ezezaguna", "Invalid image" => "Baliogabeko irudia", "web services under your control" => "web zerbitzuak zure kontrolpean", -"ZIP download is turned off." => "ZIP deskarga ez dago gaituta.", -"Files need to be downloaded one by one." => "Fitxategiak banan-banan deskargatu behar dira.", -"Back to Files" => "Itzuli fitxategietara", -"Selected files too large to generate zip file." => "Hautatuko fitxategiak oso handiak dira zip fitxategia sortzeko.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Mesedez deskargatu fitzategiak zati txikiagoetan, banan-banan edo eskatu mesedez zure administradoreari.", "No source specified when installing app" => "Ez da jatorririk zehaztu aplikazioa instalatzerakoan", "No href specified when installing app from http" => "Ez da href parametrorik zehaztu http bidez aplikazioa instalatzerakoan", "No path specified when installing app from local file" => "Ez da kokalekurik zehaztu fitxategi lokal moduan aplikazioa instalatzerakoan", diff --git a/lib/l10n/fa.php b/lib/l10n/fa.php index 11912269ba4..08c8eb26527 100644 --- a/lib/l10n/fa.php +++ b/lib/l10n/fa.php @@ -8,10 +8,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "نوع فایل ناشناخته", "Invalid image" => "عکس نامعتبر", "web services under your control" => "سرویس های تحت وب در کنترل شما", -"ZIP download is turned off." => "دانلود به صورت فشرده غیر فعال است", -"Files need to be downloaded one by one." => "فایل ها باید به صورت یکی یکی دانلود شوند", -"Back to Files" => "بازگشت به فایل ها", -"Selected files too large to generate zip file." => "فایل های انتخاب شده بزرگتر از آن هستند که بتوان یک فایل فشرده تولید کرد", "Application is not enabled" => "برنامه فعال نشده است", "Authentication error" => "خطا در اعتبار سنجی", "Token expired. Please reload page." => "رمز منقضی شده است. لطفا دوباره صفحه را بارگذاری نمایید.", diff --git a/lib/l10n/fi_FI.php b/lib/l10n/fi_FI.php index e87c7038807..15f6d8563d6 100644 --- a/lib/l10n/fi_FI.php +++ b/lib/l10n/fi_FI.php @@ -11,10 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tuntematon tiedostotyyppi", "Invalid image" => "Virheellinen kuva", "web services under your control" => "verkkopalvelut hallinnassasi", -"ZIP download is turned off." => "ZIP-lataus on poistettu käytöstä.", -"Files need to be downloaded one by one." => "Tiedostot on ladattava yksittäin.", -"Back to Files" => "Takaisin tiedostoihin", -"Selected files too large to generate zip file." => "Valitut tiedostot ovat liian suurikokoisia mahtuakseen zip-tiedostoon.", "No source specified when installing app" => "Lähdettä ei määritelty sovellusta asennettaessa", "No href specified when installing app from http" => "Href-määritettä ei asetettu asennettaessa sovellusta http:n yli", "No path specified when installing app from local file" => "Polkua ei määritelty sovellusta asennettaessa paikallisesta tiedostosta", @@ -54,6 +50,7 @@ $TRANSLATIONS = array( "Please double check the <a href='%s'>installation guides</a>." => "Lue tarkasti <a href='%s'>asennusohjeet</a>.", "%s shared »%s« with you" => "%s jakoi kohteen »%s« kanssasi", "Sharing %s failed, because the file does not exist" => "Kohteen %s jakaminen epäonnistui, koska tiedostoa ei ole olemassa", +"You are not allowed to share %s" => "Oikeutesi eivät riitä kohteen %s jakamiseen.", "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", diff --git a/lib/l10n/fr.php b/lib/l10n/fr.php index b91152a53a5..1f05c1cff89 100644 --- a/lib/l10n/fr.php +++ b/lib/l10n/fr.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Type de fichier inconnu", "Invalid image" => "Image invalide", "web services under your control" => "services web sous votre contrôle", -"ZIP download is turned off." => "Téléchargement ZIP désactivé.", -"Files need to be downloaded one by one." => "Les fichiers nécessitent d'être téléchargés un par un.", -"Back to Files" => "Retour aux Fichiers", -"Selected files too large to generate zip file." => "Les fichiers sélectionnés sont trop volumineux pour être compressés.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Merci de télécharger les fichiers séparément en parties plus petites, ou demandez aimablement à votre administrateur.", "No source specified when installing app" => "Aucune source spécifiée pour installer l'application", "No href specified when installing app from http" => "Aucun href spécifié pour installer l'application par http", "No path specified when installing app from local file" => "Aucun chemin spécifié pour installer l'application depuis un fichier local", diff --git a/lib/l10n/gl.php b/lib/l10n/gl.php index 695ba1ee36d..3a04e167ce7 100644 --- a/lib/l10n/gl.php +++ b/lib/l10n/gl.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipo de ficheiro descoñecido", "Invalid image" => "Imaxe incorrecta", "web services under your control" => "servizos web baixo o seu control", -"ZIP download is turned off." => "As descargas ZIP están desactivadas.", -"Files need to be downloaded one by one." => "Os ficheiros necesitan seren descargados dun en un.", -"Back to Files" => "Volver aos ficheiros", -"Selected files too large to generate zip file." => "Os ficheiros seleccionados son demasiado grandes como para xerar un ficheiro zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Descargue os ficheiros en fragmentos máis pequenos e por separado, ou pídallos amabelmente ao seu administrador.", "No source specified when installing app" => "Non foi especificada ningunha orixe ao instalar aplicativos", "No href specified when installing app from http" => "Non foi especificada ningunha href ao instalar aplicativos", "No path specified when installing app from local file" => "Non foi especificada ningunha ruta ao instalar aplicativos desde un ficheiro local", @@ -26,7 +21,7 @@ $TRANSLATIONS = array( "App does not provide an info.xml file" => "O aplicativo non fornece un ficheiro info.xml", "App can't be installed because of not allowed code in the App" => "Non é posíbel instalar o aplicativo por mor de conter código non permitido", "App can't be installed because it is not compatible with this version of ownCloud" => "Non é posíbel instalar o aplicativo por non seren compatíbel con esta versión do ownCloud.", -"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Non é posíbel instalar o aplicativo por conter a etiqueta\n<shipped>\n\ntrue\n</shipped>\nque non está permitida para os aplicativos non enviados", +"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Non é posíbel instalar o aplicativo por conter a etiqueta <shipped>true</shipped> que non está permitida para os aplicativos non expedidos", "App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Non é posíbel instalar o aplicativo xa que a versión en info.xml/version non é a mesma que a versión informada desde a App Store", "App directory already exists" => "Xa existe o directorio do aplicativo", "Can't create app folder. Please fix permissions. %s" => "Non é posíbel crear o cartafol de aplicativos. Corrixa os permisos. %s", @@ -44,18 +39,18 @@ $TRANSLATIONS = array( "You need to enter either an existing account or the administrator." => "Deberá introducir unha conta existente ou o administrador.", "MySQL/MariaDB username and/or password not valid" => "O nome e/ou o contrasinal do usuario de MySQL/MariaDB non é correcto", "DB Error: \"%s\"" => "Produciuse un erro na base de datos: «%s»", -"Offending command was: \"%s\"" => "A orde ofensiva foi: «%s»", +"Offending command was: \"%s\"" => "A orde infractora foi: «%s»", "MySQL/MariaDB user '%s'@'localhost' exists already." => "Xa existe o usuario «%s»@«localhost» no MySQL/MariaDB.", "Drop this user from MySQL/MariaDB" => "Eliminar este usuario do MySQL/MariaDB", "MySQL/MariaDB user '%s'@'%%' already exists" => "Xa existe o usuario «%s»@«%%» no MySQL/MariaDB", "Drop this user from MySQL/MariaDB." => "Eliminar este usuario do MySQL/MariaDB.", "Oracle connection could not be established" => "Non foi posíbel estabelecer a conexión con Oracle", "Oracle username and/or password not valid" => "Nome de usuario e/ou contrasinal de Oracle incorrecto", -"Offending command was: \"%s\", name: %s, password: %s" => "A orde ofensiva foi: «%s», nome: %s, contrasinal: %s", +"Offending command was: \"%s\", name: %s, password: %s" => "A orde infractora foi: «%s», nome: %s, contrasinal: %s", "PostgreSQL username and/or password not valid" => "Nome de usuario e/ou contrasinal de PostgreSQL incorrecto", "Set an admin username." => "Estabeleza un nome de usuario administrador", "Set an admin password." => "Estabeleza un contrasinal de administrador", -"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "O seu servidor web non está aínda configurado adecuadamente para permitir a sincronización de ficheiros xa que semella que a interface WebDAV non está a funcionar.", +"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "O seu servidor web aínda non está configurado axeidamente para permitir a sincronización de ficheiros xa que semella que a interface WebDAV non está a funcionar.", "Please double check the <a href='%s'>installation guides</a>." => "Volva comprobar as <a href='%s'>guías de instalación</a>", "%s shared »%s« with you" => "%s compartiu «%s» con vostede", "Sharing %s failed, because the file does not exist" => "Fallou a compartición de %s, o ficheiro non existe", @@ -74,7 +69,7 @@ $TRANSLATIONS = array( "Sharing backend %s must implement the interface OCP\\Share_Backend" => "A infraestrutura de compartición %s ten que implementar a interface OCP\\Share_Backend", "Sharing backend %s not found" => "Non se atopou a infraestrutura de compartición %s", "Sharing backend for %s not found" => "Non se atopou a infraestrutura de compartición para %s", -"Sharing %s failed, because the user %s is the original sharer" => "Fallou a compartición de %s, compartición orixinal é do usuario %s", +"Sharing %s failed, because the user %s is the original sharer" => "Fallou a compartición de %s, a compartición orixinal é do usuario %s", "Sharing %s failed, because the permissions exceed permissions granted to %s" => "Fallou a compartición de %s, os permisos superan os permisos concedidos a %s", "Sharing %s failed, because resharing is not allowed" => "Fallou a compartición de %s, non está permitido repetir a compartción", "Sharing %s failed, because the sharing backend for %s could not find its source" => "Fallou a compartición de %s, a infraestrutura de compartición para %s non foi quen de atopar a orixe", diff --git a/lib/l10n/he.php b/lib/l10n/he.php index 27267c2e34d..e6865e6cfd9 100644 --- a/lib/l10n/he.php +++ b/lib/l10n/he.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "משתמשים", "Admin" => "מנהל", "web services under your control" => "שירותי רשת תחת השליטה שלך", -"ZIP download is turned off." => "הורדת ZIP כבויה", -"Files need to be downloaded one by one." => "יש להוריד את הקבצים אחד אחרי השני.", -"Back to Files" => "חזרה לקבצים", -"Selected files too large to generate zip file." => "הקבצים הנבחרים גדולים מידי ליצירת קובץ zip.", "Application is not enabled" => "יישומים אינם מופעלים", "Authentication error" => "שגיאת הזדהות", "Token expired. Please reload page." => "פג תוקף. נא לטעון שוב את הדף.", diff --git a/lib/l10n/hu_HU.php b/lib/l10n/hu_HU.php index 0637773d17c..d2a54de5621 100644 --- a/lib/l10n/hu_HU.php +++ b/lib/l10n/hu_HU.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Ismeretlen file tipús", "Invalid image" => "Hibás kép", "web services under your control" => "webszolgáltatások saját kézben", -"ZIP download is turned off." => "A ZIP-letöltés nincs engedélyezve.", -"Files need to be downloaded one by one." => "A fájlokat egyenként kell letölteni.", -"Back to Files" => "Vissza a Fájlokhoz", -"Selected files too large to generate zip file." => "A kiválasztott fájlok túl nagyok a zip tömörítéshez.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "A file-t kisebb részekben töltsd le vagy beszélj az adminisztrátorral a megoldás érdekében.", "No source specified when installing app" => "Az alkalmazás telepítéséhez nincs forrás megadva", "No href specified when installing app from http" => "Az alkalmazás http-n keresztül történő telepítéséhez nincs href hivetkozás megadva", "No path specified when installing app from local file" => "Az alkalmazás helyi telepítéséhez nincs útvonal (mappa) megadva", diff --git a/lib/l10n/id.php b/lib/l10n/id.php index d694967cd42..94ed05c0fc7 100644 --- a/lib/l10n/id.php +++ b/lib/l10n/id.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipe berkas tak dikenal", "Invalid image" => "Gambar tidak sah", "web services under your control" => "layanan web dalam kendali anda", -"ZIP download is turned off." => "Pengunduhan ZIP dimatikan.", -"Files need to be downloaded one by one." => "Berkas harus diunduh satu persatu.", -"Back to Files" => "Kembali ke Berkas", -"Selected files too large to generate zip file." => "Berkas yang dipilih terlalu besar untuk dibuat berkas zip-nya.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Silahkan unduh berkas secara terpisah dalam bentuk potongan kecil atau meminta ke administrator anda.", "No source specified when installing app" => "Tidak ada sumber yang ditentukan saat menginstal apl", "No href specified when installing app from http" => "Href tidak ditentukan saat menginstal apl dari http", "No path specified when installing app from local file" => "Lokasi tidak ditentukan saat menginstal apl dari berkas lokal", diff --git a/lib/l10n/is.php b/lib/l10n/is.php index 032289fd304..9754b97bbf7 100644 --- a/lib/l10n/is.php +++ b/lib/l10n/is.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "Notendur", "Admin" => "Stjórnun", "web services under your control" => "vefþjónusta undir þinni stjórn", -"ZIP download is turned off." => "Slökkt á ZIP niðurhali.", -"Files need to be downloaded one by one." => "Skrárnar verður að sækja eina og eina", -"Back to Files" => "Aftur í skrár", -"Selected files too large to generate zip file." => "Valdar skrár eru of stórar til að búa til ZIP skrá.", "Application is not enabled" => "Forrit ekki virkt", "Authentication error" => "Villa við auðkenningu", "Token expired. Please reload page." => "Auðkenning útrunnin. Vinsamlegast skráðu þig aftur inn.", diff --git a/lib/l10n/it.php b/lib/l10n/it.php index 584d9ec4e7f..c7948cab3e9 100644 --- a/lib/l10n/it.php +++ b/lib/l10n/it.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipo di file sconosciuto", "Invalid image" => "Immagine non valida", "web services under your control" => "servizi web nelle tue mani", -"ZIP download is turned off." => "Lo scaricamento in formato ZIP è stato disabilitato.", -"Files need to be downloaded one by one." => "I file devono essere scaricati uno alla volta.", -"Back to Files" => "Torna ai file", -"Selected files too large to generate zip file." => "I file selezionati sono troppo grandi per generare un file zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Scarica i file separatamente in blocchi più piccoli o chiedi al tuo amministratore.", "No source specified when installing app" => "Nessuna fonte specificata durante l'installazione dell'applicazione", "No href specified when installing app from http" => "Nessun href specificato durante l'installazione dell'applicazione da http", "No path specified when installing app from local file" => "Nessun percorso specificato durante l'installazione dell'applicazione da file locale", diff --git a/lib/l10n/ja.php b/lib/l10n/ja.php index 195169c6e1c..bc6294ac078 100644 --- a/lib/l10n/ja.php +++ b/lib/l10n/ja.php @@ -1,6 +1,6 @@ <?php $TRANSLATIONS = array( -"You are accessing the server from an untrusted domain." => "あなたはサーバに、信用が付与されていないドメインからアクセスしています。", +"You are accessing the server from an untrusted domain." => "信頼されていないドメインからサーバーにアクセスしています。", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domain\" setting in config/config.php. An example configuration is provided in config/config.sample.php." => "管理者に連絡してください。このサーバーの管理者の場合は、\"trusted_domain\" の設定を config/config.php に設定してください。config/config.sample.php にサンプルの設定方法が記載してあります。", "App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => " \"%s\" アプリは、このバージョンのownCloudと互換性がないためインストールできません。", "No app name specified" => "アプリ名が未指定", @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "不明なファイルタイプ", "Invalid image" => "無効な画像", "web services under your control" => "管理下のウェブサービス", -"ZIP download is turned off." => "ZIPダウンロードは無効です。", -"Files need to be downloaded one by one." => "ファイルは1つずつダウンロードする必要があります。", -"Back to Files" => "ファイルに戻る", -"Selected files too large to generate zip file." => "選択したファイルはZIPファイルの生成には大きすぎます。", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "少しずつに分けてファイルをダウンロードするか、管理者に問い合わせてください。", "No source specified when installing app" => "アプリインストール時のソースが未指定", "No href specified when installing app from http" => "アプリインストール時のhttpの URL が未指定", "No path specified when installing app from local file" => "アプリインストール時のローカルファイルのパスが未指定", @@ -73,7 +68,7 @@ $TRANSLATIONS = array( "Sharing backend %s must implement the interface OCP\\Share_Backend" => "%s のバックエンドの共有には、OCP\\Share_Backend インターフェースを実装しなければなりません。", "Sharing backend %s not found" => "共有バックエンド %s が見つかりません", "Sharing backend for %s not found" => "%s のための共有バックエンドが見つかりません", -"Sharing %s failed, because the user %s is the original sharer" => "%s の共有に失敗しました。ユーザ %s が元々の共有者であるからです。", +"Sharing %s failed, because the user %s is the original sharer" => "%s の共有に失敗しました。ユーザー %s が元々の共有者であるからです。", "Sharing %s failed, because the permissions exceed permissions granted to %s" => "%s の共有に失敗しました。%s に付与されている許可を超えているからです。", "Sharing %s failed, because resharing is not allowed" => "%s の共有に失敗しました。再共有が許されていないからです。", "Sharing %s failed, because the sharing backend for %s could not find its source" => "%s の共有に失敗しました。%s のバックエンド共有に必要なソースが見つかりませんでした。", @@ -92,6 +87,6 @@ $TRANSLATIONS = array( "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" => "ユーザー名で利用できる文字列は、次のものです: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"", "A valid username must be provided" => "有効なユーザー名を指定する必要があります", "A valid password must be provided" => "有効なパスワードを指定する必要があります", -"The username is already being used" => "ユーザ名はすでに使われています" +"The username is already being used" => "ユーザー名はすでに使われています" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/l10n/ka_GE.php b/lib/l10n/ka_GE.php index f15563c297d..826bd119ded 100644 --- a/lib/l10n/ka_GE.php +++ b/lib/l10n/ka_GE.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "მომხმარებელი", "Admin" => "ადმინისტრატორი", "web services under your control" => "web services under your control", -"ZIP download is turned off." => "ZIP download–ი გათიშულია", -"Files need to be downloaded one by one." => "ფაილები უნდა გადმოიტვირთოს სათითაოდ.", -"Back to Files" => "უკან ფაილებში", -"Selected files too large to generate zip file." => "არჩეული ფაილები ძალიან დიდია zip ფაილის გენერაციისთვის.", "Application is not enabled" => "აპლიკაცია არ არის აქტიური", "Authentication error" => "ავთენტიფიკაციის შეცდომა", "Token expired. Please reload page." => "Token–ს ვადა გაუვიდა. გთხოვთ განაახლოთ გვერდი.", diff --git a/lib/l10n/km.php b/lib/l10n/km.php index d5fdc025760..7d3883b2aad 100644 --- a/lib/l10n/km.php +++ b/lib/l10n/km.php @@ -7,17 +7,15 @@ $TRANSLATIONS = array( "Settings" => "ការកំណត់", "Users" => "អ្នកប្រើ", "Admin" => "អ្នកគ្រប់គ្រង", +"Failed to upgrade \"%s\"." => "បរាជ័យការធ្វើការបន្ទាន់សម័យ\"%s\".", "Unknown filetype" => "មិនស្គាល់ប្រភេទឯកសារ", "Invalid image" => "រូបភាពមិនត្រឹមត្រូវ", "web services under your control" => "សេវាកម្មវេបក្រោមការការបញ្ជារបស់អ្នក", -"ZIP download is turned off." => "បានបិទការទាញយក ZIP ។", -"Files need to be downloaded one by one." => "ត្រូវការទាញយកឯកសារម្ដងមួយៗ។", -"Back to Files" => "ត្រឡប់ទៅឯកសារ", -"Selected files too large to generate zip file." => "ឯកសារដែលបានជ្រើស មានទំហំធំពេកក្នុងការបង្កើតជា zip ។", "App directory already exists" => "មានទីតាំងផ្ទុកកម្មវិធីរួចហើយ", "Can't create app folder. Please fix permissions. %s" => "មិនអាចបង្កើតថតកម្មវិធី។ សូមកែសម្រួលសិទ្ធិ។ %s", "Application is not enabled" => "មិនបានបើកកម្មវិធី", "Authentication error" => "កំហុសការផ្ទៀងផ្ទាត់ភាពត្រឹមត្រូវ", +"Unknown user" => "មិនស្គាល់អ្នកប្រើប្រាស់", "Files" => "ឯកសារ", "Text" => "អត្ថបទ", "Images" => "រូបភាព", diff --git a/lib/l10n/ko.php b/lib/l10n/ko.php index 977a491ad74..9ed49cc4498 100644 --- a/lib/l10n/ko.php +++ b/lib/l10n/ko.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "알 수 없는 파일 형식", "Invalid image" => "잘못된 그림", "web services under your control" => "내가 관리하는 웹 서비스", -"ZIP download is turned off." => "ZIP 다운로드가 비활성화 되었습니다.", -"Files need to be downloaded one by one." => "파일을 개별적으로 다운로드해야 합니다.", -"Back to Files" => "파일로 돌아가기", -"Selected files too large to generate zip file." => "선택한 파일들은 ZIP 파일을 생성하기에 너무 큽니다.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "작은 조각들 안에 들어있는 파일들을 받고자 하신다면, 나누어서 받으시거나 혹은 시스템 관리자에게 정중하게 물어보십시오", "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" => "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.", diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php index 88aca7aba46..57fc91f6a93 100644 --- a/lib/l10n/lt_LT.php +++ b/lib/l10n/lt_LT.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Nežinomas failo tipas", "Invalid image" => "Netinkamas paveikslėlis", "web services under your control" => "jūsų valdomos web paslaugos", -"ZIP download is turned off." => "ZIP atsisiuntimo galimybė yra išjungta.", -"Files need to be downloaded one by one." => "Failai turi būti parsiunčiami vienas po kito.", -"Back to Files" => "Atgal į Failus", -"Selected files too large to generate zip file." => "Pasirinkti failai per dideli archyvavimui į ZIP.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Prašome atsisiųsti failus mažesnėmis dalimis atskirai, arba mandagiai prašykite savo administratoriaus.", "No source specified when installing app" => "Nenurodytas šaltinis diegiant programą", "No href specified when installing app from http" => "Nenurodytas href diegiant programą iš http", "No path specified when installing app from local file" => "Nenurodytas kelias diegiant programą iš vietinio failo", diff --git a/lib/l10n/lv.php b/lib/l10n/lv.php index 1c8a31aff2f..37a11d1296b 100644 --- a/lib/l10n/lv.php +++ b/lib/l10n/lv.php @@ -7,10 +7,6 @@ $TRANSLATIONS = array( "Admin" => "Administratori", "Failed to upgrade \"%s\"." => "Kļūda atjauninot \"%s\"", "web services under your control" => "tīmekļa servisi tavā varā", -"ZIP download is turned off." => "ZIP lejupielādēšana ir izslēgta.", -"Files need to be downloaded one by one." => "Datnes var lejupielādēt tikai katru atsevišķi.", -"Back to Files" => "Atpakaļ pie datnēm", -"Selected files too large to generate zip file." => "Izvēlētās datnes ir pārāk lielas, lai izveidotu zip datni.", "Application is not enabled" => "Lietotne nav aktivēta", "Authentication error" => "Autentifikācijas kļūda", "Token expired. Please reload page." => "Pilnvarai ir beidzies termiņš. Lūdzu, pārlādējiet lapu.", diff --git a/lib/l10n/mk.php b/lib/l10n/mk.php index a0b3c39865a..934ddf0932f 100644 --- a/lib/l10n/mk.php +++ b/lib/l10n/mk.php @@ -8,10 +8,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Непознат тип на датотека", "Invalid image" => "Невалидна фотографија", "web services under your control" => "веб сервиси под Ваша контрола", -"ZIP download is turned off." => "Преземање во ZIP е исклучено", -"Files need to be downloaded one by one." => "Датотеките треба да се симнат една по една.", -"Back to Files" => "Назад кон датотеки", -"Selected files too large to generate zip file." => "Избраните датотеки се преголеми за да се генерира zip.", "Application is not enabled" => "Апликацијата не е овозможена", "Authentication error" => "Грешка во автентикација", "Token expired. Please reload page." => "Жетонот е истечен. Ве молам превчитајте ја страницата.", diff --git a/lib/l10n/my_MM.php b/lib/l10n/my_MM.php index 7fdf0d0285d..79aff10ebbb 100644 --- a/lib/l10n/my_MM.php +++ b/lib/l10n/my_MM.php @@ -4,10 +4,6 @@ $TRANSLATIONS = array( "Users" => "သုံးစွဲသူ", "Admin" => "အက်ဒမင်", "web services under your control" => "သင်၏ထိန်းချုပ်မှု့အောက်တွင်ရှိသော Web services", -"ZIP download is turned off." => "ZIP ဒေါင်းလုတ်ကိုပိတ်ထားသည်", -"Files need to be downloaded one by one." => "ဖိုင်များသည် တစ်ခုပြီး တစ်ခုဒေါင်းလုတ်ချရန်လိုအပ်သည်", -"Back to Files" => "ဖိုင်သို့ပြန်သွားမည်", -"Selected files too large to generate zip file." => "zip ဖိုင်အဖြစ်ပြုလုပ်ရန် ရွေးချယ်ထားသောဖိုင်များသည် အရမ်းကြီးလွန်းသည်", "Authentication error" => "ခွင့်ပြုချက်မအောင်မြင်", "Files" => "ဖိုင်များ", "Text" => "စာသား", diff --git a/lib/l10n/nb_NO.php b/lib/l10n/nb_NO.php index 2b601e1a807..999f4e25136 100644 --- a/lib/l10n/nb_NO.php +++ b/lib/l10n/nb_NO.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Ukjent filtype", "Invalid image" => "Ugyldig bilde", "web services under your control" => "web tjenester du kontrollerer", -"ZIP download is turned off." => "ZIP-nedlasting av avslått", -"Files need to be downloaded one by one." => "Filene må lastes ned en om gangen", -"Back to Files" => "Tilbake til filer", -"Selected files too large to generate zip file." => "De valgte filene er for store til å kunne generere ZIP-fil", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Vennligst last ned filene separat i mindre deler eller spør administratoren pent.", "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", diff --git a/lib/l10n/nl.php b/lib/l10n/nl.php index 4abd1d5a1b1..53b7ccea792 100644 --- a/lib/l10n/nl.php +++ b/lib/l10n/nl.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Onbekend bestandsformaat", "Invalid image" => "Ongeldige afbeelding", "web services under your control" => "Webdiensten in eigen beheer", -"ZIP download is turned off." => "ZIP download is uitgeschakeld.", -"Files need to be downloaded one by one." => "Bestanden moeten één voor één worden gedownload.", -"Back to Files" => "Terug naar bestanden", -"Selected files too large to generate zip file." => "De geselecteerde bestanden zijn te groot om een zip bestand te maken.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Download de bestanden afzonderlijk in kleinere porties of vraag het uw beheerder,", "No source specified when installing app" => "Geen bron opgegeven bij installatie van de app", "No href specified when installing app from http" => "Geen href opgegeven bij installeren van de app vanaf http", "No path specified when installing app from local file" => "Geen pad opgegeven bij installeren van de app vanaf een lokaal bestand", diff --git a/lib/l10n/oc.php b/lib/l10n/oc.php index 40a527cc76c..5ca84007868 100644 --- a/lib/l10n/oc.php +++ b/lib/l10n/oc.php @@ -6,9 +6,6 @@ $TRANSLATIONS = array( "Users" => "Usancièrs", "Admin" => "Admin", "web services under your control" => "Services web jos ton contraròtle", -"ZIP download is turned off." => "Avalcargar los ZIP es inactiu.", -"Files need to be downloaded one by one." => "Los fichièrs devan èsser avalcargats un per un.", -"Back to Files" => "Torna cap als fichièrs", "Authentication error" => "Error d'autentificacion", "Files" => "Fichièrs", "seconds ago" => "segonda a", diff --git a/lib/l10n/pl.php b/lib/l10n/pl.php index 90e98707806..f9a774306b6 100644 --- a/lib/l10n/pl.php +++ b/lib/l10n/pl.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Nieznany typ pliku", "Invalid image" => "Błędne zdjęcie", "web services under your control" => "Kontrolowane serwisy", -"ZIP download is turned off." => "Pobieranie ZIP jest wyłączone.", -"Files need to be downloaded one by one." => "Pliki muszą zostać pobrane pojedynczo.", -"Back to Files" => "Wróć do plików", -"Selected files too large to generate zip file." => "Wybrane pliki są zbyt duże, aby wygenerować plik zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Proszę ściągać pliki osobno w mniejszych paczkach lub poprosić administratora.", "No source specified when installing app" => "Nie określono źródła podczas instalacji aplikacji", "No href specified when installing app from http" => "Nie określono linku skąd aplikacja ma być zainstalowana", "No path specified when installing app from local file" => "Nie określono lokalnego pliku z którego miała być instalowana aplikacja", diff --git a/lib/l10n/pt_BR.php b/lib/l10n/pt_BR.php index 5d8eeb72c8e..a112b5b5cc0 100644 --- a/lib/l10n/pt_BR.php +++ b/lib/l10n/pt_BR.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tipo de arquivo desconhecido", "Invalid image" => "Imagem inválida", "web services under your control" => "serviços web sob seu controle", -"ZIP download is turned off." => "Download ZIP está desligado.", -"Files need to be downloaded one by one." => "Arquivos precisam ser baixados um de cada vez.", -"Back to Files" => "Voltar para Arquivos", -"Selected files too large to generate zip file." => "Arquivos selecionados são muito grandes para gerar arquivo zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Por favor baixe os arquivos separadamente em pedaços ou educadamente pergunte ao seu administrador.", "No source specified when installing app" => "Nenhuma fonte foi especificada enquanto instalava o aplicativo", "No href specified when installing app from http" => "Nenhuma href foi especificada enquanto instalava o aplicativo de httml", "No path specified when installing app from local file" => "Nenhum caminho foi especificado enquanto instalava o aplicativo do arquivo local", diff --git a/lib/l10n/pt_PT.php b/lib/l10n/pt_PT.php index d2257afc7bb..f39bf611412 100644 --- a/lib/l10n/pt_PT.php +++ b/lib/l10n/pt_PT.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Ficheiro desconhecido", "Invalid image" => "Imagem inválida", "web services under your control" => "serviços web sob o seu controlo", -"ZIP download is turned off." => "Descarregamento em ZIP está desligado.", -"Files need to be downloaded one by one." => "Os ficheiros precisam de ser descarregados um por um.", -"Back to Files" => "Voltar a Ficheiros", -"Selected files too large to generate zip file." => "Os ficheiros seleccionados são grandes demais para gerar um ficheiro zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Por favor descarregue os ficheiros divididos em partes mais pequenas ou peça ajuda ao seu administrador.", "No source specified when installing app" => "Não foi especificada uma fonte de instalação desta aplicação", "No href specified when installing app from http" => "Não foi especificada uma href http para instalar esta aplicação", "No path specified when installing app from local file" => "Não foi especificado o caminho de instalação desta aplicação", diff --git a/lib/l10n/ro.php b/lib/l10n/ro.php index 87e9a92c464..3d76eeeef90 100644 --- a/lib/l10n/ro.php +++ b/lib/l10n/ro.php @@ -8,10 +8,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Tip fișier necunoscut", "Invalid image" => "Imagine invalidă", "web services under your control" => "servicii web controlate de tine", -"ZIP download is turned off." => "Descărcarea ZIP este dezactivată.", -"Files need to be downloaded one by one." => "Fișierele trebuie descărcate unul câte unul.", -"Back to Files" => "Înapoi la fișiere", -"Selected files too large to generate zip file." => "Fișierele selectate sunt prea mari pentru a genera un fișier zip.", "Application is not enabled" => "Aplicația nu este activată", "Authentication error" => "Eroare la autentificare", "Token expired. Please reload page." => "Token expirat. Te rugăm să reîncarci pagina.", diff --git a/lib/l10n/ru.php b/lib/l10n/ru.php index 38532d0b3bc..a5554131004 100644 --- a/lib/l10n/ru.php +++ b/lib/l10n/ru.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Неизвестный тип файла", "Invalid image" => "Изображение повреждено", "web services under your control" => "веб-сервисы под вашим управлением", -"ZIP download is turned off." => "ZIP-скачивание отключено.", -"Files need to be downloaded one by one." => "Файлы должны быть загружены по одному.", -"Back to Files" => "Назад к файлам", -"Selected files too large to generate zip file." => "Выбранные файлы слишком велики, чтобы создать zip файл.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Загрузите файлы раздельно маленькими частями или вежливо попросите вашего администратора.", "No source specified when installing app" => "Не указан источник при установке приложения", "No href specified when installing app from http" => "Не указан атрибут href при установке приложения через http", "No path specified when installing app from local file" => "Не указан путь при установке приложения из локального файла", diff --git a/lib/l10n/si_LK.php b/lib/l10n/si_LK.php index d10804cae69..3d8bc7d4768 100644 --- a/lib/l10n/si_LK.php +++ b/lib/l10n/si_LK.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "පරිශීලකයන්", "Admin" => "පරිපාලක", "web services under your control" => "ඔබට පාලනය කළ හැකි වෙබ් සේවාවන්", -"ZIP download is turned off." => "ZIP භාගත කිරීම් අක්රියයි", -"Files need to be downloaded one by one." => "ගොනු එකින් එක භාගත යුතුයි", -"Back to Files" => "ගොනු වෙතට නැවත යන්න", -"Selected files too large to generate zip file." => "තෝරාගත් ගොනු ZIP ගොනුවක් තැනීමට විශාල වැඩිය.", "Application is not enabled" => "යෙදුම සක්රිය කර නොමැත", "Authentication error" => "සත්යාපන දෝෂයක්", "Token expired. Please reload page." => "ටෝකනය කල් ඉකුත් වී ඇත. පිටුව නැවුම් කරන්න", diff --git a/lib/l10n/sk_SK.php b/lib/l10n/sk_SK.php index 6e3a48a74fb..1a0f8bbf355 100644 --- a/lib/l10n/sk_SK.php +++ b/lib/l10n/sk_SK.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Neznámy typ súboru", "Invalid image" => "Chybný obrázok", "web services under your control" => "webové služby pod Vašou kontrolou", -"ZIP download is turned off." => "Sťahovanie súborov ZIP je vypnuté.", -"Files need to be downloaded one by one." => "Súbory musia byť nahrávané jeden za druhým.", -"Back to Files" => "Späť na súbory", -"Selected files too large to generate zip file." => "Zvolené súbory sú príliš veľké na vygenerovanie zip súboru.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Prosím, stiahnite si súbory samostatne v menších blokoch alebo sa obráťte na správcu.", "No source specified when installing app" => "Nešpecifikovaný zdroj pri inštalácii aplikácie", "No href specified when installing app from http" => "Nešpecifikovaný atribút \"href\" pri inštalácii aplikácie pomocou protokolu \"http\"", "No path specified when installing app from local file" => "Nešpecifikovaná cesta pri inštalácii aplikácie z lokálneho súboru", diff --git a/lib/l10n/sl.php b/lib/l10n/sl.php index 083f966ded4..0da229543b3 100644 --- a/lib/l10n/sl.php +++ b/lib/l10n/sl.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Neznana vrsta datoteke", "Invalid image" => "Neveljavna slika", "web services under your control" => "spletne storitve pod vašim nadzorom", -"ZIP download is turned off." => "Prejemanje datotek v paketu ZIP je onemogočeno.", -"Files need to be downloaded one by one." => "Datoteke je mogoče prejeti le posamično.", -"Back to Files" => "Nazaj na datoteke", -"Selected files too large to generate zip file." => "Izbrane datoteke so prevelike za ustvarjanje datoteke arhiva zip.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Datoteke je treba prejeti ločeno v manjših paketih, ali pa je treba za pomoč prositi skrbnika.", "No source specified when installing app" => "Ni podanega vira med nameščenjem programa", "No href specified when installing app from http" => "Ni podanega podatka naslova HREF med nameščenjem programa preko protokola HTTP.", "No path specified when installing app from local file" => "Ni podane poti med nameščenjem programa iz krajevne datoteke", diff --git a/lib/l10n/sq.php b/lib/l10n/sq.php index e29fa2cee53..baff9842c5a 100644 --- a/lib/l10n/sq.php +++ b/lib/l10n/sq.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "Përdoruesit", "Admin" => "Admin", "web services under your control" => "shërbime web nën kontrollin tënd", -"ZIP download is turned off." => "Shkarimi i skedarëve ZIP është i çaktivizuar.", -"Files need to be downloaded one by one." => "Skedarët duhet të shkarkohen një nga një.", -"Back to Files" => "Kthehu tek skedarët", -"Selected files too large to generate zip file." => "Skedarët e selektuar janë shumë të mëdhenj për të krijuar një skedar ZIP.", "Application is not enabled" => "Programi nuk është i aktivizuar.", "Authentication error" => "Veprim i gabuar gjatë vërtetimit të identitetit", "Token expired. Please reload page." => "Përmbajtja ka skaduar. Ju lutemi ringarkoni faqen.", diff --git a/lib/l10n/sr.php b/lib/l10n/sr.php index f9155bfd575..34ce90b214c 100644 --- a/lib/l10n/sr.php +++ b/lib/l10n/sr.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "Корисници", "Admin" => "Администратор", "web services under your control" => "веб сервиси под контролом", -"ZIP download is turned off." => "Преузимање ZIP-а је искључено.", -"Files need to be downloaded one by one." => "Датотеке морате преузимати једну по једну.", -"Back to Files" => "Назад на датотеке", -"Selected files too large to generate zip file." => "Изабране датотеке су превелике да бисте направили ZIP датотеку.", "Application is not enabled" => "Апликација није омогућена", "Authentication error" => "Грешка при провери идентитета", "Token expired. Please reload page." => "Жетон је истекао. Поново учитајте страницу.", diff --git a/lib/l10n/sv.php b/lib/l10n/sv.php index c30a0999774..96299ed0f1d 100644 --- a/lib/l10n/sv.php +++ b/lib/l10n/sv.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Okänd filtyp", "Invalid image" => "Ogiltig bild", "web services under your control" => "webbtjänster under din kontroll", -"ZIP download is turned off." => "Nerladdning av ZIP är avstängd.", -"Files need to be downloaded one by one." => "Filer laddas ner en åt gången.", -"Back to Files" => "Tillbaka till Filer", -"Selected files too large to generate zip file." => "Valda filer är för stora för att skapa zip-fil.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Ladda ner filerna i mindre bitar, separat eller fråga din administratör.", "No source specified when installing app" => "Ingen källa angiven vid installation av app ", "No href specified when installing app from http" => "Ingen href angiven vid installation av app från http", "No path specified when installing app from local file" => "Ingen sökväg angiven vid installation av app från lokal fil", diff --git a/lib/l10n/ta_LK.php b/lib/l10n/ta_LK.php index f761ccab0e2..f0d487cbfbd 100644 --- a/lib/l10n/ta_LK.php +++ b/lib/l10n/ta_LK.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "பயனாளர்", "Admin" => "நிர்வாகம்", "web services under your control" => "வலைய சேவைகள் உங்களுடைய கட்டுப்பாட்டின் கீழ் உள்ளது", -"ZIP download is turned off." => "வீசொலிப் பூட்டு பதிவிறக்கம் நிறுத்தப்பட்டுள்ளது.", -"Files need to be downloaded one by one." => "கோப்புகள்ஒன்றன் பின் ஒன்றாக பதிவிறக்கப்படவேண்டும்.", -"Back to Files" => "கோப்புகளுக்கு செல்க", -"Selected files too large to generate zip file." => "வீ சொலிக் கோப்புகளை உருவாக்குவதற்கு தெரிவுசெய்யப்பட்ட கோப்புகள் மிகப்பெரியவை", "Application is not enabled" => "செயலி இயலுமைப்படுத்தப்படவில்லை", "Authentication error" => "அத்தாட்சிப்படுத்தலில் வழு", "Token expired. Please reload page." => "அடையாளவில்லை காலாவதியாகிவிட்டது. தயவுசெய்து பக்கத்தை மீள் ஏற்றுக.", diff --git a/lib/l10n/th_TH.php b/lib/l10n/th_TH.php index 173d0f2856b..1c9e4385ff4 100644 --- a/lib/l10n/th_TH.php +++ b/lib/l10n/th_TH.php @@ -6,10 +6,6 @@ $TRANSLATIONS = array( "Users" => "ผู้ใช้งาน", "Admin" => "ผู้ดูแล", "web services under your control" => "เว็บเซอร์วิสที่คุณควบคุมการใช้งานได้", -"ZIP download is turned off." => "คุณสมบัติการดาวน์โหลด zip ถูกปิดการใช้งานไว้", -"Files need to be downloaded one by one." => "ไฟล์สามารถดาวน์โหลดได้ทีละครั้งเท่านั้น", -"Back to Files" => "กลับไปที่ไฟล์", -"Selected files too large to generate zip file." => "ไฟล์ที่เลือกมีขนาดใหญ่เกินกว่าที่จะสร้างเป็นไฟล์ zip", "Application is not enabled" => "แอพพลิเคชั่นดังกล่าวยังไม่ได้เปิดใช้งาน", "Authentication error" => "เกิดข้อผิดพลาดในสิทธิ์การเข้าใช้งาน", "Token expired. Please reload page." => "รหัสยืนยันความถูกต้องหมดอายุแล้ว กรุณาโหลดหน้าเว็บใหม่อีกครั้ง", diff --git a/lib/l10n/tr.php b/lib/l10n/tr.php index a8c48134cf2..81ff6dd8a2c 100644 --- a/lib/l10n/tr.php +++ b/lib/l10n/tr.php @@ -13,11 +13,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Bilinmeyen dosya türü", "Invalid image" => "Geçersiz resim", "web services under your control" => "denetiminizdeki web hizmetleri", -"ZIP download is turned off." => "ZIP indirmeleri kapatıldı.", -"Files need to be downloaded one by one." => "Dosyaların tek tek indirilmesi gerekmektedir.", -"Back to Files" => "Dosyalara Dön", -"Selected files too large to generate zip file." => "Seçilen dosyalar bir zip dosyası oluşturmak için fazla büyük.", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "Dosyaları ayrı ayrı, küçük parçalar halinde indirin veya yöneticinizden yardım isteyin. ", "No source specified when installing app" => "Uygulama kurulurken bir kaynak belirtilmedi", "No href specified when installing app from http" => "Uygulama http'den kurulurken href belirtilmedi", "No path specified when installing app from local file" => "Uygulama yerel dosyadan kurulurken dosya yolu belirtilmedi", diff --git a/lib/l10n/uk.php b/lib/l10n/uk.php index fed6277fdd8..8bd14bf2504 100644 --- a/lib/l10n/uk.php +++ b/lib/l10n/uk.php @@ -8,10 +8,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Невідомий тип файлу", "Invalid image" => "Невірне зображення", "web services under your control" => "підконтрольні Вам веб-сервіси", -"ZIP download is turned off." => "ZIP завантаження вимкнено.", -"Files need to be downloaded one by one." => "Файли повинні бути завантаженні послідовно.", -"Back to Files" => "Повернутися до файлів", -"Selected files too large to generate zip file." => "Вибрані фали завеликі для генерування zip файлу.", "Application is not enabled" => "Додаток не увімкнений", "Authentication error" => "Помилка автентифікації", "Token expired. Please reload page." => "Строк дії токена скінчився. Будь ласка, перезавантажте сторінку.", diff --git a/lib/l10n/vi.php b/lib/l10n/vi.php index c3e09e96310..e2edc6f8798 100644 --- a/lib/l10n/vi.php +++ b/lib/l10n/vi.php @@ -8,10 +8,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "Không biết kiểu tập tin", "Invalid image" => "Hình ảnh không hợp lệ", "web services under your control" => "dịch vụ web dưới sự kiểm soát của bạn", -"ZIP download is turned off." => "Tải về ZIP đã bị tắt.", -"Files need to be downloaded one by one." => "Tập tin cần phải được tải về từng người một.", -"Back to Files" => "Trở lại tập tin", -"Selected files too large to generate zip file." => "Tập tin được chọn quá lớn để tạo tập tin ZIP.", "Application is not enabled" => "Ứng dụng không được BẬT", "Authentication error" => "Lỗi xác thực", "Token expired. Please reload page." => "Mã Token đã hết hạn. Hãy tải lại trang.", diff --git a/lib/l10n/zh_CN.php b/lib/l10n/zh_CN.php index c5261a6aff0..239139cffde 100644 --- a/lib/l10n/zh_CN.php +++ b/lib/l10n/zh_CN.php @@ -12,11 +12,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "未知的文件类型", "Invalid image" => "无效的图像", "web services under your control" => "您控制的web服务", -"ZIP download is turned off." => "ZIP 下载已经关闭", -"Files need to be downloaded one by one." => "需要逐一下载文件", -"Back to Files" => "回到文件", -"Selected files too large to generate zip file." => "选择的文件太大,无法生成 zip 文件。", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "请用较小的分块下载文件或者友好地询问您的管理员。", "No source specified when installing app" => "安装 App 时未指定来源", "No href specified when installing app from http" => "从 http 安装 App 时未指定链接", "No path specified when installing app from local file" => "从本地文件安装 App 时未指定路径", diff --git a/lib/l10n/zh_TW.php b/lib/l10n/zh_TW.php index 83616cf6a42..8dbe509cad9 100644 --- a/lib/l10n/zh_TW.php +++ b/lib/l10n/zh_TW.php @@ -11,11 +11,6 @@ $TRANSLATIONS = array( "Unknown filetype" => "未知的檔案類型", "Invalid image" => "無效的圖片", "web services under your control" => "由您控制的網路服務", -"ZIP download is turned off." => "ZIP 下載已關閉。", -"Files need to be downloaded one by one." => "檔案需要逐一下載。", -"Back to Files" => "回到檔案列表", -"Selected files too large to generate zip file." => "選擇的檔案太大以致於無法產生壓縮檔。", -"Please download the files separately in smaller chunks or kindly ask your administrator." => "請分割您的檔案後下載,或請詢問您的系統管理員。", "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" => "從本地檔案安裝應用程式時沒有指定路徑", diff --git a/lib/private/app.php b/lib/private/app.php index 5e327175630..0292abb6310 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -31,7 +31,7 @@ * owncloud ecosystem. Furthermore, this class is responsible for installing, * upgrading and removing apps. */ -class OC_App{ +class OC_App { static private $settingsForms = array(); static private $adminForms = array(); static private $personalForms = array(); @@ -61,13 +61,13 @@ class OC_App{ * * if $types is set, only apps of those types will be loaded */ - public static function loadApps($types=null) { + public static function loadApps($types = null) { // Load the enabled apps here $apps = self::getEnabledApps(); // prevent app.php from printing output ob_start(); - foreach( $apps as $app ) { - if((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) { + foreach ($apps as $app) { + if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) { self::$loadedApps[] = $app; self::loadApp($app); } @@ -79,28 +79,30 @@ class OC_App{ /** * load a single app + * * @param string $app */ public static function loadApp($app) { - if(is_file(self::getAppPath($app).'/appinfo/app.php')) { + if (is_file(self::getAppPath($app) . '/appinfo/app.php')) { self::checkUpgrade($app); - require_once $app.'/appinfo/app.php'; + require_once $app . '/appinfo/app.php'; } } /** * check if an app is of a specific type + * * @param string $app - * @param string/array $types + * @param string|array $types * @return bool */ public static function isType($app, $types) { - if(is_string($types)) { - $types=array($types); + if (is_string($types)) { + $types = array($types); } - $appTypes=self::getAppTypes($app); - foreach($types as $type) { - if(array_search($type, $appTypes)!==false) { + $appTypes = self::getAppTypes($app); + foreach ($types as $type) { + if (array_search($type, $appTypes) !== false) { return true; } } @@ -109,18 +111,19 @@ class OC_App{ /** * get the types of an app + * * @param string $app * @return array */ private static function getAppTypes($app) { //load the cache - if(count(self::$appTypes)==0) { - self::$appTypes=OC_Appconfig::getValues(false, 'types'); + if (count(self::$appTypes) == 0) { + self::$appTypes = OC_Appconfig::getValues(false, 'types'); } - if(isset(self::$appTypes[$app])) { + if (isset(self::$appTypes[$app])) { return explode(',', self::$appTypes[$app]); - }else{ + } else { return array(); } } @@ -129,12 +132,12 @@ class OC_App{ * read app types from info.xml and cache them in the database */ public static function setAppTypes($app) { - $appData=self::getAppInfo($app); + $appData = self::getAppInfo($app); - if(isset($appData['types'])) { - $appTypes=implode(',', $appData['types']); - }else{ - $appTypes=''; + if (isset($appData['types'])) { + $appTypes = implode(',', $appData['types']); + } else { + $appTypes = ''; } OC_Appconfig::setValue($app, 'types', $appTypes); @@ -142,14 +145,15 @@ class OC_App{ /** * check if app is shipped + * * @param string $appid the id of the app to check * @return bool * * Check if an app that is installed is a shipped app or installed from the appstore. */ - public static function isShipped($appid){ + public static function isShipped($appid) { $info = self::getAppInfo($appid); - if(isset($info['shipped']) && $info['shipped']=='true') { + if (isset($info['shipped']) && $info['shipped'] == 'true') { return true; } else { return false; @@ -160,33 +164,37 @@ class OC_App{ * get all enabled apps */ private static $enabledAppsCache = array(); + public static function getEnabledApps($forceRefresh = false) { - if(!OC_Config::getValue('installed', false)) { + if (!OC_Config::getValue('installed', false)) { return array(); } - if(!$forceRefresh && !empty(self::$enabledAppsCache)) { + if (!$forceRefresh && !empty(self::$enabledAppsCache)) { return self::$enabledAppsCache; } - $apps=array('files'); - $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' - . ' WHERE `configkey` = \'enabled\' AND `configvalue`=\'yes\'' - . ' ORDER BY `appid`'; - if (OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { - //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison - $sql = 'SELECT `appid` FROM `*PREFIX*appconfig`' - . ' WHERE `configkey` = \'enabled\' AND to_char(`configvalue`)=\'yes\'' - . ' ORDER BY `appid`'; - } - $query = OC_DB::prepare( $sql ); - $result=$query->execute(); - if( \OC_DB::isError($result)) { - throw new DatabaseException($result->getMessage(), $query); - } - while($row=$result->fetchRow()) { - if(array_search($row['appid'], $apps)===false) { - $apps[]=$row['appid']; + $appConfig = \OC::$server->getAppConfig(); + $appStatus = $appConfig->getValues(false, 'enabled'); + foreach ($appStatus as $app => $enabled) { + if ($app === 'files') { + continue; + } + if ($enabled === 'yes') { + $apps[] = $app; + } else if ($enabled !== 'no') { + $user = \OC_User::getUser(); + $groups = json_decode($enabled); + if (is_array($groups)) { + foreach ($groups as $group) { + if (\OC_Group::inGroup($user, $group)) { + $apps[] = $app; + break; + } + } + } } } + sort($apps); + array_unshift($apps, 'files'); self::$enabledAppsCache = $apps; return $apps; } @@ -198,8 +206,8 @@ class OC_App{ * * This function checks whether or not an app is enabled. */ - public static function isEnabled( $app ) { - if('files' == $app) { + public static function isEnabled($app) { + if ('files' == $app) { return true; } $enabledApps = self::getEnabledApps(); @@ -209,18 +217,23 @@ class OC_App{ /** * enables an app * @param mixed $app app + * @param array $groups (optional) when set, only these groups will have access to the app * @throws \Exception * @return void * * This function set an app as enabled in appconfig. */ - public static function enable( $app ) { + public static function enable($app, $groups = null) { self::$enabledAppsCache = array(); // flush if (!OC_Installer::isInstalled($app)) { $app = self::installApp($app); } - OC_Appconfig::setValue( $app, 'enabled', 'yes' ); + if (!is_null($groups)) { + OC_Appconfig::setValue($app, 'enabled', json_encode($groups)); + }else{ + OC_Appconfig::setValue($app, 'enabled', 'yes'); + } } /** @@ -258,11 +271,11 @@ class OC_App{ * * This function set an app as disabled in appconfig. */ - public static function disable( $app ) { + public static function disable($app) { self::$enabledAppsCache = array(); // flush // check if app is a shipped app or not. if not delete \OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app)); - OC_Appconfig::setValue( $app, 'enabled', 'no' ); + OC_Appconfig::setValue($app, 'enabled', 'no' ); } /** @@ -282,7 +295,7 @@ class OC_App{ * - order: integer, that influences the position of your application in * the navigation. Lower values come first. */ - public static function addNavigationEntry( $data ) { + public static function addNavigationEntry($data) { OC::$server->getNavigationManager()->add($data); return true; } @@ -296,7 +309,7 @@ class OC_App{ * property from all other entries. The templates can use this for * highlighting the current position of the user. */ - public static function setActiveNavigationEntry( $id ) { + public static function setActiveNavigationEntry($id) { OC::$server->getNavigationManager()->setActiveEntry($id); return true; } @@ -309,9 +322,9 @@ class OC_App{ * Warning: destroys the existing entries */ public static function getAppNavigationEntries($app) { - if(is_file(self::getAppPath($app).'/appinfo/app.php')) { + if (is_file(self::getAppPath($app) . '/appinfo/app.php')) { OC::$server->getNavigationManager()->clear(); - require $app.'/appinfo/app.php'; + require $app . '/appinfo/app.php'; return OC::$server->getNavigationManager()->getAll(); } return array(); @@ -336,19 +349,20 @@ class OC_App{ * entries are sorted by the key 'order' ascending. */ public static function getSettingsNavigation() { - $l=OC_L10N::get('lib'); + $l = OC_L10N::get('lib'); $settings = array(); // by default, settings only contain the help menu - if(OC_Util::getEditionString() === '' && - OC_Config::getValue('knowledgebaseenabled', true)==true) { + if (OC_Util::getEditionString() === '' && + OC_Config::getValue('knowledgebaseenabled', true) == true + ) { $settings = array( array( "id" => "help", "order" => 1000, - "href" => OC_Helper::linkToRoute( "settings_help" ), + "href" => OC_Helper::linkToRoute("settings_help"), "name" => $l->t("Help"), - "icon" => OC_Helper::imagePath( "settings", "help.svg" ) + "icon" => OC_Helper::imagePath("settings", "help.svg") ) ); } @@ -359,45 +373,45 @@ class OC_App{ $settings[] = array( "id" => "personal", "order" => 1, - "href" => OC_Helper::linkToRoute( "settings_personal" ), + "href" => OC_Helper::linkToRoute("settings_personal"), "name" => $l->t("Personal"), - "icon" => OC_Helper::imagePath( "settings", "personal.svg" ) + "icon" => OC_Helper::imagePath("settings", "personal.svg") ); // if there are some settings forms - if(!empty(self::$settingsForms)) { + if (!empty(self::$settingsForms)) { // settings menu - $settings[]=array( + $settings[] = array( "id" => "settings", "order" => 1000, - "href" => OC_Helper::linkToRoute( "settings_settings" ), + "href" => OC_Helper::linkToRoute("settings_settings"), "name" => $l->t("Settings"), - "icon" => OC_Helper::imagePath( "settings", "settings.svg" ) + "icon" => OC_Helper::imagePath("settings", "settings.svg") ); } //SubAdmins are also allowed to access user management - if(OC_SubAdmin::isSubAdmin(OC_User::getUser())) { + if (OC_SubAdmin::isSubAdmin(OC_User::getUser())) { // admin users menu $settings[] = array( "id" => "core_users", "order" => 2, - "href" => OC_Helper::linkToRoute( "settings_users" ), + "href" => OC_Helper::linkToRoute("settings_users"), "name" => $l->t("Users"), - "icon" => OC_Helper::imagePath( "settings", "users.svg" ) + "icon" => OC_Helper::imagePath("settings", "users.svg") ); } // if the user is an admin - if(OC_User::isAdminUser(OC_User::getUser())) { + if (OC_User::isAdminUser(OC_User::getUser())) { // admin settings - $settings[]=array( + $settings[] = array( "id" => "admin", "order" => 1000, - "href" => OC_Helper::linkToRoute( "settings_admin" ), + "href" => OC_Helper::linkToRoute("settings_admin"), "name" => $l->t("Admin"), - "icon" => OC_Helper::imagePath( "settings", "admin.svg" ) + "icon" => OC_Helper::imagePath("settings", "admin.svg") ); } } @@ -407,33 +421,34 @@ class OC_App{ } // This is private as well. It simply works, so don't ask for more details - private static function proceedNavigation( $list ) { + private static function proceedNavigation($list) { $activeapp = OC::$server->getNavigationManager()->getActiveEntry(); - foreach( $list as &$naventry ) { - if( $naventry['id'] == $activeapp ) { + foreach ($list as &$naventry) { + if ($naventry['id'] == $activeapp) { $naventry['active'] = true; - } - else{ + } else { $naventry['active'] = false; } - } unset( $naventry ); + } + unset($naventry); - usort( $list, create_function( '$a, $b', 'if( $a["order"] == $b["order"] ) {return 0;}elseif( $a["order"] < $b["order"] ) {return -1;}else{return 1;}' )); + usort($list, create_function('$a, $b', 'if( $a["order"] == $b["order"] ) {return 0;}elseif( $a["order"] < $b["order"] ) {return -1;}else{return 1;}')); return $list; } /** * Get the path where to install apps + * * @return string */ public static function getInstallPath() { - if(OC_Config::getValue('appstoreenabled', true)==false) { + if (OC_Config::getValue('appstoreenabled', true) == false) { return false; } - foreach(OC::$APPSROOTS as $dir) { - if(isset($dir['writable']) && $dir['writable']===true) { + foreach (OC::$APPSROOTS as $dir) { + if (isset($dir['writable']) && $dir['writable'] === true) { return $dir['path']; } } @@ -457,7 +472,7 @@ class OC_App{ $possibleApps = array(); foreach(OC::$APPSROOTS as $dir) { - if(file_exists($dir['path'].'/'.$appId)) { + if(file_exists($dir['path'] . '/' . $appId)) { $possibleApps[] = $dir; } } @@ -492,8 +507,8 @@ class OC_App{ * @return string|false */ public static function getAppPath($appid) { - if( ($dir = self::findAppInDirectories($appid)) != false) { - return $dir['path'].'/'.$appid; + if (($dir = self::findAppInDirectories($appid)) != false) { + return $dir['path'] . '/' . $appid; } return false; } @@ -516,8 +531,8 @@ class OC_App{ * @return string|false */ public static function getAppWebPath($appid) { - if( ($dir = self::findAppInDirectories($appid)) != false) { - return OC::$WEBROOT.$dir['url'].'/'.$appid; + if (($dir = self::findAppInDirectories($appid)) != false) { + return OC::$WEBROOT . $dir['url'] . '/' . $appid; } return false; } @@ -543,8 +558,8 @@ class OC_App{ if(is_file($versionFile)) { return trim(file_get_contents($versionFile)); }else{ - $appData=self::getAppInfo($infoFile, true); - return isset($appData['version'])? $appData['version'] : ''; + $appData = self::getAppInfo($infoFile, true); + return isset($appData['version']) ? $appData['version'] : ''; } } @@ -555,63 +570,63 @@ class OC_App{ * @param boolean $path (optional) * @return array * @note all data is read from info.xml, not just pre-defined fields - */ - public static function getAppInfo($appid, $path=false) { - if($path) { - $file=$appid; - }else{ - if(isset(self::$appInfo[$appid])) { + */ + public static function getAppInfo($appid, $path = false) { + if ($path) { + $file = $appid; + } else { + if (isset(self::$appInfo[$appid])) { return self::$appInfo[$appid]; } $file = self::getAppPath($appid) . '/appinfo/info.xml'; } - $data=array(); - $content=@file_get_contents($file); - if(!$content) { + $data = array(); + $content = @file_get_contents($file); + if (!$content) { return null; } $xml = new SimpleXMLElement($content); - $data['info']=array(); - $data['remote']=array(); - $data['public']=array(); - foreach($xml->children() as $child) { + $data['info'] = array(); + $data['remote'] = array(); + $data['public'] = array(); + foreach ($xml->children() as $child) { /** * @var $child SimpleXMLElement */ - if($child->getName()=='remote') { - foreach($child->children() as $remote) { + if ($child->getName() == 'remote') { + foreach ($child->children() as $remote) { /** * @var $remote SimpleXMLElement */ - $data['remote'][$remote->getName()]=(string)$remote; + $data['remote'][$remote->getName()] = (string)$remote; } - }elseif($child->getName()=='public') { - foreach($child->children() as $public) { + } elseif ($child->getName() == 'public') { + foreach ($child->children() as $public) { /** * @var $public SimpleXMLElement */ - $data['public'][$public->getName()]=(string)$public; + $data['public'][$public->getName()] = (string)$public; } - }elseif($child->getName()=='types') { - $data['types']=array(); - foreach($child->children() as $type) { + } elseif ($child->getName() == 'types') { + $data['types'] = array(); + foreach ($child->children() as $type) { /** * @var $type SimpleXMLElement */ - $data['types'][]=$type->getName(); + $data['types'][] = $type->getName(); } - }elseif($child->getName()=='description') { - $xml=(string)$child->asXML(); - $data[$child->getName()]=substr($xml, 13, -14);//script <description> tags - }elseif($child->getName()=='documentation') { - foreach($child as $subchild) { + } elseif ($child->getName() == 'description') { + $xml = (string)$child->asXML(); + $data[$child->getName()] = substr($xml, 13, -14); //script <description> tags + } elseif ($child->getName() == 'documentation') { + foreach ($child as $subchild) { $data["documentation"][$subchild->getName()] = (string)$subchild; } - }else{ - $data[$child->getName()]=(string)$child; + } else { + $data[$child->getName()] = (string)$child; } } - self::$appInfo[$appid]=$data; + self::$appInfo[$appid] = $data; return $data; } @@ -627,27 +642,28 @@ class OC_App{ */ public static function getNavigation() { $entries = OC::$server->getNavigationManager()->getAll(); - $navigation = self::proceedNavigation( $entries ); + $navigation = self::proceedNavigation($entries); return $navigation; } /** * get the id of loaded app + * * @return string */ public static function getCurrentApp() { - $script=substr(OC_Request::scriptName(), strlen(OC::$WEBROOT)+1); - $topFolder=substr($script, 0, strpos($script, '/')); + $script = substr(OC_Request::scriptName(), strlen(OC::$WEBROOT) + 1); + $topFolder = substr($script, 0, strpos($script, '/')); if (empty($topFolder)) { $path_info = OC_Request::getPathInfo(); if ($path_info) { - $topFolder=substr($path_info, 1, strpos($path_info, '/', 1)-1); + $topFolder = substr($path_info, 1, strpos($path_info, '/', 1) - 1); } } - if($topFolder=='apps') { - $length=strlen($topFolder); - return substr($script, $length+1, strpos($script, '/', $length+1)-$length-1); - }else{ + if ($topFolder == 'apps') { + $length = strlen($topFolder); + return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1); + } else { return $topFolder; } } @@ -656,22 +672,22 @@ class OC_App{ * get the forms for either settings, admin or personal */ public static function getForms($type) { - $forms=array(); - switch($type) { + $forms = array(); + switch ($type) { case 'settings': - $source=self::$settingsForms; + $source = self::$settingsForms; break; case 'admin': - $source=self::$adminForms; + $source = self::$adminForms; break; case 'personal': - $source=self::$personalForms; + $source = self::$personalForms; break; default: return array(); } - foreach($source as $form) { - $forms[]=include $form; + foreach ($source as $form) { + $forms[] = include $form; } return $forms; } @@ -680,23 +696,24 @@ class OC_App{ * register a settings form to be shown */ public static function registerSettings($app, $page) { - self::$settingsForms[]= $app.'/'.$page.'.php'; + self::$settingsForms[] = $app . '/' . $page . '.php'; } /** * register an admin form to be shown + * * @param string $app * @param string $page */ public static function registerAdmin($app, $page) { - self::$adminForms[]= $app.'/'.$page.'.php'; + self::$adminForms[] = $app . '/' . $page . '.php'; } /** * register a personal form to be shown */ public static function registerPersonal($app, $page) { - self::$personalForms[]= $app.'/'.$page.'.php'; + self::$personalForms[] = $app . '/' . $page . '.php'; } public static function registerLogIn($entry) { @@ -714,19 +731,19 @@ class OC_App{ */ public static function getAllApps() { - $apps=array(); + $apps = array(); - foreach ( OC::$APPSROOTS as $apps_dir ) { - if(! is_readable($apps_dir['path'])) { - OC_Log::write('core', 'unable to read app folder : ' .$apps_dir['path'], OC_Log::WARN); + foreach (OC::$APPSROOTS as $apps_dir) { + if (!is_readable($apps_dir['path'])) { + OC_Log::write('core', 'unable to read app folder : ' . $apps_dir['path'], OC_Log::WARN); continue; } - $dh = opendir( $apps_dir['path'] ); + $dh = opendir($apps_dir['path']); - if(is_resource($dh)) { + if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { - if ($file[0] != '.' and is_file($apps_dir['path'].'/'.$file.'/appinfo/app.php')) { + if ($file[0] != '.' and is_file($apps_dir['path'] . '/' . $file . '/appinfo/app.php')) { $apps[] = $file; @@ -750,36 +767,41 @@ class OC_App{ //TODO which apps do we want to blacklist and how do we integrate // blacklisting with the multi apps folder feature? - $blacklist = array('files');//we dont want to show configuration for these + $blacklist = array('files'); //we dont want to show configuration for these $appList = array(); - foreach ( $installedApps as $app ) { - if ( array_search( $app, $blacklist ) === false ) { + foreach ($installedApps as $app) { + if (array_search($app, $blacklist) === false) { - $info=OC_App::getAppInfo($app); + $info = OC_App::getAppInfo($app); if (!isset($info['name'])) { - OC_Log::write('core', 'App id "'.$app.'" has no name in appinfo', OC_Log::ERROR); + OC_Log::write('core', 'App id "' . $app . '" has no name in appinfo', OC_Log::ERROR); continue; } - if ( OC_Appconfig::getValue( $app, 'enabled', 'no') == 'yes' ) { + $enabled = OC_Appconfig::getValue($app, 'enabled', 'no'); + $info['groups'] = null; + if ($enabled === 'yes') { $active = true; - } else { + } else if($enabled === 'no') { $active = false; + } else { + $active = true; + $info['groups'] = $enabled; } $info['active'] = $active; - if(isset($info['shipped']) and ($info['shipped']=='true')) { - $info['internal']=true; - $info['internallabel']='Internal App'; - $info['internalclass']=''; + if(isset($info['shipped']) and ($info['shipped'] == 'true')) { + $info['internal'] = true; + $info['internallabel'] = 'Internal App'; + $info['internalclass'] = ''; $info['removable'] = false; } else { - $info['internal']=false; - $info['internallabel']='3rd Party'; - $info['internalclass']='externalapp'; + $info['internal'] = false; + $info['internallabel'] = '3rd Party'; + $info['internalclass'] = 'externalapp'; $info['removable'] = true; } @@ -790,28 +812,28 @@ class OC_App{ $appList[] = $info; } } - $remoteApps = self::getAppstoreApps(); - if ( $remoteApps ) { + $remoteApps = OC_App::getAppstoreApps(); + if ($remoteApps) { // Remove duplicates - foreach ( $appList as $app ) { - foreach ( $remoteApps AS $key => $remote ) { + foreach ($appList as $app) { + foreach ($remoteApps AS $key => $remote) { if ( $app['name'] == $remote['name'] // To set duplicate detection to use OCS ID instead of string name, // enable this code, remove the line of code above, // and add <ocs_id>[ID]</ocs_id> to info.xml of each 3rd party app: // OR $app['ocs_id'] == $remote['ocs_id'] - ) { - unset( $remoteApps[$key]); + ) { + unset($remoteApps[$key]); } } } - $combinedApps = array_merge( $appList, $remoteApps ); + $combinedApps = array_merge($appList, $remoteApps); } else { $combinedApps = $appList; } // bring the apps into the right order with a custom sort funtion - usort( $combinedApps, '\OC_App::customSort' ); + usort($combinedApps, '\OC_App::customSort'); return $combinedApps; } @@ -851,29 +873,29 @@ class OC_App{ * @return array, multi-dimensional array of apps. * Keys: id, name, type, typename, personid, license, detailpage, preview, changed, description */ - public static function getAppstoreApps( $filter = 'approved' ) { + public static function getAppstoreApps($filter = 'approved') { $categoryNames = OC_OCSClient::getCategories(); - if ( is_array( $categoryNames ) ) { + if (is_array($categoryNames)) { // Check that categories of apps were retrieved correctly - if ( ! $categories = array_keys( $categoryNames ) ) { + if (!$categories = array_keys($categoryNames)) { return false; } $page = 0; - $remoteApps = OC_OCSClient::getApplications( $categories, $page, $filter ); + $remoteApps = OC_OCSClient::getApplications($categories, $page, $filter); $app1 = array(); $i = 0; - foreach ( $remoteApps as $app ) { + foreach ($remoteApps as $app) { $app1[$i] = $app; $app1[$i]['author'] = $app['personid']; $app1[$i]['ocs_id'] = $app['id']; $app1[$i]['internal'] = $app1[$i]['active'] = 0; $app1[$i]['update'] = false; $app1[$i]['removable'] = false; - if($app['label']=='recommended') { + if ($app['label'] == 'recommended') { $app1[$i]['internallabel'] = 'Recommended'; $app1[$i]['internalclass'] = 'recommendedapp'; - }else{ + } else { $app1[$i]['internallabel'] = '3rd Party'; $app1[$i]['internalclass'] = 'externalapp'; } @@ -904,20 +926,33 @@ class OC_App{ $img = OC_Helper::imagePath( "core", "rating/s11.png" ); } - $app1[$i]['score'] = '<img src="'.$img.'"> Score: '.$app['score'].'%'; + $app1[$i]['score'] = '<img src="' . $img . '"> Score: ' . $app['score'] . '%'; $i++; } } - if ( empty( $app1 ) ) { + if (empty($app1)) { return false; } else { return $app1; } } + public static function shouldUpgrade($app) { + $versions = self::getAppVersions(); + $currentVersion = OC_App::getAppVersion($app); + if ($currentVersion) { + $installedVersion = $versions[$app]; + if (version_compare($currentVersion, $installedVersion, '>')) { + return true; + } + } + return false; + } + /** * check if the app needs updating and update when needed + * * @param string $app */ public static function checkUpgrade($app) { @@ -925,27 +960,27 @@ class OC_App{ return; } self::$checkedApps[] = $app; - $versions = self::getAppVersions(); - $currentVersion=OC_App::getAppVersion($app); - if ($currentVersion) { - $installedVersion = $versions[$app]; - if (version_compare($currentVersion, $installedVersion, '>')) { - $info = self::getAppInfo($app); - OC_Log::write($app, - 'starting app upgrade from '.$installedVersion.' to '.$currentVersion, - OC_Log::DEBUG); - try { - OC_App::updateApp($app); - OC_Hook::emit('update', 'success', 'Updated '.$info['name'].' app'); - } - catch (Exception $e) { - OC_Hook::emit('update', 'failure', 'Failed to update '.$info['name'].' app: '.$e->getMessage()); - $l = OC_L10N::get('lib'); - throw new RuntimeException($l->t('Failed to upgrade "%s".', array($app)), 0, $e); - } - OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app)); - } + if (!self::shouldUpgrade($app)) { + return; } + $versions = self::getAppVersions(); + $installedVersion = $versions[$app]; + $currentVersion = OC_App::getAppVersion($app); + OC_Log::write( + $app, + 'starting app upgrade from ' . $installedVersion . ' to ' . $currentVersion, + OC_Log::DEBUG + ); + $info = self::getAppInfo($app); + try { + OC_App::updateApp($app); + OC_Hook::emit('update', 'success', 'Updated ' . $info['name'] . ' app'); + } catch (Exception $e) { + OC_Hook::emit('update', 'failure', 'Failed to update ' . $info['name'] . ' app: ' . $e->getMessage()); + $l = OC_L10N::get('lib'); + throw new RuntimeException($l->t('Failed to upgrade "%s".', array($app)), 0, $e); + } + OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app)); } /** @@ -965,16 +1000,16 @@ class OC_App{ $apps = OC_App::getEnabledApps(); } $version = OC_Util::getVersion(); - foreach($apps as $app) { + foreach ($apps as $app) { // check if the app is compatible with this version of ownCloud $info = OC_App::getAppInfo($app); if(!self::isAppCompatible($version, $info)) { OC_Log::write('core', - 'App "'.$info['name'].'" ('.$app.') can\'t be used because it is' - .' not compatible with this version of ownCloud', + 'App "' . $info['name'] . '" (' . $app . ') can\'t be used because it is' + . ' not compatible with this version of ownCloud', OC_Log::ERROR); - OC_App::disable( $app ); - OC_Hook::emit('update', 'success', 'Disabled '.$info['name'].' app because it is not compatible'); + OC_App::disable($app); + OC_Hook::emit('update', 'success', 'Disabled ' . $info['name'] . ' app because it is not compatible'); $disabledApps[] = $app; } } @@ -1058,15 +1093,15 @@ class OC_App{ */ public static function getAppVersions() { static $versions; - if (isset($versions)) { // simple cache, needs to be fixed + if (isset($versions)) { // simple cache, needs to be fixed return $versions; // when function is used besides in checkUpgrade } - $versions=array(); - $query = OC_DB::prepare( 'SELECT `appid`, `configvalue` FROM `*PREFIX*appconfig`' - .' WHERE `configkey` = \'installed_version\'' ); + $versions = array(); + $query = OC_DB::prepare('SELECT `appid`, `configvalue` FROM `*PREFIX*appconfig`' + . ' WHERE `configkey` = \'installed_version\''); $result = $query->execute(); - while($row = $result->fetchRow()) { - $versions[$row['appid']]=$row['configvalue']; + while ($row = $result->fetchRow()) { + $versions[$row['appid']] = $row['configvalue']; } return $versions; } @@ -1118,32 +1153,33 @@ class OC_App{ /** * update the database for the app and call the update script + * * @param string $appid * @return bool */ public static function updateApp($appid) { - if(file_exists(self::getAppPath($appid).'/appinfo/preupdate.php')) { + if (file_exists(self::getAppPath($appid) . '/appinfo/preupdate.php')) { self::loadApp($appid); - include self::getAppPath($appid).'/appinfo/preupdate.php'; + include self::getAppPath($appid) . '/appinfo/preupdate.php'; } - if(file_exists(self::getAppPath($appid).'/appinfo/database.xml')) { - OC_DB::updateDbFromStructure(self::getAppPath($appid).'/appinfo/database.xml'); + if (file_exists(self::getAppPath($appid) . '/appinfo/database.xml')) { + OC_DB::updateDbFromStructure(self::getAppPath($appid) . '/appinfo/database.xml'); } - if(!self::isEnabled($appid)) { - return false; + if (!self::isEnabled($appid)) { + return; } - if(file_exists(self::getAppPath($appid).'/appinfo/update.php')) { + if (file_exists(self::getAppPath($appid) . '/appinfo/update.php')) { self::loadApp($appid); - include self::getAppPath($appid).'/appinfo/update.php'; + include self::getAppPath($appid) . '/appinfo/update.php'; } //set remote/public handlers - $appData=self::getAppInfo($appid); - foreach($appData['remote'] as $name=>$path) { - OCP\CONFIG::setAppValue('core', 'remote_'.$name, $appid.'/'.$path); + $appData = self::getAppInfo($appid); + foreach ($appData['remote'] as $name => $path) { + OCP\CONFIG::setAppValue('core', 'remote_' . $name, $appid . '/' . $path); } - foreach($appData['public'] as $name=>$path) { - OCP\CONFIG::setAppValue('core', 'public_'.$name, $appid.'/'.$path); + foreach ($appData['public'] as $name => $path) { + OCP\CONFIG::setAppValue('core', 'public_' . $name, $appid . '/' . $path); } self::setAppTypes($appid); @@ -1156,19 +1192,19 @@ class OC_App{ * @return \OC\Files\View */ public static function getStorage($appid) { - if(OC_App::isEnabled($appid)) {//sanity check - if(OC_User::isLoggedIn()) { - $view = new \OC\Files\View('/'.OC_User::getUser()); - if(!$view->file_exists($appid)) { + if (OC_App::isEnabled($appid)) { //sanity check + if (OC_User::isLoggedIn()) { + $view = new \OC\Files\View('/' . OC_User::getUser()); + if (!$view->file_exists($appid)) { $view->mkdir($appid); } - return new \OC\Files\View('/'.OC_User::getUser().'/'.$appid); - }else{ - OC_Log::write('core', 'Can\'t get app storage, app '.$appid.', user not logged in', OC_Log::ERROR); + return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appid); + } else { + OC_Log::write('core', 'Can\'t get app storage, app ' . $appid . ', user not logged in', OC_Log::ERROR); return false; } - }else{ - OC_Log::write('core', 'Can\'t get app storage, app '.$appid.' not enabled', OC_Log::ERROR); + } else { + OC_Log::write('core', 'Can\'t get app storage, app ' . $appid . ' not enabled', OC_Log::ERROR); return false; } } diff --git a/lib/private/appconfig.php b/lib/private/appconfig.php index e2a961b1d6d..f20c4a08426 100644 --- a/lib/private/appconfig.php +++ b/lib/private/appconfig.php @@ -52,6 +52,11 @@ class AppConfig implements \OCP\IAppConfig { private $appsLoaded = array(); /** + * @var string[] + */ + private $apps = null; + + /** * @param \OC\DB\Connection $conn */ public function __construct(Connection $conn) { @@ -90,12 +95,16 @@ class AppConfig implements \OCP\IAppConfig { /** * Get all apps using the config + * * @return array an array of app ids * * This function returns a list of all apps that have at least one * entry in the appconfig table. */ public function getApps() { + if (is_array($this->apps)) { + return $this->apps; + } $query = 'SELECT DISTINCT `appid` FROM `*PREFIX*appconfig` ORDER BY `appid`'; $result = $this->conn->executeQuery($query); @@ -103,11 +112,13 @@ class AppConfig implements \OCP\IAppConfig { while ($appid = $result->fetchColumn()) { $apps[] = $appid; } + $this->apps = $apps; return $apps; } /** * Get the available keys for an app + * * @param string $app the app we are looking for * @return array an array of key names * @@ -123,6 +134,7 @@ class AppConfig implements \OCP\IAppConfig { /** * Gets the config value + * * @param string $app app * @param string $key key * @param string $default = null, default value if the key does not exist @@ -142,6 +154,7 @@ class AppConfig implements \OCP\IAppConfig { /** * check if a key is set in the appconfig + * * @param string $app * @param string $key * @return bool @@ -153,6 +166,7 @@ class AppConfig implements \OCP\IAppConfig { /** * sets a value in the appconfig + * * @param string $app app * @param string $key key * @param string $value value @@ -181,11 +195,15 @@ class AppConfig implements \OCP\IAppConfig { if (!isset($this->cache[$app])) { $this->cache[$app] = array(); } + if (is_array($this->apps) and array_search($app, $this->apps) === false) { + $this->apps[$app] = $app; + } $this->cache[$app][$key] = $value; } /** * Deletes a key + * * @param string $app app * @param string $key key * @return boolean|null @@ -203,6 +221,7 @@ class AppConfig implements \OCP\IAppConfig { /** * Remove app from appconfig + * * @param string $app app * @return boolean|null * @@ -214,6 +233,7 @@ class AppConfig implements \OCP\IAppConfig { ); $this->conn->delete('*PREFIX*appconfig', $where); unset($this->cache[$app]); + unset($this->apps[$app]); } /** @@ -228,28 +248,18 @@ class AppConfig implements \OCP\IAppConfig { return false; } - $fields = '`configvalue`'; - $where = 'WHERE'; - $params = array(); if ($app !== false) { - $fields .= ', `configkey`'; - $where .= ' `appid` = ?'; - $params[] = $app; - $key = 'configkey'; + return $this->getAppValues($app); } else { - $fields .= ', `appid`'; - $where .= ' `configkey` = ?'; - $params[] = $key; - $key = 'appid'; - } - $query = 'SELECT ' . $fields . ' FROM `*PREFIX*appconfig` ' . $where; - $result = $this->conn->executeQuery($query, $params); + $query = 'SELECT `configvalue`, `appid` FROM `*PREFIX*appconfig` WHERE `configkey` = ?'; + $result = $this->conn->executeQuery($query, array($key)); - $values = array(); - while ($row = $result->fetch((\PDO::FETCH_ASSOC))) { - $values[$row[$key]] = $row['configvalue']; - } + $values = array(); + while ($row = $result->fetch((\PDO::FETCH_ASSOC))) { + $values[$row['appid']] = $row['configvalue']; + } - return $values; + return $values; + } } } diff --git a/lib/private/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php index 9fa13c25851..6641097cf90 100644 --- a/lib/private/backgroundjob/joblist.php +++ b/lib/private/backgroundjob/joblist.php @@ -149,6 +149,9 @@ class JobList implements IJobList { /** * @var Job $job */ + if ($class === 'OC_Cache_FileGlobalGC') { + $class = '\OC\Cache\FileGlobalGC'; + } $job = new $class(); $job->setId($row['id']); $job->setLastRun($row['last_run']); diff --git a/lib/private/connector/sabre/ServiceUnavailable.php b/lib/private/connector/sabre/ServiceUnavailable.php deleted file mode 100644 index c1cc815c989..00000000000 --- a/lib/private/connector/sabre/ServiceUnavailable.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * ownCloud - * - * @author Thomas Müller - * @copyright 2013 Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL3 - */ - -class Sabre_DAV_Exception_ServiceUnavailable extends Sabre_DAV_Exception { - - /** - * Returns the HTTP statuscode for this exception - * - * @return int - */ - public function getHTTPCode() { - - return 503; - } -} diff --git a/lib/private/connector/sabre/aborteduploaddetectionplugin.php b/lib/private/connector/sabre/aborteduploaddetectionplugin.php index 1a092a59a82..b569f9a83c3 100644 --- a/lib/private/connector/sabre/aborteduploaddetectionplugin.php +++ b/lib/private/connector/sabre/aborteduploaddetectionplugin.php @@ -12,12 +12,12 @@ * This plugin will verify if the uploaded data has been stored completely. * This is done by comparing the content length of the request with the file size on storage. */ -class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPlugin { +class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends \Sabre\DAV\ServerPlugin { /** * Reference to main server object * - * @var Sabre_DAV_Server + * @var \Sabre\DAV\Server */ private $server; @@ -36,14 +36,14 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl /** * This initializes the plugin. * - * This function is called by Sabre_DAV_Server, after + * This function is called by \Sabre\DAV\Server, after * addPlugin is called. * * This method should set up the requires event subscriptions. * - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server */ - public function initialize(Sabre_DAV_Server $server) { + public function initialize(\Sabre\DAV\Server $server) { $this->server = $server; @@ -53,10 +53,10 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl /** * @param string $filePath - * @param Sabre_DAV_INode $node - * @throws Sabre_DAV_Exception_BadRequest + * @param \Sabre\DAV\INode $node + * @throws \Sabre\DAV\Exception\BadRequest */ - public function verifyContentLength($filePath, Sabre_DAV_INode $node = null) { + public function verifyContentLength($filePath, \Sabre\DAV\INode $node = null) { // we should only react on PUT which is used for upload // e.g. with LOCK this will not work, but LOCK uses createFile() as well @@ -78,7 +78,7 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl $actual = $this->fileView->filesize($filePath); if ($actual != $expected) { $this->fileView->unlink($filePath); - throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $actual); + throw new \Sabre\DAV\Exception\BadRequest('expected filesize ' . $expected . ' got ' . $actual); } } diff --git a/lib/private/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php index 9ebf5fc05cf..b1ef698583d 100644 --- a/lib/private/connector/sabre/auth.php +++ b/lib/private/connector/sabre/auth.php @@ -21,7 +21,7 @@ * */ -class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { +class OC_Connector_Sabre_Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic { /** * Validates a username and password * @@ -69,11 +69,11 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { * even if there are no HTTP Basic Auth headers. * In other case, just fallback to the parent implementation. * - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server * @param $realm * @return bool */ - public function authenticate(Sabre_DAV_Server $server, $realm) { + public function authenticate(\Sabre\DAV\Server $server, $realm) { $result = $this->auth($server, $realm); @@ -84,11 +84,11 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { } /** - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server * @param $realm * @return bool */ - private function auth(Sabre_DAV_Server $server, $realm) { + private function auth(\Sabre\DAV\Server $server, $realm) { if (OC_User::handleApacheAuth() || OC_User::isLoggedIn()) { $user = OC_User::getUser(); OC_Util::setupFS($user); diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php index 1bb526e451e..aa467cec535 100644 --- a/lib/private/connector/sabre/directory.php +++ b/lib/private/connector/sabre/directory.php @@ -21,7 +21,8 @@ * */ -class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sabre_DAV_ICollection, Sabre_DAV_IQuota { +class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node + implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota { /** * Creates a new file in the directory @@ -45,7 +46,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * * @param string $name Name of the file * @param resource|string $data Initial payload - * @throws Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\Forbidden * @return null|string */ public function createFile($name, $data = null) { @@ -58,13 +59,13 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $info = OC_FileChunking::decodeName($name); if (!$this->fileView->isCreatable($this->path) && !$this->fileView->isUpdatable($this->path . '/' . $info['name'])) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } } else { // For non-chunked upload it is enough to check if we can create a new file if (!$this->fileView->isCreatable($this->path)) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } } @@ -79,17 +80,17 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * Creates a new subdirectory * * @param string $name - * @throws Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\Forbidden * @return void */ public function createDirectory($name) { if (!$this->fileView->isCreatable($this->path)) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } $newPath = $this->path . '/' . $name; if(!$this->fileView->mkdir($newPath)) { - throw new Sabre_DAV_Exception_Forbidden('Could not create directory '.$newPath); + throw new \Sabre\DAV\Exception\Forbidden('Could not create directory '.$newPath); } } @@ -99,8 +100,8 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * * @param string $name * @param \OCP\Files\FileInfo $info - * @throws Sabre_DAV_Exception_NotFound - * @return Sabre_DAV_INode + * @throws \Sabre\DAV\Exception\FileNotFound + * @return \Sabre\DAV\INode */ public function getChild($name, $info = null) { @@ -110,7 +111,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } if (!$info) { - throw new Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located'); + throw new \Sabre\DAV\Exception\NotFound('File with name ' . $path . ' could not be located'); } if ($info['mimetype'] == 'httpd/unix-directory') { @@ -124,7 +125,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa /** * Returns an array with all the child nodes * - * @return Sabre_DAV_INode[] + * @return \Sabre\DAV\INode[] */ public function getChildren() { @@ -183,12 +184,12 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * Deletes all files in this directory, and then itself * * @return void - * @throws Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\Forbidden */ public function delete() { if (!$this->info->isDeletable()) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } $this->fileView->rmdir($this->path); diff --git a/lib/private/connector/sabre/exception/entitytoolarge.php b/lib/private/connector/sabre/exception/entitytoolarge.php index 2bda51f2f3e..2524fbaa74c 100644 --- a/lib/private/connector/sabre/exception/entitytoolarge.php +++ b/lib/private/connector/sabre/exception/entitytoolarge.php @@ -6,7 +6,7 @@ * This exception is thrown whenever a user tries to upload a file which exceeds hard limitations * */ -class OC_Connector_Sabre_Exception_EntityTooLarge extends Sabre_DAV_Exception { +class OC_Connector_Sabre_Exception_EntityTooLarge extends \Sabre\DAV\Exception { /** * Returns the HTTP status code for this exception diff --git a/lib/private/connector/sabre/exception/filelocked.php b/lib/private/connector/sabre/exception/filelocked.php new file mode 100644 index 00000000000..59d932d22de --- /dev/null +++ b/lib/private/connector/sabre/exception/filelocked.php @@ -0,0 +1,28 @@ +<?php +/** + * ownCloud + * + * @author Owen Winkler + * @copyright 2013 Owen Winkler <owen@owncloud.com> + * + */ + +class OC_Connector_Sabre_Exception_FileLocked extends \Sabre\DAV\Exception { + + public function __construct($message = "", $code = 0, Exception $previous = null) { + if($previous instanceof \OCP\Files\LockNotAcquiredException) { + $message = sprintf('Target file %s is locked by another process.', $previous->path); + } + parent::__construct($message, $code, $previous); + } + + /** + * Returns the HTTP status code for this exception + * + * @return int + */ + public function getHTTPCode() { + + return 503; + } +} diff --git a/lib/private/connector/sabre/exception/unsupportedmediatype.php b/lib/private/connector/sabre/exception/unsupportedmediatype.php index 95d6a8cc651..9b285196ebd 100644 --- a/lib/private/connector/sabre/exception/unsupportedmediatype.php +++ b/lib/private/connector/sabre/exception/unsupportedmediatype.php @@ -6,7 +6,7 @@ * This exception is thrown whenever a user tries to upload a file which holds content which is not allowed * */ -class OC_Connector_Sabre_Exception_UnsupportedMediaType extends Sabre_DAV_Exception { +class OC_Connector_Sabre_Exception_UnsupportedMediaType extends \Sabre\DAV\Exception { /** * Returns the HTTP status code for this exception diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php index 5eaf1e87621..5963123709b 100644 --- a/lib/private/connector/sabre/exceptionloggerplugin.php +++ b/lib/private/connector/sabre/exceptionloggerplugin.php @@ -9,17 +9,17 @@ * @license AGPL3 */ -class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin +class OC_Connector_Sabre_ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin { private $nonFatalExceptions = array( - 'Sabre_DAV_Exception_NotAuthenticated' => true, + 'Sabre\DAV\Exception\NotAuthenticated' => true, // the sync client uses this to find out whether files exist, // so it is not always an error, log it as debug - 'Sabre_DAV_Exception_NotFound' => true, + 'Sabre\DAV\Exception\NotFound' => true, // this one mostly happens when the same file is uploaded at // exactly the same time from two clients, only one client // wins, the second one gets "Precondition failed" - 'Sabre_DAV_Exception_PreconditionFailed' => true, + 'Sabre\DAV\Exception\PreconditionFailed' => true, ); private $appName; @@ -34,15 +34,15 @@ class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin /** * This initializes the plugin. * - * This function is called by Sabre_DAV_Server, after + * This function is called by \Sabre\DAV\Server, after * addPlugin is called. * * This method should set up the required event subscriptions. * - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server * @return void */ - public function initialize(Sabre_DAV_Server $server) { + public function initialize(\Sabre\DAV\Server $server) { $server->subscribeEvent('exception', array($this, 'logException'), 10); } diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php index 8a16ba55e7a..4e90d46ad41 100644 --- a/lib/private/connector/sabre/file.php +++ b/lib/private/connector/sabre/file.php @@ -21,7 +21,7 @@ * */ -class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_DAV_IFile { +class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements \Sabre\DAV\IFile { /** * Updates the data @@ -41,28 +41,28 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * return an ETag, and just return null. * * @param resource $data - * @throws Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\Forbidden * @throws OC_Connector_Sabre_Exception_UnsupportedMediaType - * @throws Sabre_DAV_Exception_BadRequest - * @throws Sabre_DAV_Exception + * @throws \Sabre\DAV\Exception\BadRequest + * @throws \Sabre\DAV\Exception * @throws OC_Connector_Sabre_Exception_EntityTooLarge - * @throws Sabre_DAV_Exception_ServiceUnavailable + * @throws \Sabre\DAV\Exception\ServiceUnavailable * @return string|null */ public function put($data) { if ($this->info && $this->fileView->file_exists($this->path) && !$this->info->isUpdateable()) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } // throw an exception if encryption was disabled but the files are still encrypted if (\OC_Util::encryptedFiles()) { - throw new \Sabre_DAV_Exception_ServiceUnavailable(); + throw new \Sabre\DAV\Exception\ServiceUnavailable(); } $fileName = basename($this->path); if (!\OCP\Util::isValidFileName($fileName)) { - throw new \Sabre_DAV_Exception_BadRequest(); + throw new \Sabre\DAV\Exception\BadRequest(); } // chunked handling @@ -79,11 +79,11 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D \OC_Log::write('webdav', '\OC\Files\Filesystem::file_put_contents() failed', \OC_Log::ERROR); $this->fileView->unlink($partpath); // because we have no clue about the cause we can only throw back a 500/Internal Server Error - throw new Sabre_DAV_Exception('Could not write file contents'); + throw new \Sabre\DAV\Exception('Could not write file contents'); } } catch (\OCP\Files\NotPermittedException $e) { // a more general case - due to whatever reason the content could not be written - throw new Sabre_DAV_Exception_Forbidden($e->getMessage()); + throw new \Sabre\DAV\Exception\Forbidden($e->getMessage()); } catch (\OCP\Files\EntityTooLargeException $e) { // the file is too big to be stored @@ -96,16 +96,25 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D } catch (\OCP\Files\InvalidPathException $e) { // the path for the file was not valid // TODO: find proper http status code for this case - throw new Sabre_DAV_Exception_Forbidden($e->getMessage()); + throw new \Sabre\DAV\Exception\Forbidden($e->getMessage()); + } catch (\OCP\Files\LockNotAcquiredException $e) { + // the file is currently being written to by another process + throw new OC_Connector_Sabre_Exception_FileLocked($e->getMessage(), $e->getCode(), $e); } // rename to correct path - $renameOkay = $this->fileView->rename($partpath, $this->path); - $fileExists = $this->fileView->file_exists($this->path); - if ($renameOkay === false || $fileExists === false) { - \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); - $this->fileView->unlink($partpath); - throw new Sabre_DAV_Exception('Could not rename part file to final file'); + try { + $renameOkay = $this->fileView->rename($partpath, $this->path); + $fileExists = $this->fileView->file_exists($this->path); + if ($renameOkay === false || $fileExists === false) { + \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR); + $this->fileView->unlink($partpath); + throw new \Sabre\DAV\Exception('Could not rename part file to final file'); + } + } + catch (\OCP\Files\LockNotAcquiredException $e) { + // the file is currently being written to by another process + throw new OC_Connector_Sabre_Exception_FileLocked($e->getMessage(), $e->getCode(), $e); } // allow sync clients to send the mtime along in a header @@ -129,7 +138,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D //throw exception if encryption is disabled but files are still encrypted if (\OC_Util::encryptedFiles()) { - throw new \Sabre_DAV_Exception_ServiceUnavailable(); + throw new \Sabre\DAV\Exception\ServiceUnavailable(); } else { return $this->fileView->fopen($this->path, 'rb'); } @@ -140,11 +149,11 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * Delete the current file * * @return void - * @throws Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\Forbidden */ public function delete() { if (!$this->info->isDeletable()) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } $this->fileView->unlink($this->path); @@ -196,11 +205,11 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ private function createFileChunked($data) { - list($path, $name) = \Sabre_DAV_URLUtil::splitPath($this->path); + list($path, $name) = \Sabre\DAV\URLUtil::splitPath($this->path); $info = OC_FileChunking::decodeName($name); if (empty($info)) { - throw new Sabre_DAV_Exception_NotImplemented(); + throw new \Sabre\DAV\Exception\NotImplemented(); } $chunk_handler = new OC_FileChunking($info); $bytesWritten = $chunk_handler->store($info['index'], $data); @@ -211,7 +220,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D $expected = $_SERVER['CONTENT_LENGTH']; if ($bytesWritten != $expected) { $chunk_handler->remove($info['index']); - throw new Sabre_DAV_Exception_BadRequest( + throw new \Sabre\DAV\Exception\BadRequest( 'expected filesize ' . $expected . ' got ' . $bytesWritten); } } @@ -233,7 +242,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D if ($fileExists) { $this->fileView->unlink($targetPath); } - throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks'); + throw new \Sabre\DAV\Exception('Could not rename part file assembled from chunks'); } // allow sync clients to send the mtime along in a header diff --git a/lib/private/connector/sabre/filesplugin.php b/lib/private/connector/sabre/filesplugin.php index 25d7fd53343..871fac88e68 100644 --- a/lib/private/connector/sabre/filesplugin.php +++ b/lib/private/connector/sabre/filesplugin.php @@ -9,7 +9,7 @@ * @license AGPL3 */ -class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin +class OC_Connector_Sabre_FilesPlugin extends \Sabre\DAV\ServerPlugin { // namespace @@ -18,22 +18,22 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin /** * Reference to main server object * - * @var Sabre_DAV_Server + * @var \Sabre\DAV\Server */ private $server; /** * This initializes the plugin. * - * This function is called by Sabre_DAV_Server, after + * This function is called by \Sabre\DAV\Server, after * addPlugin is called. * * This method should set up the required event subscriptions. * - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server * @return void */ - public function initialize(Sabre_DAV_Server $server) { + public function initialize(\Sabre\DAV\Server $server) { $server->xmlNamespaces[self::NS_OWNCLOUD] = 'oc'; $server->protectedProperties[] = '{' . self::NS_OWNCLOUD . '}id'; @@ -49,12 +49,12 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin * Adds all ownCloud-specific properties * * @param string $path - * @param Sabre_DAV_INode $node + * @param \Sabre\DAV\INode $node * @param array $requestedProperties * @param array $returnedProperties * @return void */ - public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) { + public function beforeGetProperties($path, \Sabre\DAV\INode $node, array &$requestedProperties, array &$returnedProperties) { if ($node instanceof OC_Connector_Sabre_Node) { @@ -84,13 +84,13 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin /** * @param string $filePath - * @param Sabre_DAV_INode $node - * @throws Sabre_DAV_Exception_BadRequest + * @param \Sabre\DAV\INode $node + * @throws \Sabre\DAV\Exception\BadRequest */ - public function sendFileIdHeader($filePath, Sabre_DAV_INode $node = null) { + public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) { // chunked upload handling if (isset($_SERVER['HTTP_OC_CHUNKED'])) { - list($path, $name) = \Sabre_DAV_URLUtil::splitPath($filePath); + list($path, $name) = \Sabre\DAV\URLUtil::splitPath($filePath); $info = OC_FileChunking::decodeName($name); if (!empty($info)) { $filePath = $path . '/' . $info['name']; diff --git a/lib/private/connector/sabre/locks.php b/lib/private/connector/sabre/locks.php index 69496c15ada..09bf874ec70 100644 --- a/lib/private/connector/sabre/locks.php +++ b/lib/private/connector/sabre/locks.php @@ -21,10 +21,10 @@ * */ -class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { +class OC_Connector_Sabre_Locks extends \Sabre\DAV\Locks\Backend\AbstractBackend { /** - * Returns a list of Sabre_DAV_Locks_LockInfo objects + * Returns a list of \Sabre\DAV\Locks_LockInfo objects * * This method should return all the locks for a particular uri, including * locks that might be set on a parent uri. @@ -93,7 +93,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { $lockList = array(); while( $row = $result->fetchRow()) { - $lockInfo = new Sabre_DAV_Locks_LockInfo(); + $lockInfo = new \Sabre\DAV\Locks\LockInfo(); $lockInfo->owner = $row['owner']; $lockInfo->token = $row['token']; $lockInfo->timeout = $row['timeout']; @@ -113,10 +113,10 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { * Locks a uri * * @param string $uri - * @param Sabre_DAV_Locks_LockInfo $lockInfo + * @param \Sabre\DAV\Locks\LockInfo $lockInfo * @return bool */ - public function lock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) { + public function lock($uri, \Sabre\DAV\Locks\LockInfo $lockInfo) { // We're making the lock timeout 5 minutes $lockInfo->timeout = 300; @@ -170,10 +170,10 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { * Removes a lock from a uri * * @param string $uri - * @param Sabre_DAV_Locks_LockInfo $lockInfo + * @param \Sabre\DAV\Locks\LockInfo $lockInfo * @return bool */ - public function unlock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) { + public function unlock($uri, \Sabre\DAV\Locks\LockInfo $lockInfo) { $sql = 'DELETE FROM `*PREFIX*locks` WHERE `userid` = ? AND `uri` = ? AND `token` = ?'; if (OC_Config::getValue( "dbtype") === 'oci') { diff --git a/lib/private/connector/sabre/maintenanceplugin.php b/lib/private/connector/sabre/maintenanceplugin.php index 2eda269afc2..0208f3fb5a6 100644 --- a/lib/private/connector/sabre/maintenanceplugin.php +++ b/lib/private/connector/sabre/maintenanceplugin.php @@ -9,30 +9,28 @@ * @license AGPL3 */ -require 'ServiceUnavailable.php'; - -class OC_Connector_Sabre_MaintenancePlugin extends Sabre_DAV_ServerPlugin +class OC_Connector_Sabre_MaintenancePlugin extends \Sabre\DAV\ServerPlugin { /** * Reference to main server object * - * @var Sabre_DAV_Server + * @var \Sabre\DAV\Server */ private $server; /** * This initializes the plugin. * - * This function is called by Sabre_DAV_Server, after + * This function is called by \Sabre\DAV\Server, after * addPlugin is called. * * This method should set up the required event subscriptions. * - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server * @return void */ - public function initialize(Sabre_DAV_Server $server) { + public function initialize(\Sabre\DAV\Server $server) { $this->server = $server; $this->server->subscribeEvent('beforeMethod', array($this, 'checkMaintenanceMode'), 10); @@ -42,16 +40,16 @@ class OC_Connector_Sabre_MaintenancePlugin extends Sabre_DAV_ServerPlugin * This method is called before any HTTP method and returns http status code 503 * in case the system is in maintenance mode. * - * @throws Sabre_DAV_Exception_ServiceUnavailable + * @throws \Sabre\DAV\Exception\ServiceUnavailable * @internal param string $method * @return bool */ public function checkMaintenanceMode() { if (OC_Config::getValue('maintenance', false)) { - throw new Sabre_DAV_Exception_ServiceUnavailable(); + throw new \Sabre\DAV\Exception\ServiceUnavailable(); } if (OC::checkUpgrade(false)) { - throw new Sabre_DAV_Exception_ServiceUnavailable('Upgrade needed'); + throw new \Sabre\DAV\Exception\ServiceUnavailable('Upgrade needed'); } return true; diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php index f124b754443..8a369eccf6b 100644 --- a/lib/private/connector/sabre/node.php +++ b/lib/private/connector/sabre/node.php @@ -1,4 +1,5 @@ <?php +use Sabre\DAV\URLUtil; /** * ownCloud @@ -20,7 +21,7 @@ * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ -abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { +abstract class OC_Connector_Sabre_Node implements \Sabre\DAV\INode, \Sabre\DAV\IProperties { const GETETAG_PROPERTYNAME = '{DAV:}getetag'; const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified'; @@ -81,21 +82,21 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr /** * Renames the node * @param string $name The new name - * @throws Sabre_DAV_Exception_BadRequest - * @throws Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\BadRequest + * @throws \Sabre\DAV\Exception\Forbidden */ public function setName($name) { // rename is only allowed if the update privilege is granted if (!$this->info->isUpdateable()) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } - list($parentPath,) = Sabre_DAV_URLUtil::splitPath($this->path); - list(, $newName) = Sabre_DAV_URLUtil::splitPath($name); + list($parentPath,) = URLUtil::splitPath($this->path); + list(, $newName) = URLUtil::splitPath($name); if (!\OCP\Util::isValidFileName($newName)) { - throw new \Sabre_DAV_Exception_BadRequest(); + throw new \Sabre\DAV\Exception\BadRequest(); } $newPath = $parentPath . '/' . $newName; @@ -139,7 +140,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr /** * Updates properties on this node, - * @see Sabre_DAV_IProperties::updateProperties + * @see \Sabre\DAV\IProperties::updateProperties * @param array $properties * @return boolean */ diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php index 35cc1679ab6..a3de2efaa50 100644 --- a/lib/private/connector/sabre/objecttree.php +++ b/lib/private/connector/sabre/objecttree.php @@ -11,7 +11,7 @@ namespace OC\Connector\Sabre; use OC\Files\FileInfo; use OC\Files\Filesystem; -class ObjectTree extends \Sabre_DAV_ObjectTree { +class ObjectTree extends \Sabre\DAV\ObjectTree { /** * @var \OC\Files\View @@ -27,10 +27,10 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { } /** - * @param \Sabre_DAV_ICollection $rootNode + * @param \Sabre\DAV\ICollection $rootNode * @param \OC\Files\View $view */ - public function init(\Sabre_DAV_ICollection $rootNode, \OC\Files\View $view) { + public function init(\Sabre\DAV\ICollection $rootNode, \OC\Files\View $view) { $this->rootNode = $rootNode; $this->fileView = $view; } @@ -39,13 +39,13 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { * Returns the INode object for the requested path * * @param string $path - * @throws \Sabre_DAV_Exception_ServiceUnavailable - * @throws \Sabre_DAV_Exception_NotFound - * @return \Sabre_DAV_INode + * @throws \Sabre\DAV\Exception\ServiceUnavailable + * @throws \Sabre\DAV\Exception\NotFound + * @return \Sabre\DAV\INode */ public function getNodeForPath($path) { if (!$this->fileView) { - throw new \Sabre_DAV_Exception_ServiceUnavailable('filesystem not setup'); + throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup'); } $path = trim($path, '/'); @@ -79,7 +79,7 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { } if (!$info) { - throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located'); + throw new \Sabre\DAV\Exception\NotFound('File with name ' . $path . ' could not be located'); } if ($info->getType() === 'dir') { @@ -98,22 +98,22 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { * * @param string $sourcePath The path to the file which should be moved * @param string $destinationPath The full destination path, so not just the destination parent node - * @throws \Sabre_DAV_Exception_BadRequest - * @throws \Sabre_DAV_Exception_ServiceUnavailable - * @throws \Sabre_DAV_Exception_Forbidden + * @throws \Sabre\DAV\Exception\BadRequest + * @throws \Sabre\DAV\Exception\ServiceUnavailable + * @throws \Sabre\DAV\Exception\Forbidden * @return int */ public function move($sourcePath, $destinationPath) { if (!$this->fileView) { - throw new \Sabre_DAV_Exception_ServiceUnavailable('filesystem not setup'); + throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup'); } $sourceNode = $this->getNodeForPath($sourcePath); - if ($sourceNode instanceof \Sabre_DAV_ICollection and $this->nodeExists($destinationPath)) { - throw new \Sabre_DAV_Exception_Forbidden('Could not copy directory ' . $sourceNode . ', target exists'); + if ($sourceNode instanceof \Sabre\DAV\ICollection and $this->nodeExists($destinationPath)) { + throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode . ', target exists'); } - list($sourceDir,) = \Sabre_DAV_URLUtil::splitPath($sourcePath); - list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destinationPath); + list($sourceDir,) = \Sabre\DAV\URLUtil::splitPath($sourcePath); + list($destinationDir,) = \Sabre\DAV\URLUtil::splitPath($destinationPath); $isShareMountPoint = false; list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath( '/' . \OCP\User::getUser() . '/files/' . $sourcePath); @@ -123,38 +123,39 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { // check update privileges if (!$this->fileView->isUpdatable($sourcePath) && !$isShareMountPoint) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } if ($sourceDir !== $destinationDir) { // for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir if (ltrim($destinationDir, '/') === '') { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } if (!$this->fileView->isUpdatable($sourceDir)) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } if (!$this->fileView->isUpdatable($destinationDir)) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } if (!$this->fileView->isDeletable($sourcePath)) { - throw new \Sabre_DAV_Exception_Forbidden(); + throw new \Sabre\DAV\Exception\Forbidden(); } } $fileName = basename($destinationPath); if (!\OCP\Util::isValidFileName($fileName)) { - throw new \Sabre_DAV_Exception_BadRequest(); + throw new \Sabre\DAV\Exception\BadRequest(); } $renameOkay = $this->fileView->rename($sourcePath, $destinationPath); if (!$renameOkay) { - throw new \Sabre_DAV_Exception_Forbidden(''); + throw new \Sabre\DAV\Exception\Forbidden(''); } // update properties $query = \OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?' . ' WHERE `userid` = ? AND `propertypath` = ?'); - $query->execute(array(\OC\Files\Filesystem::normalizePath($destinationPath), \OC_User::getUser(), \OC\Files\Filesystem::normalizePath($sourcePath))); + $query->execute(array(\OC\Files\Filesystem::normalizePath($destinationPath), \OC_User::getUser(), + \OC\Files\Filesystem::normalizePath($sourcePath))); $this->markDirty($sourceDir); $this->markDirty($destinationDir); @@ -169,12 +170,12 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { * * @param string $source * @param string $destination - * @throws \Sabre_DAV_Exception_ServiceUnavailable + * @throws \Sabre\DAV\Exception\ServiceUnavailable * @return void */ public function copy($source, $destination) { if (!$this->fileView) { - throw new \Sabre_DAV_Exception_ServiceUnavailable('filesystem not setup'); + throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup'); } if ($this->fileView->is_file($source)) { @@ -192,7 +193,7 @@ class ObjectTree extends \Sabre_DAV_ObjectTree { } } - list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destination); + list($destinationDir,) = \Sabre\DAV\URLUtil::splitPath($destination); $this->markDirty($destinationDir); } } diff --git a/lib/private/connector/sabre/principal.php b/lib/private/connector/sabre/principal.php index 2075aa55c86..9bad3b9df16 100644 --- a/lib/private/connector/sabre/principal.php +++ b/lib/private/connector/sabre/principal.php @@ -7,7 +7,7 @@ * See the COPYING-README file. */ -class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend { +class OC_Connector_Sabre_Principal implements \Sabre\DAVACL\PrincipalBackend\BackendInterface { /** * Returns a list of principals based on a prefix. * @@ -68,7 +68,7 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend { // TODO: for now the group principal has only one member, the user itself $principal = $this->getPrincipalByPath($principal); if (!$principal) { - throw new Sabre_DAV_Exception('Principal not found'); + throw new \Sabre\DAV\Exception('Principal not found'); } return array( @@ -83,13 +83,13 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend { * @return array */ public function getGroupMembership($principal) { - list($prefix, $name) = Sabre_DAV_URLUtil::splitPath($principal); + list($prefix, $name) = \Sabre\DAV\URLUtil::splitPath($principal); $group_membership = array(); if ($prefix == 'principals') { $principal = $this->getPrincipalByPath($principal); if (!$principal) { - throw new Sabre_DAV_Exception('Principal not found'); + throw new \Sabre\DAV\Exception('Principal not found'); } // TODO: for now the user principal has only its own groups @@ -115,7 +115,7 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend { * @return void */ public function setGroupMemberSet($principal, array $members) { - throw new Sabre_DAV_Exception('Setting members of the group is not supported yet'); + throw new \Sabre\DAV\Exception('Setting members of the group is not supported yet'); } function updatePrincipal($path, $mutations) { diff --git a/lib/private/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php index c9b8336b57b..cf3c1103f84 100644 --- a/lib/private/connector/sabre/quotaplugin.php +++ b/lib/private/connector/sabre/quotaplugin.php @@ -1,4 +1,5 @@ <?php +use Sabre\DAV\URLUtil; /** * This plugin check user quota and deny creating files when they exceeds the quota. @@ -7,7 +8,7 @@ * @copyright Copyright (C) 2012 entreCables S.L. All rights reserved. * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { +class OC_Connector_Sabre_QuotaPlugin extends \Sabre\DAV\ServerPlugin { /** * @var \OC\Files\View @@ -17,7 +18,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { /** * Reference to main server object * - * @var Sabre_DAV_Server + * @var \Sabre\DAV\Server */ private $server; @@ -31,15 +32,15 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { /** * This initializes the plugin. * - * This function is called by Sabre_DAV_Server, after + * This function is called by \Sabre\DAV\Server, after * addPlugin is called. * * This method should set up the requires event subscriptions. * - * @param Sabre_DAV_Server $server + * @param \Sabre\DAV\Server $server * @return void */ - public function initialize(Sabre_DAV_Server $server) { + public function initialize(\Sabre\DAV\Server $server) { $this->server = $server; @@ -52,7 +53,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { * * @param string $uri * @param null $data - * @throws Sabre_DAV_Exception_InsufficientStorage + * @throws \Sabre\DAV\Exception\InsufficientStorage * @return bool */ public function checkQuota($uri, $data = null) { @@ -61,7 +62,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { if (substr($uri, 0, 1) !== '/') { $uri = '/' . $uri; } - list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri); + list($parentUri, $newName) = URLUtil::splitPath($uri); $req = $this->server->httpRequest; if ($req->getHeader('OC-Chunked')) { $info = OC_FileChunking::decodeName($newName); @@ -75,7 +76,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin { if (isset($chunkHandler)) { $chunkHandler->cleanup(); } - throw new Sabre_DAV_Exception_InsufficientStorage(); + throw new \Sabre\DAV\Exception\InsufficientStorage(); } } return true; diff --git a/lib/private/connector/sabre/request.php b/lib/private/connector/sabre/request.php index d70c25c4e70..c98b28c4d74 100644 --- a/lib/private/connector/sabre/request.php +++ b/lib/private/connector/sabre/request.php @@ -21,7 +21,7 @@ * */ -class OC_Connector_Sabre_Request extends Sabre_HTTP_Request { +class OC_Connector_Sabre_Request extends \Sabre\HTTP\Request { /** * Returns the requested uri * diff --git a/lib/private/connector/sabre/server.php b/lib/private/connector/sabre/server.php index cf28b11163f..e4ee5dcefbf 100644 --- a/lib/private/connector/sabre/server.php +++ b/lib/private/connector/sabre/server.php @@ -12,7 +12,7 @@ /** * Class OC_Connector_Sabre_Server * - * This class reimplements some methods from @see Sabre_DAV_Server. + * This class reimplements some methods from @see \Sabre\DAV\Server. * * Basically we add handling of depth: infinity. * @@ -24,16 +24,16 @@ * * For ownCloud 7 we will upgrade SabreDAV and submit the patch - if needed. * - * @see Sabre_DAV_Server + * @see \Sabre\DAV\Server */ -class OC_Connector_Sabre_Server extends Sabre_DAV_Server { +class OC_Connector_Sabre_Server extends Sabre\DAV\Server { /** - * @see Sabre_DAV_Server + * @see \Sabre\DAV\Server */ protected function httpPropfind($uri) { - // $xml = new Sabre_DAV_XMLReader(file_get_contents('php://input')); + // $xml = new \Sabre\DAV\XMLReader(file_get_contents('php://input')); $requestedProperties = $this->parsePropFindRequest($this->httpRequest->getBody(true)); $depth = $this->getHTTPDepth(1); @@ -72,7 +72,7 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server { private function addPathNodesRecursively(&$nodes, $path) { foreach($this->tree->getChildren($path) as $childNode) { $nodes[$path . '/' . $childNode->getName()] = $childNode; - if ($childNode instanceof Sabre_DAV_ICollection) + if ($childNode instanceof \Sabre\DAV\ICollection) $this->addPathNodesRecursively($nodes, $path . '/' . $childNode->getName()); } } @@ -89,10 +89,10 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server { $nodes = array( $path => $parentNode ); - if ($depth==1 && $parentNode instanceof Sabre_DAV_ICollection) { + if ($depth==1 && $parentNode instanceof \Sabre\DAV\ICollection) { foreach($this->tree->getChildren($path) as $childNode) $nodes[$path . '/' . $childNode->getName()] = $childNode; - } else if ($depth == self::DEPTH_INFINITY && $parentNode instanceof Sabre_DAV_ICollection) { + } else if ($depth == self::DEPTH_INFINITY && $parentNode instanceof \Sabre\DAV\ICollection) { $this->addPathNodesRecursively($nodes, $path); } @@ -140,7 +140,7 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server { if (count($currentPropertyNames) > 0) { - if ($node instanceof Sabre_DAV_IProperties) { + if ($node instanceof \Sabre\DAV\IProperties) { $nodeProperties = $node->getProperties($currentPropertyNames); // The getProperties method may give us too much, @@ -165,9 +165,9 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server { if (isset($newProperties[200][$prop])) continue; switch($prop) { - case '{DAV:}getlastmodified' : if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); break; + case '{DAV:}getlastmodified' : if ($node->getLastModified()) $newProperties[200][$prop] = new \Sabre\DAV\Property\GetLastModified($node->getLastModified()); break; case '{DAV:}getcontentlength' : - if ($node instanceof Sabre_DAV_IFile) { + if ($node instanceof \Sabre\DAV\IFile) { $size = $node->getSize(); if (!is_null($size)) { $newProperties[200][$prop] = 0 + $size; @@ -175,28 +175,28 @@ class OC_Connector_Sabre_Server extends Sabre_DAV_Server { } break; case '{DAV:}quota-used-bytes' : - if ($node instanceof Sabre_DAV_IQuota) { + if ($node instanceof \Sabre\DAV\IQuota) { $quotaInfo = $node->getQuotaInfo(); $newProperties[200][$prop] = $quotaInfo[0]; } break; case '{DAV:}quota-available-bytes' : - if ($node instanceof Sabre_DAV_IQuota) { + if ($node instanceof \Sabre\DAV\IQuota) { $quotaInfo = $node->getQuotaInfo(); $newProperties[200][$prop] = $quotaInfo[1]; } break; - case '{DAV:}getetag' : if ($node instanceof Sabre_DAV_IFile && $etag = $node->getETag()) $newProperties[200][$prop] = $etag; break; - case '{DAV:}getcontenttype' : if ($node instanceof Sabre_DAV_IFile && $ct = $node->getContentType()) $newProperties[200][$prop] = $ct; break; + case '{DAV:}getetag' : if ($node instanceof \Sabre\DAV\IFile && $etag = $node->getETag()) $newProperties[200][$prop] = $etag; break; + case '{DAV:}getcontenttype' : if ($node instanceof \Sabre\DAV\IFile && $ct = $node->getContentType()) $newProperties[200][$prop] = $ct; break; case '{DAV:}supported-report-set' : $reports = array(); foreach($this->plugins as $plugin) { $reports = array_merge($reports, $plugin->getSupportedReportSet($myPath)); } - $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports); + $newProperties[200][$prop] = new \Sabre\DAV\Property\SupportedReportSet($reports); break; case '{DAV:}resourcetype' : - $newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType(); + $newProperties[200]['{DAV:}resourcetype'] = new \Sabre\DAV\Property\ResourceType(); foreach($this->resourceTypeMapping as $className => $resourceType) { if ($node instanceof $className) $newProperties[200]['{DAV:}resourcetype']->add($resourceType); } diff --git a/lib/private/davclient.php b/lib/private/davclient.php index a7bf0486519..6a544d27068 100644 --- a/lib/private/davclient.php +++ b/lib/private/davclient.php @@ -25,7 +25,7 @@ * like request timeout. */ -class OC_DAVClient extends \Sabre_DAV_Client { +class OC_DAVClient extends \Sabre\DAV\Client { protected $requestTimeout; diff --git a/lib/private/db.php b/lib/private/db.php index 422f783c745..82affe293ed 100644 --- a/lib/private/db.php +++ b/lib/private/db.php @@ -322,6 +322,23 @@ class OC_DB { } /** + * simulate the database schema update + * @param string $file file to read structure from + * @throws Exception + * @return string|boolean + */ + public static function simulateUpdateDbFromStructure($file) { + $schemaManager = self::getMDB2SchemaManager(); + try { + $result = $schemaManager->simulateUpdateDbFromStructure($file); + } catch (Exception $e) { + OC_Log::write('core', 'Simulated database structure update failed ('.$e.')', OC_Log::FATAL); + throw $e; + } + return $result; + } + + /** * drop a table - the database prefix will be prepended * @param string $tableName the table to drop */ diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php index 4208dbd18f4..734ba18d1ac 100644 --- a/lib/private/db/mdb2schemamanager.php +++ b/lib/private/db/mdb2schemamanager.php @@ -8,6 +8,11 @@ namespace OC\DB; +use Doctrine\DBAL\Platforms\MySqlPlatform; +use Doctrine\DBAL\Platforms\OraclePlatform; +use Doctrine\DBAL\Platforms\PostgreSqlPlatform; +use Doctrine\DBAL\Platforms\SqlitePlatform; + class MDB2SchemaManager { /** * @var \OC\DB\Connection $conn @@ -31,7 +36,7 @@ class MDB2SchemaManager { * * TODO: write more documentation */ - public function getDbStructure( $file, $mode = MDB2_SCHEMA_DUMP_STRUCTURE) { + public function getDbStructure($file, $mode = MDB2_SCHEMA_DUMP_STRUCTURE) { $sm = $this->conn->getSchemaManager(); return \OC_DB_MDB2SchemaWriter::saveSchemaToFile($file, $sm); @@ -44,58 +49,82 @@ class MDB2SchemaManager { * * TODO: write more documentation */ - public function createDbFromStructure( $file ) { + public function createDbFromStructure($file) { $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform()); $toSchema = $schemaReader->loadSchemaFromFile($file); return $this->executeSchemaChange($toSchema); } /** + * @return \OC\DB\Migrator + */ + protected function getMigrator() { + $platform = $this->conn->getDatabasePlatform(); + if ($platform instanceof SqlitePlatform) { + return new SQLiteMigrator($this->conn); + } else if ($platform instanceof OraclePlatform) { + return new OracleMigrator($this->conn); + } else if ($platform instanceof MySqlPlatform) { + return new MySQLMigrator($this->conn); + } else if ($platform instanceof PostgreSqlPlatform) { + return new Migrator($this->conn); + } else { + return new NoCheckMigrator($this->conn); + } + } + + /** + * Reads database schema from file + * + * @param string $file file to read from + */ + private function readSchemaFromFile($file) { + $platform = $this->conn->getDatabasePlatform(); + $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $platform); + return $schemaReader->loadSchemaFromFile($file); + } + + /** * update the database scheme * @param string $file file to read structure from + * @param bool $generateSql only return the sql needed for the upgrade * @return string|boolean */ public function updateDbFromStructure($file, $generateSql = false) { - $sm = $this->conn->getSchemaManager(); - $fromSchema = $sm->createSchema(); - - $schemaReader = new MDB2SchemaReader(\OC_Config::getObject(), $this->conn->getDatabasePlatform()); - $toSchema = $schemaReader->loadSchemaFromFile($file); - - // remove tables we don't know about - /** @var $table \Doctrine\DBAL\Schema\Table */ - foreach($fromSchema->getTables() as $table) { - if (!$toSchema->hasTable($table->getName())) { - $fromSchema->dropTable($table->getName()); - } - } - // remove sequences we don't know about - foreach($fromSchema->getSequences() as $table) { - if (!$toSchema->hasSequence($table->getName())) { - $fromSchema->dropSequence($table->getName()); - } - } - - $comparator = new \Doctrine\DBAL\Schema\Comparator(); - $schemaDiff = $comparator->compare($fromSchema, $toSchema); - - $platform = $this->conn->getDatabasePlatform(); - foreach($schemaDiff->changedTables as $tableDiff) { - $tableDiff->name = $platform->quoteIdentifier($tableDiff->name); - foreach($tableDiff->changedColumns as $column) { - $column->oldColumnName = $platform->quoteIdentifier($column->oldColumnName); - } - } + $toSchema = $this->readSchemaFromFile($file); + $migrator = $this->getMigrator(); if ($generateSql) { - return $this->generateChangeScript($schemaDiff); + return $migrator->generateChangeScript($toSchema); + } else { + $migrator->migrate($toSchema); + return true; } + } - return $this->executeSchemaChange($schemaDiff); + /** + * update the database scheme + * @param string $file file to read structure from + * @return string|boolean + */ + public function simulateUpdateDbFromStructure($file) { + $toSchema = $this->readSchemaFromFile($file); + $migrator = $this->getMigrator()->checkMigrate($toSchema); + return true; + } + + /** + * @param \Doctrine\DBAL\Schema\Schema $schema + * @return string + */ + public function generateChangeScript($schema) { + $migrator = $this->getMigrator(); + return $migrator->generateChangeScript($schema); } /** * remove all tables defined in a database structure xml file + * * @param string $file the xml file describing the tables */ public function removeDBStructure($file) { @@ -103,7 +132,7 @@ class MDB2SchemaManager { $fromSchema = $schemaReader->loadSchemaFromFile($file); $toSchema = clone $fromSchema; /** @var $table \Doctrine\DBAL\Schema\Table */ - foreach($toSchema->getTables() as $table) { + foreach ($toSchema->getTables() as $table) { $toSchema->dropTable($table->getName()); } $comparator = new \Doctrine\DBAL\Schema\Comparator(); @@ -117,26 +146,10 @@ class MDB2SchemaManager { */ private function executeSchemaChange($schema) { $this->conn->beginTransaction(); - foreach($schema->toSql($this->conn->getDatabasePlatform()) as $sql) { + foreach ($schema->toSql($this->conn->getDatabasePlatform()) as $sql) { $this->conn->query($sql); } $this->conn->commit(); return true; } - - /** - * @param \Doctrine\DBAL\Schema\Schema $schema - * @return string - */ - public function generateChangeScript($schema) { - - $script = ''; - $sqls = $schema->toSql($this->conn->getDatabasePlatform()); - foreach($sqls as $sql) { - $script .= $sql . ';'; - $script .= PHP_EOL; - } - - return $script; - } } diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php index 597650985fa..61f58a1f200 100644 --- a/lib/private/db/mdb2schemareader.php +++ b/lib/private/db/mdb2schemareader.php @@ -130,7 +130,7 @@ class MDB2SchemaReader { * @throws \DomainException */ private function loadField($table, $xml) { - $options = array(); + $options = array( 'notnull' => false ); foreach ($xml->children() as $child) { /** * @var \SimpleXMLElement $child diff --git a/lib/private/db/migrationexception.php b/lib/private/db/migrationexception.php new file mode 100644 index 00000000000..2afec9700a0 --- /dev/null +++ b/lib/private/db/migrationexception.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + + +class MigrationException extends \Exception { + private $table; + + public function __construct($table, $message) { + $this->table = $table; + parent::__construct($message); + } + + /** + * @return string + */ + public function getTable() { + return $this->table; + } +} diff --git a/lib/private/db/migrator.php b/lib/private/db/migrator.php new file mode 100644 index 00000000000..517be8399e8 --- /dev/null +++ b/lib/private/db/migrator.php @@ -0,0 +1,196 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +use \Doctrine\DBAL\DBALException; +use \Doctrine\DBAL\Schema\Index; +use \Doctrine\DBAL\Schema\Table; +use \Doctrine\DBAL\Schema\Schema; +use \Doctrine\DBAL\Schema\SchemaConfig; +use \Doctrine\DBAL\Schema\Comparator; + +class Migrator { + /** + * @var \Doctrine\DBAL\Connection $connection + */ + protected $connection; + + /** + * @param \Doctrine\DBAL\Connection $connection + */ + public function __construct(\Doctrine\DBAL\Connection $connection) { + $this->connection = $connection; + } + + /** + * @param \Doctrine\DBAL\Schema\Schema $targetSchema + */ + public function migrate(Schema $targetSchema) { + $this->applySchema($targetSchema); + } + + /** + * @param \Doctrine\DBAL\Schema\Schema $targetSchema + * @return string + */ + public function generateChangeScript(Schema $targetSchema) { + $schemaDiff = $this->getDiff($targetSchema, $this->connection); + + $script = ''; + $sqls = $schemaDiff->toSql($this->connection->getDatabasePlatform()); + foreach ($sqls as $sql) { + $script .= $sql . ';'; + $script .= PHP_EOL; + } + + return $script; + } + + /** + * @param Schema $targetSchema + * @throws \OC\DB\MigrationException + */ + public function checkMigrate(Schema $targetSchema) { + /** + * @var \Doctrine\DBAL\Schema\Table[] $tables + */ + $tables = $targetSchema->getTables(); + + $existingTables = $this->connection->getSchemaManager()->listTableNames(); + + foreach ($tables as $table) { + if (strpos($table->getName(), '.')) { + list(, $tableName) = explode('.', $table->getName()); + } else { + $tableName = $table->getName(); + } + // don't need to check for new tables + if (array_search($tableName, $existingTables) !== false) { + $this->checkTableMigrate($table); + } + } + } + + /** + * Create a unique name for the temporary table + * + * @param string $name + * @return string + */ + protected function generateTemporaryTableName($name) { + return 'oc_' . $name . '_' . uniqid(); + } + + /** + * Check the migration of a table on a copy so we can detect errors before messing with the real table + * + * @param \Doctrine\DBAL\Schema\Table $table + * @throws \OC\DB\MigrationException + */ + protected function checkTableMigrate(Table $table) { + $name = $table->getName(); + $tmpName = $this->generateTemporaryTableName($name); + + $this->copyTable($name, $tmpName); + + //create the migration schema for the temporary table + $tmpTable = $this->renameTableSchema($table, $tmpName); + $schemaConfig = new SchemaConfig(); + $schemaConfig->setName($this->connection->getDatabase()); + $schema = new Schema(array($tmpTable), array(), $schemaConfig); + + try { + $this->applySchema($schema); + $this->dropTable($tmpName); + } catch (DBALException $e) { + // pgsql needs to commit it's failed transaction before doing anything else + $this->connection->commit(); + $this->dropTable($tmpName); + throw new MigrationException($table->getName(), $e->getMessage()); + } + } + + /** + * @param \Doctrine\DBAL\Schema\Table $table + * @param string $newName + * @return \Doctrine\DBAL\Schema\Table + */ + protected function renameTableSchema(Table $table, $newName) { + /** + * @var \Doctrine\DBAL\Schema\Index[] $indexes + */ + $indexes = $table->getIndexes(); + $newIndexes = array(); + foreach ($indexes as $index) { + $indexName = 'oc_' . uniqid(); // avoid conflicts in index names + $newIndexes[] = new Index($indexName, $index->getColumns(), $index->isUnique(), $index->isPrimary()); + } + + // foreign keys are not supported so we just set it to an empty array + return new Table($newName, $table->getColumns(), $newIndexes, array(), 0, $table->getOptions()); + } + + protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { + $sourceSchema = $connection->getSchemaManager()->createSchema(); + + // remove tables we don't know about + /** @var $table \Doctrine\DBAL\Schema\Table */ + foreach ($sourceSchema->getTables() as $table) { + if (!$targetSchema->hasTable($table->getName())) { + $sourceSchema->dropTable($table->getName()); + } + } + // remove sequences we don't know about + foreach ($sourceSchema->getSequences() as $table) { + if (!$targetSchema->hasSequence($table->getName())) { + $sourceSchema->dropSequence($table->getName()); + } + } + + $comparator = new Comparator(); + return $comparator->compare($sourceSchema, $targetSchema); + } + + /** + * @param \Doctrine\DBAL\Schema\Schema $targetSchema + * @param \Doctrine\DBAL\Connection $connection + */ + protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) { + if (is_null($connection)) { + $connection = $this->connection; + } + + $schemaDiff = $this->getDiff($targetSchema, $connection); + + $connection->beginTransaction(); + foreach ($schemaDiff->toSql($connection->getDatabasePlatform()) as $sql) { + $connection->query($sql); + } + $connection->commit(); + } + + /** + * @param string $sourceName + * @param string $targetName + */ + protected function copyTable($sourceName, $targetName) { + $quotedSource = $this->connection->quoteIdentifier($sourceName); + $quotedTarget = $this->connection->quoteIdentifier($targetName); + + $this->connection->exec('CREATE TABLE ' . $quotedTarget . ' (LIKE ' . $quotedSource . ')'); + $this->connection->exec('INSERT INTO ' . $quotedTarget . ' SELECT * FROM ' . $quotedSource); + } + + /** + * @param string $name + */ + protected function dropTable($name) { + $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($name)); + } +} diff --git a/lib/private/db/mysqlmigrator.php b/lib/private/db/mysqlmigrator.php new file mode 100644 index 00000000000..97495f52032 --- /dev/null +++ b/lib/private/db/mysqlmigrator.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +use Doctrine\DBAL\Schema\Schema; + +class MySQLMigrator extends Migrator { + /** + * @param Schema $targetSchema + * @param \Doctrine\DBAL\Connection $connection + * @return \Doctrine\DBAL\Schema\SchemaDiff + */ + protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { + $schemaDiff = parent::getDiff($targetSchema, $connection); + + // identifiers need to be quoted for mysql + foreach ($schemaDiff->changedTables as $tableDiff) { + $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name); + foreach ($tableDiff->changedColumns as $column) { + $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName); + } + } + + return $schemaDiff; + } +} diff --git a/lib/private/db/nocheckmigrator.php b/lib/private/db/nocheckmigrator.php new file mode 100644 index 00000000000..cd2b47c214a --- /dev/null +++ b/lib/private/db/nocheckmigrator.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +use Doctrine\DBAL\Schema\Schema; + +/** + * migrator for database platforms that don't support the upgrade check + * + * @package OC\DB + */ +class NoCheckMigrator extends Migrator { + /** + * @param \Doctrine\DBAL\Schema\Schema $targetSchema + * @throws \OC\DB\MigrationException + */ + public function checkMigrate(Schema $targetSchema) {} +} diff --git a/lib/private/db/oraclemigrator.php b/lib/private/db/oraclemigrator.php new file mode 100644 index 00000000000..1a8df2def9c --- /dev/null +++ b/lib/private/db/oraclemigrator.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +use Doctrine\DBAL\Schema\Schema; + +class OracleMigrator extends NoCheckMigrator { + /** + * @param Schema $targetSchema + * @param \Doctrine\DBAL\Connection $connection + * @return \Doctrine\DBAL\Schema\SchemaDiff + */ + protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { + $schemaDiff = parent::getDiff($targetSchema, $connection); + + // oracle forces us to quote the identifiers + foreach ($schemaDiff->changedTables as $tableDiff) { + $tableDiff->name = $this->connection->quoteIdentifier($tableDiff->name); + foreach ($tableDiff->changedColumns as $column) { + $column->oldColumnName = $this->connection->quoteIdentifier($column->oldColumnName); + } + } + + return $schemaDiff; + } + + /** + * @param string $name + * @return string + */ + protected function generateTemporaryTableName($name) { + return 'oc_' . uniqid(); + } +} diff --git a/lib/private/db/sqlitemigrator.php b/lib/private/db/sqlitemigrator.php new file mode 100644 index 00000000000..f5f78986771 --- /dev/null +++ b/lib/private/db/sqlitemigrator.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\DB; + +use Doctrine\DBAL\DBALException; + +class SQLiteMigrator extends Migrator { + /** + * @param \Doctrine\DBAL\Schema\Schema $targetSchema + * @throws \OC\DB\MigrationException + * + * For sqlite we simple make a copy of the entire database, and test the migration on that + */ + public function checkMigrate(\Doctrine\DBAL\Schema\Schema $targetSchema) { + $dbFile = $this->connection->getDatabase(); + $tmpFile = \OC_Helper::tmpFile('.db'); + copy($dbFile, $tmpFile); + + $connectionParams = array( + 'path' => $tmpFile, + 'driver' => 'pdo_sqlite', + ); + $conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); + try { + $this->applySchema($targetSchema, $conn); + $conn->close(); + unlink($tmpFile); + } catch (DBALException $e) { + $conn->close(); + unlink($tmpFile); + throw new MigrationException('', $e->getMessage()); + } + } +} diff --git a/lib/private/files.php b/lib/private/files.php index 7c437a16a98..739dae64180 100644 --- a/lib/private/files.php +++ b/lib/private/files.php @@ -108,7 +108,6 @@ class OC_Files { $xsendfile = false; } } else { - self::validateZipDownload($dir, $files); $zip = new ZipStreamer(false); } OC_Util::obEnd(); @@ -222,53 +221,6 @@ class OC_Files { } /** - * checks if the selected files are within the size constraint. If not, outputs an error page. - * - * @param string $dir - * @param array|string $files - */ - static function validateZipDownload($dir, $files) { - if (!OC_Config::getValue('allowZipDownload', true)) { - $l = OC_L10N::get('lib'); - header("HTTP/1.0 409 Conflict"); - OC_Template::printErrorPage( - $l->t('ZIP download is turned off.'), - $l->t('Files need to be downloaded one by one.') - . '<br/><a href="'.OCP\Util::linkTo('files', 'index.php', array('dir' => $dir)).'">' . $l->t('Back to Files') . '</a>' - ); - exit; - } - - $zipLimit = OC_Config::getValue('maxZipInputSize', OC_Helper::computerFileSize('800 MB')); - if ($zipLimit > 0) { - $totalsize = 0; - if(!is_array($files)) { - $files = array($files); - } - foreach ($files as $file) { - $path = $dir . '/' . $file; - if(\OC\Files\Filesystem::is_dir($path)) { - foreach (\OC\Files\Filesystem::getDirectoryContent($path) as $i) { - $totalsize += $i['size']; - } - } else { - $totalsize += \OC\Files\Filesystem::filesize($path); - } - } - if ($totalsize > $zipLimit) { - $l = OC_L10N::get('lib'); - header("HTTP/1.0 409 Conflict"); - OC_Template::printErrorPage( - $l->t('Selected files too large to generate zip file.'), - $l->t('Please download the files separately in smaller chunks or kindly ask your administrator.') - . '<br/><a href="'.OCP\Util::linkTo('files', 'index.php', array('dir' => $dir)).'">' . $l->t('Back to Files') . '</a>' - ); - exit; - } - } - } - - /** * set the maximum upload size limit for apache hosts using .htaccess * * @param int $size file size in bytes diff --git a/lib/private/files/cache/backgroundwatcher.php b/lib/private/files/cache/backgroundwatcher.php deleted file mode 100644 index 2194651233d..00000000000 --- a/lib/private/files/cache/backgroundwatcher.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files\Cache; - -use \OC\Files\Mount; -use \OC\Files\Filesystem; - -class BackgroundWatcher { - static $folderMimetype = null; - - static private function getFolderMimetype() { - if (!is_null(self::$folderMimetype)) { - return self::$folderMimetype; - } - $sql = 'SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'; - $result = \OC_DB::executeAudited($sql, array('httpd/unix-directory')); - $row = $result->fetchRow(); - return $row['id']; - } - - /** - * @param integer $id - */ - static private function checkUpdate($id) { - $cacheItem = Cache::getById($id); - if (is_null($cacheItem)) { - return; - } - list($storageId, $internalPath) = $cacheItem; - $mounts = Filesystem::getMountByStorageId($storageId); - - if (count($mounts) === 0) { - //if the storage we need isn't mounted on default, try to find a user that has access to the storage - $permissionsCache = new Permissions($storageId); - $users = $permissionsCache->getUsers($id); - if (count($users) === 0) { - return; - } - Filesystem::initMountPoints($users[0]); - $mounts = Filesystem::getMountByStorageId($storageId); - if (count($mounts) === 0) { - return; - } - } - $storage = $mounts[0]->getStorage(); - $watcher = new Watcher($storage); - $watcher->checkUpdate($internalPath); - } - - /** - * get the next fileid in the cache - * - * @param int $previous - * @param bool $folder - * @return int - */ - static private function getNextFileId($previous, $folder) { - if ($folder) { - $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` = ? ORDER BY `fileid` ASC', 1); - } else { - $stmt = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` > ? AND `mimetype` != ? ORDER BY `fileid` ASC', 1); - } - $result = \OC_DB::executeAudited($stmt, array($previous,self::getFolderMimetype())); - if ($row = $result->fetchRow()) { - return $row['fileid']; - } else { - return 0; - } - } - - static public function checkNext() { - // check both 1 file and 1 folder, this way new files are detected quicker because there are less folders than files usually - $previousFile = \OC_Appconfig::getValue('files', 'backgroundwatcher_previous_file', 0); - $previousFolder = \OC_Appconfig::getValue('files', 'backgroundwatcher_previous_folder', 0); - $nextFile = self::getNextFileId($previousFile, false); - $nextFolder = self::getNextFileId($previousFolder, true); - \OC_Appconfig::setValue('files', 'backgroundwatcher_previous_file', $nextFile); - \OC_Appconfig::setValue('files', 'backgroundwatcher_previous_folder', $nextFolder); - if ($nextFile > 0) { - self::checkUpdate($nextFile); - } - if ($nextFolder > 0) { - self::checkUpdate($nextFolder); - } - } - - static public function checkAll() { - $previous = 0; - $next = 1; - while ($next != 0) { - $next = self::getNextFileId($previous, true); - self::checkUpdate($next); - } - $previous = 0; - $next = 1; - while ($next != 0) { - $next = self::getNextFileId($previous, false); - self::checkUpdate($next); - } - } -} diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 59963f41e3d..bfd280a91a1 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -123,7 +123,7 @@ class Cache { $params = array($file); } $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` + `storage_mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` ' . $where; $result = \OC_DB::executeAudited($sql, $params); $data = $result->fetchRow(); @@ -153,6 +153,7 @@ class Cache { if ($data['storage_mtime'] == 0) { $data['storage_mtime'] = $data['mtime']; } + $data['permissions'] = (int)$data['permissions']; } return $data; @@ -178,7 +179,7 @@ class Cache { public function getFolderContentsById($fileId) { if ($fileId > -1) { $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `storage_mtime`, `encrypted`, `unencrypted_size`, `etag` + `storage_mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC'; $result = \OC_DB::executeAudited($sql,array($fileId)); $files = $result->fetchAll(); @@ -192,6 +193,7 @@ class Cache { $file['encrypted_size'] = $file['size']; $file['size'] = $file['unencrypted_size']; } + $file['permissions'] = (int)$file['permissions']; } return $files; } else { @@ -277,7 +279,9 @@ class Cache { * @return array */ function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'unencrypted_size', 'etag'); + $fields = array( + 'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'unencrypted_size', + 'etag', 'permissions'); $params = array(); $queryParts = array(); foreach ($data as $name => $value) { @@ -370,9 +374,6 @@ class Cache { $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'; \OC_DB::executeAudited($sql, array($entry['fileid'])); - - $permissionsCache = new Permissions($this->storageId); - $permissionsCache->remove($entry['fileid']); } /** @@ -457,7 +458,7 @@ class Cache { // normalize pattern $pattern = $this->normalize($pattern); - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'; $result = \OC_DB::executeAudited($sql, array($pattern, $this->getNumericStorageId())); $files = array(); @@ -481,7 +482,7 @@ class Cache { } else { $where = '`mimepart` = ?'; } - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` + $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`, `permissions` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'; $mimetype = $this->getMimetypeId($mimetype); $result = \OC_DB::executeAudited($sql, array($mimetype, $this->getNumericStorageId())); diff --git a/lib/private/files/cache/changepropagator.php b/lib/private/files/cache/changepropagator.php new file mode 100644 index 00000000000..30f2e675e2e --- /dev/null +++ b/lib/private/files/cache/changepropagator.php @@ -0,0 +1,98 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +/** + * Propagates changes in etag and mtime up the filesystem tree + * + * @package OC\Files\Cache + */ +class ChangePropagator { + /** + * @var string[] + */ + protected $changedFiles = array(); + + /** + * @var \OC\Files\View + */ + protected $view; + + /** + * @param \OC\Files\View $view + */ + public function __construct(\OC\Files\View $view) { + $this->view = $view; + } + + public function addChange($path) { + $this->changedFiles[] = $path; + } + + public function getChanges() { + return $this->changedFiles; + } + + /** + * propagate the registered changes to their parent folders + * + * @param int $time (optional) the mtime to set for the folders, if not set the current time is used + */ + public function propagateChanges($time = null) { + $parents = $this->getAllParents(); + $this->changedFiles = array(); + if (!$time) { + $time = time(); + } + foreach ($parents as $parent) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + + list($storage, $internalPath) = $this->view->resolvePath($parent); + $cache = $storage->getCache(); + $id = $cache->getId($internalPath); + $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); + } + } + + /** + * @return string[] + */ + public function getAllParents() { + $parents = array(); + foreach ($this->getChanges() as $path) { + $parents = array_values(array_unique(array_merge($parents, $this->getParents($path)))); + } + return $parents; + } + + /** + * get all parent folders of $path + * + * @param string $path + * @return string[] + */ + protected function getParents($path) { + $parts = explode('/', $path); + + // remove the singe file + array_pop($parts); + $result = array('/'); + $resultPath = ''; + foreach ($parts as $part) { + if ($part) { + $resultPath .= '/' . $part; + $result[] = $resultPath; + } + } + return $result; + } +} diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php index f61769f0b9b..06ae62015a5 100644 --- a/lib/private/files/cache/homecache.php +++ b/lib/private/files/cache/homecache.php @@ -17,7 +17,7 @@ class HomeCache extends Cache { * @return int */ public function calculateFolderSize($path, $entry = null) { - if ($path !== '/' and $path !== '' and $path !== 'files' and $path !== 'files_trashbin') { + if ($path !== '/' and $path !== '' and $path !== 'files' and $path !== 'files_trashbin' and $path !== 'files_versions') { return parent::calculateFolderSize($path, $entry); } elseif ($path === '' or $path === '/') { // since the size of / isn't used (the size of /files is used instead) there is no use in calculating it diff --git a/lib/private/files/cache/permissions.php b/lib/private/files/cache/permissions.php deleted file mode 100644 index eba18af3863..00000000000 --- a/lib/private/files/cache/permissions.php +++ /dev/null @@ -1,156 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files\Cache; - -class Permissions { - /** - * @var string $storageId - */ - private $storageId; - - /** - * @param \OC\Files\Storage\Storage|string $storage - */ - public function __construct($storage) { - if ($storage instanceof \OC\Files\Storage\Storage) { - $this->storageId = $storage->getId(); - } else { - $this->storageId = $storage; - } - } - - /** - * get the permissions for a single file - * - * @param int $fileId - * @param string $user - * @return int (-1 if file no permissions set) - */ - public function get($fileId, $user) { - $sql = 'SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($user, $fileId)); - if ($row = $result->fetchRow()) { - return $this->updatePermissions($row['permissions']); - } else { - return -1; - } - } - - /** - * set the permissions of a file - * - * @param int $fileId - * @param string $user - * @param int $permissions - */ - public function set($fileId, $user, $permissions) { - if (self::get($fileId, $user) !== -1) { - $sql = 'UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'; - } else { - $sql = 'INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`) VALUES(?, ?,? )'; - } - \OC_DB::executeAudited($sql, array($permissions, $user, $fileId)); - } - - /** - * get the permissions of multiply files - * - * @param int[] $fileIds - * @param string $user - * @return int[] - */ - public function getMultiple($fileIds, $user) { - if (count($fileIds) === 0) { - return array(); - } - $params = $fileIds; - $params[] = $user; - $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - - $sql = 'SELECT `fileid`, `permissions` FROM `*PREFIX*permissions`' - . ' WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'; - $result = \OC_DB::executeAudited($sql, $params); - $filePermissions = array(); - while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $this->updatePermissions($row['permissions']); - } - return $filePermissions; - } - - /** - * get the permissions for all files in a folder - * - * @param int $parentId - * @param string $user - * @return int[] - */ - public function getDirectoryPermissions($parentId, $user) { - $sql = 'SELECT `*PREFIX*permissions`.`fileid`, `permissions` - FROM `*PREFIX*permissions` - INNER JOIN `*PREFIX*filecache` ON `*PREFIX*permissions`.`fileid` = `*PREFIX*filecache`.`fileid` - WHERE `*PREFIX*filecache`.`parent` = ? AND `*PREFIX*permissions`.`user` = ?'; - - $result = \OC_DB::executeAudited($sql, array($parentId, $user)); - $filePermissions = array(); - while ($row = $result->fetchRow()) { - $filePermissions[$row['fileid']] = $this->updatePermissions($row['permissions']); - } - return $filePermissions; - } - - /** - * remove the permissions for a file - * - * @param int $fileId - * @param string $user - */ - public function remove($fileId, $user = null) { - if (is_null($user)) { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ?', array($fileId)); - } else { - $sql = 'DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'; - \OC_DB::executeAudited($sql, array($fileId, $user)); - } - } - - public function removeMultiple($fileIds, $user) { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); - foreach ($fileIds as $fileId) { - \OC_DB::executeAudited($query, array($fileId, $user)); - } - } - - /** - * get the list of users which have permissions stored for a file - * - * @param int $fileId - */ - public function getUsers($fileId) { - $sql = 'SELECT `user` FROM `*PREFIX*permissions` WHERE `fileid` = ?'; - $result = \OC_DB::executeAudited($sql, array($fileId)); - $users = array(); - while ($row = $result->fetchRow()) { - $users[] = $row['user']; - } - return $users; - } - - /** - * check if admin removed the share permission for the user and update the permissions - * - * @param int $permissions - * @return int - */ - protected function updatePermissions($permissions) { - if (\OCP\Util::isSharingDisabledForUser()) { - $permissions &= ~\OCP\PERMISSION_SHARE; - } - return $permissions; - } -} diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index b97070fcdf0..965013c5c98 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -40,11 +40,6 @@ class Scanner extends BasicEmitter { protected $cache; /** - * @var \OC\Files\Cache\Permissions $permissionsCache - */ - protected $permissionsCache; - - /** * @var boolean $cacheActive If true, perform cache operations, if false, do not affect cache */ protected $cacheActive; @@ -59,7 +54,6 @@ class Scanner extends BasicEmitter { $this->storage = $storage; $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); - $this->permissionsCache = $storage->getPermissionsCache(); $this->cacheActive = !Config::getSystemValue('filesystem_cache_readonly', false); } @@ -86,6 +80,7 @@ class Scanner extends BasicEmitter { } $data['etag'] = $this->storage->getETag($path); $data['storage_mtime'] = $data['mtime']; + $data['permissions'] = $this->storage->getPermissions($path); return $data; } @@ -117,41 +112,21 @@ class Scanner extends BasicEmitter { $newData = $data; $cacheData = $this->cache->get($file); if ($cacheData) { - if (isset($cacheData['fileid'])) { - $this->permissionsCache->remove($cacheData['fileid']); - } if ($reuseExisting) { // prevent empty etag if (empty($cacheData['etag'])) { $etag = $data['etag']; - $propagateETagChange = true; } else { $etag = $cacheData['etag']; - $propagateETagChange = false; } // only reuse data if the file hasn't explicitly changed if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) { + $data['mtime'] = $cacheData['mtime']; if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) { $data['size'] = $cacheData['size']; } if ($reuseExisting & self::REUSE_ETAG) { $data['etag'] = $etag; - if ($propagateETagChange) { - $parent = $file; - while ($parent !== '') { - $parent = dirname($parent); - if ($parent === '.') { - $parent = ''; - } - $parentCacheData = $this->cache->get($parent); - \OC_Hook::emit('Scanner', 'updateCache', array('file' => $file, 'data' => $data)); - if($this->cacheActive) { - $this->cache->update($parentCacheData['fileid'], array( - 'etag' => $this->storage->getETag($parent), - )); - } - } - } } } // Only update metadata that has changed @@ -166,24 +141,53 @@ class Scanner extends BasicEmitter { } } if (!empty($newData)) { - \OC_Hook::emit('Scanner', 'addToCache', array('file' => $file, 'data' => $newData)); - if($this->cacheActive) { - $data['fileid'] = $this->cache->put($file, $newData); - } + $data['fileid'] = $this->addToCache($file, $newData); $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId)); \OC_Hook::emit('\OC\Files\Cache\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId)); } } else { - \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $file)); - if($this->cacheActive) { - $this->cache->remove($file); - } + $this->removeFromCache($file); } return $data; } return null; } + protected function removeFromCache($path) { + \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $path)); + $this->emit('\OC\Files\Cache\Scanner', 'removeFromCache', array($path)); + if ($this->cacheActive) { + $this->cache->remove($path); + } + } + + /** + * @param string $path + * @param array $data + * @return int the id of the added file + */ + protected function addToCache($path, $data) { + \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data)); + $this->emit('\OC\Files\Cache\Scanner', 'addToCache', array($path, $this->storageId, $data)); + if ($this->cacheActive) { + return $this->cache->put($path, $data); + } else { + return -1; + } + } + + /** + * @param string $path + * @param array $data + */ + protected function updateCache($path, $data) { + \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data)); + $this->emit('\OC\Files\Cache\Scanner', 'updateCache', array($path, $this->storageId, $data)); + if ($this->cacheActive) { + $this->cache->put($path, $data); + } + } + /** * scan a folder and all it's children * @@ -236,18 +240,15 @@ class Scanner extends BasicEmitter { try { $data = $this->scanFile($child, $reuse, true); if ($data) { - if ($data['size'] === -1) { - if ($recursive === self::SCAN_RECURSIVE) { - $childQueue[] = $child; - } else { - $size = -1; - } + if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) { + $childQueue[] = $child; + } else if ($data['size'] === -1) { + $size = -1; } else if ($size !== -1) { $size += $data['size']; } } - } - catch (\Doctrine\DBAL\DBALException $ex){ + } catch (\Doctrine\DBAL\DBALException $ex) { // might happen if inserting duplicate while a scanning // process is running in parallel // log and ignore @@ -260,13 +261,10 @@ class Scanner extends BasicEmitter { $removedChildren = \array_diff($existingChildren, $newChildren); foreach ($removedChildren as $childName) { $child = ($path) ? $path . '/' . $childName : $childName; - \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $child)); - if($this->cacheActive) { - $this->cache->remove($child); - } + $this->removeFromCache($child); } \OC_DB::commit(); - if ($exceptionOccurred){ + if ($exceptionOccurred) { // It might happen that the parallel scan process has already // inserted mimetypes but those weren't available yet inside the transaction // To make sure to have the updated mime types in such cases, @@ -278,15 +276,11 @@ class Scanner extends BasicEmitter { $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse); if ($childSize === -1) { $size = -1; - } else { + } else if ($size !== -1) { $size += $childSize; } } - $newData = array('size' => $size); - \OC_Hook::emit('Scanner', 'addToCache', array('file' => $child, 'data' => $newData)); - if($this->cacheActive) { - $this->cache->put($path, $newData); - } + $this->updateCache($path, array('size' => $size)); } $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId)); return $size; @@ -296,6 +290,7 @@ class Scanner extends BasicEmitter { * check if the file should be ignored when scanning * NOTE: files with a '.part' extension are ignored as well! * prevents unfinished put requests to be scanned + * * @param string $file * @return boolean */ @@ -314,7 +309,7 @@ class Scanner extends BasicEmitter { while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); - if($this->cacheActive) { + if ($this->cacheActive) { $this->cache->correctFolderSize($path); } $lastPath = $path; @@ -323,6 +318,7 @@ class Scanner extends BasicEmitter { /** * Set whether the cache is affected by scan operations + * * @param boolean $active The active state of the cache */ public function setCacheActive($active) { diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php index ad7213d2368..2cc4a2130eb 100644 --- a/lib/private/files/filesystem.php +++ b/lib/private/files/filesystem.php @@ -168,8 +168,8 @@ class Filesystem { /** * @param callable $wrapper */ - public static function addStorageWrapper($wrapper) { - self::getLoader()->addStorageWrapper($wrapper); + public static function addStorageWrapper($wrapperName, $wrapper) { + self::getLoader()->addStorageWrapper($wrapperName, $wrapper); $mounts = self::getMountManager()->getAll(); foreach ($mounts as $mount) { diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php index 1af34fc2be6..3e23f5c2c94 100644 --- a/lib/private/files/node/folder.php +++ b/lib/private/files/node/folder.php @@ -71,13 +71,11 @@ class Folder extends Node implements \OCP\Files\Folder { list($storage, $internalPath) = $this->view->resolvePath($this->path); if ($storage) { $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); //trigger cache update check $this->view->getFileInfo($this->path); $files = $cache->getFolderContents($internalPath); - $permissions = $permissionsCache->getDirectoryPermissions($this->getId(), $this->root->getUser()->getUID()); } else { $files = array(); } @@ -129,9 +127,6 @@ class Folder extends Node implements \OCP\Files\Folder { foreach ($files as $file) { if ($file) { - if (isset($permissions[$file['fileid']])) { - $file['permissions'] = $permissions[$file['fileid']]; - } $node = $this->createNode($this->path . '/' . $file['name'], $file); $result[] = $node; } diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 6b11603323a..4d5a2078ef7 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -301,13 +301,6 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->scanner; } - public function getPermissionsCache($path = '') { - if (!isset($this->permissioncache)) { - $this->permissioncache = new \OC\Files\Cache\Permissions($this); - } - return $this->permissioncache; - } - public function getWatcher($path = '') { if (!isset($this->watcher)) { $this->watcher = new \OC\Files\Cache\Watcher($this); diff --git a/lib/private/files/storage/loader.php b/lib/private/files/storage/loader.php index 966234cb04d..c75a0a976a7 100644 --- a/lib/private/files/storage/loader.php +++ b/lib/private/files/storage/loader.php @@ -21,8 +21,8 @@ class Loader { * * @param callable $callback */ - public function addStorageWrapper($callback) { - $this->storageWrappers[] = $callback; + public function addStorageWrapper($wrapperName, $callback) { + $this->storageWrappers[$wrapperName] = $callback; } /** diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php index 5be90f24756..f085a0590b4 100644 --- a/lib/private/files/storage/storage.php +++ b/lib/private/files/storage/storage.php @@ -41,14 +41,6 @@ interface Storage extends \OCP\Files\Storage { public function getOwner($path); /** - * get a permissions cache instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Permissions - */ - public function getPermissionsCache($path = ''); - - /** * get a watcher instance for the cache * * @param string $path diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php index 364475a68e0..057c31c3cd8 100644 --- a/lib/private/files/storage/wrapper/wrapper.php +++ b/lib/private/files/storage/wrapper/wrapper.php @@ -389,16 +389,6 @@ class Wrapper implements \OC\Files\Storage\Storage { } /** - * get a permissions cache instance for the cache - * - * @param string $path - * @return \OC\Files\Cache\Permissions - */ - public function getPermissionsCache($path = '') { - return $this->storage->getPermissionsCache($path); - } - - /** * get a watcher instance for the cache * * @param string $path diff --git a/lib/private/files/stream/quota.php b/lib/private/files/stream/quota.php index 60e60da8e67..bb4623b1a7b 100644 --- a/lib/private/files/stream/quota.php +++ b/lib/private/files/stream/quota.php @@ -123,7 +123,7 @@ class Quota { } public function stream_lock($mode) { - flock($this->source, $mode); + return flock($this->source, $mode); } public function stream_flush() { diff --git a/lib/private/files/utils/scanner.php b/lib/private/files/utils/scanner.php index a802a8fcb8b..1bb3e694c96 100644 --- a/lib/private/files/utils/scanner.php +++ b/lib/private/files/utils/scanner.php @@ -8,6 +8,8 @@ namespace OC\Files\Utils; +use OC\Files\View; +use OC\Files\Cache\ChangePropagator; use OC\Files\Filesystem; use OC\Hooks\PublicEmitter; @@ -27,10 +29,16 @@ class Scanner extends PublicEmitter { private $user; /** + * @var \OC\Files\Cache\ChangePropagator + */ + protected $propagator; + + /** * @param string $user */ public function __construct($user) { $this->user = $user; + $this->propagator = new ChangePropagator(new View('')); } /** @@ -67,6 +75,15 @@ class Scanner extends PublicEmitter { $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function ($path) use ($mount, $emitter) { $emitter->emit('\OC\Files\Utils\Scanner', 'scanFolder', array($mount->getMountPoint() . $path)); }); + + // propagate etag and mtimes when files are changed or removed + $propagator = $this->propagator; + $propagatorListener = function ($path) use ($mount, $propagator) { + $fullPath = Filesystem::normalizePath($mount->getMountPoint() . $path); + $propagator->addChange($fullPath); + }; + $scanner->listen('\OC\Files\Cache\Scanner', 'addToCache', $propagatorListener); + $scanner->listen('\OC\Files\Cache\Scanner', 'removeFromCache', $propagatorListener); } /** @@ -82,6 +99,7 @@ class Scanner extends PublicEmitter { $this->attachListener($mount); $scanner->backgroundScan(); } + $this->propagator->propagateChanges(time()); } /** @@ -95,8 +113,9 @@ class Scanner extends PublicEmitter { } $scanner = $mount->getStorage()->getScanner(); $this->attachListener($mount); - $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG); + $scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE); } + $this->propagator->propagateChanges(time()); } } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 0b8d336f260..09b100d7cfd 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -807,7 +807,8 @@ class View { * get the filesystem info * * @param string $path - * @param boolean $includeMountPoints whether to add mountpoint sizes, + * @param boolean|string $includeMountPoints true to add mountpoint sizes, + * 'ext' to add only ext storage mount point sizes. Defaults to true. * defaults to true * @return \OC\Files\FileInfo|false */ @@ -826,8 +827,6 @@ class View { $data = null; if ($storage) { $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); - $user = \OC_User::getUser(); if (!$cache->inCache($internalPath)) { if (!$storage->file_exists($internalPath)) { @@ -847,23 +846,21 @@ class View { if ($data and isset($data['fileid'])) { if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder + $extOnly = ($includeMountPoints === 'ext'); $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { + // exclude shared storage ? + if ($extOnly && $subStorage instanceof \OC\Files\Storage\Shared) { + continue; + } $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += isset($rootEntry['size']) ? $rootEntry['size'] : 0; } } } - - $permissions = $permissionsCache->get($data['fileid'], $user); - if ($permissions === -1) { - $permissions = $storage->getPermissions($internalPath); - $permissionsCache->set($data['fileid'], $user, $permissions); - } - $data['permissions'] = $permissions; } } if (!$data) { @@ -896,7 +893,6 @@ class View { list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { $cache = $storage->getCache($internalPath); - $permissionsCache = $storage->getPermissionsCache($internalPath); $user = \OC_User::getUser(); if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { @@ -913,7 +909,6 @@ class View { foreach ($contents as $content) { $files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content); } - $permissions = $permissionsCache->getDirectoryPermissions($folderId, $user); $ids = array(); foreach ($files as $i => $file) { @@ -922,7 +917,6 @@ class View { if (!isset($permissions[$file['fileid']])) { $permissions[$file['fileid']] = $storage->getPermissions($file['path']); - $permissionsCache->set($file['fileid'], $user, $permissions[$file['fileid']]); } $files[$i]['permissions'] = $permissions[$file['fileid']]; } @@ -954,12 +948,7 @@ class View { } else { //mountpoint in this folder, add an entry for it $rootEntry['name'] = $relativePath; $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $subPermissionsCache = $subStorage->getPermissionsCache(''); - $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); - if ($permissions === -1) { - $permissions = $subStorage->getPermissions($rootEntry['path']); - $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); - } + $permissions = $rootEntry['permissions']; // do not allow renaming/deleting the mount point if they are not shared files/folders // for shared files/folders we use the permissions given by the owner if ($subStorage instanceof \OC\Files\Storage\Shared) { diff --git a/lib/private/group/group.php b/lib/private/group/group.php index 3e245ab6bbe..e0a35924854 100644 --- a/lib/private/group/group.php +++ b/lib/private/group/group.php @@ -186,7 +186,7 @@ class Group { * @param string $search * @return int|bool */ - public function count($search) { + public function count($search = '') { $users = false; foreach ($this->backends as $backend) { if($backend->implementsActions(OC_GROUP_BACKEND_COUNT_USERS)) { diff --git a/lib/private/group/metadata.php b/lib/private/group/metadata.php new file mode 100644 index 00000000000..1883ba727e0 --- /dev/null +++ b/lib/private/group/metadata.php @@ -0,0 +1,188 @@ +<?php + +/** + * Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Group; + +class MetaData { + const SORT_NONE = 0; + const SORT_USERCOUNT = 1; + + /** + * @var string $user + */ + protected $user; + + /** + * @var bool $isAdmin + */ + protected $isAdmin; + + /** + * @var string[] $groups + */ + protected $groups = array(); + + /** + * @var \OC\Group\Manager $groupManager + */ + protected $groupManager; + + /** + * @var int $sorting + */ + protected $sorting = false; + + /** + * @var string $lastSearch + */ + protected $lastSearch; + + /** + * @param string the uid of the current user + * @param bool whether the current users is an admin + * @param \OC\Group\Manager + */ + public function __construct( + $user, + $isAdmin, + \OC\Group\Manager $groupManager + ) { + $this->user = $user; + $this->isAdmin = (bool)$isAdmin; + $this->groupManager = $groupManager; + } + + /** + * returns an array with meta data about all available groups + * the array is structured as follows: + * [0] array containing meta data about admin groups + * [1] array containing meta data about unprivileged groups + * @param string only effective when instance was created with isAdmin being + * true + * @return array + */ + public function get($search = '') { + if($this->lastSearch !== $search) { + $this->lastSearch = $search; + $this->groups = array(); + } + + $adminGroups = array(); + $groups = array(); + $sortGroupsIndex = 0; + $sortGroupsKeys = array(); + $sortAdminGroupsIndex = 0; + $sortAdminGroupsKeys = array(); + + foreach($this->getGroups($search) as $group) { + $groupMetaData = $this->generateGroupMetaData($group); + if (strtolower($group->getGID()) !== 'admin') { + $this->addEntry( + $groups, + $sortGroupsKeys, + $sortGroupsIndex, + $groupMetaData); + } else { + //admin group is hard coded to 'admin' for now. In future, + //backends may define admin groups too. Then the if statement + //has to be adjusted accordingly. + $this->addEntry( + $adminGroups, + $sortAdminGroupsKeys, + $sortAdminGroupsIndex, + $groupMetaData); + } + } + + //whether sorting is necessary is will be checked in sort() + $this->sort($groups, $sortGroupsKeys); + $this->sort($adminGroups, $sortAdminGroupsKeys); + + return array($adminGroups, $groups); + } + + /** + * @brief sets the sort mode, currently 0 (none) and 1 (user entries, + * descending) are supported + * @param int the sortMode (SORT_NONE, SORT_USERCOUNT) + */ + public function setSorting($sortMode) { + if($sortMode >= 0 && $sortMode <= 1) { + $this->sorting = $sortMode; + } else { + $this->sorting = 0; + } + } + + /** + * @brief adds an group entry to the resulting array + * @param array the resulting array, by reference + * @param array the sort key array, by reference + * @param array the sort key index, by reference + * @param array the group's meta data as returned by generateGroupMetaData() + * @return null + */ + private function addEntry(&$entries, &$sortKeys, &$sortIndex, $data) { + $entries[] = $data; + if($this->sorting === 1) { + $sortKeys[$sortIndex] = $data['usercount']; + $sortIndex++; + } + } + + /** + * @brief creates an array containing the group meta data + * @param \OC\Group\Group + * @return array with the keys 'id', 'name' and 'usercount' + */ + private function generateGroupMetaData(\OC\Group\Group $group) { + return array( + 'id' => str_replace(' ','', $group->getGID()), + 'name' => $group->getGID(), + 'usercount' => $group->count() + ); + } + + /** + * @brief sorts the result array, if applicable + * @param array the result array, by reference + * @param array the array containing the sort keys + * @param return null + */ + private function sort(&$entries, $sortKeys) { + if($this->sorting > 0) { + array_multisort($sortKeys, SORT_DESC, $entries); + } + } + + /** + * @brief returns the available groups + * @param string a search string + * @return \OC\Group\Group[] + */ + private function getGroups($search = '') { + if(count($this->groups) === 0) { + $this->fetchGroups($search); + } + return $this->groups; + } + + /** + * @brief fetches the group using the group manager or the subAdmin API + * @param string a search string + * @return null + */ + private function fetchGroups($search = '') { + if($this->isAdmin) { + $this->groups = $this->groupManager->search($search); + } else { + $this->groups = \OC_SubAdmin::getSubAdminsGroups($this->user); + } + } +} diff --git a/lib/private/helper.php b/lib/private/helper.php index e9ca036a32c..a054fc485a4 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -936,6 +936,8 @@ class OC_Helper { */ public static function getStorageInfo($path, $rootInfo = null) { // return storage info without adding mount points + $includeExtStorage = \OC_Config::getValue('quota_include_external_storage', false); + if (is_null($rootInfo)) { $rootInfo = \OC\Files\Filesystem::getFileInfo($path, false); } @@ -944,9 +946,21 @@ class OC_Helper { $used = 0; } $quota = 0; - // TODO: need a better way to get total space from storage $storage = $rootInfo->getStorage(); - if ($storage instanceof \OC\Files\Storage\Wrapper\Quota) { + if ($includeExtStorage && $storage->instanceOfStorage('\OC\Files\Storage\Shared')) { + $includeExtStorage = false; + } + if ($includeExtStorage) { + $quota = OC_Util::getUserQuota(\OCP\User::getUser()); + if ($quota !== \OC\Files\SPACE_UNLIMITED) { + // always get free space / total space from root + mount points + $path = ''; + return self::getGlobalStorageInfo(); + } + } + + // TODO: need a better way to get total space from storage + if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) { $quota = $storage->getQuota(); } $free = $storage->free_space(''); @@ -967,4 +981,35 @@ class OC_Helper { return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative); } + + /** + * Get storage info including all mount points and quota + * + * @return array + */ + private static function getGlobalStorageInfo() { + $quota = OC_Util::getUserQuota(\OCP\User::getUser()); + + $rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext'); + $used = $rootInfo['size']; + if ($used < 0) { + $used = 0; + } + + $total = $quota; + $free = $quota - $used; + + if ($total > 0) { + if ($quota > 0 && $total > $quota) { + $total = $quota; + } + // prevent division by zero or error codes (negative values) + $relative = round(($used / $total) * 10000) / 100; + } else { + $relative = 0; + } + + return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative); + + } } diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index 3590bbd436d..08d0b7d5f93 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -28,6 +28,7 @@ class OC_Log_Owncloud { static protected $logFile; + static protected $reqId; /** * Init class data @@ -68,8 +69,20 @@ class OC_Log_Owncloud { $timezone = new DateTimeZone('UTC'); } $time = new DateTime(null, $timezone); - // remove username/passswords from URLs before writing the to the log file - $entry=array('app'=>$app, 'message'=>$message, 'level'=>$level, 'time'=> $time->format($format)); + // remove username/passwords from URLs before writing the to the log file + $time = $time->format($format); + if($minLevel == OC_Log::DEBUG) { + if(empty(self::$reqId)) { + self::$reqId = uniqid(); + } + $reqId = self::$reqId; + $url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '--'; + $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '--'; + $entry = compact('reqId', 'app', 'message', 'level', 'time', 'method', 'url'); + } + else { + $entry = compact('app', 'message', 'level', 'time'); + } $entry = json_encode($entry); $handle = @fopen(self::$logFile, 'a'); @chmod(self::$logFile, 0640); diff --git a/lib/private/request.php b/lib/private/request.php index 09928021a7f..619eae3e9b5 100755 --- a/lib/private/request.php +++ b/lib/private/request.php @@ -184,7 +184,7 @@ class OC_Request { $path_info = $_SERVER['PATH_INFO']; }else{ $path_info = self::getRawPathInfo(); - // following is taken from Sabre_DAV_URLUtil::decodePathSegment + // following is taken from \Sabre\DAV\URLUtil::decodePathSegment $path_info = rawurldecode($path_info); $encoding = mb_detect_encoding($path_info, array('UTF-8', 'ISO-8859-1')); @@ -220,7 +220,7 @@ class OC_Request { $path_info = $requestUri; // strip off the script name's dir and file name - list($path, $name) = \Sabre_DAV_URLUtil::splitPath($scriptName); + list($path, $name) = \Sabre\DAV\URLUtil::splitPath($scriptName); if (!empty($path)) { if( $path === $path_info || strpos($path_info, $path.'/') === 0) { $path_info = substr($path_info, strlen($path)); diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 46796c26370..189be2363ea 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1744,10 +1744,10 @@ class Share extends \OC\Share\Constants { if (isset($uidOwner)) { if ($fileDependent) { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,' - . ' `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`,' + . ' `share_type`, `share_with`, `file_source`, `path`, `*PREFIX*share`.`permissions`, `stime`,' . ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`'; } else { - $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`,' + $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,' . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`'; } } else { @@ -1755,12 +1755,12 @@ class Share extends \OC\Share\Constants { if ($format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, ' . '`share_type`, `share_with`, `file_source`, `path`, `file_target`, `stime`, ' - . '`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' + . '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' . '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, - `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`'; + `file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`'; } } } diff --git a/lib/private/updater.php b/lib/private/updater.php index 58d3cab73aa..106970c4121 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -125,29 +125,63 @@ class Updater extends BasicEmitter { * STOP CONFIG CHANGES FOR OLDER VERSIONS */ + $canUpgrade = false; + // simulate DB upgrade try { - \OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); - $this->emit('\OC\Updater', 'dbUpgrade'); - + // simulate core DB upgrade + \OC_DB::simulateUpdateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); + + // simulate apps DB upgrade + $version = \OC_Util::getVersion(); + $apps = \OC_App::getEnabledApps(); + foreach ($apps as $appId) { + $info = \OC_App::getAppInfo($appId); + if (\OC_App::isAppCompatible($version, $info) && \OC_App::shouldUpgrade($appId)) { + if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) { + \OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml'); + } + } + } + + $this->emit('\OC\Updater', 'dbSimulateUpgrade'); + + $canUpgrade = true; } catch (\Exception $exception) { $this->emit('\OC\Updater', 'failure', array($exception->getMessage())); } - \OC_Config::setValue('version', implode('.', \OC_Util::getVersion())); - $disabledApps = \OC_App::checkAppsRequirements(); - if (!empty($disabledApps)) { - $this->emit('\OC\Updater', 'disabledApps', array($disabledApps)); - } - // load all apps to also upgrade enabled apps - \OC_App::loadApps(); - $repair = new Repair(); - $repair->run(); + if ($canUpgrade) { + // proceed with real upgrade + try { + // do the real upgrade + \OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); + $this->emit('\OC\Updater', 'dbUpgrade'); + + } catch (\Exception $exception) { + $this->emit('\OC\Updater', 'failure', array($exception->getMessage())); + return false; + } + // TODO: why not do this at the end ? + \OC_Config::setValue('version', implode('.', \OC_Util::getVersion())); + $disabledApps = \OC_App::checkAppsRequirements(); + if (!empty($disabledApps)) { + $this->emit('\OC\Updater', 'disabledApps', array($disabledApps)); + } + // load all apps to also upgrade enabled apps + \OC_App::loadApps(); + + $repair = new Repair(); + $repair->run(); + + //Invalidate update feed + \OC_Appconfig::setValue('core', 'lastupdatedat', 0); + } - //Invalidate update feed - \OC_Appconfig::setValue('core', 'lastupdatedat', 0); \OC_Config::setValue('maintenance', false); $this->emit('\OC\Updater', 'maintenanceEnd'); + + return $canUpgrade; } } diff --git a/lib/private/user.php b/lib/private/user.php index 5d3ebb57c8c..a8431af97fd 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -365,7 +365,7 @@ class OC_User { return $backend->getLogoutAttribute(); } - return 'href="' . link_to('', 'index.php') . '?logout=true"'; + return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . OC_Util::callRegister() . '"'; } /** diff --git a/lib/private/util.php b/lib/private/util.php index 306e37b9478..0daef78ce7f 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -53,7 +53,7 @@ class OC_Util { //if we aren't logged in, there is no use to set up the filesystem if( $user != "" ) { - \OC\Files\Filesystem::addStorageWrapper(function($mountPoint, $storage){ + \OC\Files\Filesystem::addStorageWrapper('oc_quota', function($mountPoint, $storage){ // set up quota for home storages, even for other users // which can happen when using sharing @@ -973,7 +973,7 @@ class OC_Util { try { // test PROPFIND $client->propfind('', array('{DAV:}resourcetype')); - } catch (\Sabre_DAV_Exception_NotAuthenticated $e) { + } catch (\Sabre\DAV\Exception\NotAuthenticated $e) { $return = true; } catch (\Exception $e) { OC_Log::write('core', 'isWebDAVWorking: NO - Reason: '.$e->getMessage(). ' ('.get_class($e).')', OC_Log::WARN); diff --git a/lib/public/appframework/controller.php b/lib/public/appframework/controller.php index 50b5ed3a80d..96ab5e75e82 100644 --- a/lib/public/appframework/controller.php +++ b/lib/public/appframework/controller.php @@ -57,14 +57,6 @@ abstract class Controller { * constructor of the controller * @param string $appName the name of the app * @param IRequest $request an instance of the request - * @param string $corsMethods: comma seperated string of HTTP verbs which - * should be allowed for websites or webapps when calling your API, defaults to - * 'PUT, POST, GET, DELETE, PATCH' - * @param string $corsAllowedHeaders: comma seperated string of HTTP headers - * which should be allowed for websites or webapps when calling your API, - * defaults to 'Authorization, Content-Type, Accept' - * @param int $corsMaxAge number in seconds how long a preflighted OPTIONS - * request should be cached, defaults to 1728000 seconds */ public function __construct($appName, IRequest $request){ @@ -146,7 +138,7 @@ abstract class Controller { /** * Returns all params that were received, be it from the request - * (as GET or POST) or throuh the URL by the route + * (as GET or POST) or through the URL by the route * @deprecated use $this->request instead * @return array the array with all parameters */ diff --git a/lib/public/config.php b/lib/public/config.php index 8e3791b449b..ea3e0c1372a 100644 --- a/lib/public/config.php +++ b/lib/public/config.php @@ -71,6 +71,16 @@ class Config { } /** + * Deletes a value from config.php + * @param string $key key + * + * This function deletes the value from config.php. + */ + public static function deleteSystemValue( $key ) { + return \OC_Config::deleteKey( $key ); + } + + /** * Gets the config value * @param string $app app * @param string $key key diff --git a/lib/public/files/locknotacquiredexception.php b/lib/public/files/locknotacquiredexception.php new file mode 100644 index 00000000000..9fb70e7cbe2 --- /dev/null +++ b/lib/public/files/locknotacquiredexception.php @@ -0,0 +1,47 @@ +<?php +/** + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * Public interface of ownCloud for apps to use. + * Files/LockNotAcquiredException class + */ + +// use OCP namespace for all classes that are considered public. +// This means that they should be used by apps instead of the internal ownCloud classes +namespace OCP\Files; + +/** + * Exception for a file that is locked + */ +class LockNotAcquiredException extends \Exception { + /** @var string $path The path that could not be locked */ + public $path; + + /** @var integer $lockType The type of the lock that was attempted */ + public $lockType; + + public function __construct($path, $lockType, $code = 0, \Exception $previous = null) { + $message = \OC_L10N::get('core')->t('Could not obtain lock type %d on "%s".', array($lockType, $path)); + parent::__construct($message, $code, $previous); + } + + // custom string representation of object + public function __toString() { + return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; + } +}
\ No newline at end of file |