diff options
Diffstat (limited to 'lib')
87 files changed, 1291 insertions, 838 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php index efab84b44f9..eca326ffc14 100644 --- a/lib/autoloader.php +++ b/lib/autoloader.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -63,7 +64,7 @@ class Autoloader { * * @param string $root */ - public function addValidRoot($root) { + public function addValidRoot(string $root) { $root = stream_resolve_include_path($root); $this->validRoots[$root] = true; } @@ -86,12 +87,12 @@ class Autoloader { * get the possible paths for a class * * @param string $class - * @return array|bool an array of possible paths or false if the class is not part of ownCloud + * @return array an array of possible paths */ - public function findClass($class) { + public function findClass(string $class): array { $class = trim($class, '\\'); - $paths = array(); + $paths = []; if ($this->useGlobalClassPath && array_key_exists($class, \OC::$CLASSPATH)) { $paths[] = \OC::$CLASSPATH[$class]; /** @@ -124,8 +125,9 @@ class Autoloader { /** * @param string $fullPath * @return bool + * @throws AutoloadNotAllowedException */ - protected function isValidPath($fullPath) { + protected function isValidPath(string $fullPath): bool { foreach ($this->validRoots as $root => $true) { if (substr($fullPath, 0, strlen($root) + 1) === $root . '/') { return true; @@ -139,8 +141,9 @@ class Autoloader { * * @param string $class * @return bool + * @throws AutoloadNotAllowedException */ - public function load($class) { + public function load(string $class): bool { $pathsToRequire = null; if ($this->memoryCache) { $pathsToRequire = $this->memoryCache->get($class); diff --git a/lib/base.php b/lib/base.php index 05da2814d4c..c5eabe1910a 100644 --- a/lib/base.php +++ b/lib/base.php @@ -373,6 +373,7 @@ class OC { // get third party apps $ocVersion = \OCP\Util::getVersion(); + $ocVersion = implode('.', $ocVersion); $incompatibleApps = $appManager->getIncompatibleApps($ocVersion); $incompatibleShippedApps = []; foreach ($incompatibleApps as $appInfo) { diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 3eb532be0c6..b3158ac7e04 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -521,6 +521,7 @@ return array( 'OC\\Core\\Controller\\JsController' => $baseDir . '/core/Controller/JsController.php', 'OC\\Core\\Controller\\LoginController' => $baseDir . '/core/Controller/LoginController.php', 'OC\\Core\\Controller\\LostController' => $baseDir . '/core/Controller/LostController.php', + 'OC\\Core\\Controller\\NavigationController' => $baseDir . '/core/Controller/NavigationController.php', 'OC\\Core\\Controller\\OCJSController' => $baseDir . '/core/Controller/OCJSController.php', 'OC\\Core\\Controller\\OCSController' => $baseDir . '/core/Controller/OCSController.php', 'OC\\Core\\Controller\\PreviewController' => $baseDir . '/core/Controller/PreviewController.php', @@ -652,6 +653,7 @@ return array( 'OC\\Files\\ObjectStore\\S3Signature' => $baseDir . '/lib/private/Files/ObjectStore/S3Signature.php', 'OC\\Files\\ObjectStore\\StorageObjectStore' => $baseDir . '/lib/private/Files/ObjectStore/StorageObjectStore.php', 'OC\\Files\\ObjectStore\\Swift' => $baseDir . '/lib/private/Files/ObjectStore/Swift.php', + 'OC\\Files\\ObjectStore\\SwiftFactory' => $baseDir . '/lib/private/Files/ObjectStore/SwiftFactory.php', 'OC\\Files\\Search\\SearchBinaryOperator' => $baseDir . '/lib/private/Files/Search/SearchBinaryOperator.php', 'OC\\Files\\Search\\SearchComparison' => $baseDir . '/lib/private/Files/Search/SearchComparison.php', 'OC\\Files\\Search\\SearchOrder' => $baseDir . '/lib/private/Files/Search/SearchOrder.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 2483b5689b3..65b36cc489e 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -551,6 +551,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Core\\Controller\\JsController' => __DIR__ . '/../../..' . '/core/Controller/JsController.php', 'OC\\Core\\Controller\\LoginController' => __DIR__ . '/../../..' . '/core/Controller/LoginController.php', 'OC\\Core\\Controller\\LostController' => __DIR__ . '/../../..' . '/core/Controller/LostController.php', + 'OC\\Core\\Controller\\NavigationController' => __DIR__ . '/../../..' . '/core/Controller/NavigationController.php', 'OC\\Core\\Controller\\OCJSController' => __DIR__ . '/../../..' . '/core/Controller/OCJSController.php', 'OC\\Core\\Controller\\OCSController' => __DIR__ . '/../../..' . '/core/Controller/OCSController.php', 'OC\\Core\\Controller\\PreviewController' => __DIR__ . '/../../..' . '/core/Controller/PreviewController.php', @@ -682,6 +683,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Files\\ObjectStore\\S3Signature' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3Signature.php', 'OC\\Files\\ObjectStore\\StorageObjectStore' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/StorageObjectStore.php', 'OC\\Files\\ObjectStore\\Swift' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Swift.php', + 'OC\\Files\\ObjectStore\\SwiftFactory' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/SwiftFactory.php', 'OC\\Files\\Search\\SearchBinaryOperator' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchBinaryOperator.php', 'OC\\Files\\Search\\SearchComparison' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchComparison.php', 'OC\\Files\\Search\\SearchOrder' => __DIR__ . '/../../..' . '/lib/private/Files/Search/SearchOrder.php', diff --git a/lib/l10n/ar.js b/lib/l10n/ar.js index d5c3652f6d0..1cfe6fa1ce2 100644 --- a/lib/l10n/ar.js +++ b/lib/l10n/ar.js @@ -21,23 +21,41 @@ OC.L10N.register( "The library %s is not available." : "مكتبة %s غير متوفرة.", "Unknown filetype" : "نوع الملف غير معروف", "Invalid image" : "الصورة غير صالحة", + "Avatar image is not square" : "الصورة الرمزية ليست على شكل مربّع", "today" : "اليوم", + "tomorrow" : "غدًا", "yesterday" : "يوم أمس", "_%n day ago_::_%n days ago_" : ["قبل ساعات","قبل يوم","قبل يومين","قبل %n يوماً","قبل %n يوماً","قبل %n يوماً"], + "next month" : "الشهر القادم", "last month" : "الشهر الماضي", "_%n month ago_::_%n months ago_" : ["قبل عدة أيام","قبل شهر","قبل شهرين","قبل %n شهراً","قبل %n شهراً","قبل %n شهراً"], + "next year" : "العام القادم", "last year" : "السنةالماضية", + "in a few seconds" : "خلال بضع ثواني", "seconds ago" : "منذ ثواني", "File name is a reserved word" : "اسم الملف كلمة محجوزة", "File name contains at least one invalid character" : "اسم الملف به ، على الأقل ، حرف غير صالح", "File name is too long" : "اسم الملف طويل جداً", "Empty filename is not allowed" : "لا يسمح بأسماء فارغة للملفات", + "Help" : "المساعدة", "Apps" : "التطبيقات", + "Settings" : "الإعدادات", + "Log out" : "الخروج", "Users" : "المستخدمين", "Unknown user" : "المستخدم غير معروف", "Basic settings" : "الإعدادات الأساسية", + "Sharing" : "المشاركة", + "Security" : "الأمان", + "Encryption" : "التعمية", "Additional settings" : "الإعدادات المتقدمة", + "Tips & tricks" : "نصائح و تلميحات", + "Personal info" : "المعلومات الشخصية", + "Sync clients" : "مزامنة العملاء", + "Unlimited" : "غير محدود", "__language_name__" : "اللغة العربية", + "Verifying" : "التحقق", + "Verifying …" : "عملية التحقق جارية …", + "Verify" : "التحقق", "%s enter the database username and name." : "%s أدخِل اسم قاعدة البيانات واسم مستخدمها.", "%s enter the database username." : "%s ادخل اسم المستخدم الخاص بقاعدة البيانات.", "%s enter the database name." : "%s ادخل اسم فاعدة البيانات", @@ -58,13 +76,67 @@ OC.L10N.register( "Sharing %s failed, because the user %s does not exist" : "فشلت مشاركة %s لأن المستخدم %s غير موجود", "Share type %s is not valid for %s" : "مشاركة النوع %s غير صالحة لـ %s", "%s shared »%s« with you" : "%s شارك »%s« معك", + "Click the button below to open it." : "أنقر على الزر أدناه لفتحه.", "%s via %s" : "%s عبر %s", "Could not find category \"%s\"" : "تعذر العثور على المجلد \"%s\"", + "Sunday" : "الأحد", + "Monday" : "الإثنين", + "Tuesday" : "الثلاثاء", + "Wednesday" : "الأربعاء", + "Thursday" : "الخميس", + "Friday" : "الجمعة", + "Saturday" : "السبت", + "Sun." : "أح.", + "Mon." : "إث.", + "Tue." : "ثلا.", + "Wed." : "أر.", + "Thu." : "خم.", + "Fri." : "جم.", + "Sat." : "سب.", + "Su" : "أح", + "Mo" : "إث", + "Tu" : "ثلا", + "We" : "أر", + "Th" : "خم", + "Fr" : "جم", + "Sa" : "سب", + "January" : "جانفي", + "February" : "فيفري", + "March" : "مارس", + "April" : "أفريل", + "May" : "ماي", + "June" : "جوان", + "July" : "جويلية", + "August" : "أوت", + "September" : "سبتمبر", + "October" : "أكتوبر", + "November" : "نوفمبر", + "December" : "ديسمبر", + "Jan." : "جان.", + "Feb." : "فيف.", + "Mar." : "مار.", + "Apr." : "أفر.", + "May." : "ماي", + "Jun." : "جوا.", + "Jul." : "جوي.", + "Aug." : "أوت", + "Sep." : "سبت.", + "Oct." : "أكت.", + "Nov." : "نوف.", + "Dec." : "ديس.", "A valid username must be provided" : "يجب ادخال اسم مستخدم صحيح", + "Username contains whitespace at the beginning or at the end" : "إنّ إسم المستخدم يحتوي على مسافة بيضاء سواءا في البداية أو النهاية", "A valid password must be provided" : "يجب ادخال كلمة مرور صحيحة", + "Could not create user" : "لا يمكن إنشاء المستخدم", + "User disabled" : "المستخدم معطّل", + "Login canceled by app" : "تم إلغاء الدخول مِن طرف التطبيق", "a safe home for all your data" : "المكان الآمن لجميع بياناتك", + "File is currently busy, please try again later" : "إنّ الملف مشغول الآمن، يرجى إعادة المحاولة لاحقًا", + "Can't read file" : "لا يمكن قراءة الملف", "Application is not enabled" : "التطبيق غير مفعّل", "Authentication error" : "لم يتم التأكد من الشخصية بنجاح", - "Token expired. Please reload page." : "انتهت صلاحية الكلمة , يرجى اعادة تحميل الصفحة" + "Token expired. Please reload page." : "انتهت صلاحية الكلمة , يرجى اعادة تحميل الصفحة", + "Personal" : "الحساب الشخصي", + "Admin" : "المدير" }, "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"); diff --git a/lib/l10n/ar.json b/lib/l10n/ar.json index 7c8b3f37ac1..386a516e0a6 100644 --- a/lib/l10n/ar.json +++ b/lib/l10n/ar.json @@ -19,23 +19,41 @@ "The library %s is not available." : "مكتبة %s غير متوفرة.", "Unknown filetype" : "نوع الملف غير معروف", "Invalid image" : "الصورة غير صالحة", + "Avatar image is not square" : "الصورة الرمزية ليست على شكل مربّع", "today" : "اليوم", + "tomorrow" : "غدًا", "yesterday" : "يوم أمس", "_%n day ago_::_%n days ago_" : ["قبل ساعات","قبل يوم","قبل يومين","قبل %n يوماً","قبل %n يوماً","قبل %n يوماً"], + "next month" : "الشهر القادم", "last month" : "الشهر الماضي", "_%n month ago_::_%n months ago_" : ["قبل عدة أيام","قبل شهر","قبل شهرين","قبل %n شهراً","قبل %n شهراً","قبل %n شهراً"], + "next year" : "العام القادم", "last year" : "السنةالماضية", + "in a few seconds" : "خلال بضع ثواني", "seconds ago" : "منذ ثواني", "File name is a reserved word" : "اسم الملف كلمة محجوزة", "File name contains at least one invalid character" : "اسم الملف به ، على الأقل ، حرف غير صالح", "File name is too long" : "اسم الملف طويل جداً", "Empty filename is not allowed" : "لا يسمح بأسماء فارغة للملفات", + "Help" : "المساعدة", "Apps" : "التطبيقات", + "Settings" : "الإعدادات", + "Log out" : "الخروج", "Users" : "المستخدمين", "Unknown user" : "المستخدم غير معروف", "Basic settings" : "الإعدادات الأساسية", + "Sharing" : "المشاركة", + "Security" : "الأمان", + "Encryption" : "التعمية", "Additional settings" : "الإعدادات المتقدمة", + "Tips & tricks" : "نصائح و تلميحات", + "Personal info" : "المعلومات الشخصية", + "Sync clients" : "مزامنة العملاء", + "Unlimited" : "غير محدود", "__language_name__" : "اللغة العربية", + "Verifying" : "التحقق", + "Verifying …" : "عملية التحقق جارية …", + "Verify" : "التحقق", "%s enter the database username and name." : "%s أدخِل اسم قاعدة البيانات واسم مستخدمها.", "%s enter the database username." : "%s ادخل اسم المستخدم الخاص بقاعدة البيانات.", "%s enter the database name." : "%s ادخل اسم فاعدة البيانات", @@ -56,13 +74,67 @@ "Sharing %s failed, because the user %s does not exist" : "فشلت مشاركة %s لأن المستخدم %s غير موجود", "Share type %s is not valid for %s" : "مشاركة النوع %s غير صالحة لـ %s", "%s shared »%s« with you" : "%s شارك »%s« معك", + "Click the button below to open it." : "أنقر على الزر أدناه لفتحه.", "%s via %s" : "%s عبر %s", "Could not find category \"%s\"" : "تعذر العثور على المجلد \"%s\"", + "Sunday" : "الأحد", + "Monday" : "الإثنين", + "Tuesday" : "الثلاثاء", + "Wednesday" : "الأربعاء", + "Thursday" : "الخميس", + "Friday" : "الجمعة", + "Saturday" : "السبت", + "Sun." : "أح.", + "Mon." : "إث.", + "Tue." : "ثلا.", + "Wed." : "أر.", + "Thu." : "خم.", + "Fri." : "جم.", + "Sat." : "سب.", + "Su" : "أح", + "Mo" : "إث", + "Tu" : "ثلا", + "We" : "أر", + "Th" : "خم", + "Fr" : "جم", + "Sa" : "سب", + "January" : "جانفي", + "February" : "فيفري", + "March" : "مارس", + "April" : "أفريل", + "May" : "ماي", + "June" : "جوان", + "July" : "جويلية", + "August" : "أوت", + "September" : "سبتمبر", + "October" : "أكتوبر", + "November" : "نوفمبر", + "December" : "ديسمبر", + "Jan." : "جان.", + "Feb." : "فيف.", + "Mar." : "مار.", + "Apr." : "أفر.", + "May." : "ماي", + "Jun." : "جوا.", + "Jul." : "جوي.", + "Aug." : "أوت", + "Sep." : "سبت.", + "Oct." : "أكت.", + "Nov." : "نوف.", + "Dec." : "ديس.", "A valid username must be provided" : "يجب ادخال اسم مستخدم صحيح", + "Username contains whitespace at the beginning or at the end" : "إنّ إسم المستخدم يحتوي على مسافة بيضاء سواءا في البداية أو النهاية", "A valid password must be provided" : "يجب ادخال كلمة مرور صحيحة", + "Could not create user" : "لا يمكن إنشاء المستخدم", + "User disabled" : "المستخدم معطّل", + "Login canceled by app" : "تم إلغاء الدخول مِن طرف التطبيق", "a safe home for all your data" : "المكان الآمن لجميع بياناتك", + "File is currently busy, please try again later" : "إنّ الملف مشغول الآمن، يرجى إعادة المحاولة لاحقًا", + "Can't read file" : "لا يمكن قراءة الملف", "Application is not enabled" : "التطبيق غير مفعّل", "Authentication error" : "لم يتم التأكد من الشخصية بنجاح", - "Token expired. Please reload page." : "انتهت صلاحية الكلمة , يرجى اعادة تحميل الصفحة" + "Token expired. Please reload page." : "انتهت صلاحية الكلمة , يرجى اعادة تحميل الصفحة", + "Personal" : "الحساب الشخصي", + "Admin" : "المدير" },"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;" }
\ No newline at end of file diff --git a/lib/l10n/ast.js b/lib/l10n/ast.js index 73955dbdb93..3d9a5084ab9 100644 --- a/lib/l10n/ast.js +++ b/lib/l10n/ast.js @@ -25,6 +25,7 @@ OC.L10N.register( "Invalid image" : "Imaxe inválida", "Avatar image is not square" : "La imaxe del avatar nun ye cuadrada", "today" : "güei", + "tomorrow" : "mañana", "yesterday" : "ayeri", "_%n day ago_::_%n days ago_" : ["hai %n día","hai %n díes"], "last month" : "mes caberu", diff --git a/lib/l10n/ast.json b/lib/l10n/ast.json index 3e0047ee423..a52d3721b34 100644 --- a/lib/l10n/ast.json +++ b/lib/l10n/ast.json @@ -23,6 +23,7 @@ "Invalid image" : "Imaxe inválida", "Avatar image is not square" : "La imaxe del avatar nun ye cuadrada", "today" : "güei", + "tomorrow" : "mañana", "yesterday" : "ayeri", "_%n day ago_::_%n days ago_" : ["hai %n día","hai %n díes"], "last month" : "mes caberu", diff --git a/lib/l10n/es.js b/lib/l10n/es.js index b411012a627..a0f23e34d2c 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -75,18 +75,18 @@ OC.L10N.register( "Personal info" : "Información personal", "Sync clients" : "Clientes de sincronización", "Unlimited" : "Ilimitado", - "__language_name__" : "Español", + "__language_name__" : "Castellano", "Verifying" : "Verificando", "Verifying …" : "Verificando...", "Verify" : "Verificar", "%s enter the database username and name." : "%s introduzca el nombre de usuario y la contraseña de la BBDD.", - "%s enter the database username." : "%s ingresar el usuario de la base de datos.", - "%s enter the database name." : "%s ingresar el nombre de la base de datos", + "%s enter the database username." : "%s introduzca el usuario de la base de datos.", + "%s enter the database name." : "%s introduzca el nombre de la base de datos", "%s you may not use dots in the database name" : "%s puede utilizar puntos en el nombre de la base de datos", "Oracle connection could not be established" : "No se pudo establecer la conexión a Oracle", "Oracle username and/or password not valid" : "Usuario y/o contraseña de Oracle no válidos", "PostgreSQL username and/or password not valid" : "Usuario y/o contraseña de PostgreSQL no válidos", - "You need to enter details of an existing account." : "Necesita ingresar detalles de una cuenta existente.", + "You need to enter details of an existing account." : "Tienes que introducir los datos de una cuenta existente.", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X no está soportado y %s no funcionará bien en esta plataforma. ¡Úsela bajo su propio riesgo! ", "For the best results, please consider using a GNU/Linux server instead." : "Para obtener los mejores resultados, considera utilizar un servidor GNU/Linux.", "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Parece que esta instancia %s está funcionando en un entorno PHP de 32-bits y el open_basedir se ha configurado en php.ini. Esto acarreará problemas con arhivos de tamaño superior a 4GB y resulta totalmente desaconsejado.", diff --git a/lib/l10n/es.json b/lib/l10n/es.json index 0607da188b6..ec5252d028f 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -73,18 +73,18 @@ "Personal info" : "Información personal", "Sync clients" : "Clientes de sincronización", "Unlimited" : "Ilimitado", - "__language_name__" : "Español", + "__language_name__" : "Castellano", "Verifying" : "Verificando", "Verifying …" : "Verificando...", "Verify" : "Verificar", "%s enter the database username and name." : "%s introduzca el nombre de usuario y la contraseña de la BBDD.", - "%s enter the database username." : "%s ingresar el usuario de la base de datos.", - "%s enter the database name." : "%s ingresar el nombre de la base de datos", + "%s enter the database username." : "%s introduzca el usuario de la base de datos.", + "%s enter the database name." : "%s introduzca el nombre de la base de datos", "%s you may not use dots in the database name" : "%s puede utilizar puntos en el nombre de la base de datos", "Oracle connection could not be established" : "No se pudo establecer la conexión a Oracle", "Oracle username and/or password not valid" : "Usuario y/o contraseña de Oracle no válidos", "PostgreSQL username and/or password not valid" : "Usuario y/o contraseña de PostgreSQL no válidos", - "You need to enter details of an existing account." : "Necesita ingresar detalles de una cuenta existente.", + "You need to enter details of an existing account." : "Tienes que introducir los datos de una cuenta existente.", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X no está soportado y %s no funcionará bien en esta plataforma. ¡Úsela bajo su propio riesgo! ", "For the best results, please consider using a GNU/Linux server instead." : "Para obtener los mejores resultados, considera utilizar un servidor GNU/Linux.", "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Parece que esta instancia %s está funcionando en un entorno PHP de 32-bits y el open_basedir se ha configurado en php.ini. Esto acarreará problemas con arhivos de tamaño superior a 4GB y resulta totalmente desaconsejado.", diff --git a/lib/l10n/lt_LT.js b/lib/l10n/lt_LT.js index bb8c53361f9..41c0e32e0a6 100644 --- a/lib/l10n/lt_LT.js +++ b/lib/l10n/lt_LT.js @@ -72,6 +72,7 @@ OC.L10N.register( "PostgreSQL username and/or password not valid" : "Neteisingas PostgreSQL naudotojo vardas ir/arba slaptažodis", "You need to enter details of an existing account." : "Jūs turite suvesti egzistuojančios paskyros duomenis.", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X nėra palaikomas, %s neveiks tinkamai šioje platformoje. Naudodami prisiimate visą riziką !", + "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Pašalinkite savo php.ini faile open_basedir nustatymą arba persijunkite į 64-bitų PHP.", "Set an admin username." : "Nustatyti administratoriaus naudotojo vardą.", "Set an admin password." : "Nustatyti administratoriaus slaptažodį.", "Can't create or write into the data directory %s" : "Negalima nuskaityti arba rašyti į duomenų katalogą. %s", @@ -198,6 +199,11 @@ OC.L10N.register( "Storage incomplete configuration. %s" : "Nepilna saugyklos konfigūracija. %s", "Storage connection error. %s" : "Saugyklos sujungimo ryšio klaida. %s", "Storage is temporarily not available" : "Saugykla yra laikinai neprieinama", - "Storage connection timeout. %s" : "Sujungimo su saugykla laikas baigėsi. %s" + "Storage connection timeout. %s" : "Sujungimo su saugykla laikas baigėsi. %s", + "DB Error: \"%s\"" : "DB klaida: \"%s\"", + "Files can't be shared with delete permissions" : "Failai negali būti bendrinami su ištrynimo leidimais", + "Files can't be shared with create permissions" : "Failai negali būti bendrinami su sukūrimo leidimais", + "No app name specified" : "Nenurodytas programėlės pavadinimas", + "App '%s' could not be installed!" : "Nepavyko įdiegti \"%s\" programėlės!" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/lib/l10n/lt_LT.json b/lib/l10n/lt_LT.json index 5548e6ceebe..34fbc073acf 100644 --- a/lib/l10n/lt_LT.json +++ b/lib/l10n/lt_LT.json @@ -70,6 +70,7 @@ "PostgreSQL username and/or password not valid" : "Neteisingas PostgreSQL naudotojo vardas ir/arba slaptažodis", "You need to enter details of an existing account." : "Jūs turite suvesti egzistuojančios paskyros duomenis.", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X nėra palaikomas, %s neveiks tinkamai šioje platformoje. Naudodami prisiimate visą riziką !", + "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Pašalinkite savo php.ini faile open_basedir nustatymą arba persijunkite į 64-bitų PHP.", "Set an admin username." : "Nustatyti administratoriaus naudotojo vardą.", "Set an admin password." : "Nustatyti administratoriaus slaptažodį.", "Can't create or write into the data directory %s" : "Negalima nuskaityti arba rašyti į duomenų katalogą. %s", @@ -196,6 +197,11 @@ "Storage incomplete configuration. %s" : "Nepilna saugyklos konfigūracija. %s", "Storage connection error. %s" : "Saugyklos sujungimo ryšio klaida. %s", "Storage is temporarily not available" : "Saugykla yra laikinai neprieinama", - "Storage connection timeout. %s" : "Sujungimo su saugykla laikas baigėsi. %s" + "Storage connection timeout. %s" : "Sujungimo su saugykla laikas baigėsi. %s", + "DB Error: \"%s\"" : "DB klaida: \"%s\"", + "Files can't be shared with delete permissions" : "Failai negali būti bendrinami su ištrynimo leidimais", + "Files can't be shared with create permissions" : "Failai negali būti bendrinami su sukūrimo leidimais", + "No app name specified" : "Nenurodytas programėlės pavadinimas", + "App '%s' could not be installed!" : "Nepavyko įdiegti \"%s\" programėlės!" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file diff --git a/lib/l10n/lv.js b/lib/l10n/lv.js index b3d655e3769..54d625af61c 100644 --- a/lib/l10n/lv.js +++ b/lib/l10n/lv.js @@ -4,7 +4,7 @@ OC.L10N.register( "Cannot write into \"config\" directory!" : "Nevar rakstīt \"config\" mapē!", "This can usually be fixed by giving the webserver write access to the config directory" : "To parasti var labot, dodot tīmekļa servera rakstīšanas piekļuvi config direktorijai", "See %s" : "Skatīt %s", - "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Faili no programmas %$1s netika aizvietoti pareizi. Pārliecinieties, vai tā ir versija, kas ir saderīga ar serveri.", + "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Datnes no programmas %$1s netika aizvietotas pareizi. Pārliecinieties, vai tā ir versija, kas ir saderīga ar serveri.", "Sample configuration detected" : "Atrasta konfigurācijas paraugs", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Konstatēts, ka paraug konfigurācija ir nokopēta. Tas var izjaukt jūsu instalāciju un nav atbalstīts. Lūdzu, izlasiet dokumentāciju, pirms veicat izmaiņas config.php", "%1$s and %2$s" : "%1$s un %2$s", diff --git a/lib/l10n/lv.json b/lib/l10n/lv.json index 33956326c84..7a549f53c4f 100644 --- a/lib/l10n/lv.json +++ b/lib/l10n/lv.json @@ -2,7 +2,7 @@ "Cannot write into \"config\" directory!" : "Nevar rakstīt \"config\" mapē!", "This can usually be fixed by giving the webserver write access to the config directory" : "To parasti var labot, dodot tīmekļa servera rakstīšanas piekļuvi config direktorijai", "See %s" : "Skatīt %s", - "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Faili no programmas %$1s netika aizvietoti pareizi. Pārliecinieties, vai tā ir versija, kas ir saderīga ar serveri.", + "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Datnes no programmas %$1s netika aizvietotas pareizi. Pārliecinieties, vai tā ir versija, kas ir saderīga ar serveri.", "Sample configuration detected" : "Atrasta konfigurācijas paraugs", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Konstatēts, ka paraug konfigurācija ir nokopēta. Tas var izjaukt jūsu instalāciju un nav atbalstīts. Lūdzu, izlasiet dokumentāciju, pirms veicat izmaiņas config.php", "%1$s and %2$s" : "%1$s un %2$s", diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js index 393927174da..a13c99f77d8 100644 --- a/lib/l10n/nl.js +++ b/lib/l10n/nl.js @@ -230,6 +230,10 @@ OC.L10N.register( "Storage connection timeout. %s" : "Opslag verbinding time-out. %s", "Personal" : "Persoonlijk", "Admin" : "Beheerder", - "DB Error: \"%s\"" : "DB Fout: \"%s\"" + "DB Error: \"%s\"" : "DB Fout: \"%s\"", + "Files can't be shared with delete permissions" : "Bestanden kunnen niet gedeeld worden met 'verwijder' rechten", + "Files can't be shared with create permissions" : "Bestanden kunnen niet gedeeld worden met 'creëer' rechten", + "No app name specified" : "Geen app naam gespecificeerd", + "App '%s' could not be installed!" : "App '%s' kon niet geïnstalleerd worden!" }, "nplurals=2; plural=(n != 1);"); diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json index c3c8f6cf072..3cd3b329711 100644 --- a/lib/l10n/nl.json +++ b/lib/l10n/nl.json @@ -228,6 +228,10 @@ "Storage connection timeout. %s" : "Opslag verbinding time-out. %s", "Personal" : "Persoonlijk", "Admin" : "Beheerder", - "DB Error: \"%s\"" : "DB Fout: \"%s\"" + "DB Error: \"%s\"" : "DB Fout: \"%s\"", + "Files can't be shared with delete permissions" : "Bestanden kunnen niet gedeeld worden met 'verwijder' rechten", + "Files can't be shared with create permissions" : "Bestanden kunnen niet gedeeld worden met 'creëer' rechten", + "No app name specified" : "Geen app naam gespecificeerd", + "App '%s' could not be installed!" : "App '%s' kon niet geïnstalleerd worden!" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/lib/l10n/pt_PT.js b/lib/l10n/pt_PT.js index 223f7286a00..a79b72ae673 100644 --- a/lib/l10n/pt_PT.js +++ b/lib/l10n/pt_PT.js @@ -1,12 +1,21 @@ OC.L10N.register( "lib", { - "Cannot write into \"config\" directory!" : "Não é possível gravar na diretoria \"configurar\"!", + "Cannot write into \"config\" directory!" : "Não é possível gravar no directório \"config\"!", "This can usually be fixed by giving the webserver write access to the config directory" : "Isto normalmente pode ser resolvido, dando ao servidor da Web direitos de gravação para a diretoria de configuração", "See %s" : "Ver %s", "This can usually be fixed by giving the webserver write access to the config directory. See %s" : "Isto pode geralmente ser corrigido ao adicionar permissões de escrita à pasta de configuração ao servidor web. Ver %s.", + "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Os ficheiros na aplicação %$1s não foram correctamente substituídos. Garanta que é uma versão compatível com o servidor.", "Sample configuration detected" : "Detetado exemplo de configuração", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Foi detectado que a configuração de amostra foi copiada. Isso pode danificar a sua instalação e não é suportado. Por favor, leia a documentação antes de realizar mudanças no config.php", + "%1$s and %2$s" : "%1$s e %2$s", + "%1$s, %2$s and %3$s" : "%1$s, %2$s e %3$s", + "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s e %4$s", + "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s e %5$s", + "Education Edition" : "Edição Educação", + "Enterprise bundle" : "Pacote Empresa", + "Groupware bundle" : "Pacote Colaborativo", + "Social sharing bundle" : "Pacote Partilha Social", "PHP %s or higher is required." : "Necessário PHP %s ou superior.", "PHP with a version lower than %s is required." : "É necessário um PHP com uma versão inferir a %s.", "%sbit or higher PHP required." : "Necessário PHP %sbit ou superior.", @@ -16,22 +25,38 @@ OC.L10N.register( "Library %s with a version higher than %s is required - available version %s." : "É necessário a biblioteca %s com uma versão superior a %s - versão disponível: %s.", "Library %s with a version lower than %s is required - available version %s." : "É necessário a biblioteca %s com uma versão inferior a %s - versão disponível: %s.", "Following platforms are supported: %s" : "São suportadas as seguintes plataformas: %s", + "Server version %s or higher is required." : "É necessária versão do servidor %s or superior. ", + "Server version %s or lower is required." : "É necessária versão do servidor %s or inferior.", "Unknown filetype" : "Tipo de ficheiro desconhecido", "Invalid image" : "Imagem inválida", + "Avatar image is not square" : "A imagem do avatar não é quadrada.", "today" : "hoje", "tomorrow" : "Amanhã", "yesterday" : "ontem", + "_in %n day_::_in %n days_" : ["em %n dia","em %n dias"], "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"], + "next month" : "Próximo mês", "last month" : "ultimo mês", + "_in %n month_::_in %n months_" : ["em %n mês","em %n meses"], + "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás"], + "next year" : "Próximo ano", "last year" : "ano passado", + "_in %n year_::_in %n years_" : ["dentro de%n ano","dentro de%n anos"], "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"], + "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas"], + "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás"], + "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás"], + "in a few seconds" : "em breves segundos", "seconds ago" : "Minutos atrás", + "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Módulo com ID: %s não existe. Por favor active-o nas definições da aplicação ou contacte o administrador.", "File name is a reserved word" : "Nome de ficheiro é uma palavra reservada", "File name contains at least one invalid character" : "Nome de ficheiro contém pelo menos um caráter inválido", "File name is too long" : "Nome do ficheiro demasiado longo", "Dot files are not allowed" : "Ficheiros dot não são permitidos", "Empty filename is not allowed" : "Não é permitido um ficheiro sem nome", "App \"%s\" cannot be installed because appinfo file cannot be read." : "A app \"%s\" não pode ser instalada porque o ficheiro appinfo não pode ser lido.", + "App \"%s\" cannot be installed because it is not compatible with this version of the server." : "A aplicação \"%s\" não pode ser instada porque não é compatível com esta versão do servidor.", "This is an automatically sent email, please do not reply." : "Este e-mail foi enviado automaticamente, por favor não responda a este e-mail.", "Help" : "Ajuda", "Apps" : "Apps", @@ -39,9 +64,21 @@ OC.L10N.register( "Log out" : "Sair", "Users" : "Utilizadores", "Unknown user" : "Utilizador desconhecido", + "APCu" : "APCu", + "Redis" : "Redis", + "Basic settings" : "Definições básicas", "Sharing" : "Partilhar", "Security" : "Segurança", + "Encryption" : "Encriptação", + "Additional settings" : "Definições adicionais", + "Tips & tricks" : "Dicas e truques", + "Personal info" : "Informação pessoal", + "Sync clients" : "Sincronizar clientes", + "Unlimited" : "Ilimitado", "__language_name__" : "Português", + "Verifying" : "A verificar", + "Verifying …" : "A verificar...", + "Verify" : "Verificar", "%s enter the database username and name." : "%s introduza o nome de utilizador da base de dados e o nome da base de dados.", "%s enter the database username." : "%s introduza o nome de utilizador da base de dados", "%s enter the database name." : "%s introduza o nome da base de dados", @@ -49,6 +86,7 @@ OC.L10N.register( "Oracle connection could not be established" : "Não foi possível estabelecer a ligação Oracle", "Oracle username and/or password not valid" : "Nome de utilizador/password do Oracle inválida", "PostgreSQL username and/or password not valid" : "Nome de utilizador/password do PostgreSQL inválido", + "You need to enter details of an existing account." : "Precisa de introduzir detalhes de uma conta existente.", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Esta plataforma não suporta o sistema operativo Mac OS X e o %s poderá não funcionar correctamente. Utilize por sua conta e risco.", "For the best results, please consider using a GNU/Linux server instead." : "Para um melhor resultado, utilize antes o servidor GNU/Linux.", "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Parece que a instância %s está a ser executada num ambiente PHP de 32-bits e o open_basedir foi configurado no php.ini. Isto levará a problemas com ficheiros de tamanho superior a 4 GB e é altamente desencorajado.", @@ -82,19 +120,74 @@ OC.L10N.register( "Sharing %s failed, because resharing is not allowed" : "A partilha %s falhou, porque repartilhar não é permitido", "Sharing %s failed, because the sharing backend for %s could not find its source" : "A partilha %s falhou porque a partilha da interface para %s não conseguiu encontrar a sua fonte", "Sharing %s failed, because the file could not be found in the file cache" : "A partilha %s falhou, devido ao ficheiro não poder ser encontrado na cache de ficheiros", + "Can’t increase permissions of %s" : "Não é possível aumentar as permissões de %s", + "Files can’t be shared with delete permissions" : "Ficheiros não podem ser partilhados com permissões de apagar", + "Files can’t be shared with create permissions" : "Ficheiros não podem ser partilhados com permissões de criação", "Expiration date is in the past" : "A data de expiração está no passado", + "Can’t set expiration date more than %s days in the future" : "Não é possível definir data de expiração a mais de %s dias no futuro", "%s shared »%s« with you" : "%s partilhado »%s« consigo", + "%s shared »%s« with you." : "%s partilhou »%s« consigo.", + "Click the button below to open it." : "Clicar no botão abaixo para abrir.", + "Open »%s«" : "Abrir »%s«", "%s via %s" : "%s via %s", + "The requested share does not exist anymore" : "A partilha requisitada já não existe", "Could not find category \"%s\"" : "Não foi encontrado a categoria \"%s\"", + "Sunday" : "Domingo", + "Monday" : "Segunda-feira", + "Tuesday" : "Terça-feira", + "Wednesday" : "Quarta-feira", + "Thursday" : "Quinta-feira", + "Friday" : "Sexta-feira", + "Saturday" : "Sábado", + "Sun." : "Dom.", + "Mon." : "Seg.", + "Tue." : "Ter.", + "Wed." : "Qua.", + "Thu." : "Qui.", + "Fri." : "Sex.", + "Sat." : "Sáb.", + "Su" : "Dom", + "Mo" : "Seg", + "Tu" : "Ter", + "We" : "Qua", + "Th" : "Qui", + "Fr" : "Sex", + "Sa" : "Sáb", + "January" : "Janeiro", + "February" : "Fevereiro", + "March" : "Março", + "April" : "Abril", + "May" : "Maio", + "June" : "Junho", + "July" : "Julho", + "August" : "Agosto", + "September" : "Setembro", + "October" : "Outubro", + "November" : "Novembro", + "December" : "Dezembro", + "Jan." : "Jan.", + "Feb." : "Fev.", + "Mar." : "Mar.", + "Apr." : "Abr.", + "May." : "Mai.", + "Jun." : "Jun.", + "Jul." : "Jul.", + "Aug." : "Ago.", + "Sep." : "Set.", + "Oct." : "Out.", + "Nov." : "Nov.", + "Dec." : "Dez.", "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Apenas os seguintes caracteres são permitidos num nome de utilizador: \"a-z\", \"A-Z\", \"0-9\", e \"_.@-'\"", "A valid username must be provided" : "Um nome de utilizador válido deve ser fornecido", "Username contains whitespace at the beginning or at the end" : "Nome de utilizador contém espaço em branco no início ou no fim", + "Username must not consist of dots only" : "O utilizador não pode consistir de apenas pontos", "A valid password must be provided" : "Uma password válida deve ser fornecida", "The username is already being used" : "O nome de utilizador já está a ser usado", "Could not create user" : "Não foi possível criar o utilizador", "User disabled" : "Utilizador desativado", "Login canceled by app" : "Sessão cancelada pela app", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "A aplicação \"%s\" não pode ser instalada porque as seguintes dependências não podem ser realizadas: %s", + "a safe home for all your data" : "Um lugar seguro para todos os seus dados", "File is currently busy, please try again later" : "O ficheiro está ocupado, por favor, tente mais tarde", "Can't read file" : "Não é possível ler o ficheiro", "Application is not enabled" : "A aplicação não está activada", @@ -103,11 +196,16 @@ OC.L10N.register( "No database drivers (sqlite, mysql, or postgresql) installed." : "Nenhuma base de dados de drivers (sqlite, mysql, or postgresql) instaladas.", "Cannot write into \"config\" directory" : "Não é possível escrever na directoria \"configurar\"", "Cannot write into \"apps\" directory" : "Não é possivel escrever na directoria \"aplicações\"", + "This can usually be fixed by giving the webserver write access to the apps directory or disabling the appstore in the config file. See %s" : "Isto pode ser normalmente resolvido dando ao servidor web direito de escrita para o directório de aplicação ou desactivando a loja de aplicações no ficheiro de configuração. Ver %s", + "Cannot create \"data\" directory" : "Não é possivel criar a directoria \"data\"", + "This can usually be fixed by giving the webserver write access to the root directory. See %s" : "Isto pode geralmente ser corrigido ao adicionar permissões de escrita à pasta de raiz. Ver %s", + "Permissions can usually be fixed by giving the webserver write access to the root directory. See %s." : "As permissões podem geralmente ser corrigidas dando ao servidor web permissões de escrita na pasta de raiz. Ver %s.", "Setting locale to %s failed" : "Definindo local para %s falhado", "Please install one of these locales on your system and restart your webserver." : "Por favor instale um destes locais no seu sistema e reinicie o seu servidor web.", "Please ask your server administrator to install the module." : "Por favor pergunte ao seu administrador do servidor para instalar o modulo.", "PHP module %s not installed." : "O modulo %s PHP não está instalado.", "PHP setting \"%s\" is not set to \"%s\"." : "Configuração PHP \"%s\" não está definida para \"%s\".", + "Adjusting this setting in php.ini will make Nextcloud run again" : "Ajustar esta definição no php.ini fará com que o Nextcloud inicie novamente", "mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload está configurado para \"%s\" invés do valor habitual de \"0\"", "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Para corrigir este problema altere o <code>mbstring.func_overload</code> para <code>0</code> no seu php.ini", "libxml2 2.7.0 is at least required. Currently %s is installed." : "Necessária pelo menos libxml2 2.7.0. Atualmente %s está instalada.", @@ -119,11 +217,30 @@ OC.L10N.register( "PostgreSQL >= 9 required" : "Necessita PostgreSQL >= 9", "Please upgrade your database version" : "Por favor actualize a sua versão da base de dados", "Please change the permissions to 0770 so that the directory cannot be listed by other users." : "Por favor altere as permissões para 0770 para que esse directório não possa ser listado por outros utilizadores.", + "Your data directory is readable by other users" : "O seu directório de dados é legível por outros utilizadores", + "Your data directory must be an absolute path" : "O seu directório de dados deve ser um caminho absoluto", "Check the value of \"datadirectory\" in your configuration" : "Verifique o valor de \"datadirectory\" na sua configuração", + "Your data directory is invalid" : "O seu directório de dados é inválido", + "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Garanta que existe um ficheiro chamado \".occdata\" na raiz do directório de dados", "Could not obtain lock type %d on \"%s\"." : "Não foi possível obter o tipo de bloqueio %d em \"%s\".", "Storage unauthorized. %s" : "Armazenamento desautorizado. %s", "Storage incomplete configuration. %s" : "Configuração incompleta do armazenamento. %s", "Storage connection error. %s" : "Erro de ligação ao armazenamento. %s", - "Storage connection timeout. %s" : "Tempo de ligação ao armazenamento expirou. %s" + "Storage is temporarily not available" : "Armazenamento temporariamente indisponível", + "Storage connection timeout. %s" : "Tempo de ligação ao armazenamento expirou. %s", + "Personal" : "Pessoal", + "Admin" : "Admin", + "DB Error: \"%s\"" : "Erro de BD:\"%s\"", + "Offending command was: \"%s\"" : "O comando transgressor foi:\"%s\"", + "Offending command was: \"%s\", name: %s, password: %s" : "O comando transgressor foi: \"%s\", nome: %s, password: %s", + "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Definição das permissões para %s falhou porque excedem as permissões concedidas a %s", + "Setting permissions for %s failed, because the item was not found" : "Definição das permissões para %s falhou porque o item não foi encontrado", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Não é possível remover a data de expiração. Partilhas precisam de ter data de expiração.", + "Cannot increase permissions of %s" : "Não é possível aumentar as permissões de %s", + "Files can't be shared with delete permissions" : "Ficheiros não podem ser partilhados com permissões para apagar", + "Files can't be shared with create permissions" : "Ficheiros não podem ser partilhados com permissões para criar", + "Cannot set expiration date more than %s days in the future" : "Não é possível definir data de expiração superior a %s dias no futuro", + "No app name specified" : "Nome da aplicação não especificado", + "App '%s' could not be installed!" : "Aplicação '%s' não pôde ser instalada" }, "nplurals=2; plural=(n != 1);"); diff --git a/lib/l10n/pt_PT.json b/lib/l10n/pt_PT.json index d0403a5fcce..9161b238040 100644 --- a/lib/l10n/pt_PT.json +++ b/lib/l10n/pt_PT.json @@ -1,10 +1,19 @@ { "translations": { - "Cannot write into \"config\" directory!" : "Não é possível gravar na diretoria \"configurar\"!", + "Cannot write into \"config\" directory!" : "Não é possível gravar no directório \"config\"!", "This can usually be fixed by giving the webserver write access to the config directory" : "Isto normalmente pode ser resolvido, dando ao servidor da Web direitos de gravação para a diretoria de configuração", "See %s" : "Ver %s", "This can usually be fixed by giving the webserver write access to the config directory. See %s" : "Isto pode geralmente ser corrigido ao adicionar permissões de escrita à pasta de configuração ao servidor web. Ver %s.", + "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Os ficheiros na aplicação %$1s não foram correctamente substituídos. Garanta que é uma versão compatível com o servidor.", "Sample configuration detected" : "Detetado exemplo de configuração", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Foi detectado que a configuração de amostra foi copiada. Isso pode danificar a sua instalação e não é suportado. Por favor, leia a documentação antes de realizar mudanças no config.php", + "%1$s and %2$s" : "%1$s e %2$s", + "%1$s, %2$s and %3$s" : "%1$s, %2$s e %3$s", + "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s e %4$s", + "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s e %5$s", + "Education Edition" : "Edição Educação", + "Enterprise bundle" : "Pacote Empresa", + "Groupware bundle" : "Pacote Colaborativo", + "Social sharing bundle" : "Pacote Partilha Social", "PHP %s or higher is required." : "Necessário PHP %s ou superior.", "PHP with a version lower than %s is required." : "É necessário um PHP com uma versão inferir a %s.", "%sbit or higher PHP required." : "Necessário PHP %sbit ou superior.", @@ -14,22 +23,38 @@ "Library %s with a version higher than %s is required - available version %s." : "É necessário a biblioteca %s com uma versão superior a %s - versão disponível: %s.", "Library %s with a version lower than %s is required - available version %s." : "É necessário a biblioteca %s com uma versão inferior a %s - versão disponível: %s.", "Following platforms are supported: %s" : "São suportadas as seguintes plataformas: %s", + "Server version %s or higher is required." : "É necessária versão do servidor %s or superior. ", + "Server version %s or lower is required." : "É necessária versão do servidor %s or inferior.", "Unknown filetype" : "Tipo de ficheiro desconhecido", "Invalid image" : "Imagem inválida", + "Avatar image is not square" : "A imagem do avatar não é quadrada.", "today" : "hoje", "tomorrow" : "Amanhã", "yesterday" : "ontem", + "_in %n day_::_in %n days_" : ["em %n dia","em %n dias"], "_%n day ago_::_%n days ago_" : ["%n dia atrás","%n dias atrás"], + "next month" : "Próximo mês", "last month" : "ultimo mês", + "_in %n month_::_in %n months_" : ["em %n mês","em %n meses"], + "_%n month ago_::_%n months ago_" : ["%n mês atrás","%n meses atrás"], + "next year" : "Próximo ano", "last year" : "ano passado", + "_in %n year_::_in %n years_" : ["dentro de%n ano","dentro de%n anos"], "_%n year ago_::_%n years ago_" : ["%n ano atrás","%n anos atrás"], + "_in %n hour_::_in %n hours_" : ["dentro de %n hora","dentro de %n horas"], + "_%n hour ago_::_%n hours ago_" : ["%n hora atrás","%n horas atrás"], + "_in %n minute_::_in %n minutes_" : ["dentro de %n minuto","dentro de %n minutos"], + "_%n minute ago_::_%n minutes ago_" : ["%n minuto atrás","%n minutos atrás"], + "in a few seconds" : "em breves segundos", "seconds ago" : "Minutos atrás", + "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Módulo com ID: %s não existe. Por favor active-o nas definições da aplicação ou contacte o administrador.", "File name is a reserved word" : "Nome de ficheiro é uma palavra reservada", "File name contains at least one invalid character" : "Nome de ficheiro contém pelo menos um caráter inválido", "File name is too long" : "Nome do ficheiro demasiado longo", "Dot files are not allowed" : "Ficheiros dot não são permitidos", "Empty filename is not allowed" : "Não é permitido um ficheiro sem nome", "App \"%s\" cannot be installed because appinfo file cannot be read." : "A app \"%s\" não pode ser instalada porque o ficheiro appinfo não pode ser lido.", + "App \"%s\" cannot be installed because it is not compatible with this version of the server." : "A aplicação \"%s\" não pode ser instada porque não é compatível com esta versão do servidor.", "This is an automatically sent email, please do not reply." : "Este e-mail foi enviado automaticamente, por favor não responda a este e-mail.", "Help" : "Ajuda", "Apps" : "Apps", @@ -37,9 +62,21 @@ "Log out" : "Sair", "Users" : "Utilizadores", "Unknown user" : "Utilizador desconhecido", + "APCu" : "APCu", + "Redis" : "Redis", + "Basic settings" : "Definições básicas", "Sharing" : "Partilhar", "Security" : "Segurança", + "Encryption" : "Encriptação", + "Additional settings" : "Definições adicionais", + "Tips & tricks" : "Dicas e truques", + "Personal info" : "Informação pessoal", + "Sync clients" : "Sincronizar clientes", + "Unlimited" : "Ilimitado", "__language_name__" : "Português", + "Verifying" : "A verificar", + "Verifying …" : "A verificar...", + "Verify" : "Verificar", "%s enter the database username and name." : "%s introduza o nome de utilizador da base de dados e o nome da base de dados.", "%s enter the database username." : "%s introduza o nome de utilizador da base de dados", "%s enter the database name." : "%s introduza o nome da base de dados", @@ -47,6 +84,7 @@ "Oracle connection could not be established" : "Não foi possível estabelecer a ligação Oracle", "Oracle username and/or password not valid" : "Nome de utilizador/password do Oracle inválida", "PostgreSQL username and/or password not valid" : "Nome de utilizador/password do PostgreSQL inválido", + "You need to enter details of an existing account." : "Precisa de introduzir detalhes de uma conta existente.", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Esta plataforma não suporta o sistema operativo Mac OS X e o %s poderá não funcionar correctamente. Utilize por sua conta e risco.", "For the best results, please consider using a GNU/Linux server instead." : "Para um melhor resultado, utilize antes o servidor GNU/Linux.", "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Parece que a instância %s está a ser executada num ambiente PHP de 32-bits e o open_basedir foi configurado no php.ini. Isto levará a problemas com ficheiros de tamanho superior a 4 GB e é altamente desencorajado.", @@ -80,19 +118,74 @@ "Sharing %s failed, because resharing is not allowed" : "A partilha %s falhou, porque repartilhar não é permitido", "Sharing %s failed, because the sharing backend for %s could not find its source" : "A partilha %s falhou porque a partilha da interface para %s não conseguiu encontrar a sua fonte", "Sharing %s failed, because the file could not be found in the file cache" : "A partilha %s falhou, devido ao ficheiro não poder ser encontrado na cache de ficheiros", + "Can’t increase permissions of %s" : "Não é possível aumentar as permissões de %s", + "Files can’t be shared with delete permissions" : "Ficheiros não podem ser partilhados com permissões de apagar", + "Files can’t be shared with create permissions" : "Ficheiros não podem ser partilhados com permissões de criação", "Expiration date is in the past" : "A data de expiração está no passado", + "Can’t set expiration date more than %s days in the future" : "Não é possível definir data de expiração a mais de %s dias no futuro", "%s shared »%s« with you" : "%s partilhado »%s« consigo", + "%s shared »%s« with you." : "%s partilhou »%s« consigo.", + "Click the button below to open it." : "Clicar no botão abaixo para abrir.", + "Open »%s«" : "Abrir »%s«", "%s via %s" : "%s via %s", + "The requested share does not exist anymore" : "A partilha requisitada já não existe", "Could not find category \"%s\"" : "Não foi encontrado a categoria \"%s\"", + "Sunday" : "Domingo", + "Monday" : "Segunda-feira", + "Tuesday" : "Terça-feira", + "Wednesday" : "Quarta-feira", + "Thursday" : "Quinta-feira", + "Friday" : "Sexta-feira", + "Saturday" : "Sábado", + "Sun." : "Dom.", + "Mon." : "Seg.", + "Tue." : "Ter.", + "Wed." : "Qua.", + "Thu." : "Qui.", + "Fri." : "Sex.", + "Sat." : "Sáb.", + "Su" : "Dom", + "Mo" : "Seg", + "Tu" : "Ter", + "We" : "Qua", + "Th" : "Qui", + "Fr" : "Sex", + "Sa" : "Sáb", + "January" : "Janeiro", + "February" : "Fevereiro", + "March" : "Março", + "April" : "Abril", + "May" : "Maio", + "June" : "Junho", + "July" : "Julho", + "August" : "Agosto", + "September" : "Setembro", + "October" : "Outubro", + "November" : "Novembro", + "December" : "Dezembro", + "Jan." : "Jan.", + "Feb." : "Fev.", + "Mar." : "Mar.", + "Apr." : "Abr.", + "May." : "Mai.", + "Jun." : "Jun.", + "Jul." : "Jul.", + "Aug." : "Ago.", + "Sep." : "Set.", + "Oct." : "Out.", + "Nov." : "Nov.", + "Dec." : "Dez.", "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Apenas os seguintes caracteres são permitidos num nome de utilizador: \"a-z\", \"A-Z\", \"0-9\", e \"_.@-'\"", "A valid username must be provided" : "Um nome de utilizador válido deve ser fornecido", "Username contains whitespace at the beginning or at the end" : "Nome de utilizador contém espaço em branco no início ou no fim", + "Username must not consist of dots only" : "O utilizador não pode consistir de apenas pontos", "A valid password must be provided" : "Uma password válida deve ser fornecida", "The username is already being used" : "O nome de utilizador já está a ser usado", "Could not create user" : "Não foi possível criar o utilizador", "User disabled" : "Utilizador desativado", "Login canceled by app" : "Sessão cancelada pela app", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "A aplicação \"%s\" não pode ser instalada porque as seguintes dependências não podem ser realizadas: %s", + "a safe home for all your data" : "Um lugar seguro para todos os seus dados", "File is currently busy, please try again later" : "O ficheiro está ocupado, por favor, tente mais tarde", "Can't read file" : "Não é possível ler o ficheiro", "Application is not enabled" : "A aplicação não está activada", @@ -101,11 +194,16 @@ "No database drivers (sqlite, mysql, or postgresql) installed." : "Nenhuma base de dados de drivers (sqlite, mysql, or postgresql) instaladas.", "Cannot write into \"config\" directory" : "Não é possível escrever na directoria \"configurar\"", "Cannot write into \"apps\" directory" : "Não é possivel escrever na directoria \"aplicações\"", + "This can usually be fixed by giving the webserver write access to the apps directory or disabling the appstore in the config file. See %s" : "Isto pode ser normalmente resolvido dando ao servidor web direito de escrita para o directório de aplicação ou desactivando a loja de aplicações no ficheiro de configuração. Ver %s", + "Cannot create \"data\" directory" : "Não é possivel criar a directoria \"data\"", + "This can usually be fixed by giving the webserver write access to the root directory. See %s" : "Isto pode geralmente ser corrigido ao adicionar permissões de escrita à pasta de raiz. Ver %s", + "Permissions can usually be fixed by giving the webserver write access to the root directory. See %s." : "As permissões podem geralmente ser corrigidas dando ao servidor web permissões de escrita na pasta de raiz. Ver %s.", "Setting locale to %s failed" : "Definindo local para %s falhado", "Please install one of these locales on your system and restart your webserver." : "Por favor instale um destes locais no seu sistema e reinicie o seu servidor web.", "Please ask your server administrator to install the module." : "Por favor pergunte ao seu administrador do servidor para instalar o modulo.", "PHP module %s not installed." : "O modulo %s PHP não está instalado.", "PHP setting \"%s\" is not set to \"%s\"." : "Configuração PHP \"%s\" não está definida para \"%s\".", + "Adjusting this setting in php.ini will make Nextcloud run again" : "Ajustar esta definição no php.ini fará com que o Nextcloud inicie novamente", "mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload está configurado para \"%s\" invés do valor habitual de \"0\"", "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Para corrigir este problema altere o <code>mbstring.func_overload</code> para <code>0</code> no seu php.ini", "libxml2 2.7.0 is at least required. Currently %s is installed." : "Necessária pelo menos libxml2 2.7.0. Atualmente %s está instalada.", @@ -117,11 +215,30 @@ "PostgreSQL >= 9 required" : "Necessita PostgreSQL >= 9", "Please upgrade your database version" : "Por favor actualize a sua versão da base de dados", "Please change the permissions to 0770 so that the directory cannot be listed by other users." : "Por favor altere as permissões para 0770 para que esse directório não possa ser listado por outros utilizadores.", + "Your data directory is readable by other users" : "O seu directório de dados é legível por outros utilizadores", + "Your data directory must be an absolute path" : "O seu directório de dados deve ser um caminho absoluto", "Check the value of \"datadirectory\" in your configuration" : "Verifique o valor de \"datadirectory\" na sua configuração", + "Your data directory is invalid" : "O seu directório de dados é inválido", + "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Garanta que existe um ficheiro chamado \".occdata\" na raiz do directório de dados", "Could not obtain lock type %d on \"%s\"." : "Não foi possível obter o tipo de bloqueio %d em \"%s\".", "Storage unauthorized. %s" : "Armazenamento desautorizado. %s", "Storage incomplete configuration. %s" : "Configuração incompleta do armazenamento. %s", "Storage connection error. %s" : "Erro de ligação ao armazenamento. %s", - "Storage connection timeout. %s" : "Tempo de ligação ao armazenamento expirou. %s" + "Storage is temporarily not available" : "Armazenamento temporariamente indisponível", + "Storage connection timeout. %s" : "Tempo de ligação ao armazenamento expirou. %s", + "Personal" : "Pessoal", + "Admin" : "Admin", + "DB Error: \"%s\"" : "Erro de BD:\"%s\"", + "Offending command was: \"%s\"" : "O comando transgressor foi:\"%s\"", + "Offending command was: \"%s\", name: %s, password: %s" : "O comando transgressor foi: \"%s\", nome: %s, password: %s", + "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Definição das permissões para %s falhou porque excedem as permissões concedidas a %s", + "Setting permissions for %s failed, because the item was not found" : "Definição das permissões para %s falhou porque o item não foi encontrado", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Não é possível remover a data de expiração. Partilhas precisam de ter data de expiração.", + "Cannot increase permissions of %s" : "Não é possível aumentar as permissões de %s", + "Files can't be shared with delete permissions" : "Ficheiros não podem ser partilhados com permissões para apagar", + "Files can't be shared with create permissions" : "Ficheiros não podem ser partilhados com permissões para criar", + "Cannot set expiration date more than %s days in the future" : "Não é possível definir data de expiração superior a %s dias no futuro", + "No app name specified" : "Nome da aplicação não especificado", + "App '%s' could not be installed!" : "Aplicação '%s' não pôde ser instalada" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/lib/l10n/ru.js b/lib/l10n/ru.js index 084a79561bb..76c7165d87c 100644 --- a/lib/l10n/ru.js +++ b/lib/l10n/ru.js @@ -227,6 +227,16 @@ OC.L10N.register( "Storage incomplete configuration. %s" : "Неполная конфигурация хранилища. %s", "Storage connection error. %s" : "Ошибка подключения к хранилищу. %s", "Storage is temporarily not available" : "Хранилище временно недоступно", - "Storage connection timeout. %s" : "Истекло время ожидания подключения к хранилищу. %s" + "Storage connection timeout. %s" : "Истекло время ожидания подключения к хранилищу. %s", + "Personal" : "Личное", + "Admin" : "Администратор", + "DB Error: \"%s\"" : "Ошибка БД: «%s»", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Невозможно очистить дату истечения срока действия. Общие ресурсы должны иметь срок действия.", + "Cannot increase permissions of %s" : "Невозможно повысить права доступа %s", + "Files can't be shared with delete permissions" : "Права на удаление файлов не позволяют открывать общий доступ к ним", + "Files can't be shared with create permissions" : "Права на создание файлов не позволяют открывать общий доступ к ним", + "Cannot set expiration date more than %s days in the future" : "Срок окончания не может быть более %s дней (дня)", + "No app name specified" : "Не указано имя приложения", + "App '%s' could not be installed!" : "Приложение «%s» не может быть установлено!" }, "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); diff --git a/lib/l10n/ru.json b/lib/l10n/ru.json index f9bd45402e8..1ae1702af49 100644 --- a/lib/l10n/ru.json +++ b/lib/l10n/ru.json @@ -225,6 +225,16 @@ "Storage incomplete configuration. %s" : "Неполная конфигурация хранилища. %s", "Storage connection error. %s" : "Ошибка подключения к хранилищу. %s", "Storage is temporarily not available" : "Хранилище временно недоступно", - "Storage connection timeout. %s" : "Истекло время ожидания подключения к хранилищу. %s" + "Storage connection timeout. %s" : "Истекло время ожидания подключения к хранилищу. %s", + "Personal" : "Личное", + "Admin" : "Администратор", + "DB Error: \"%s\"" : "Ошибка БД: «%s»", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Невозможно очистить дату истечения срока действия. Общие ресурсы должны иметь срок действия.", + "Cannot increase permissions of %s" : "Невозможно повысить права доступа %s", + "Files can't be shared with delete permissions" : "Права на удаление файлов не позволяют открывать общий доступ к ним", + "Files can't be shared with create permissions" : "Права на создание файлов не позволяют открывать общий доступ к ним", + "Cannot set expiration date more than %s days in the future" : "Срок окончания не может быть более %s дней (дня)", + "No app name specified" : "Не указано имя приложения", + "App '%s' could not be installed!" : "Приложение «%s» не может быть установлено!" },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" }
\ No newline at end of file diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php index 0e921ba1b7f..4bf15c23fab 100644 --- a/lib/private/App/AppManager.php +++ b/lib/private/App/AppManager.php @@ -380,10 +380,10 @@ class AppManager implements IAppManager { return $data; } - public function getAppVersion(string $appId, bool $useCache = true) { + public function getAppVersion(string $appId, bool $useCache = true): string { if(!$useCache || !isset($this->appVersions[$appId])) { $appInfo = \OC::$server->getAppManager()->getAppInfo($appId); - $this->appVersions[$appId] = ($appInfo !== null) ? $appInfo['version'] : '0'; + $this->appVersions[$appId] = ($appInfo !== null && isset($appInfo['version'])) ? $appInfo['version'] : '0'; } return $this->appVersions[$appId]; } @@ -397,7 +397,7 @@ class AppManager implements IAppManager { * * @internal */ - public function getIncompatibleApps($version) { + public function getIncompatibleApps(string $version): array { $apps = $this->getInstalledApps(); $incompatibleApps = array(); foreach ($apps as $appId) { @@ -411,6 +411,7 @@ class AppManager implements IAppManager { /** * @inheritdoc + * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::isShipped() */ public function isShipped($appId) { $this->loadShippedJson(); @@ -422,6 +423,10 @@ class AppManager implements IAppManager { return in_array($appId, $alwaysEnabled, true); } + /** + * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::loadShippedJson() + * @throws \Exception + */ private function loadShippedJson() { if ($this->shippedApps === null) { $shippedJson = \OC::$SERVERROOT . '/core/shipped.json'; diff --git a/lib/private/App/AppStore/Fetcher/Fetcher.php b/lib/private/App/AppStore/Fetcher/Fetcher.php index 8bf9ca15349..4dbc360c0c4 100644 --- a/lib/private/App/AppStore/Fetcher/Fetcher.php +++ b/lib/private/App/AppStore/Fetcher/Fetcher.php @@ -174,6 +174,7 @@ abstract class Fetcher { $this->logger->logException($e, ['app' => 'appstoreFetcher', 'level' => Util::INFO, 'message' => 'Could not connect to appstore']); return []; } catch (\Exception $e) { + $this->logger->logException($e, ['app' => 'appstoreFetcher', 'level' => Util::INFO]); return []; } } diff --git a/lib/private/App/CodeChecker/DeprecationCheck.php b/lib/private/App/CodeChecker/DeprecationCheck.php index c337e71f27e..722697f3313 100644 --- a/lib/private/App/CodeChecker/DeprecationCheck.php +++ b/lib/private/App/CodeChecker/DeprecationCheck.php @@ -146,6 +146,8 @@ class DeprecationCheck extends AbstractCheck { 'OCP\IServerContainer::getDb' => '8.1.0', 'OCP\IServerContainer::getHTTPHelper' => '8.1.0', + 'OCP\Response::disableCaching' => '14.0.0', + 'OCP\User::getUser' => '8.0.0', 'OCP\User::getUsers' => '8.1.0', 'OCP\User::getDisplayName' => '8.1.0', diff --git a/lib/private/App/CodeChecker/InfoChecker.php b/lib/private/App/CodeChecker/InfoChecker.php index e8791bd7037..f5de6d376d8 100644 --- a/lib/private/App/CodeChecker/InfoChecker.php +++ b/lib/private/App/CodeChecker/InfoChecker.php @@ -23,121 +23,88 @@ namespace OC\App\CodeChecker; -use OC\App\InfoParser; use OC\Hooks\BasicEmitter; +use OCP\App\AppPathNotFoundException; +use OCP\App\IAppManager; class InfoChecker extends BasicEmitter { - /** @var InfoParser */ - private $infoParser; + /** @var string[] */ + private $shippedApps; - private $mandatoryFields = [ - 'author', - 'description', - 'dependencies', - 'id', - 'licence', - 'name', - 'version', - ]; - private $optionalFields = [ - 'bugs', - 'category', - 'default_enable', - 'documentation', - 'namespace', - 'ocsid', - 'public', - 'remote', - 'repository', - 'types', - 'website', - ]; - private $deprecatedFields = [ - 'info', - 'require', - 'requiremax', - 'requiremin', - 'shipped', - 'standalone', - ]; - - public function __construct(InfoParser $infoParser) { - $this->infoParser = $infoParser; - } + /** @var string[] */ + private $alwaysEnabled; /** * @param string $appId * @return array + * @throws \RuntimeException */ - public function analyse($appId) { + public function analyse($appId): array { $appPath = \OC_App::getAppPath($appId); if ($appPath === false) { throw new \RuntimeException("No app with given id <$appId> known."); } - $errors = []; - - $info = $this->infoParser->parse($appPath . '/appinfo/info.xml'); - - if (!isset($info['dependencies']['nextcloud']['@attributes']['min-version'])) { - $errors[] = [ - 'type' => 'missingRequirement', - 'field' => 'min', - ]; - $this->emit('InfoChecker', 'missingRequirement', ['min']); - } - - if (!isset($info['dependencies']['nextcloud']['@attributes']['max-version'])) { - $errors[] = [ - 'type' => 'missingRequirement', - 'field' => 'max', - ]; - $this->emit('InfoChecker', 'missingRequirement', ['max']); - } - - foreach ($info as $key => $value) { - if(is_array($value)) { - $value = json_encode($value); - } - if (in_array($key, $this->mandatoryFields)) { - $this->emit('InfoChecker', 'mandatoryFieldFound', [$key, $value]); - continue; - } + $xml = new \DOMDocument(); + $xml->load($appPath . '/appinfo/info.xml'); - if (in_array($key, $this->optionalFields)) { - $this->emit('InfoChecker', 'optionalFieldFound', [$key, $value]); - continue; + $schema = \OC::$SERVERROOT . '/resources/app-info.xsd'; + try { + if ($this->isShipped($appId)) { + // Shipped apps are allowed to have the public and default_enabled tags + $schema = \OC::$SERVERROOT . '/resources/app-info-shipped.xsd'; } - - if (in_array($key, $this->deprecatedFields)) { - // skip empty arrays - empty arrays for remote and public are always added - if($value === '[]' && in_array($key, ['public', 'remote', 'info'])) { - continue; - } - $this->emit('InfoChecker', 'deprecatedFieldFound', [$key, $value]); - continue; - } - - $this->emit('InfoChecker', 'unusedFieldFound', [$key, $value]); + } catch (\Exception $e) { + // Assume it is not shipped } - foreach ($this->mandatoryFields as $key) { - if(!isset($info[$key])) { - $this->emit('InfoChecker', 'mandatoryFieldMissing', [$key]); + $errors = []; + if (!$xml->schemaValidate($schema)) { + foreach (libxml_get_errors() as $error) { $errors[] = [ - 'type' => 'mandatoryFieldMissing', - 'field' => $key, + 'type' => 'parseError', + 'field' => $error->message, ]; + $this->emit('InfoChecker', 'parseError', [$error->message]); } } - $versionFile = $appPath . '/appinfo/version'; - if (is_file($versionFile)) { - $version = trim(file_get_contents($versionFile)); - $this->emit('InfoChecker', 'migrateVersion', [$version]); - } - return $errors; } + + /** + * This is a copy of \OC\App\AppManager::isShipped(), keep both in sync. + * This method is copied, so the code checker works even when Nextcloud is + * not installed yet. The AppManager requires a database connection, which + * fails in that case. + * + * @param string $appId + * @return bool + * @throws \Exception + */ + protected function isShipped(string $appId): bool { + $this->loadShippedJson(); + return \in_array($appId, $this->shippedApps, true); + } + + /** + * This is a copy of \OC\App\AppManager::loadShippedJson(), keep both in sync + * This method is copied, so the code checker works even when Nextcloud is + * not installed yet. The AppManager requires a database connection, which + * fails in that case. + * + * @throws \Exception + */ + protected function loadShippedJson() { + if ($this->shippedApps === null) { + $shippedJson = \OC::$SERVERROOT . '/core/shipped.json'; + if (!file_exists($shippedJson)) { + throw new \Exception("File not found: $shippedJson"); + } + $content = json_decode(file_get_contents($shippedJson), true); + $this->shippedApps = $content['shippedApps']; + $this->alwaysEnabled = $content['alwaysEnabled']; + } + } } diff --git a/lib/private/App/DependencyAnalyzer.php b/lib/private/App/DependencyAnalyzer.php index 4193ee5083f..e8da5a0b63a 100644 --- a/lib/private/App/DependencyAnalyzer.php +++ b/lib/private/App/DependencyAnalyzer.php @@ -140,19 +140,19 @@ class DependencyAnalyzer { if (isset($dependencies['php']['@attributes']['min-version'])) { $minVersion = $dependencies['php']['@attributes']['min-version']; if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) { - $missing[] = (string)$this->l->t('PHP %s or higher is required.', $minVersion); + $missing[] = (string)$this->l->t('PHP %s or higher is required.', [$minVersion]); } } if (isset($dependencies['php']['@attributes']['max-version'])) { $maxVersion = $dependencies['php']['@attributes']['max-version']; if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) { - $missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', $maxVersion); + $missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', [$maxVersion]); } } if (isset($dependencies['php']['@attributes']['min-int-size'])) { $intSize = $dependencies['php']['@attributes']['min-int-size']; if ($intSize > $this->platform->getIntSize()*8) { - $missing[] = (string)$this->l->t('%sbit or higher PHP required.', $intSize); + $missing[] = (string)$this->l->t('%sbit or higher PHP required.', [$intSize]); } } return $missing; @@ -209,7 +209,7 @@ class DependencyAnalyzer { } $commandName = $this->getValue($command); if (!$this->platform->isCommandKnown($commandName)) { - $missing[] = (string)$this->l->t('The command line tool %s could not be found', $commandName); + $missing[] = (string)$this->l->t('The command line tool %s could not be found', [$commandName]); } } return $missing; @@ -236,7 +236,7 @@ class DependencyAnalyzer { $libName = $this->getValue($lib); $libVersion = $this->platform->getLibraryVersion($libName); if (is_null($libVersion)) { - $missing[] = (string)$this->l->t('The library %s is not available.', $libName); + $missing[] = (string)$this->l->t('The library %s is not available.', [$libName]); continue; } diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 5fe925c2998..44c268bdea6 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -152,10 +152,6 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $c->query('ServerContainer')->getWebRoot(); }); - $this->registerService('fromMailAddress', function() { - return Util::getDefaultEmailAddress('no-reply'); - }); - $this->registerService('OC_Defaults', function ($c) { return $c->getServer()->getThemingDefaults(); }); diff --git a/lib/private/AppFramework/Http/Dispatcher.php b/lib/private/AppFramework/Http/Dispatcher.php index ecf8462ebb6..7b9ad015de6 100644 --- a/lib/private/AppFramework/Http/Dispatcher.php +++ b/lib/private/AppFramework/Http/Dispatcher.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -44,9 +45,16 @@ use OCP\IRequest; */ class Dispatcher { + /** @var MiddlewareDispatcher */ private $middlewareDispatcher; + + /** @var Http */ private $protocol; + + /** @var ControllerMethodReflector */ private $reflector; + + /** @var IRequest */ private $request; /** @@ -78,8 +86,8 @@ class Dispatcher { * the response output * @throws \Exception */ - public function dispatch(Controller $controller, $methodName) { - $out = array(null, array(), null); + public function dispatch(Controller $controller, string $methodName): array { + $out = [null, [], null]; try { // prefill reflector with everything thats needed for the @@ -97,9 +105,6 @@ class Dispatcher { } catch(\Exception $exception){ $response = $this->middlewareDispatcher->afterException( $controller, $methodName, $exception); - if (is_null($response)) { - throw $exception; - } } $response = $this->middlewareDispatcher->afterController( @@ -126,11 +131,11 @@ class Dispatcher { * @param string $methodName the method on the controller that should be executed * @return Response */ - private function executeController($controller, $methodName) { - $arguments = array(); + private function executeController(Controller $controller, string $methodName): Response { + $arguments = []; // valid types that will be casted - $types = array('int', 'integer', 'bool', 'boolean', 'float'); + $types = ['int', 'integer', 'bool', 'boolean', 'float']; foreach($this->reflector->getParameters() as $param => $default) { @@ -151,14 +156,14 @@ class Dispatcher { ) { $value = false; - } elseif($value !== null && in_array($type, $types)) { + } elseif($value !== null && \in_array($type, $types, true)) { settype($value, $type); } $arguments[] = $value; } - $response = call_user_func_array(array($controller, $methodName), $arguments); + $response = \call_user_func_array([$controller, $methodName], $arguments); // format response if($response instanceof DataResponse || !($response instanceof Response)) { diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index 975c4255d5a..86ba884141f 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -87,8 +88,8 @@ class Request implements \ArrayAccess, \Countable, IRequest { protected $inputStream; protected $content; - protected $items = array(); - protected $allowedKeys = array( + protected $items = []; + protected $allowedKeys = [ 'get', 'post', 'files', @@ -99,7 +100,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { 'parameters', 'method', 'requesttoken', - ); + ]; /** @var ISecureRandom */ protected $secureRandom; /** @var IConfig */ @@ -131,13 +132,13 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $stream * @see http://www.php.net/manual/en/reserved.variables.php */ - public function __construct(array $vars=array(), + public function __construct(array $vars= [], ISecureRandom $secureRandom = null, IConfig $config, CsrfTokenManager $csrfTokenManager = null, - $stream = 'php://input') { + string $stream = 'php://input') { $this->inputStream = $stream; - $this->items['params'] = array(); + $this->items['params'] = []; $this->secureRandom = $secureRandom; $this->config = $config; $this->csrfTokenManager = $csrfTokenManager; @@ -149,7 +150,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { foreach($this->allowedKeys as $name) { $this->items[$name] = isset($vars[$name]) ? $vars[$name] - : array(); + : []; } $this->items['parameters'] = array_merge( @@ -175,8 +176,8 @@ class Request implements \ArrayAccess, \Countable, IRequest { * Countable method * @return int */ - public function count() { - return count(array_keys($this->items['parameters'])); + public function count(): int { + return \count($this->items['parameters']); } /** @@ -199,13 +200,15 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $offset The key to lookup * @return boolean */ - public function offsetExists($offset) { + public function offsetExists($offset): bool { return isset($this->items['parameters'][$offset]); } /** - * @see offsetExists - */ + * @see offsetExists + * @param string $offset + * @return mixed + */ public function offsetGet($offset) { return isset($this->items['parameters'][$offset]) ? $this->items['parameters'][$offset] @@ -213,15 +216,18 @@ class Request implements \ArrayAccess, \Countable, IRequest { } /** - * @see offsetExists - */ + * @see offsetExists + * @param string $offset + * @param mixed $value + */ public function offsetSet($offset, $value) { throw new \RuntimeException('You cannot change the contents of the request object'); } /** - * @see offsetExists - */ + * @see offsetExists + * @param string $offset + */ public function offsetUnset($offset) { throw new \RuntimeException('You cannot change the contents of the request object'); } @@ -284,7 +290,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @return bool */ public function __isset($name) { - if (in_array($name, $this->allowedKeys, true)) { + if (\in_array($name, $this->allowedKeys, true)) { return true; } return isset($this->items['parameters'][$name]); @@ -305,9 +311,9 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $name * @return string */ - public function getHeader($name) { + public function getHeader(string $name): string { - $name = strtoupper(str_replace(array('-'),array('_'),$name)); + $name = strtoupper(str_replace('-', '_',$name)); if (isset($this->server['HTTP_' . $name])) { return $this->server['HTTP_' . $name]; } @@ -340,7 +346,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param mixed $default If the key is not found, this value will be returned * @return mixed the content of the array */ - public function getParam($key, $default = null) { + public function getParam(string $key, $default = null) { return isset($this->parameters[$key]) ? $this->parameters[$key] : $default; @@ -351,7 +357,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * (as GET or POST) or throuh the URL by the route * @return array the array with all parameters */ - public function getParams() { + public function getParams(): array { return $this->parameters; } @@ -359,7 +365,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * Returns the method of the request * @return string the method of the request (POST, GET, etc) */ - public function getMethod() { + public function getMethod(): string { return $this->method; } @@ -368,7 +374,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $key the key that will be taken from the $_FILES array * @return array the file in the $_FILES element */ - public function getUploadedFile($key) { + public function getUploadedFile(string $key) { return isset($this->files[$key]) ? $this->files[$key] : null; } @@ -377,7 +383,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $key the key that will be taken from the $_ENV array * @return array the value in the $_ENV element */ - public function getEnv($key) { + public function getEnv(string $key) { return isset($this->env[$key]) ? $this->env[$key] : null; } @@ -386,7 +392,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $key the key that will be taken from the $_COOKIE array * @return string the value in the $_COOKIE element */ - public function getCookie($key) { + public function getCookie(string $key) { return isset($this->cookies[$key]) ? $this->cookies[$key] : null; } @@ -435,7 +441,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { // 'application/json' must be decoded manually. if (strpos($this->getHeader('Content-Type'), 'application/json') !== false) { $params = json_decode(file_get_contents($this->inputStream), true); - if($params !== null && count($params) > 0) { + if($params !== null && \count($params) > 0) { $this->items['params'] = $params; if($this->method === 'POST') { $this->items['post'] = $params; @@ -449,12 +455,12 @@ class Request implements \ArrayAccess, \Countable, IRequest { && strpos($this->getHeader('Content-Type'), 'application/x-www-form-urlencoded') !== false) { parse_str(file_get_contents($this->inputStream), $params); - if(is_array($params)) { + if(\is_array($params)) { $this->items['params'] = $params; } } - if (is_array($params)) { + if (\is_array($params)) { $this->items['parameters'] = array_merge($this->items['parameters'], $params); } $this->contentDecoded = true; @@ -465,7 +471,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * Checks if the CSRF check was correct * @return bool true if CSRF check passed */ - public function passesCSRFCheck() { + public function passesCSRFCheck(): bool { if($this->csrfTokenManager === null) { return false; } @@ -494,7 +500,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * * @return bool */ - private function cookieCheckRequired() { + private function cookieCheckRequired(): bool { if ($this->getHeader('OCS-APIREQUEST')) { return false; } @@ -510,7 +516,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * * @return array */ - public function getCookieParams() { + public function getCookieParams(): array { return session_get_cookie_params(); } @@ -520,7 +526,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $name * @return string */ - protected function getProtectedCookieName($name) { + protected function getProtectedCookieName(string $name): string { $cookieParams = $this->getCookieParams(); $prefix = ''; if($cookieParams['secure'] === true && $cookieParams['path'] === '/') { @@ -537,7 +543,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @return bool * @since 9.1.0 */ - public function passesStrictCookieCheck() { + public function passesStrictCookieCheck(): bool { if(!$this->cookieCheckRequired()) { return true; } @@ -557,7 +563,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @return bool * @since 9.1.0 */ - public function passesLaxCookieCheck() { + public function passesLaxCookieCheck(): bool { if(!$this->cookieCheckRequired()) { return true; } @@ -575,7 +581,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * If `mod_unique_id` is installed this value will be taken. * @return string */ - public function getId() { + public function getId(): string { if(isset($this->server['UNIQUE_ID'])) { return $this->server['UNIQUE_ID']; } @@ -595,11 +601,11 @@ class Request implements \ArrayAccess, \Countable, IRequest { * Do always use this instead of $_SERVER['REMOTE_ADDR'] * @return string IP address */ - public function getRemoteAddress() { + public function getRemoteAddress(): string { $remoteAddress = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''; $trustedProxies = $this->config->getSystemValue('trusted_proxies', []); - if(is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) { + if(\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies)) { $forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', [ 'HTTP_X_FORWARDED_FOR' // only have one default, so we cannot ship an insecure product out of the box @@ -625,7 +631,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param string $type * @return bool */ - private function isOverwriteCondition($type = '') { + private function isOverwriteCondition(string $type = ''): bool { $regex = '/' . $this->config->getSystemValue('overwritecondaddr', '') . '/'; $remoteAddr = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''; return $regex === '//' || preg_match($regex, $remoteAddr) === 1 @@ -637,7 +643,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * and load balancers * @return string Server protocol (http or https) */ - public function getServerProtocol() { + public function getServerProtocol(): string { if($this->config->getSystemValue('overwriteprotocol') !== '' && $this->isOverwriteCondition('protocol')) { return $this->config->getSystemValue('overwriteprotocol'); @@ -671,8 +677,12 @@ class Request implements \ArrayAccess, \Countable, IRequest { * * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0. */ - public function getHttpProtocol() { - $claimedProtocol = strtoupper($this->server['SERVER_PROTOCOL']); + public function getHttpProtocol(): string { + $claimedProtocol = $this->server['SERVER_PROTOCOL']; + + if (\is_string($claimedProtocol)) { + $claimedProtocol = strtoupper($claimedProtocol); + } $validProtocols = [ 'HTTP/1.0', @@ -680,7 +690,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { 'HTTP/2', ]; - if(in_array($claimedProtocol, $validProtocols, true)) { + if(\in_array($claimedProtocol, $validProtocols, true)) { return $claimedProtocol; } @@ -692,10 +702,10 @@ class Request implements \ArrayAccess, \Countable, IRequest { * reverse proxies * @return string */ - public function getRequestUri() { + public function getRequestUri(): string { $uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : ''; if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) { - $uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME'])); + $uri = $this->getScriptName() . substr($uri, \strlen($this->server['SCRIPT_NAME'])); } return $uri; } @@ -705,7 +715,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @throws \Exception * @return string Path info */ - public function getRawPathInfo() { + public function getRawPathInfo(): string { $requestUri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : ''; // remove too many leading slashes - can be caused by reverse proxy configuration if (strpos($requestUri, '/') === 0) { @@ -727,16 +737,20 @@ class Request implements \ArrayAccess, \Countable, IRequest { list($path, $name) = \Sabre\Uri\split($scriptName); if (!empty($path)) { if($path === $pathInfo || strpos($pathInfo, $path.'/') === 0) { - $pathInfo = substr($pathInfo, strlen($path)); + $pathInfo = substr($pathInfo, \strlen($path)); } else { throw new \Exception("The requested uri($requestUri) cannot be processed by the script '$scriptName')"); } } + if ($name === null) { + $name = ''; + } + if (strpos($pathInfo, '/'.$name) === 0) { - $pathInfo = substr($pathInfo, strlen($name) + 1); + $pathInfo = substr($pathInfo, \strlen($name) + 1); } - if (strpos($pathInfo, $name) === 0) { - $pathInfo = substr($pathInfo, strlen($name)); + if ($name !== '' && strpos($pathInfo, $name) === 0) { + $pathInfo = substr($pathInfo, \strlen($name)); } if($pathInfo === false || $pathInfo === '/'){ return ''; @@ -770,13 +784,13 @@ class Request implements \ArrayAccess, \Countable, IRequest { * reverse proxies * @return string the script name */ - public function getScriptName() { + public function getScriptName(): string { $name = $this->server['SCRIPT_NAME']; $overwriteWebRoot = $this->config->getSystemValue('overwritewebroot'); if ($overwriteWebRoot !== '' && $this->isOverwriteCondition()) { // FIXME: This code is untestable due to __DIR__, also that hardcoded path is really dangerous - $serverRoot = str_replace('\\', '/', substr(__DIR__, 0, -strlen('lib/private/appframework/http/'))); - $suburi = str_replace('\\', '/', substr(realpath($this->server['SCRIPT_FILENAME']), strlen($serverRoot))); + $serverRoot = str_replace('\\', '/', substr(__DIR__, 0, -\strlen('lib/private/appframework/http/'))); + $suburi = str_replace('\\', '/', substr(realpath($this->server['SCRIPT_FILENAME']), \strlen($serverRoot))); $name = '/' . ltrim($overwriteWebRoot . $suburi, '/'); } return $name; @@ -787,7 +801,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param array $agent array of agent names * @return bool true if at least one of the given agent matches, false otherwise */ - public function isUserAgent(array $agent) { + public function isUserAgent(array $agent): bool { if (!isset($this->server['HTTP_USER_AGENT'])) { return false; } @@ -804,7 +818,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * whether it is a trusted domain * @return string Server host */ - public function getInsecureServerHost() { + public function getInsecureServerHost(): string { $host = 'localhost'; if (isset($this->server['HTTP_X_FORWARDED_HOST'])) { if (strpos($this->server['HTTP_X_FORWARDED_HOST'], ',') !== false) { @@ -829,7 +843,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { * trusted domain if the host isn't in the trusted list * @return string Server host */ - public function getServerHost() { + public function getServerHost(): string { // overwritehost is always trusted $host = $this->getOverwriteHost(); if ($host !== null) { diff --git a/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php b/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php index 60d2ae8b5c9..e1262b6c712 100644 --- a/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php +++ b/lib/private/AppFramework/Middleware/MiddlewareDispatcher.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -30,7 +31,7 @@ namespace OC\AppFramework\Middleware; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Response; -use OCP\AppFramework\MiddleWare; +use OCP\AppFramework\Middleware; /** * This class is used to store and run all the middleware in correct order @@ -53,7 +54,7 @@ class MiddlewareDispatcher { * Constructor */ public function __construct(){ - $this->middlewares = array(); + $this->middlewares = []; $this->middlewareCounter = 0; } @@ -71,7 +72,7 @@ class MiddlewareDispatcher { * returns an array with all middleware elements * @return array the middlewares */ - public function getMiddlewares(){ + public function getMiddlewares(): array { return $this->middlewares; } @@ -84,10 +85,10 @@ class MiddlewareDispatcher { * @param string $methodName the name of the method that will be called on * the controller */ - public function beforeController(Controller $controller, $methodName){ + public function beforeController(Controller $controller, string $methodName){ // we need to count so that we know which middlewares we have to ask in // case there is an exception - $middlewareCount = count($this->middlewares); + $middlewareCount = \count($this->middlewares); for($i = 0; $i < $middlewareCount; $i++){ $this->middlewareCounter++; $middleware = $this->middlewares[$i]; @@ -111,7 +112,7 @@ class MiddlewareDispatcher { * exception * @throws \Exception the passed in exception if it can't handle it */ - public function afterException(Controller $controller, $methodName, \Exception $exception){ + public function afterException(Controller $controller, string $methodName, \Exception $exception): Response { for($i=$this->middlewareCounter-1; $i>=0; $i--){ $middleware = $this->middlewares[$i]; try { @@ -134,8 +135,8 @@ class MiddlewareDispatcher { * @param Response $response the generated response from the controller * @return Response a Response object */ - public function afterController(Controller $controller, $methodName, Response $response){ - for($i=count($this->middlewares)-1; $i>=0; $i--){ + public function afterController(Controller $controller, string $methodName, Response $response): Response { + for($i= \count($this->middlewares)-1; $i>=0; $i--){ $middleware = $this->middlewares[$i]; $response = $middleware->afterController($controller, $methodName, $response); } @@ -153,8 +154,8 @@ class MiddlewareDispatcher { * @param string $output the generated output from a response * @return string the output that should be printed */ - public function beforeOutput(Controller $controller, $methodName, $output){ - for($i=count($this->middlewares)-1; $i>=0; $i--){ + public function beforeOutput(Controller $controller, string $methodName, string $output): string { + for($i= \count($this->middlewares)-1; $i>=0; $i--){ $middleware = $this->middlewares[$i]; $output = $middleware->beforeOutput($controller, $methodName, $output); } diff --git a/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php b/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php index 79359b142ac..e09dfdfcb87 100644 --- a/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php @@ -26,7 +26,6 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Security\Bruteforce\Throttler; -use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Middleware; use OCP\IRequest; diff --git a/lib/private/AppFramework/Middleware/Security/RateLimitingMiddleware.php b/lib/private/AppFramework/Middleware/Security/RateLimitingMiddleware.php index c3b5a844ed5..dca761bdfc0 100644 --- a/lib/private/AppFramework/Middleware/Security/RateLimitingMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/RateLimitingMiddleware.php @@ -27,7 +27,6 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Security\RateLimiting\Exception\RateLimitExceededException; use OC\Security\RateLimiting\Limiter; -use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Middleware; diff --git a/lib/private/AppFramework/Utility/ControllerMethodReflector.php b/lib/private/AppFramework/Utility/ControllerMethodReflector.php index 7c777c52c12..ef4a1959d66 100644 --- a/lib/private/AppFramework/Utility/ControllerMethodReflector.php +++ b/lib/private/AppFramework/Utility/ControllerMethodReflector.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -42,32 +43,34 @@ class ControllerMethodReflector implements IControllerMethodReflector { * @param object $object an object or classname * @param string $method the method which we want to inspect */ - public function reflect($object, $method){ + public function reflect($object, string $method){ $reflection = new \ReflectionMethod($object, $method); $docs = $reflection->getDocComment(); - // extract everything prefixed by @ and first letter uppercase - preg_match_all('/^\h+\*\h+@(?P<annotation>[A-Z]\w+)((?P<parameter>.*))?$/m', $docs, $matches); - foreach($matches['annotation'] as $key => $annontation) { - $annotationValue = $matches['parameter'][$key]; - if(isset($annotationValue[0]) && $annotationValue[0] === '(' && $annotationValue[strlen($annotationValue) - 1] === ')') { - $cutString = substr($annotationValue, 1, -1); - $cutString = str_replace(' ', '', $cutString); - $splittedArray = explode(',', $cutString); - foreach($splittedArray as $annotationValues) { - list($key, $value) = explode('=', $annotationValues); - $this->annotations[$annontation][$key] = $value; + if ($docs !== false) { + // extract everything prefixed by @ and first letter uppercase + preg_match_all('/^\h+\*\h+@(?P<annotation>[A-Z]\w+)((?P<parameter>.*))?$/m', $docs, $matches); + foreach ($matches['annotation'] as $key => $annontation) { + $annotationValue = $matches['parameter'][$key]; + if (isset($annotationValue[0]) && $annotationValue[0] === '(' && $annotationValue[\strlen($annotationValue) - 1] === ')') { + $cutString = substr($annotationValue, 1, -1); + $cutString = str_replace(' ', '', $cutString); + $splittedArray = explode(',', $cutString); + foreach ($splittedArray as $annotationValues) { + list($key, $value) = explode('=', $annotationValues); + $this->annotations[$annontation][$key] = $value; + } + continue; } - continue; + + $this->annotations[$annontation] = [$annotationValue]; } - $this->annotations[$annontation] = [$annotationValue]; + // extract type parameter information + preg_match_all('/@param\h+(?P<type>\w+)\h+\$(?P<var>\w+)/', $docs, $matches); + $this->types = array_combine($matches['var'], $matches['type']); } - // extract type parameter information - preg_match_all('/@param\h+(?P<type>\w+)\h+\$(?P<var>\w+)/', $docs, $matches); - $this->types = array_combine($matches['var'], $matches['type']); - foreach ($reflection->getParameters() as $param) { // extract type information from PHP 7 scalar types and prefer them // over phpdoc annotations @@ -78,10 +81,9 @@ class ControllerMethodReflector implements IControllerMethodReflector { } } + $default = null; if($param->isOptional()) { $default = $param->getDefaultValue(); - } else { - $default = null; } $this->parameters[$param->name] = $default; } @@ -94,18 +96,18 @@ class ControllerMethodReflector implements IControllerMethodReflector { * @return string|null type in the type parameters (@param int $something) * would return int or null if not existing */ - public function getType($parameter) { + public function getType(string $parameter) { if(array_key_exists($parameter, $this->types)) { return $this->types[$parameter]; - } else { - return null; } + + return null; } /** * @return array the arguments of the method with key => default value */ - public function getParameters() { + public function getParameters(): array { return $this->parameters; } @@ -114,7 +116,7 @@ class ControllerMethodReflector implements IControllerMethodReflector { * @param string $name the name of the annotation * @return bool true if the annotation is found */ - public function hasAnnotation($name) { + public function hasAnnotation(string $name): bool { return array_key_exists($name, $this->annotations); } @@ -125,7 +127,7 @@ class ControllerMethodReflector implements IControllerMethodReflector { * @param string $key the string of the annotation * @return string */ - public function getAnnotationParameter($name, $key) { + public function getAnnotationParameter(string $name, string $key): string { if(isset($this->annotations[$name][$key])) { return $this->annotations[$name][$key]; } diff --git a/lib/private/Avatar.php b/lib/private/Avatar.php index 4cacc801689..14632075ca1 100644 --- a/lib/private/Avatar.php +++ b/lib/private/Avatar.php @@ -263,7 +263,7 @@ class Avatar implements IAvatar { * @return string */ private function generateAvatar($userDisplayName, $size) { - $text = strtoupper($userDisplayName[0]); + $text = mb_strtoupper(mb_substr($userDisplayName, 0, 1), 'UTF-8'); $backgroundColor = $this->avatarBackgroundColor($userDisplayName); $im = imagecreatetruecolor($size, $size); @@ -271,7 +271,7 @@ class Avatar implements IAvatar { $white = imagecolorallocate($im, 255, 255, 255); imagefilledrectangle($im, 0, 0, $size, $size, $background); - $font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.woff'; + $font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf'; $fontSize = $size * 0.4; $box = imagettfbbox($fontSize, 0, $font, $text); diff --git a/lib/private/Collaboration/Collaborators/MailPlugin.php b/lib/private/Collaboration/Collaborators/MailPlugin.php index 2d85ff334bc..b4964825182 100644 --- a/lib/private/Collaboration/Collaborators/MailPlugin.php +++ b/lib/private/Collaboration/Collaborators/MailPlugin.php @@ -175,6 +175,8 @@ class MailPlugin implements ISearchPlugin { if (!$this->shareeEnumeration) { $result['wide'] = []; + } else { + $result['wide'] = array_slice($result['wide'], $offset, $limit); } if (!$searchResult->hasExactIdMatch($emailType) && filter_var($search, FILTER_VALIDATE_EMAIL)) { diff --git a/lib/private/Collaboration/Collaborators/RemotePlugin.php b/lib/private/Collaboration/Collaborators/RemotePlugin.php index b17a64e4ff1..e0f5298f83b 100644 --- a/lib/private/Collaboration/Collaborators/RemotePlugin.php +++ b/lib/private/Collaboration/Collaborators/RemotePlugin.php @@ -102,6 +102,8 @@ class RemotePlugin implements ISearchPlugin { if (!$this->shareeEnumeration) { $result['wide'] = []; + } else { + $result['wide'] = array_slice($result['wide'], $offset, $limit); } if (!$searchResult->hasExactIdMatch($resultType) && $this->cloudIdManager->isValidCloudId($search) && $offset === 0) { diff --git a/lib/private/Contacts/ContactsMenu/ContactsStore.php b/lib/private/Contacts/ContactsMenu/ContactsStore.php index 43600470e1f..73319151d6e 100644 --- a/lib/private/Contacts/ContactsMenu/ContactsStore.php +++ b/lib/private/Contacts/ContactsMenu/ContactsStore.php @@ -27,14 +27,12 @@ namespace OC\Contacts\ContactsMenu; -use OC\Share\Share; use OCP\Contacts\ContactsMenu\IEntry; use OCP\Contacts\IManager; use OCP\IConfig; use OCP\IGroupManager; use OCP\IUser; use OCP\IUserManager; -use OCP\IUserSession; use OCP\Contacts\ContactsMenu\IContactsStore; class ContactsStore implements IContactsStore { diff --git a/lib/private/DB/MigrationService.php b/lib/private/DB/MigrationService.php index 29f717b886c..77ac23fe5d2 100644 --- a/lib/private/DB/MigrationService.php +++ b/lib/private/DB/MigrationService.php @@ -31,8 +31,6 @@ use OCP\AppFramework\QueryException; use OCP\IDBConnection; use OCP\Migration\IMigrationStep; use OCP\Migration\IOutput; -use Doctrine\DBAL\Schema\Column; -use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; class MigrationService { diff --git a/lib/private/DB/SchemaWrapper.php b/lib/private/DB/SchemaWrapper.php index 4f05b7b00ef..35aae082699 100644 --- a/lib/private/DB/SchemaWrapper.php +++ b/lib/private/DB/SchemaWrapper.php @@ -23,7 +23,6 @@ namespace OC\DB; -use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Schema\Schema; use OCP\DB\ISchemaWrapper; use OCP\IDBConnection; diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php index 384e6e5e457..cc655018f8d 100644 --- a/lib/private/Files/Config/UserMountCache.php +++ b/lib/private/Files/Config/UserMountCache.php @@ -25,7 +25,6 @@ namespace OC\Files\Config; -use OC\DB\QueryBuilder\Literal; use OCA\Files_Sharing\SharedMount; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Config\ICachedMountFileInfo; diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php index defeda4c21a..280a8efa81c 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -23,10 +23,7 @@ namespace OC\Files\ObjectStore; -use Aws\Exception\MultipartUploadException; -use Aws\S3\MultipartUploader; use Aws\S3\S3Client; -use Psr\Http\Message\StreamInterface; const S3_UPLOAD_PART_SIZE = 524288000; // 500MB diff --git a/lib/private/Files/ObjectStore/Swift.php b/lib/private/Files/ObjectStore/Swift.php index a3cba488f5f..4451fbcc750 100644 --- a/lib/private/Files/ObjectStore/Swift.php +++ b/lib/private/Files/ObjectStore/Swift.php @@ -25,223 +25,37 @@ namespace OC\Files\ObjectStore; -use Guzzle\Http\Exception\ClientErrorResponseException; -use Guzzle\Http\Exception\CurlException; +use function GuzzleHttp\Psr7\stream_for; use Icewind\Streams\RetryWrapper; use OCP\Files\ObjectStore\IObjectStore; use OCP\Files\StorageAuthException; -use OCP\Files\StorageNotAvailableException; -use OpenCloud\Common\Service\Catalog; -use OpenCloud\Common\Service\CatalogItem; -use OpenCloud\Identity\Resource\Token; -use OpenCloud\ObjectStore\Service; -use OpenCloud\OpenStack; -use OpenCloud\Rackspace; class Swift implements IObjectStore { - - /** - * @var \OpenCloud\OpenStack - */ - private $client; - /** * @var array */ private $params; /** - * @var \OpenCloud\ObjectStore\Service - */ - private $objectStoreService; - - /** - * @var \OpenCloud\ObjectStore\Resource\Container + * @var \OpenStack\ObjectStore\v1\Models\Container|null */ - private $container; - - private $memcache; - - public function __construct($params) { - if (isset($params['bucket'])) { - $params['container'] = $params['bucket']; - } - if (!isset($params['container'])) { - $params['container'] = 'owncloud'; - } - if (!isset($params['autocreate'])) { - // should only be true for tests - $params['autocreate'] = false; - } - - if (isset($params['apiKey'])) { - $this->client = new Rackspace($params['url'], $params); - $cacheKey = $params['username'] . '@' . $params['url'] . '/' . $params['bucket']; - } else { - $this->client = new OpenStack($params['url'], $params); - $cacheKey = $params['username'] . '@' . $params['url'] . '/' . $params['bucket']; - } + private $container = null; - $cacheFactory = \OC::$server->getMemCacheFactory(); - $this->memcache = $cacheFactory->createDistributed('swift::' . $cacheKey); + /** @var SwiftFactory */ + private $swiftFactory; + public function __construct($params, SwiftFactory $connectionFactory = null) { + $this->swiftFactory = $connectionFactory ?: new SwiftFactory(\OC::$server->getMemCacheFactory()->createDistributed('swift::'), $params); $this->params = $params; } /** - * @suppress PhanNonClassMethodCall - */ - protected function init() { - if ($this->container) { - return; - } - - $this->importToken(); - - /** @var Token $token */ - $token = $this->client->getTokenObject(); - - if (!$token || $token->hasExpired()) { - try { - $this->client->authenticate(); - $this->exportToken(); - } catch (ClientErrorResponseException $e) { - $statusCode = $e->getResponse()->getStatusCode(); - if ($statusCode == 412) { - throw new StorageAuthException('Precondition failed, verify the keystone url', $e); - } else if ($statusCode === 401) { - throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e); - } else { - throw new StorageAuthException('Unknown error', $e); - } - } - } - - - /** @var Catalog $catalog */ - $catalog = $this->client->getCatalog(); - - if (count($catalog->getItems()) === 0) { - throw new StorageAuthException('Keystone did not provide a valid catalog, verify the credentials'); - } - - if (isset($this->params['serviceName'])) { - $serviceName = $this->params['serviceName']; - } else { - $serviceName = Service::DEFAULT_NAME; - } - - if (isset($this->params['urlType'])) { - $urlType = $this->params['urlType']; - if ($urlType !== 'internalURL' && $urlType !== 'publicURL') { - throw new StorageNotAvailableException('Invalid url type'); - } - } else { - $urlType = Service::DEFAULT_URL_TYPE; - } - - $catalogItem = $this->getCatalogForService($catalog, $serviceName); - if (!$catalogItem) { - $available = implode(', ', $this->getAvailableServiceNames($catalog)); - throw new StorageNotAvailableException( - "Service $serviceName not found in service catalog, available services: $available" - ); - } else if (isset($this->params['region'])) { - $this->validateRegion($catalogItem, $this->params['region']); - } - - $this->objectStoreService = $this->client->objectStoreService($serviceName, $this->params['region'], $urlType); - - try { - $this->container = $this->objectStoreService->getContainer($this->params['container']); - } catch (ClientErrorResponseException $ex) { - // if the container does not exist and autocreate is true try to create the container on the fly - if (isset($this->params['autocreate']) && $this->params['autocreate'] === true) { - $this->container = $this->objectStoreService->createContainer($this->params['container']); - } else { - throw $ex; - } - } catch (CurlException $e) { - if ($e->getErrorNo() === 7) { - $host = $e->getCurlHandle()->getUrl()->getHost() . ':' . $e->getCurlHandle()->getUrl()->getPort(); - \OC::$server->getLogger()->error("Can't connect to object storage server at $host"); - throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e); - } - throw $e; - } - } - - private function exportToken() { - $export = $this->client->exportCredentials(); - $export['catalog'] = array_map(function (CatalogItem $item) { - return [ - 'name' => $item->getName(), - 'endpoints' => $item->getEndpoints(), - 'type' => $item->getType() - ]; - }, $export['catalog']->getItems()); - $this->memcache->set('token', json_encode($export)); - } - - private function importToken() { - $cachedTokenString = $this->memcache->get('token'); - if ($cachedTokenString) { - $cachedToken = json_decode($cachedTokenString, true); - $cachedToken['catalog'] = array_map(function (array $item) { - $itemClass = new \stdClass(); - $itemClass->name = $item['name']; - $itemClass->endpoints = array_map(function (array $endpoint) { - return (object)$endpoint; - }, $item['endpoints']); - $itemClass->type = $item['type']; - - return $itemClass; - }, $cachedToken['catalog']); - try { - $this->client->importCredentials($cachedToken); - } catch (\Exception $e) { - $this->client->setTokenObject(new Token()); - } - } - } - - /** - * @param Catalog $catalog - * @param $name - * @return null|CatalogItem + * @return \OpenStack\ObjectStore\v1\Models\Container + * @throws StorageAuthException + * @throws \OCP\Files\StorageNotAvailableException */ - private function getCatalogForService(Catalog $catalog, $name) { - foreach ($catalog->getItems() as $item) { - /** @var CatalogItem $item */ - if ($item->hasType(Service::DEFAULT_TYPE) && $item->hasName($name)) { - return $item; - } - } - - return null; - } - - private function validateRegion(CatalogItem $item, $region) { - $endPoints = $item->getEndpoints(); - foreach ($endPoints as $endPoint) { - if ($endPoint->region === $region) { - return; - } - } - - $availableRegions = implode(', ', array_map(function ($endpoint) { - return $endpoint->region; - }, $endPoints)); - - throw new StorageNotAvailableException("Invalid region '$region', available regions: $availableRegions"); - } - - private function getAvailableServiceNames(Catalog $catalog) { - return array_map(function (CatalogItem $item) { - return $item->getName(); - }, array_filter($catalog->getItems(), function (CatalogItem $item) { - return $item->hasType(Service::DEFAULT_TYPE); - })); + private function getContainer() { + return $this->swiftFactory->getContainer(); } /** @@ -254,29 +68,29 @@ class Swift implements IObjectStore { /** * @param string $urn the unified resource name used to identify the object * @param resource $stream stream with the data to write - * @throws Exception from openstack lib when something goes wrong + * @throws \Exception from openstack lib when something goes wrong */ public function writeObject($urn, $stream) { - $this->init(); - $this->container->uploadObject($urn, $stream); + $this->getContainer()->createObject([ + 'name' => $urn, + 'stream' => stream_for($stream) + ]); } /** * @param string $urn the unified resource name used to identify the object * @return resource stream with the read data - * @throws Exception from openstack lib when something goes wrong + * @throws \Exception from openstack lib when something goes wrong */ public function readObject($urn) { - $this->init(); - $object = $this->container->getObject($urn); + $object = $this->getContainer()->getObject($urn); // we need to keep a reference to objectContent or // the stream will be closed before we can do anything with it - /** @var $objectContent \Guzzle\Http\EntityBody * */ - $objectContent = $object->getContent(); + $objectContent = $object->download(); $objectContent->rewind(); - $stream = $objectContent->getStream(); + $stream = $objectContent->detach(); // save the object content in the context of the stream to prevent it being gc'd until the stream is closed stream_context_set_option($stream, 'swift', 'content', $objectContent); @@ -286,17 +100,18 @@ class Swift implements IObjectStore { /** * @param string $urn Unified Resource Name * @return void - * @throws Exception from openstack lib when something goes wrong + * @throws \Exception from openstack lib when something goes wrong */ public function deleteObject($urn) { - $this->init(); - // see https://github.com/rackspace/php-opencloud/issues/243#issuecomment-30032242 - $this->container->dataObject()->setName($urn)->delete(); + $this->getContainer()->getObject($urn)->delete(); } - public function deleteContainer($recursive = false) { - $this->init(); - $this->container->delete($recursive); + /** + * @return void + * @throws \Exception from openstack lib when something goes wrong + */ + public function deleteContainer() { + $this->getContainer()->delete(); } } diff --git a/lib/private/Files/ObjectStore/SwiftFactory.php b/lib/private/Files/ObjectStore/SwiftFactory.php new file mode 100644 index 00000000000..0df6fb6efcd --- /dev/null +++ b/lib/private/Files/ObjectStore/SwiftFactory.php @@ -0,0 +1,174 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Files\ObjectStore; + +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Exception\RequestException; +use GuzzleHttp\HandlerStack; +use OCP\Files\StorageAuthException; +use OCP\Files\StorageNotAvailableException; +use OCP\ICache; +use OpenStack\Common\Error\BadResponseError; +use OpenStack\Identity\v2\Models\Token; +use OpenStack\Identity\v2\Service; +use OpenStack\OpenStack; +use OpenStack\Common\Transport\Utils as TransportUtils; +use Psr\Http\Message\RequestInterface; +use OpenStack\ObjectStore\v1\Models\Container; + +class SwiftFactory { + private $cache; + private $params; + /** @var Container|null */ + private $container = null; + + public function __construct(ICache $cache, array $params) { + $this->cache = $cache; + $this->params = $params; + } + + private function getCachedToken(string $cacheKey) { + $cachedTokenString = $this->cache->get($cacheKey . '/token'); + if ($cachedTokenString) { + return json_decode($cachedTokenString); + } else { + return null; + } + } + + private function cacheToken(Token $token, string $cacheKey) { + $this->cache->set($cacheKey . '/token', json_encode($token)); + } + + /** + * @return OpenStack + * @throws StorageAuthException + */ + private function getClient() { + if (isset($this->params['bucket'])) { + $this->params['container'] = $this->params['bucket']; + } + if (!isset($this->params['container'])) { + $this->params['container'] = 'owncloud'; + } + if (!isset($this->params['autocreate'])) { + // should only be true for tests + $this->params['autocreate'] = false; + } + if (!isset($this->params['username']) && isset($this->params['user'])) { + $this->params['username'] = $this->params['user']; + } + if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) { + $this->params['tenantName'] = $this->params['tenant']; + } + + $cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket']; + $token = $this->getCachedToken($cacheKey); + $hasToken = is_array($token) && (new \DateTimeImmutable($token['expires_at'])) > (new \DateTimeImmutable('now')); + if ($hasToken) { + $this->params['cachedToken'] = $token; + } + $httpClient = new Client([ + 'base_uri' => TransportUtils::normalizeUrl($this->params['url']), + 'handler' => HandlerStack::create() + ]); + + $authService = Service::factory($httpClient); + $this->params['identityService'] = $authService; + $this->params['authUrl'] = $this->params['url']; + $client = new OpenStack($this->params); + + if (!$hasToken) { + try { + $token = $authService->generateToken($this->params); + $this->cacheToken($token, $cacheKey); + } catch (ConnectException $e) { + throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e); + } catch (ClientException $e) { + $statusCode = $e->getResponse()->getStatusCode(); + if ($statusCode === 404) { + throw new StorageAuthException('Keystone not found, verify the keystone url', $e); + } else if ($statusCode === 412) { + throw new StorageAuthException('Precondition failed, verify the keystone url', $e); + } else if ($statusCode === 401) { + throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e); + } else { + throw new StorageAuthException('Unknown error', $e); + } + } catch (RequestException $e) { + throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e); + } + } + + return $client; + } + + /** + * @return \OpenStack\ObjectStore\v1\Models\Container + * @throws StorageAuthException + * @throws StorageNotAvailableException + */ + public function getContainer() { + if (is_null($this->container)) { + $this->container = $this->createContainer(); + } + + return $this->container; + } + + /** + * @return \OpenStack\ObjectStore\v1\Models\Container + * @throws StorageAuthException + * @throws StorageNotAvailableException + */ + private function createContainer() { + $client = $this->getClient(); + $objectStoreService = $client->objectStoreV1(); + + $autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true; + try { + $container = $objectStoreService->getContainer($this->params['container']); + if ($autoCreate) { + $container->getMetadata(); + } + return $container; + } catch (BadResponseError $ex) { + // if the container does not exist and autocreate is true try to create the container on the fly + if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) { + return $objectStoreService->createContainer([ + 'name' => $this->params['container'] + ]); + } else { + throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $e); + } + } catch (ConnectException $e) { + /** @var RequestInterface $request */ + $request = $e->getRequest(); + $host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort(); + \OC::$server->getLogger()->error("Can't connect to object storage server at $host"); + throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e); + } + } +} diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php index f9c6175308c..1496fda5140 100644 --- a/lib/private/Files/Storage/DAV.php +++ b/lib/private/Files/Storage/DAV.php @@ -35,7 +35,7 @@ namespace OC\Files\Storage; use Exception; use GuzzleHttp\Exception\RequestException; -use GuzzleHttp\Message\ResponseInterface; +use Psr\Http\Message\ResponseInterface; use Icewind\Streams\CallbackWrapper; use OC\Files\Filesystem; use Icewind\Streams\IteratorDirectory; @@ -344,7 +344,7 @@ class DAV extends Common { 'auth' => [$this->user, $this->password], 'stream' => true ]); - } catch (RequestException $e) { + } catch (\GuzzleHttp\Exception\ClientException $e) { if ($e->getResponse() instanceof ResponseInterface && $e->getResponse()->getStatusCode() === 404) { return false; diff --git a/lib/private/Http/Client/Client.php b/lib/private/Http/Client/Client.php index 4e6843d7b9f..0387fcabfaf 100644 --- a/lib/private/Http/Client/Client.php +++ b/lib/private/Http/Client/Client.php @@ -25,10 +25,13 @@ declare(strict_types=1); namespace OC\Http\Client; use GuzzleHttp\Client as GuzzleClient; +use GuzzleHttp\HandlerStack; +use GuzzleHttp\Middleware; use OCP\Http\Client\IClient; use OCP\Http\Client\IResponse; use OCP\ICertificateManager; use OCP\IConfig; +use Psr\Http\Message\RequestInterface; /** * Class Client @@ -43,17 +46,23 @@ class Client implements IClient { /** @var ICertificateManager */ private $certificateManager; private $configured = false; + /** @var HandlerStack */ + private $stack; /** * @param IConfig $config * @param ICertificateManager $certificateManager * @param GuzzleClient $client */ - public function __construct(IConfig $config, - ICertificateManager $certificateManager, - GuzzleClient $client) { + public function __construct( + IConfig $config, + ICertificateManager $certificateManager, + GuzzleClient $client, + HandlerStack $stack + ) { $this->config = $config; $this->client = $client; + $this->stack = $stack; $this->certificateManager = $certificateManager; } @@ -65,25 +74,37 @@ class Client implements IClient { return; } $this->configured = true; - // Either use user bundle or the system bundle if nothing is specified + + $this->stack->push(Middleware::mapRequest(function (RequestInterface $request) { + return $request + ->withHeader('User-Agent', 'Nextcloud Server Crawler'); + })); + } + + private function getRequestOptions() { + $options = [ + 'verify' => $this->getCertBundle(), + ]; + $proxyUri = $this->getProxyUri(); + if ($proxyUri !== '') { + $options['proxy'] = $proxyUri; + } + return $options; + } + + private function getCertBundle() { if ($this->certificateManager->listCertificates() !== []) { - $this->client->setDefaultOption('verify', $this->certificateManager->getAbsoluteBundlePath()); + return $this->certificateManager->getAbsoluteBundlePath(); } else { // If the instance is not yet setup we need to use the static path as // $this->certificateManager->getAbsoluteBundlePath() tries to instantiiate // a view if ($this->config->getSystemValue('installed', false)) { - $this->client->setDefaultOption('verify', $this->certificateManager->getAbsoluteBundlePath(null)); + return $this->certificateManager->getAbsoluteBundlePath(null); } else { - $this->client->setDefaultOption('verify', \OC::$SERVERROOT . '/resources/config/ca-bundle.crt'); + return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt'; } } - - $this->client->setDefaultOption('headers/User-Agent', 'Nextcloud Server Crawler'); - $proxyUri = $this->getProxyUri(); - if ($proxyUri !== '') { - $this->client->setDefaultOption('proxy', $proxyUri); - } } /** @@ -137,7 +158,7 @@ class Client implements IClient { */ public function get(string $uri, array $options = []): IResponse { $this->setDefaultOptions(); - $response = $this->client->get($uri, $options); + $response = $this->client->request('get', $uri, array_merge($options, $this->getRequestOptions())); $isStream = isset($options['stream']) && $options['stream']; return new Response($response, $isStream); } @@ -168,7 +189,7 @@ class Client implements IClient { */ public function head(string $uri, array $options = []): IResponse { $this->setDefaultOptions(); - $response = $this->client->head($uri, $options); + $response = $this->client->request('head', $uri, array_merge($options, $this->getRequestOptions())); return new Response($response); } @@ -203,7 +224,11 @@ class Client implements IClient { */ public function post(string $uri, array $options = []): IResponse { $this->setDefaultOptions(); - $response = $this->client->post($uri, $options); + if (isset($options['body']) && is_array($options['body'])) { + $options['form_params'] = $options['body']; + unset($options['body']); + } + $response = $this->client->request('post', $uri, array_merge($options, $this->getRequestOptions())); return new Response($response); } @@ -238,7 +263,7 @@ class Client implements IClient { */ public function put(string $uri, array $options = []): IResponse { $this->setDefaultOptions(); - $response = $this->client->put($uri, $options); + $response = $this->client->request('put', $uri, array_merge($options, $this->getRequestOptions())); return new Response($response); } @@ -273,7 +298,7 @@ class Client implements IClient { */ public function delete(string $uri, array $options = []): IResponse { $this->setDefaultOptions(); - $response = $this->client->delete($uri, $options); + $response = $this->client->request('delete', $uri, array_merge($options, $this->getRequestOptions())); return new Response($response); } @@ -309,7 +334,7 @@ class Client implements IClient { */ public function options(string $uri, array $options = []): IResponse { $this->setDefaultOptions(); - $response = $this->client->options($uri, $options); + $response = $this->client->request('options', $uri, array_merge($options, $this->getRequestOptions())); return new Response($response); } } diff --git a/lib/private/Http/Client/ClientService.php b/lib/private/Http/Client/ClientService.php index 1df54010a2d..fa8544f07a5 100644 --- a/lib/private/Http/Client/ClientService.php +++ b/lib/private/Http/Client/ClientService.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace OC\Http\Client; use GuzzleHttp\Client as GuzzleClient; +use GuzzleHttp\HandlerStack; use OCP\Http\Client\IClient; use OCP\Http\Client\IClientService; use OCP\ICertificateManager; @@ -54,6 +55,6 @@ class ClientService implements IClientService { * @return Client */ public function newClient(): IClient { - return new Client($this->config, $this->certificateManager, new GuzzleClient()); + return new Client($this->config, $this->certificateManager, new GuzzleClient(), HandlerStack::create()); } } diff --git a/lib/private/Http/Client/Response.php b/lib/private/Http/Client/Response.php index 0ce6cc98e0d..73c14c2926d 100644 --- a/lib/private/Http/Client/Response.php +++ b/lib/private/Http/Client/Response.php @@ -25,7 +25,7 @@ declare(strict_types=1); namespace OC\Http\Client; use OCP\Http\Client\IResponse; -use GuzzleHttp\Message\ResponseInterface as GuzzleResponse; +use Psr\Http\Message\ResponseInterface; /** * Class Response @@ -33,7 +33,7 @@ use GuzzleHttp\Message\ResponseInterface as GuzzleResponse; * @package OC\Http */ class Response implements IResponse { - /** @var GuzzleResponse */ + /** @var ResponseInterface */ private $response; /** @@ -42,10 +42,10 @@ class Response implements IResponse { private $stream; /** - * @param GuzzleResponse $response + * @param ResponseInterface $response * @param bool $stream */ - public function __construct(GuzzleResponse $response, $stream = false) { + public function __construct(ResponseInterface $response, $stream = false) { $this->response = $response; $this->stream = $stream; } @@ -71,7 +71,7 @@ class Response implements IResponse { * @return string */ public function getHeader(string $key): string { - return $this->response->getHeader($key); + return $this->response->getHeader($key)[0]; } /** diff --git a/lib/private/Installer.php b/lib/private/Installer.php index ad2dcb60f20..8a8ece82077 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -36,17 +36,12 @@ namespace OC; use Doctrine\DBAL\Exception\TableExistsException; -use OC\App\AppManager; use OC\App\AppStore\Bundles\Bundle; use OC\App\AppStore\Fetcher\AppFetcher; -use OC\App\CodeChecker\CodeChecker; -use OC\App\CodeChecker\EmptyCheck; -use OC\App\CodeChecker\PrivateCheck; use OC\Archive\TAR; use OC_App; use OC_DB; use OC_Helper; -use OCP\App\IAppManager; use OCP\Http\Client\IClientService; use OCP\IConfig; use OCP\ILogger; @@ -117,7 +112,7 @@ class Installer { ); } - $version = \OCP\Util::getVersion(); + $version = implode('.', \OCP\Util::getVersion()); if (!\OC_App::isAppCompatible($version, $info)) { throw new \Exception( // TODO $l diff --git a/lib/private/IntegrityCheck/Checker.php b/lib/private/IntegrityCheck/Checker.php index 771ac891ab4..44544b6770e 100644 --- a/lib/private/IntegrityCheck/Checker.php +++ b/lib/private/IntegrityCheck/Checker.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -97,9 +98,9 @@ class Checker { * * @return bool */ - public function isCodeCheckEnforced() { + public function isCodeCheckEnforced(): bool { $notSignedChannels = [ '', 'git']; - if (in_array($this->environmentHelper->getChannel(), $notSignedChannels, true)) { + if (\in_array($this->environmentHelper->getChannel(), $notSignedChannels, true)) { return false; } @@ -108,10 +109,9 @@ class Checker { * applicable for very specific scenarios and we should not advertise it * too prominent. So please do not add it to config.sample.php. */ + $isIntegrityCheckDisabled = false; if ($this->config !== null) { $isIntegrityCheckDisabled = $this->config->getSystemValue('integrity.check.disabled', false); - } else { - $isIntegrityCheckDisabled = false; } if ($isIntegrityCheckDisabled === true) { return false; @@ -128,7 +128,7 @@ class Checker { * @return \RecursiveIteratorIterator * @throws \Exception */ - private function getFolderIterator($folderToIterate, $root = '') { + private function getFolderIterator(string $folderToIterate, string $root = ''): \RecursiveIteratorIterator { $dirItr = new \RecursiveDirectoryIterator( $folderToIterate, \RecursiveDirectoryIterator::SKIP_DOTS @@ -156,12 +156,12 @@ class Checker { * @return array Array of hashes. */ private function generateHashes(\RecursiveIteratorIterator $iterator, - $path) { + string $path): array { $hashes = []; $copiedWebserverSettingFiles = false; $tmpFolder = ''; - $baseDirectoryLength = strlen($path); + $baseDirectoryLength = \strlen($path); foreach($iterator as $filename => $data) { /** @var \DirectoryIterator $data */ if($data->isDir()) { @@ -220,7 +220,7 @@ class Checker { if($filename === $this->environmentHelper->getServerRoot() . '/.htaccess') { $fileContent = file_get_contents($tmpFolder . '/.htaccess'); $explodedArray = explode('#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####', $fileContent); - if(count($explodedArray) === 2) { + if(\count($explodedArray) === 2) { $hashes[$relativeFileName] = hash('sha512', $explodedArray[0]); continue; } @@ -238,11 +238,11 @@ class Checker { * @param array $hashes * @param X509 $certificate * @param RSA $privateKey - * @return string + * @return array */ private function createSignatureData(array $hashes, X509 $certificate, - RSA $privateKey) { + RSA $privateKey): array { ksort($hashes); $privateKey->setSignatureMode(RSA::SIGNATURE_PSS); @@ -328,13 +328,18 @@ class Checker { * @throws InvalidSignatureException * @throws \Exception */ - private function verify($signaturePath, $basePath, $certificateCN) { + private function verify(string $signaturePath, string $basePath, string $certificateCN): array { if(!$this->isCodeCheckEnforced()) { return []; } - $signatureData = json_decode($this->fileAccessHelper->file_get_contents($signaturePath), true); - if(!is_array($signatureData)) { + $content = $this->fileAccessHelper->file_get_contents($signaturePath); + $signatureData = null; + + if (\is_string($content)) { + $signatureData = json_decode($content, true); + } + if(!\is_array($signatureData)) { throw new InvalidSignatureException('Signature data not found.'); } @@ -422,7 +427,7 @@ class Checker { * * @return bool */ - public function hasPassedCheck() { + public function hasPassedCheck(): bool { $results = $this->getResults(); if(empty($results)) { return true; @@ -434,9 +439,9 @@ class Checker { /** * @return array */ - public function getResults() { + public function getResults(): array { $cachedResults = $this->cache->get(self::CACHE_KEY); - if(!is_null($cachedResults)) { + if(!\is_null($cachedResults)) { return json_decode($cachedResults, true); } @@ -452,7 +457,7 @@ class Checker { * @param string $scope * @param array $result */ - private function storeResults($scope, array $result) { + private function storeResults(string $scope, array $result) { $resultArray = $this->getResults(); unset($resultArray[$scope]); if(!empty($result)) { @@ -505,7 +510,7 @@ class Checker { * @param string $path Optional path. If none is given it will be guessed. * @return array */ - public function verifyAppSignature($appId, $path = '') { + public function verifyAppSignature(string $appId, string $path = ''): array { try { if($path === '') { $path = $this->appLocator->getAppPath($appId); @@ -518,7 +523,7 @@ class Checker { } catch (\Exception $e) { $result = [ 'EXCEPTION' => [ - 'class' => get_class($e), + 'class' => \get_class($e), 'message' => $e->getMessage(), ], ]; @@ -558,7 +563,7 @@ class Checker { * * @return array */ - public function verifyCoreSignature() { + public function verifyCoreSignature(): array { try { $result = $this->verify( $this->environmentHelper->getServerRoot() . '/core/signature.json', @@ -568,7 +573,7 @@ class Checker { } catch (\Exception $e) { $result = [ 'EXCEPTION' => [ - 'class' => get_class($e), + 'class' => \get_class($e), 'message' => $e->getMessage(), ], ]; diff --git a/lib/private/IntegrityCheck/Helpers/AppLocator.php b/lib/private/IntegrityCheck/Helpers/AppLocator.php index c8d4e1b9b27..9ec5361d9d5 100644 --- a/lib/private/IntegrityCheck/Helpers/AppLocator.php +++ b/lib/private/IntegrityCheck/Helpers/AppLocator.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -37,7 +38,7 @@ class AppLocator { * @return string * @throws \Exception If the app cannot be found */ - public function getAppPath($appId) { + public function getAppPath(string $appId): string { $path = \OC_App::getAppPath($appId); if($path === false) { @@ -51,7 +52,7 @@ class AppLocator { * * @return array */ - public function getAllApps() { + public function getAllApps(): array { return \OC_App::getAllApps(); } } diff --git a/lib/private/IntegrityCheck/Helpers/EnvironmentHelper.php b/lib/private/IntegrityCheck/Helpers/EnvironmentHelper.php index c5e91997130..b69af591bc2 100644 --- a/lib/private/IntegrityCheck/Helpers/EnvironmentHelper.php +++ b/lib/private/IntegrityCheck/Helpers/EnvironmentHelper.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -34,7 +35,7 @@ class EnvironmentHelper { * * @return string */ - public function getServerRoot() { + public function getServerRoot(): string { return rtrim(\OC::$SERVERROOT, '/'); } @@ -43,7 +44,7 @@ class EnvironmentHelper { * * @return string */ - public function getChannel() { + public function getChannel(): string { return \OC_Util::getChannel(); } } diff --git a/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php b/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php index ef8e8b41b3f..e73b84b73c4 100644 --- a/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php +++ b/lib/private/IntegrityCheck/Helpers/FileAccessHelper.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -36,7 +37,7 @@ class FileAccessHelper { * @param string $filename * @return string|false */ - public function file_get_contents($filename) { + public function file_get_contents(string $filename) { return file_get_contents($filename); } @@ -46,7 +47,7 @@ class FileAccessHelper { * @param string $filename * @return bool */ - public function file_exists($filename) { + public function file_exists(string $filename): bool { return file_exists($filename); } @@ -58,9 +59,9 @@ class FileAccessHelper { * @return int * @throws \Exception */ - public function file_put_contents($filename, $data) { + public function file_put_contents(string $filename, string $data): int { $bytesWritten = @file_put_contents($filename, $data); - if ($bytesWritten === false || $bytesWritten !== strlen($data)){ + if ($bytesWritten === false || $bytesWritten !== \strlen($data)){ throw new \Exception('Failed to write into ' . $filename); } return $bytesWritten; @@ -70,7 +71,7 @@ class FileAccessHelper { * @param string $path * @return bool */ - public function is_writable($path) { + public function is_writable(string $path): bool { return is_writable($path); } @@ -78,7 +79,7 @@ class FileAccessHelper { * @param string $path * @throws \Exception */ - public function assertDirectoryExists($path) { + public function assertDirectoryExists(string $path) { if (!is_dir($path)) { throw new \Exception('Directory ' . $path . ' does not exist.'); } diff --git a/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php b/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php index 4801d7bb748..e0ad6a550e5 100644 --- a/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php +++ b/lib/private/IntegrityCheck/Iterator/ExcludeFileByNameFilterIterator.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -52,7 +53,7 @@ class ExcludeFileByNameFilterIterator extends \RecursiveFilterIterator { return true; } - return !in_array( + return !\in_array( $this->current()->getFilename(), $this->excludedFilenames, true diff --git a/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php b/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php index 31dd05ef312..56524abe6a0 100644 --- a/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php +++ b/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -24,7 +25,7 @@ namespace OC\IntegrityCheck\Iterator; class ExcludeFoldersByPathFilterIterator extends \RecursiveFilterIterator { - private $excludedFolders = []; + private $excludedFolders; public function __construct(\RecursiveIterator $iterator, $root = '') { parent::__construct($iterator); @@ -59,7 +60,7 @@ class ExcludeFoldersByPathFilterIterator extends \RecursiveFilterIterator { * @return bool */ public function accept() { - return !in_array( + return !\in_array( $this->current()->getPathName(), $this->excludedFolders, true diff --git a/lib/private/L10N/L10N.php b/lib/private/L10N/L10N.php index e9e720a3766..a9b1b7377aa 100644 --- a/lib/private/L10N/L10N.php +++ b/lib/private/L10N/L10N.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -60,7 +61,6 @@ class L10N implements IL10N { $this->app = $app; $this->lang = $lang; - $this->translations = []; foreach ($files as $languageFile) { $this->load($languageFile); } @@ -71,20 +71,24 @@ class L10N implements IL10N { * * @return string language */ - public function getLanguageCode() { + public function getLanguageCode(): string { return $this->lang; } /** * Translating * @param string $text The text we need a translation for - * @param array $parameters default:array() Parameters for sprintf + * @param array|string $parameters default:array() Parameters for sprintf * @return string Translation or the same text * * Returns the translation. If no translation is found, $text will be * returned. */ - public function t($text, $parameters = array()) { + public function t(string $text, $parameters = []): string { + if (!\is_array($parameters)) { + $parameters = [$parameters]; + } + return (string) new L10NString($this, $text, $parameters); } @@ -103,17 +107,17 @@ class L10N implements IL10N { * provided by the po file. * */ - public function n($text_singular, $text_plural, $count, $parameters = array()) { + public function n(string $text_singular, string $text_plural, int $count, array $parameters = []): string { $identifier = "_${text_singular}_::_${text_plural}_"; if (isset($this->translations[$identifier])) { return (string) new L10NString($this, $identifier, $parameters, $count); - } else { - if ($count === 1) { - return (string) new L10NString($this, $text_singular, $parameters, $count); - } else { - return (string) new L10NString($this, $text_plural, $parameters, $count); - } } + + if ($count === 1) { + return (string) new L10NString($this, $text_singular, $parameters, $count); + } + + return (string) new L10NString($this, $text_plural, $parameters, $count); } /** @@ -138,7 +142,7 @@ class L10N implements IL10N { * - firstday: Returns the first day of the week (0 sunday - 6 saturday) * - jsdate: Returns the short JS date format */ - public function l($type, $data = null, $options = array()) { + public function l(string $type, $data = null, array $options = []) { // Use the language of the instance $locale = $this->getLanguageCode(); if ($locale === 'sr@latin') { @@ -155,14 +159,15 @@ class L10N implements IL10N { $value = new \DateTime(); if ($data instanceof \DateTime) { $value = $data; - } else if (is_string($data) && !is_numeric($data)) { + } else if (\is_string($data) && !is_numeric($data)) { $data = strtotime($data); $value->setTimestamp($data); } else if ($data !== null) { + $data = (int)$data; $value->setTimestamp($data); } - $options = array_merge(array('width' => 'long'), $options); + $options = array_merge(['width' => 'long'], $options); $width = $options['width']; switch ($type) { case 'date': @@ -184,7 +189,7 @@ class L10N implements IL10N { * Called by \OC_L10N_String * @return array */ - public function getTranslations() { + public function getTranslations(): array { return $this->translations; } @@ -192,10 +197,10 @@ class L10N implements IL10N { * Returnsed function accepts the argument $n * * Called by \OC_L10N_String - * @return string the plural form function + * @return \Closure the plural form function */ - public function getPluralFormFunction() { - if (is_null($this->pluralFormFunction)) { + public function getPluralFormFunction(): \Closure { + if (\is_null($this->pluralFormFunction)) { $lang = $this->getLanguageCode(); $this->pluralFormFunction = function($n) use ($lang) { return PluralizationRules::get($n, $lang); @@ -206,12 +211,12 @@ class L10N implements IL10N { } /** - * @param $translationFile + * @param string $translationFile * @return bool */ - protected function load($translationFile) { + protected function load(string $translationFile): bool { $json = json_decode(file_get_contents($translationFile), true); - if (!is_array($json)) { + if (!\is_array($json)) { $jsonError = json_last_error(); \OC::$server->getLogger()->warning("Failed to load $translationFile - json error code: $jsonError", ['app' => 'l10n']); return false; diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php index 31d147a3b80..279c899c5fa 100644 --- a/lib/private/NavigationManager.php +++ b/lib/private/NavigationManager.php @@ -104,26 +104,61 @@ class NavigationManager implements INavigationManager { } /** - * returns all the added Menu entries - * @param string $type - * @return array an array of the added entries + * Get a list of navigation entries + * + * @param string $type type of the navigation entries + * @return array */ - public function getAll($type = 'link') { + public function getAll(string $type = 'link'): array { $this->init(); foreach ($this->closureEntries as $c) { $this->add($c()); } $this->closureEntries = array(); - if ($type === 'all') { - return $this->entries; + $result = $this->entries; + if ($type !== 'all') { + $result = array_filter($this->entries, function($entry) use ($type) { + return $entry['type'] === $type; + }); } - return array_filter($this->entries, function($entry) use ($type) { - return $entry['type'] === $type; + return $this->proceedNavigation($result); + } + + /** + * Sort navigation entries by order, name and set active flag + * + * @param array $list + * @return array + */ + private function proceedNavigation(array $list): array { + usort($list, function($a, $b) { + if (isset($a['order']) && isset($b['order'])) { + return ($a['order'] < $b['order']) ? -1 : 1; + } else if (isset($a['order']) || isset($b['order'])) { + return isset($a['order']) ? -1 : 1; + } else { + return ($a['name'] < $b['name']) ? -1 : 1; + } }); + + $activeApp = $this->getActiveEntry(); + if ($activeApp !== null) { + foreach ($list as $index => &$navEntry) { + if ($navEntry['id'] == $activeApp) { + $navEntry['active'] = true; + } else { + $navEntry['active'] = false; + } + } + unset($navEntry); + } + + return $list; } + /** * removes all the entries */ diff --git a/lib/private/Repair.php b/lib/private/Repair.php index d787a1c802b..a257ef061e7 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -30,8 +30,6 @@ namespace OC; -use OC\App\AppStore\Bundles\BundleFetcher; -use OC\Files\AppData\Factory; use OC\Repair\CleanTags; use OC\Repair\ClearFrontendCaches; use OC\Repair\Collation; diff --git a/lib/private/Repair/Collation.php b/lib/private/Repair/Collation.php index 2642985371b..f2cc9373176 100644 --- a/lib/private/Repair/Collation.php +++ b/lib/private/Repair/Collation.php @@ -6,6 +6,7 @@ * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Robin Müller <robin.mueller@1und1.de> * * @license AGPL-3.0 * @@ -124,7 +125,7 @@ class Collation implements IRepairStep { " FROM INFORMATION_SCHEMA . COLUMNS" . " WHERE TABLE_SCHEMA = ?" . " AND (COLLATION_NAME <> '" . $characterSet . "_bin' OR CHARACTER_SET_NAME <> '" . $characterSet . "')" . - " AND TABLE_NAME LIKE \"*PREFIX*%\"", + " AND TABLE_NAME LIKE '*PREFIX*%'", array($dbName) ); $rows = $statement->fetchAll(); @@ -139,7 +140,7 @@ class Collation implements IRepairStep { " FROM INFORMATION_SCHEMA . TABLES" . " WHERE TABLE_SCHEMA = ?" . " AND TABLE_COLLATION <> '" . $characterSet . "_bin'" . - " AND TABLE_NAME LIKE \"*PREFIX*%\"", + " AND TABLE_NAME LIKE '*PREFIX*%'", [$dbName] ); $rows = $statement->fetchAll(); diff --git a/lib/private/Server.php b/lib/private/Server.php index 228f0ab5f97..d586bab15b9 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -814,7 +814,7 @@ class Server extends ServerContainer implements IServerContainer { 'cookies' => $_COOKIE, 'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD'])) ? $_SERVER['REQUEST_METHOD'] - : null, + : '', 'urlParams' => $urlParams, ], $this->getSecureRandom(), diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 1798969ca53..e6056679c1c 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -39,12 +39,7 @@ namespace OC\Share; -use OC\Files\Filesystem; use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\ILogger; -use OCP\IUserManager; -use OCP\IUserSession; -use OCP\IDBConnection; use OCP\IConfig; use OCP\Util; diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index b9ab7a46873..3c56b24707c 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -30,7 +30,6 @@ namespace OC\Share20; use OC\Files\Cache\Cache; -use OCP\Files\File; use OCP\Files\Folder; use OCP\Share\IShareProvider; use OC\Share20\Exception\InvalidShare; diff --git a/lib/private/SystemTag/ManagerFactory.php b/lib/private/SystemTag/ManagerFactory.php index 12af2523f47..839a819a04a 100644 --- a/lib/private/SystemTag/ManagerFactory.php +++ b/lib/private/SystemTag/ManagerFactory.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -57,7 +58,7 @@ class ManagerFactory implements ISystemTagManagerFactory { * @return ISystemTagManager * @since 9.0.0 */ - public function getManager() { + public function getManager(): ISystemTagManager { return new SystemTagManager( $this->serverContainer->getDatabaseConnection(), $this->serverContainer->getGroupManager(), @@ -72,7 +73,7 @@ class ManagerFactory implements ISystemTagManagerFactory { * @return ISystemTagObjectMapper * @since 9.0.0 */ - public function getObjectMapper() { + public function getObjectMapper(): ISystemTagObjectMapper { return new SystemTagObjectMapper( $this->serverContainer->getDatabaseConnection(), $this->getManager(), diff --git a/lib/private/SystemTag/SystemTag.php b/lib/private/SystemTag/SystemTag.php index 15eb15efd9e..3b0cf23c9a8 100644 --- a/lib/private/SystemTag/SystemTag.php +++ b/lib/private/SystemTag/SystemTag.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -55,7 +56,7 @@ class SystemTag implements ISystemTag { * @param bool $userVisible whether the tag is user visible * @param bool $userAssignable whether the tag is user assignable */ - public function __construct($id, $name, $userVisible, $userAssignable) { + public function __construct(string $id, string $name, bool $userVisible, bool $userAssignable) { $this->id = $id; $this->name = $name; $this->userVisible = $userVisible; @@ -65,28 +66,28 @@ class SystemTag implements ISystemTag { /** * {@inheritdoc} */ - public function getId() { + public function getId(): string { return $this->id; } /** * {@inheritdoc} */ - public function getName() { + public function getName(): string { return $this->name; } /** * {@inheritdoc} */ - public function isUserVisible() { + public function isUserVisible(): bool { return $this->userVisible; } /** * {@inheritdoc} */ - public function isUserAssignable() { + public function isUserAssignable(): bool { return $this->userAssignable; } } diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php index 642ce515801..055b744e5c3 100644 --- a/lib/private/SystemTag/SystemTagManager.php +++ b/lib/private/SystemTag/SystemTagManager.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -65,6 +66,7 @@ class SystemTagManager implements ISystemTagManager { * Constructor. * * @param IDBConnection $connection database connection + * @param IGroupManager $groupManager * @param EventDispatcherInterface $dispatcher */ public function __construct( @@ -87,8 +89,8 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function getTagsByIds($tagIds) { - if (!is_array($tagIds)) { + public function getTagsByIds($tagIds): array { + if (!\is_array($tagIds)) { $tagIds = [$tagIds]; } @@ -117,7 +119,7 @@ class SystemTagManager implements ISystemTagManager { $result->closeCursor(); - if (count($tags) !== count($tagIds)) { + if (\count($tags) !== \count($tagIds)) { throw new TagNotFoundException( 'Tag id(s) not found', 0, null, array_diff($tagIds, array_keys($tags)) ); @@ -129,14 +131,14 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function getAllTags($visibilityFilter = null, $nameSearchPattern = null) { + public function getAllTags($visibilityFilter = null, $nameSearchPattern = null): array { $tags = []; $query = $this->connection->getQueryBuilder(); $query->select('*') ->from(self::TAG_TABLE); - if (!is_null($visibilityFilter)) { + if (!\is_null($visibilityFilter)) { $query->andWhere($query->expr()->eq('visibility', $query->createNamedParameter((int)$visibilityFilter))); } @@ -167,14 +169,11 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function getTag($tagName, $userVisible, $userAssignable) { - $userVisible = (int)$userVisible; - $userAssignable = (int)$userAssignable; - + public function getTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag { $result = $this->selectTagQuery ->setParameter('name', $tagName) - ->setParameter('visibility', $userVisible) - ->setParameter('editable', $userAssignable) + ->setParameter('visibility', $userVisible ? 1 : 0) + ->setParameter('editable', $userAssignable ? 1 : 0) ->execute(); $row = $result->fetch(); @@ -191,16 +190,13 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function createTag($tagName, $userVisible, $userAssignable) { - $userVisible = (int)$userVisible; - $userAssignable = (int)$userAssignable; - + public function createTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag { $query = $this->connection->getQueryBuilder(); $query->insert(self::TAG_TABLE) ->values([ 'name' => $query->createNamedParameter($tagName), - 'visibility' => $query->createNamedParameter($userVisible), - 'editable' => $query->createNamedParameter($userAssignable), + 'visibility' => $query->createNamedParameter($userVisible ? 1 : 0), + 'editable' => $query->createNamedParameter($userAssignable ? 1 : 0), ]); try { @@ -216,10 +212,10 @@ class SystemTagManager implements ISystemTagManager { $tagId = $query->getLastInsertId(); $tag = new SystemTag( - (int)$tagId, + (string)$tagId, $tagName, - (bool)$userVisible, - (bool)$userAssignable + $userVisible, + $userAssignable ); $this->dispatcher->dispatch(ManagerEvent::EVENT_CREATE, new ManagerEvent( @@ -232,10 +228,7 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function updateTag($tagId, $tagName, $userVisible, $userAssignable) { - $userVisible = (int)$userVisible; - $userAssignable = (int)$userAssignable; - + public function updateTag(string $tagId, string $tagName, bool $userVisible, bool $userAssignable) { try { $tags = $this->getTagsByIds($tagId); } catch (TagNotFoundException $e) { @@ -246,10 +239,10 @@ class SystemTagManager implements ISystemTagManager { $beforeUpdate = array_shift($tags); $afterUpdate = new SystemTag( - (int) $tagId, + $tagId, $tagName, - (bool) $userVisible, - (bool) $userAssignable + $userVisible, + $userAssignable ); $query = $this->connection->getQueryBuilder(); @@ -259,8 +252,8 @@ class SystemTagManager implements ISystemTagManager { ->set('editable', $query->createParameter('editable')) ->where($query->expr()->eq('id', $query->createParameter('tagid'))) ->setParameter('name', $tagName) - ->setParameter('visibility', $userVisible) - ->setParameter('editable', $userAssignable) + ->setParameter('visibility', $userVisible ? 1 : 0) + ->setParameter('editable', $userAssignable ? 1 : 0) ->setParameter('tagid', $tagId); try { @@ -286,7 +279,7 @@ class SystemTagManager implements ISystemTagManager { * {@inheritdoc} */ public function deleteTags($tagIds) { - if (!is_array($tagIds)) { + if (!\is_array($tagIds)) { $tagIds = [$tagIds]; } @@ -337,7 +330,7 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function canUserAssignTag(ISystemTag $tag, IUser $user) { + public function canUserAssignTag(ISystemTag $tag, IUser $user): bool { // early check to avoid unneeded group lookups if ($tag->isUserAssignable() && $tag->isUserVisible()) { return true; @@ -365,7 +358,7 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function canUserSeeTag(ISystemTag $tag, IUser $user) { + public function canUserSeeTag(ISystemTag $tag, IUser $user): bool { if ($tag->isUserVisible()) { return true; } @@ -378,13 +371,13 @@ class SystemTagManager implements ISystemTagManager { } private function createSystemTagFromRow($row) { - return new SystemTag((int)$row['id'], $row['name'], (bool)$row['visibility'], (bool)$row['editable']); + return new SystemTag((string)$row['id'], $row['name'], (bool)$row['visibility'], (bool)$row['editable']); } /** * {@inheritdoc} */ - public function setTagGroups(ISystemTag $tag, $groupIds) { + public function setTagGroups(ISystemTag $tag, array $groupIds) { // delete relationships first $this->connection->beginTransaction(); try { @@ -418,7 +411,7 @@ class SystemTagManager implements ISystemTagManager { /** * {@inheritdoc} */ - public function getTagGroups(ISystemTag $tag) { + public function getTagGroups(ISystemTag $tag): array { $groupIds = []; $query = $this->connection->getQueryBuilder(); $query->select('gid') diff --git a/lib/private/SystemTag/SystemTagObjectMapper.php b/lib/private/SystemTag/SystemTagObjectMapper.php index 75bf37c652c..8ecc46b4357 100644 --- a/lib/private/SystemTag/SystemTagObjectMapper.php +++ b/lib/private/SystemTag/SystemTagObjectMapper.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -63,8 +64,8 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { /** * {@inheritdoc} */ - public function getTagIdsForObjects($objIds, $objectType) { - if (!is_array($objIds)) { + public function getTagIdsForObjects($objIds, string $objectType): array { + if (!\is_array($objIds)) { $objIds = [$objIds]; } else if (empty($objIds)) { return []; @@ -99,8 +100,8 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { /** * {@inheritdoc} */ - public function getObjectIdsForTags($tagIds, $objectType, $limit = 0, $offset = '') { - if (!is_array($tagIds)) { + public function getObjectIdsForTags($tagIds, string $objectType, int $limit = 0, string $offset = ''): array { + if (!\is_array($tagIds)) { $tagIds = [$tagIds]; } @@ -113,7 +114,7 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { ->andWhere($query->expr()->eq('objecttype', $query->createNamedParameter($objectType))); if ($limit) { - if (count($tagIds) !== 1) { + if (\count($tagIds) !== 1) { throw new \InvalidArgumentException('Limit is only allowed with a single tag'); } @@ -138,8 +139,8 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { /** * {@inheritdoc} */ - public function assignTags($objId, $objectType, $tagIds) { - if (!is_array($tagIds)) { + public function assignTags(string $objId, string $objectType, $tagIds) { + if (!\is_array($tagIds)) { $tagIds = [$tagIds]; } @@ -173,8 +174,8 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { /** * {@inheritdoc} */ - public function unassignTags($objId, $objectType, $tagIds) { - if (!is_array($tagIds)) { + public function unassignTags(string $objId, string $objectType, $tagIds) { + if (!\is_array($tagIds)) { $tagIds = [$tagIds]; } @@ -201,10 +202,10 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { /** * {@inheritdoc} */ - public function haveTag($objIds, $objectType, $tagId, $all = true) { + public function haveTag($objIds, string $objectType, string $tagId, bool $all = true): bool { $this->assertTagsExist([$tagId]); - if (!is_array($objIds)) { + if (!\is_array($objIds)) { $objIds = [$objIds]; } @@ -232,10 +233,10 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { $result->closeCursor(); if ($all) { - return ((int)$row[0] === count($objIds)); - } else { - return (bool) $row; + return ((int)$row[0] === \count($objIds)); } + + return (bool) $row; } /** @@ -247,7 +248,7 @@ class SystemTagObjectMapper implements ISystemTagObjectMapper { */ private function assertTagsExist($tagIds) { $tags = $this->tagManager->getTagsByIds($tagIds); - if (count($tags) !== count($tagIds)) { + if (\count($tags) !== \count($tagIds)) { // at least one tag missing, bail out $foundTagIds = array_map( function(ISystemTag $tag) { diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index d37a8bbabbe..8cc235bf818 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -80,9 +80,9 @@ class TemplateLayout extends \OC_Template { // Add navigation entry $this->assign( 'application', ''); $this->assign( 'appid', $appId ); - $navigation = \OC_App::getNavigation(); + $navigation = \OC::$server->getNavigationManager()->getAll(); $this->assign( 'navigation', $navigation); - $settingsNavigation = \OC_App::getSettingsNavigation(); + $settingsNavigation = \OC::$server->getNavigationManager()->getAll('settings'); $this->assign( 'settingsnavigation', $settingsNavigation); foreach($navigation as $entry) { if ($entry['active']) { diff --git a/lib/private/Updater.php b/lib/private/Updater.php index 43096e7c1f8..c70113e1c7d 100644 --- a/lib/private/Updater.php +++ b/lib/private/Updater.php @@ -250,7 +250,7 @@ class Updater extends BasicEmitter { $this->upgradeAppStoreApps(\OC::$server->getAppManager()->getInstalledApps()); // install new shipped apps on upgrade - OC_App::loadApps('authentication'); + OC_App::loadApps(['authentication']); $errors = Installer::installShippedApps(true); foreach ($errors as $appId => $exception) { /** @var \Exception $exception */ @@ -346,7 +346,7 @@ class Updater extends BasicEmitter { if(!isset($stacks[$type])) { $stacks[$type] = array(); } - if (\OC_App::isType($appId, $type)) { + if (\OC_App::isType($appId, [$type])) { $stacks[$type][] = $appId; $priorityType = true; break; @@ -385,7 +385,7 @@ class Updater extends BasicEmitter { private function checkAppsRequirements() { $isCoreUpgrade = $this->isCodeUpgrade(); $apps = OC_App::getEnabledApps(); - $version = Util::getVersion(); + $version = implode('.', Util::getVersion()); $disabledApps = []; $appManager = \OC::$server->getAppManager(); foreach ($apps as $app) { diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index c2b58c37cdb..4ac8888cee1 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -55,7 +55,6 @@ use OCP\ILogger; use OCP\IRequest; use OCP\ISession; use OCP\IUser; -use OCP\IUserManager; use OCP\IUserSession; use OCP\Lockdown\ILockdownManager; use OCP\Security\ISecureRandom; diff --git a/lib/private/legacy/app.php b/lib/private/legacy/app.php index b19d63f560e..16e57d43ebc 100644 --- a/lib/private/legacy/app.php +++ b/lib/private/legacy/app.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch> @@ -62,21 +63,21 @@ use OCP\App\ManagerEvent; * upgrading and removing apps. */ class OC_App { - static private $adminForms = array(); - static private $personalForms = array(); - static private $appTypes = array(); - static private $loadedApps = array(); - static private $altLogin = array(); + static private $adminForms = []; + static private $personalForms = []; + static private $appTypes = []; + static private $loadedApps = []; + static private $altLogin = []; static private $alreadyRegistered = []; const officialApp = 200; /** * clean the appId * - * @param string|boolean $app AppId that needs to be cleaned + * @param string $app AppId that needs to be cleaned * @return string */ - public static function cleanAppId($app) { + public static function cleanAppId(string $app): string { return str_replace(array('\0', '/', '\\', '..'), '', $app); } @@ -86,23 +87,23 @@ class OC_App { * @param string $app * @return bool */ - public static function isAppLoaded($app) { + public static function isAppLoaded(string $app): bool { return in_array($app, self::$loadedApps, true); } /** * loads all apps * - * @param string[] | string | null $types + * @param string[] $types * @return bool * * This function walks through the ownCloud directory and loads all apps * it can find. A directory contains an app if the file /appinfo/info.xml * exists. * - * if $types is set, only apps of those types will be loaded + * if $types is set to non-empty array, only apps of those types will be loaded */ - public static function loadApps($types = null) { + public static function loadApps(array $types = []): bool { if (\OC::$server->getSystemConfig()->getValue('maintenance', false)) { return false; } @@ -120,7 +121,7 @@ class OC_App { // 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)) { + if (($types === [] or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) { self::loadApp($app); } } @@ -133,8 +134,9 @@ class OC_App { * load a single app * * @param string $app + * @throws Exception */ - public static function loadApp($app) { + public static function loadApp(string $app) { self::$loadedApps[] = $app; $appPath = self::getAppPath($app); if($appPath === false) { @@ -146,13 +148,21 @@ class OC_App { if (is_file($appPath . '/appinfo/app.php')) { \OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app); - self::requireAppFile($app); + try { + self::requireAppFile($app); + } catch (Error $ex) { + \OC::$server->getLogger()->logException($ex); + if (!\OC::$server->getAppManager()->isShipped($app)) { + // Only disable apps which are not shipped + self::disable($app); + } + } if (self::isType($app, array('authentication'))) { // since authentication apps affect the "is app enabled for group" check, // the enabled apps cache needs to be cleared to make sure that the // next time getEnableApps() is called it will also include apps that were // enabled for groups - self::$enabledAppsCache = array(); + self::$enabledAppsCache = []; } \OC::$server->getEventLogger()->end('load_app_' . $app); } @@ -218,7 +228,7 @@ class OC_App { * @param string $app * @param string $path */ - public static function registerAutoloading($app, $path) { + public static function registerAutoloading(string $app, string $path) { $key = $app . '-' . $path; if(isset(self::$alreadyRegistered[$key])) { return; @@ -248,31 +258,21 @@ class OC_App { * Load app.php from the given app * * @param string $app app name + * @throws Error */ - private static function requireAppFile($app) { - try { - // encapsulated here to avoid variable scope conflicts - require_once $app . '/appinfo/app.php'; - } catch (Error $ex) { - \OC::$server->getLogger()->logException($ex); - if (!\OC::$server->getAppManager()->isShipped($app)) { - // Only disable apps which are not shipped - self::disable($app); - } - } + private static function requireAppFile(string $app) { + // encapsulated here to avoid variable scope conflicts + require_once $app . '/appinfo/app.php'; } /** * check if an app is of a specific type * * @param string $app - * @param string|array $types + * @param array $types * @return bool */ - public static function isType($app, $types) { - if (is_string($types)) { - $types = array($types); - } + public static function isType(string $app, array $types): bool { $appTypes = self::getAppTypes($app); foreach ($types as $type) { if (array_search($type, $appTypes) !== false) { @@ -288,7 +288,7 @@ class OC_App { * @param string $app * @return array */ - private static function getAppTypes($app) { + private static function getAppTypes(string $app): array { //load the cache if (count(self::$appTypes) == 0) { self::$appTypes = \OC::$server->getAppConfig()->getValues(false, 'types'); @@ -296,16 +296,17 @@ class OC_App { if (isset(self::$appTypes[$app])) { return explode(',', self::$appTypes[$app]); - } else { - return array(); } + + return []; } /** * read app types from info.xml and cache them in the database */ - public static function setAppTypes($app) { - $appData = self::getAppInfo($app); + public static function setAppTypes(string $app) { + $appManager = \OC::$server->getAppManager(); + $appData = $appManager->getAppInfo($app); if(!is_array($appData)) { return; } @@ -317,12 +318,13 @@ class OC_App { $appData['types'] = []; } - \OC::$server->getConfig()->setAppValue($app, 'types', $appTypes); + $config = \OC::$server->getConfig(); + $config->setAppValue($app, 'types', $appTypes); - if (\OC::$server->getAppManager()->hasProtectedAppType($appData['types'])) { - $enabled = \OC::$server->getConfig()->getAppValue($app, 'enabled', 'yes'); + if ($appManager->hasProtectedAppType($appData['types'])) { + $enabled = $config->getAppValue($app, 'enabled', 'yes'); if ($enabled !== 'yes' && $enabled !== 'no') { - \OC::$server->getConfig()->setAppValue($app, 'enabled', 'yes'); + $config->setAppValue($app, 'enabled', 'yes'); } } } @@ -330,7 +332,7 @@ class OC_App { /** * get all enabled apps */ - protected static $enabledAppsCache = array(); + protected static $enabledAppsCache = []; /** * Returns apps enabled for the current user. @@ -340,9 +342,9 @@ class OC_App { * currently logged in one * @return string[] */ - public static function getEnabledApps($forceRefresh = false, $all = false) { + public static function getEnabledApps(bool $forceRefresh = false, bool $all = false): array { if (!\OC::$server->getSystemConfig()->getValue('installed', false)) { - return array(); + return []; } // in incognito mode or when logged out, $user will be false, // which is also the case during an upgrade @@ -375,7 +377,7 @@ class OC_App { * * This function checks whether or not an app is enabled. */ - public static function isEnabled($app) { + public static function isEnabled(string $app): bool { return \OC::$server->getAppManager()->isEnabledForUser($app); } @@ -389,8 +391,8 @@ class OC_App { * * This function set an app as enabled in appconfig. */ - public function enable($appId, - $groups = null) { + public function enable(string $appId, + array $groups = []) { self::$enabledAppsCache = []; // flush // Check if app is already downloaded @@ -404,7 +406,7 @@ class OC_App { $installer->installApp($appId); $appManager = \OC::$server->getAppManager(); - if (!is_null($groups)) { + if ($groups !== []) { $groupManager = \OC::$server->getGroupManager(); $groupsList = []; foreach ($groups as $group) { @@ -425,9 +427,9 @@ class OC_App { * @param string $app app * @throws Exception */ - public static function disable($app) { + public static function disable(string $app) { // flush - self::$enabledAppsCache = array(); + self::$enabledAppsCache = []; // run uninstall steps $appData = OC_App::getAppInfo($app); @@ -443,31 +445,6 @@ class OC_App { $appManager->disableApp($app); } - // This is private as well. It simply works, so don't ask for more details - private static function proceedNavigation($list) { - usort($list, function($a, $b) { - if (isset($a['order']) && isset($b['order'])) { - return ($a['order'] < $b['order']) ? -1 : 1; - } else if (isset($a['order']) || isset($b['order'])) { - return isset($a['order']) ? -1 : 1; - } else { - return ($a['name'] < $b['name']) ? -1 : 1; - } - }); - - $activeApp = OC::$server->getNavigationManager()->getActiveEntry(); - foreach ($list as $index => &$navEntry) { - if ($navEntry['id'] == $activeApp) { - $navEntry['active'] = true; - } else { - $navEntry['active'] = false; - } - } - unset($navEntry); - - return $list; - } - /** * Get the path where to install apps * @@ -495,18 +472,18 @@ class OC_App { * @param string $appId * @return false|string */ - public static function findAppInDirectories($appId) { + public static function findAppInDirectories(string $appId) { $sanitizedAppId = self::cleanAppId($appId); if($sanitizedAppId !== $appId) { return false; } - static $app_dir = array(); + static $app_dir = []; if (isset($app_dir[$appId])) { return $app_dir[$appId]; } - $possibleApps = array(); + $possibleApps = []; foreach (OC::$APPSROOTS as $dir) { if (file_exists($dir['path'] . '/' . $appId)) { $possibleApps[] = $dir; @@ -520,7 +497,7 @@ class OC_App { $app_dir[$appId] = $dir; return $dir; } else { - $versionToLoad = array(); + $versionToLoad = []; foreach ($possibleApps as $possibleApp) { $version = self::getAppVersionByPath($possibleApp['path']); if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) { @@ -543,7 +520,7 @@ class OC_App { * @param string $appId * @return string|false */ - public static function getAppPath($appId) { + public static function getAppPath(string $appId) { if ($appId === null || trim($appId) === '') { return false; } @@ -561,7 +538,7 @@ class OC_App { * @param string $appId * @return string|false */ - public static function getAppWebPath($appId) { + public static function getAppWebPath(string $appId) { if (($dir = self::findAppInDirectories($appId)) != false) { return OC::$WEBROOT . $dir['url'] . '/' . $appId; } @@ -576,7 +553,7 @@ class OC_App { * @return string * @deprecated 14.0.0 use \OC::$server->getAppManager()->getAppVersion() */ - public static function getAppVersion($appId, $useCache = true) { + public static function getAppVersion(string $appId, bool $useCache = true): string { return \OC::$server->getAppManager()->getAppVersion($appId, $useCache); } @@ -586,7 +563,7 @@ class OC_App { * @param string $path * @return string */ - public static function getAppVersionByPath($path) { + public static function getAppVersionByPath(string $path): string { $infoFile = $path . '/appinfo/info.xml'; $appData = \OC::$server->getAppManager()->getAppInfo($infoFile, true); return isset($appData['version']) ? $appData['version'] : ''; @@ -603,7 +580,7 @@ class OC_App { * @note all data is read from info.xml, not just pre-defined fields * @deprecated 14.0.0 use \OC::$server->getAppManager()->getAppInfo() */ - public static function getAppInfo($appId, $path = false, $lang = null) { + public static function getAppInfo(string $appId, bool $path = false, string $lang = null) { return \OC::$server->getAppManager()->getAppInfo($appId, $path, $lang); } @@ -611,28 +588,28 @@ class OC_App { * Returns the navigation * * @return array + * @deprecated 14.0.0 use \OC::$server->getNavigationManager()->getAll() * * This function returns an array containing all entries added. The * entries are sorted by the key 'order' ascending. Additional to the keys * given for each app the following keys exist: * - active: boolean, signals if the user is on this navigation entry */ - public static function getNavigation() { - $entries = OC::$server->getNavigationManager()->getAll(); - return self::proceedNavigation($entries); + public static function getNavigation(): array { + return OC::$server->getNavigationManager()->getAll(); } /** * Returns the Settings Navigation * * @return string[] + * @deprecated 14.0.0 use \OC::$server->getNavigationManager()->getAll('settings') * * This function returns an array containing all settings pages added. The * entries are sorted by the key 'order' ascending. */ - public static function getSettingsNavigation() { - $entries = OC::$server->getNavigationManager()->getAll('settings'); - return self::proceedNavigation($entries); + public static function getSettingsNavigation(): array { + return OC::$server->getNavigationManager()->getAll('settings'); } /** @@ -640,7 +617,7 @@ class OC_App { * * @return string */ - public static function getCurrentApp() { + public static function getCurrentApp(): string { $request = \OC::$server->getRequest(); $script = substr($request->getScriptName(), strlen(OC::$WEBROOT) + 1); $topFolder = substr($script, 0, strpos($script, '/') ?: 0); @@ -652,7 +629,7 @@ class OC_App { } if ($topFolder == 'apps') { $length = strlen($topFolder); - return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1); + return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1) ?: ''; } else { return $topFolder; } @@ -662,8 +639,8 @@ class OC_App { * @param string $type * @return array */ - public static function getForms($type) { - $forms = array(); + public static function getForms(string $type): array { + $forms = []; switch ($type) { case 'admin': $source = self::$adminForms; @@ -672,7 +649,7 @@ class OC_App { $source = self::$personalForms; break; default: - return array(); + return []; } foreach ($source as $form) { $forms[] = include $form; @@ -686,7 +663,7 @@ class OC_App { * @param string $app * @param string $page */ - public static function registerAdmin($app, $page) { + public static function registerAdmin(string $app, string $page) { self::$adminForms[] = $app . '/' . $page . '.php'; } @@ -695,7 +672,7 @@ class OC_App { * @param string $app * @param string $page */ - public static function registerPersonal($app, $page) { + public static function registerPersonal(string $app, string $page) { self::$personalForms[] = $app . '/' . $page . '.php'; } @@ -709,7 +686,7 @@ class OC_App { /** * @return array */ - public static function getAlternativeLogIns() { + public static function getAlternativeLogIns(): array { return self::$altLogin; } @@ -719,9 +696,9 @@ class OC_App { * @return array an array of app names (string IDs) * @todo: change the name of this method to getInstalledApps, which is more accurate */ - public static function getAllApps() { + public static function getAllApps(): array { - $apps = array(); + $apps = []; foreach (OC::$APPSROOTS as $apps_dir) { if (!is_readable($apps_dir['path'])) { @@ -751,13 +728,13 @@ class OC_App { * * @return array */ - public function listAllApps() { + public function listAllApps(): array { $installedApps = OC_App::getAllApps(); $appManager = \OC::$server->getAppManager(); //we don't want to show configuration for these $blacklist = $appManager->getAlwaysEnabledApps(); - $appList = array(); + $appList = []; $langCode = \OC::$server->getL10N('core')->getLanguageCode(); $urlGenerator = \OC::$server->getURLGenerator(); @@ -832,7 +809,7 @@ class OC_App { return $appList; } - public static function shouldUpgrade($app) { + public static function shouldUpgrade(string $app): bool { $versions = self::getAppVersions(); $currentVersion = OC_App::getAppVersion($app); if ($currentVersion && isset($versions[$app])) { @@ -852,7 +829,7 @@ class OC_App { * @param string $version2 version to take the number of parts from * @return string shortened $version1 */ - private static function adjustVersionParts($version1, $version2) { + private static function adjustVersionParts(string $version1, string $version2): string { $version1 = explode('.', $version1); $version2 = explode('.', $version2); // reduce $version1 to match the number of parts in $version2 @@ -882,7 +859,7 @@ class OC_App { * * @return boolean true if compatible, otherwise false */ - public static function isAppCompatible($ocVersion, $appInfo) { + public static function isAppCompatible(string $ocVersion, array $appInfo): bool { $requireMin = ''; $requireMax = ''; if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) { @@ -903,10 +880,6 @@ class OC_App { $requireMax = $appInfo['requiremax']; } - if (is_array($ocVersion)) { - $ocVersion = implode('.', $ocVersion); - } - if (!empty($requireMin) && version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<') ) { @@ -942,7 +915,7 @@ class OC_App { * @param string $appId * @return bool */ - public static function updateApp($appId) { + public static function updateApp(string $appId): bool { $appPath = self::getAppPath($appId); if($appPath === false) { return false; @@ -1001,7 +974,7 @@ class OC_App { * @param string[] $steps * @throws \OC\NeedsUpdateException */ - public static function executeRepairSteps($appId, array $steps) { + public static function executeRepairSteps(string $appId, array $steps) { if (empty($steps)) { return; } @@ -1035,7 +1008,7 @@ class OC_App { * @param string $appId * @param string[] $steps */ - private static function setupLiveMigrations($appId, array $steps) { + private static function setupLiveMigrations(string $appId, array $steps) { $queue = \OC::$server->getJobList(); foreach ($steps as $step) { $queue->add('OC\Migration\BackgroundRepair', [ @@ -1048,7 +1021,7 @@ class OC_App { * @param string $appId * @return \OC\Files\View|false */ - public static function getStorage($appId) { + public static function getStorage(string $appId) { if (\OC::$server->getAppManager()->isEnabledForUser($appId)) { //sanity check if (\OC::$server->getUserSession()->isLoggedIn()) { $view = new \OC\Files\View('/' . OC_User::getUser()); @@ -1066,7 +1039,7 @@ class OC_App { } } - protected static function findBestL10NOption($options, $lang) { + protected static function findBestL10NOption(array $options, string $lang): string { $fallback = $similarLangFallback = $englishFallback = false; $lang = strtolower($lang); @@ -1118,7 +1091,7 @@ class OC_App { * @param string $lang * @return array improved app data */ - public static function parseAppInfo(array $data, $lang = null) { + public static function parseAppInfo(array $data, $lang = null): array { if ($lang && isset($data['name']) && is_array($data['name'])) { $data['name'] = self::findBestL10NOption($data['name'], $lang); @@ -1143,7 +1116,7 @@ class OC_App { * @param array $info * @throws \Exception */ - public static function checkAppDependencies($config, $l, $info) { + public static function checkAppDependencies(\OCP\IConfig $config, \OCP\IL10N $l, array $info) { $dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l); $missing = $dependencyAnalyzer->analyze($info); if (!empty($missing)) { diff --git a/lib/private/legacy/files.php b/lib/private/legacy/files.php index 24324bca095..def9f82fab9 100644 --- a/lib/private/legacy/files.php +++ b/lib/private/legacy/files.php @@ -75,7 +75,9 @@ class OC_Files { private static function sendHeaders($filename, $name, array $rangeArray) { OC_Response::setContentDispositionHeader($name, 'attachment'); header('Content-Transfer-Encoding: binary', true); - OC_Response::disableCaching(); + header('Pragma: public');// enable caching in IE + header('Expires: 0'); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); $fileSize = \OC\Files\Filesystem::filesize($filename); $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename)); if ($fileSize > -1) { diff --git a/lib/private/legacy/response.php b/lib/private/legacy/response.php index 975ff570485..1b0b01de972 100644 --- a/lib/private/legacy/response.php +++ b/lib/private/legacy/response.php @@ -55,7 +55,7 @@ class OC_Response { header('Cache-Control: max-age='.$cache_time.', must-revalidate'); } else { - self::setExpiresHeader(0); + header('Expires: 0'); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); } } @@ -67,14 +67,6 @@ class OC_Response { } /** - * disable browser caching - * @see enableCaching with cache_time = 0 - */ - static public function disableCaching() { - self::enableCaching(0); - } - - /** * Set response status * @param int $status a HTTP status code, see also the STATUS constants */ diff --git a/lib/public/App/IAppManager.php b/lib/public/App/IAppManager.php index 0c087b61515..f0f14061e35 100644 --- a/lib/public/App/IAppManager.php +++ b/lib/public/App/IAppManager.php @@ -51,10 +51,10 @@ interface IAppManager { * * @param string $appId * @param bool $useCache - * @return mixed + * @return string * @since 14.0.0 */ - public function getAppVersion(string $appId, bool $useCache = true); + public function getAppVersion(string $appId, bool $useCache = true): string; /** * Check if an app is enabled for user diff --git a/lib/public/AppFramework/Http/Response.php b/lib/public/AppFramework/Http/Response.php index e47e01349e7..512b312dae1 100644 --- a/lib/public/AppFramework/Http/Response.php +++ b/lib/public/AppFramework/Http/Response.php @@ -232,11 +232,11 @@ class Response { /** * By default renders no output - * @return string|null + * @return string * @since 6.0.0 */ public function render() { - return null; + return ''; } diff --git a/lib/public/AppFramework/Utility/IControllerMethodReflector.php b/lib/public/AppFramework/Utility/IControllerMethodReflector.php index e9fb4a5a969..e2074b9fe00 100644 --- a/lib/public/AppFramework/Utility/IControllerMethodReflector.php +++ b/lib/public/AppFramework/Utility/IControllerMethodReflector.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -40,7 +41,7 @@ interface IControllerMethodReflector { * @return void * @since 8.0.0 */ - public function reflect($object, $method); + public function reflect($object, string $method); /** * Inspects the PHPDoc parameters for types @@ -51,13 +52,13 @@ interface IControllerMethodReflector { * would return int or null if not existing * @since 8.0.0 */ - public function getType($parameter); + public function getType(string $parameter); /** * @return array the arguments of the method with key => default value * @since 8.0.0 */ - public function getParameters(); + public function getParameters(): array; /** * Check if a method contains an annotation @@ -66,6 +67,6 @@ interface IControllerMethodReflector { * @return bool true if the annotation is found * @since 8.0.0 */ - public function hasAnnotation($name); + public function hasAnnotation(string $name): bool; } diff --git a/lib/public/IL10N.php b/lib/public/IL10N.php index 7af5008b814..2e55c151f62 100644 --- a/lib/public/IL10N.php +++ b/lib/public/IL10N.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -44,14 +45,14 @@ interface IL10N { /** * Translating * @param string $text The text we need a translation for - * @param array $parameters default:array() Parameters for sprintf + * @param array|string $parameters default:array() Parameters for sprintf * @return string Translation or the same text * * Returns the translation. If no translation is found, $text will be * returned. * @since 6.0.0 */ - public function t($text, $parameters = array()); + public function t(string $text, $parameters = []): string; /** * Translating @@ -69,7 +70,7 @@ interface IL10N { * @since 6.0.0 * */ - public function n($text_singular, $text_plural, $count, $parameters = array()); + public function n(string $text_singular, string $text_plural, int $count, array $parameters = []): string; /** * Localization @@ -96,7 +97,7 @@ interface IL10N { * - params: timestamp (int/string) * @since 6.0.0 - parameter $options was added in 8.0.0 */ - public function l($type, $data, $options = array()); + public function l(string $type, $data, array $options = []); /** @@ -105,5 +106,5 @@ interface IL10N { * @return string language * @since 7.0.0 */ - public function getLanguageCode(); + public function getLanguageCode(): string ; } diff --git a/lib/public/INavigationManager.php b/lib/public/INavigationManager.php index 216f8a897d8..77b881b8b15 100644 --- a/lib/public/INavigationManager.php +++ b/lib/public/INavigationManager.php @@ -57,4 +57,13 @@ interface INavigationManager { * @since 6.0.0 */ public function setActiveEntry($appId); + + /** + * Get a list of navigation entries + * + * @param string $type type of the navigation entries + * @return array + * @since 14.0.0 + */ + public function getAll(string $type = 'link'): array; } diff --git a/lib/public/IRequest.php b/lib/public/IRequest.php index a14b6b5f459..b3130207111 100644 --- a/lib/public/IRequest.php +++ b/lib/public/IRequest.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -95,7 +96,7 @@ interface IRequest { * @return string * @since 6.0.0 */ - public function getHeader($name); + public function getHeader(string $name): string; /** * Lets you access post and get parameters by the index @@ -111,7 +112,7 @@ interface IRequest { * @return mixed the content of the array * @since 6.0.0 */ - public function getParam($key, $default = null); + public function getParam(string $key, $default = null); /** @@ -122,7 +123,7 @@ interface IRequest { * @return array the array with all parameters * @since 6.0.0 */ - public function getParams(); + public function getParams(): array; /** * Returns the method of the request @@ -130,7 +131,7 @@ interface IRequest { * @return string the method of the request (POST, GET, etc) * @since 6.0.0 */ - public function getMethod(); + public function getMethod(): string; /** * Shortcut for accessing an uploaded file through the $_FILES array @@ -139,7 +140,7 @@ interface IRequest { * @return array the file in the $_FILES element * @since 6.0.0 */ - public function getUploadedFile($key); + public function getUploadedFile(string $key); /** @@ -149,7 +150,7 @@ interface IRequest { * @return array the value in the $_ENV element * @since 6.0.0 */ - public function getEnv($key); + public function getEnv(string $key); /** @@ -159,7 +160,7 @@ interface IRequest { * @return string|null the value in the $_COOKIE element * @since 6.0.0 */ - public function getCookie($key); + public function getCookie(string $key); /** @@ -168,7 +169,7 @@ interface IRequest { * @return bool true if CSRF check passed * @since 6.0.0 */ - public function passesCSRFCheck(); + public function passesCSRFCheck(): bool; /** * Checks if the strict cookie has been sent with the request if the request @@ -177,7 +178,7 @@ interface IRequest { * @return bool * @since 9.0.0 */ - public function passesStrictCookieCheck(); + public function passesStrictCookieCheck(): bool; /** * Checks if the lax cookie has been sent with the request if the request @@ -186,7 +187,7 @@ interface IRequest { * @return bool * @since 9.0.0 */ - public function passesLaxCookieCheck(); + public function passesLaxCookieCheck(): bool; /** * Returns an ID for the request, value is not guaranteed to be unique and is mostly meant for logging @@ -195,7 +196,7 @@ interface IRequest { * @return string * @since 8.1.0 */ - public function getId(); + public function getId(): string; /** * Returns the remote address, if the connection came from a trusted proxy @@ -206,7 +207,7 @@ interface IRequest { * @return string IP address * @since 8.1.0 */ - public function getRemoteAddress(); + public function getRemoteAddress(): string; /** * Returns the server protocol. It respects reverse proxy servers and load @@ -215,7 +216,7 @@ interface IRequest { * @return string Server protocol (http or https) * @since 8.1.0 */ - public function getServerProtocol(); + public function getServerProtocol(): string; /** * Returns the used HTTP protocol. @@ -223,7 +224,7 @@ interface IRequest { * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0. * @since 8.2.0 */ - public function getHttpProtocol(); + public function getHttpProtocol(): string; /** * Returns the request uri, even if the website uses one or more @@ -232,7 +233,7 @@ interface IRequest { * @return string * @since 8.1.0 */ - public function getRequestUri(); + public function getRequestUri(): string; /** * Get raw PathInfo from request (not urldecoded) @@ -241,7 +242,7 @@ interface IRequest { * @return string Path info * @since 8.1.0 */ - public function getRawPathInfo(); + public function getRawPathInfo(): string; /** * Get PathInfo from request @@ -259,7 +260,7 @@ interface IRequest { * @return string the script name * @since 8.1.0 */ - public function getScriptName(); + public function getScriptName(): string; /** * Checks whether the user agent matches a given regex @@ -268,7 +269,7 @@ interface IRequest { * @return bool true if at least one of the given agent matches, false otherwise * @since 8.1.0 */ - public function isUserAgent(array $agent); + public function isUserAgent(array $agent): bool; /** * Returns the unverified server host from the headers without checking @@ -277,7 +278,7 @@ interface IRequest { * @return string Server host * @since 8.1.0 */ - public function getInsecureServerHost(); + public function getInsecureServerHost(): string; /** * Returns the server host from the headers, or the first configured @@ -286,5 +287,5 @@ interface IRequest { * @return string Server host * @since 8.1.0 */ - public function getServerHost(); + public function getServerHost(): string; } diff --git a/lib/public/Response.php b/lib/public/Response.php index dd029e12dbf..dbd506d379d 100644 --- a/lib/public/Response.php +++ b/lib/public/Response.php @@ -89,9 +89,12 @@ class Response { * Disable browser caching * @see enableCaching with cache_time = 0 * @since 4.0.0 + * @deprecated 14.0.0 just set the headers */ static public function disableCaching() { - \OC_Response::disableCaching(); + header('Pragma: public');// enable caching in IE + header('Expires: 0'); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); } /** diff --git a/lib/public/SystemTag/ISystemTag.php b/lib/public/SystemTag/ISystemTag.php index 539c7835fae..da434e8b5a0 100644 --- a/lib/public/SystemTag/ISystemTag.php +++ b/lib/public/SystemTag/ISystemTag.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -36,7 +37,7 @@ interface ISystemTag { * * @since 9.0.0 */ - public function getId(); + public function getId(): string; /** * Returns the tag display name @@ -45,7 +46,7 @@ interface ISystemTag { * * @since 9.0.0 */ - public function getName(); + public function getName(): string; /** * Returns whether the tag is visible for regular users @@ -54,7 +55,7 @@ interface ISystemTag { * * @since 9.0.0 */ - public function isUserVisible(); + public function isUserVisible(): bool; /** * Returns whether the tag can be assigned to objects by regular users @@ -63,7 +64,7 @@ interface ISystemTag { * * @since 9.0.0 */ - public function isUserAssignable(); + public function isUserAssignable(): bool; } diff --git a/lib/public/SystemTag/ISystemTagManager.php b/lib/public/SystemTag/ISystemTagManager.php index fff0a439116..4cce106790a 100644 --- a/lib/public/SystemTag/ISystemTagManager.php +++ b/lib/public/SystemTag/ISystemTagManager.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -37,15 +38,15 @@ interface ISystemTagManager { * * @param array|string $tagIds id or array of unique ids of the tag to retrieve * - * @return \OCP\SystemTag\ISystemTag[] array of system tags with tag id as key + * @return ISystemTag[] array of system tags with tag id as key * * @throws \InvalidArgumentException if at least one given tag ids is invalid (string instead of integer, etc.) - * @throws \OCP\SystemTag\TagNotFoundException if at least one given tag ids did no exist + * @throws TagNotFoundException if at least one given tag ids did no exist * The message contains a json_encoded array of the ids that could not be found * * @since 9.0.0 */ - public function getTagsByIds($tagIds); + public function getTagsByIds($tagIds): array; /** * Returns the tag object matching the given attributes. @@ -54,13 +55,13 @@ interface ISystemTagManager { * @param bool $userVisible whether the tag is visible by users * @param bool $userAssignable whether the tag is assignable by users * - * @return \OCP\SystemTag\ISystemTag system tag + * @return ISystemTag system tag * - * @throws \OCP\SystemTag\TagNotFoundException if tag does not exist + * @throws TagNotFoundException if tag does not exist * * @since 9.0.0 */ - public function getTag($tagName, $userVisible, $userAssignable); + public function getTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag; /** * Creates the tag object using the given attributes. @@ -69,13 +70,13 @@ interface ISystemTagManager { * @param bool $userVisible whether the tag is visible by users * @param bool $userAssignable whether the tag is assignable by users * - * @return \OCP\SystemTag\ISystemTag system tag + * @return ISystemTag system tag * - * @throws \OCP\SystemTag\TagAlreadyExistsException if tag already exists + * @throws TagAlreadyExistsException if tag already exists * * @since 9.0.0 */ - public function createTag($tagName, $userVisible, $userAssignable); + public function createTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag; /** * Returns all known tags, optionally filtered by visibility. @@ -83,11 +84,11 @@ interface ISystemTagManager { * @param bool|null $visibilityFilter filter by visibility if non-null * @param string $nameSearchPattern optional search pattern for the tag name * - * @return \OCP\SystemTag\ISystemTag[] array of system tags or empty array if none found + * @return ISystemTag[] array of system tags or empty array if none found * * @since 9.0.0 */ - public function getAllTags($visibilityFilter = null, $nameSearchPattern = null); + public function getAllTags($visibilityFilter = null, $nameSearchPattern = null): array; /** * Updates the given tag @@ -97,20 +98,20 @@ interface ISystemTagManager { * @param bool $userVisible whether the tag is visible by users * @param bool $userAssignable whether the tag is assignable by users * - * @throws \OCP\SystemTag\TagNotFoundException if tag with the given id does not exist - * @throws \OCP\SystemTag\TagAlreadyExistsException if there is already another tag + * @throws TagNotFoundException if tag with the given id does not exist + * @throws TagAlreadyExistsException if there is already another tag * with the same attributes * * @since 9.0.0 */ - public function updateTag($tagId, $newName, $userVisible, $userAssignable); + public function updateTag(string $tagId, string $newName, bool $userVisible, bool $userAssignable); /** * Delete the given tags from the database and all their relationships. * * @param string|array $tagIds array of tag ids * - * @throws \OCP\SystemTag\TagNotFoundException if at least one tag did not exist + * @throws TagNotFoundException if at least one tag did not exist * * @since 9.0.0 */ @@ -127,7 +128,7 @@ interface ISystemTagManager { * * @since 9.1.0 */ - public function canUserAssignTag(ISystemTag $tag, IUser $user); + public function canUserAssignTag(ISystemTag $tag, IUser $user): bool; /** * Checks whether the given user is allowed to see the tag with the given id. @@ -139,7 +140,7 @@ interface ISystemTagManager { * * @since 9.1.0 */ - public function canUserSeeTag(ISystemTag $tag, IUser $userId); + public function canUserSeeTag(ISystemTag $tag, IUser $user): bool; /** * Set groups that can assign a given tag. @@ -149,7 +150,7 @@ interface ISystemTagManager { * * @since 9.1.0 */ - public function setTagGroups(ISystemTag $tag, $groupIds); + public function setTagGroups(ISystemTag $tag, array $groupIds); /** * Get groups that can assign a given tag. @@ -160,5 +161,5 @@ interface ISystemTagManager { * * @since 9.1.0 */ - public function getTagGroups(ISystemTag $tag); + public function getTagGroups(ISystemTag $tag): array; } diff --git a/lib/public/SystemTag/ISystemTagManagerFactory.php b/lib/public/SystemTag/ISystemTagManagerFactory.php index 0d652697490..25956b41df4 100644 --- a/lib/public/SystemTag/ISystemTagManagerFactory.php +++ b/lib/public/SystemTag/ISystemTagManagerFactory.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -47,7 +48,7 @@ interface ISystemTagManagerFactory { * @return ISystemTagManager * @since 9.0.0 */ - public function getManager(); + public function getManager(): ISystemTagManager; /** * creates and returns an instance of the system tag object @@ -56,5 +57,5 @@ interface ISystemTagManagerFactory { * @return ISystemTagObjectMapper * @since 9.0.0 */ - public function getObjectMapper(); + public function getObjectMapper(): ISystemTagObjectMapper; } diff --git a/lib/public/SystemTag/ISystemTagObjectMapper.php b/lib/public/SystemTag/ISystemTagObjectMapper.php index 3e28ab15773..1705bde23c5 100644 --- a/lib/public/SystemTag/ISystemTagObjectMapper.php +++ b/lib/public/SystemTag/ISystemTagObjectMapper.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -51,7 +52,7 @@ interface ISystemTagObjectMapper { * * @since 9.0.0 */ - public function getTagIdsForObjects($objIds, $objectType); + public function getTagIdsForObjects($objIds, string $objectType): array; /** * Get a list of objects tagged with $tagIds. @@ -63,14 +64,14 @@ interface ISystemTagObjectMapper { * * @return string[] array of object ids or empty array if none found * - * @throws \OCP\SystemTag\TagNotFoundException if at least one of the + * @throws TagNotFoundException if at least one of the * given tags does not exist * @throws \InvalidArgumentException When a limit is specified together with * multiple tag ids * * @since 9.0.0 */ - public function getObjectIdsForTags($tagIds, $objectType, $limit = 0, $offset = ''); + public function getObjectIdsForTags($tagIds, string $objectType, int $limit = 0, string $offset = ''): array; /** * Assign the given tags to the given object. @@ -84,12 +85,12 @@ interface ISystemTagObjectMapper { * @param string $objectType object type * @param string|array $tagIds tag id or array of tag ids to assign * - * @throws \OCP\SystemTag\TagNotFoundException if at least one of the + * @throws TagNotFoundException if at least one of the * given tags does not exist * * @since 9.0.0 */ - public function assignTags($objId, $objectType, $tagIds); + public function assignTags(string $objId, string $objectType, $tagIds); /** * Unassign the given tags from the given object. @@ -103,12 +104,12 @@ interface ISystemTagObjectMapper { * @param string $objectType object type * @param string|array $tagIds tag id or array of tag ids to unassign * - * @throws \OCP\SystemTag\TagNotFoundException if at least one of the + * @throws TagNotFoundException if at least one of the * given tags does not exist * * @since 9.0.0 */ - public function unassignTags($objId, $objectType, $tagIds); + public function unassignTags(string $objId, string $objectType, $tagIds); /** * Checks whether the given objects have the given tag. @@ -122,10 +123,10 @@ interface ISystemTagObjectMapper { * @return bool true if the condition set by $all is matched, false * otherwise * - * @throws \OCP\SystemTag\TagNotFoundException if the tag does not exist + * @throws TagNotFoundException if the tag does not exist * * @since 9.0.0 */ - public function haveTag($objIds, $objectType, $tagId, $all = true); + public function haveTag($objIds, string $objectType, string $tagId, bool $all = true): bool; } diff --git a/lib/public/SystemTag/ManagerEvent.php b/lib/public/SystemTag/ManagerEvent.php index bb9fcc01f83..452c0d5da8f 100644 --- a/lib/public/SystemTag/ManagerEvent.php +++ b/lib/public/SystemTag/ManagerEvent.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -52,7 +53,7 @@ class ManagerEvent extends Event { * @param ISystemTag|null $beforeTag * @since 9.0.0 */ - public function __construct($event, ISystemTag $tag, ISystemTag $beforeTag = null) { + public function __construct(string $event, ISystemTag $tag, ISystemTag $beforeTag = null) { $this->event = $event; $this->tag = $tag; $this->beforeTag = $beforeTag; @@ -62,7 +63,7 @@ class ManagerEvent extends Event { * @return string * @since 9.0.0 */ - public function getEvent() { + public function getEvent(): string { return $this->event; } @@ -70,15 +71,16 @@ class ManagerEvent extends Event { * @return ISystemTag * @since 9.0.0 */ - public function getTag() { + public function getTag(): ISystemTag { return $this->tag; } /** * @return ISystemTag * @since 9.0.0 + * @throws \BadMethodCallException */ - public function getTagBefore() { + public function getTagBefore(): ISystemTag { if ($this->event !== self::EVENT_UPDATE) { throw new \BadMethodCallException('getTagBefore is only available on the update Event'); } diff --git a/lib/public/SystemTag/MapperEvent.php b/lib/public/SystemTag/MapperEvent.php index a86497c8440..d98caf1317b 100644 --- a/lib/public/SystemTag/MapperEvent.php +++ b/lib/public/SystemTag/MapperEvent.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -53,7 +54,7 @@ class MapperEvent extends Event { * @param int[] $tags * @since 9.0.0 */ - public function __construct($event, $objectType, $objectId, array $tags) { + public function __construct(string $event, string $objectType, string $objectId, array $tags) { $this->event = $event; $this->objectType = $objectType; $this->objectId = $objectId; @@ -64,7 +65,7 @@ class MapperEvent extends Event { * @return string * @since 9.0.0 */ - public function getEvent() { + public function getEvent(): string { return $this->event; } @@ -72,7 +73,7 @@ class MapperEvent extends Event { * @return string * @since 9.0.0 */ - public function getObjectType() { + public function getObjectType(): string { return $this->objectType; } @@ -80,7 +81,7 @@ class MapperEvent extends Event { * @return string * @since 9.0.0 */ - public function getObjectId() { + public function getObjectId(): string { return $this->objectId; } @@ -88,7 +89,7 @@ class MapperEvent extends Event { * @return int[] * @since 9.0.0 */ - public function getTags() { + public function getTags(): array { return $this->tags; } } diff --git a/lib/public/SystemTag/SystemTagsEntityEvent.php b/lib/public/SystemTag/SystemTagsEntityEvent.php index 15ae4439986..e439c16d9c6 100644 --- a/lib/public/SystemTag/SystemTagsEntityEvent.php +++ b/lib/public/SystemTag/SystemTagsEntityEvent.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -45,7 +46,7 @@ class SystemTagsEntityEvent extends Event { * @param string $event * @since 9.1.0 */ - public function __construct($event) { + public function __construct(string $event) { $this->event = $event; $this->collections = []; } @@ -59,7 +60,7 @@ class SystemTagsEntityEvent extends Event { * @throws \OutOfBoundsException when the entity name is already taken * @since 9.1.0 */ - public function addEntityCollection($name, \Closure $entityExistsFunction) { + public function addEntityCollection(string $name, \Closure $entityExistsFunction) { if (isset($this->collections[$name])) { throw new \OutOfBoundsException('Duplicate entity name "' . $name . '"'); } @@ -71,7 +72,7 @@ class SystemTagsEntityEvent extends Event { * @return \Closure[] * @since 9.1.0 */ - public function getEntityCollections() { + public function getEntityCollections(): array { return $this->collections; } } diff --git a/lib/public/SystemTag/TagAlreadyExistsException.php b/lib/public/SystemTag/TagAlreadyExistsException.php index caf0d9f08bc..fbe8234d281 100644 --- a/lib/public/SystemTag/TagAlreadyExistsException.php +++ b/lib/public/SystemTag/TagAlreadyExistsException.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * diff --git a/lib/public/SystemTag/TagNotFoundException.php b/lib/public/SystemTag/TagNotFoundException.php index 9b06259807f..9f83c20e6c5 100644 --- a/lib/public/SystemTag/TagNotFoundException.php +++ b/lib/public/SystemTag/TagNotFoundException.php @@ -1,4 +1,5 @@ <?php +declare(strict_types=1); /** * @copyright Copyright (c) 2016, ownCloud, Inc. * @@ -43,7 +44,7 @@ class TagNotFoundException extends \RuntimeException { * @param string[] $tags * @since 9.0.0 */ - public function __construct($message = '', $code = 0, \Exception $previous = null, array $tags = []) { + public function __construct(string $message = '', int $code = 0, \Exception $previous = null, array $tags = []) { parent::__construct($message, $code, $previous); $this->tags = $tags; } @@ -52,7 +53,7 @@ class TagNotFoundException extends \RuntimeException { * @return string[] * @since 9.0.0 */ - public function getMissingTags() { + public function getMissingTags(): array { return $this->tags; } } diff --git a/lib/public/Util.php b/lib/public/Util.php index 2fb6bdf491d..106107591c3 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -51,7 +51,6 @@ // 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; -use DateTimeZone; /** * This class provides different helper functions to make the life of a developer easier |