diff --git a/README.md b/README.md index 166254c..f2f39dd 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ It shall NOT be edited by hand. # IFM for YunoHost -[![Integration level](https://dash.yunohost.org/integration/ifm.svg)](https://dash.yunohost.org/appci/app/ifm) ![](https://ci-apps.yunohost.org/ci/badges/ifm.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/ifm.maintain.svg) +[![Integration level](https://dash.yunohost.org/integration/ifm.svg)](https://dash.yunohost.org/appci/app/ifm) ![Working status](https://ci-apps.yunohost.org/ci/badges/ifm.status.svg) ![Maintenance status](https://ci-apps.yunohost.org/ci/badges/ifm.maintain.svg) [![Install IFM with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=ifm) *[Lire ce readme en français.](./README_fr.md)* @@ -29,33 +29,34 @@ The IFM is a web-based filemanager, which comes as a single file solution using - simple authentication (LDAP via `ldap_bind` possible) -**Shipped version:** 2.6.3~ynh3 +**Shipped version:** 4.0.0~ynh1 **Demo:** https://ifmdemo.gitea.de/ ## Screenshots -![](./doc/screenshots/ifm_screenshot.png) +![Screenshot of IFM](./doc/screenshots/ifm_screenshot.png) ## Disclaimers / important information The IFM is usually locked to it's own directory (`/home/yunohost.app/ifm`), so you are not able to go above. You can change that by setting `env[IFM_ROOT_DIR] = /home/yunohost.app/ifm` in the PHP config `/etc/php/7.3/fpm/pool.d/ifm.conf` L.434 with the help of this [documentation](https://github.com/misterunknown/ifm/wiki/Configuration). ## Documentation and resources -* Official app website: https://github.com/misterunknown/ifm -* Upstream app code repository: https://github.com/misterunknown/ifm -* YunoHost documentation for this app: https://yunohost.org/app_ifm -* Report a bug: https://github.com/YunoHost-Apps/ifm_ynh/issues +* Official app website: +* Upstream app code repository: +* YunoHost documentation for this app: +* Report a bug: ## Developer info Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/ifm_ynh/tree/testing). To try the testing branch, please proceed like that. -``` + +``` bash sudo yunohost app install https://github.com/YunoHost-Apps/ifm_ynh/tree/testing --debug or sudo yunohost app upgrade ifm -u https://github.com/YunoHost-Apps/ifm_ynh/tree/testing --debug ``` -**More info regarding app packaging:** https://yunohost.org/packaging_apps \ No newline at end of file +**More info regarding app packaging:** diff --git a/README_fr.md b/README_fr.md index e172dd0..931f9d0 100644 --- a/README_fr.md +++ b/README_fr.md @@ -1,10 +1,14 @@ + + # IFM pour YunoHost -[![Niveau d'intégration](https://dash.yunohost.org/integration/ifm.svg)](https://dash.yunohost.org/appci/app/ifm) ![](https://ci-apps.yunohost.org/ci/badges/ifm.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/ifm.maintain.svg) +[![Niveau d'intégration](https://dash.yunohost.org/integration/ifm.svg)](https://dash.yunohost.org/appci/app/ifm) ![Statut du fonctionnement](https://ci-apps.yunohost.org/ci/badges/ifm.status.svg) ![Statut de maintenance](https://ci-apps.yunohost.org/ci/badges/ifm.maintain.svg) [![Installer IFM avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=ifm) *[Read this readme in english.](./README.md)* -*[Lire ce readme en français.](./README_fr.md)* > *Ce package vous permet d'installer IFM rapidement et simplement sur un serveur YunoHost. Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* @@ -24,33 +28,34 @@ L'IFM est un gestionnaire de fichiers basé sur le Web, qui se présente sous la - aperçu de l'image - authentification simple (LDAP via `ldap_bind` possible) -**Version incluse :** 2.6.3~ynh3 +**Version incluse :** 4.0.0~ynh1 **Démo :** https://ifmdemo.gitea.de/ ## Captures d'écran -![](./doc/screenshots/ifm_screenshot.png) +![Capture d'écran de IFM](./doc/screenshots/ifm_screenshot.png) ## Avertissements / informations importantes L'IFM est généralement verrouillé dans son propre répertoire (`/home/yunohost.app/ifm`), vous ne pouvez donc pas aller sur d'autres répertoires. Vous pouvez changer cela en définissant `env[IFM_ROOT_DIR] = /home/yunohost.app/ifm` dans la configuration PHP `/etc/php/7.3/fpm/pool.d/ifm.conf` L.434 en vous aidant de cette [documentation](https://github.com/misterunknown/ifm/wiki/Configuration). ## Documentations et ressources -* Site officiel de l'app : https://github.com/misterunknown/ifm -* Dépôt de code officiel de l'app : https://github.com/misterunknown/ifm -* Documentation YunoHost pour cette app : https://yunohost.org/app_ifm -* Signaler un bug : https://github.com/YunoHost-Apps/ifm_ynh/issues +* Site officiel de l'app : +* Dépôt de code officiel de l'app : +* Documentation YunoHost pour cette app : +* Signaler un bug : ## Informations pour les développeurs Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/ifm_ynh/tree/testing). Pour essayer la branche testing, procédez comme suit. -``` + +``` bash sudo yunohost app install https://github.com/YunoHost-Apps/ifm_ynh/tree/testing --debug ou sudo yunohost app upgrade ifm -u https://github.com/YunoHost-Apps/ifm_ynh/tree/testing --debug ``` -**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file +**Plus d'infos sur le packaging d'applications :** diff --git a/conf/app.src b/conf/app.src index fb74725..9a6d915 100644 --- a/conf/app.src +++ b/conf/app.src @@ -1,4 +1,4 @@ -SOURCE_URL=https://github.com/misterunknown/ifm/releases/download/v2.6.3/ifm.php +SOURCE_URL=https://github.com/misterunknown/ifm/releases/download/v4.0.0/ifm.php SOURCE_SUM=sha256 checksum SOURCE_SUM_PRG=sha256sum SOURCE_FORMAT=tar.gz diff --git a/conf/ifm.php b/conf/ifm.php index ef8e2ef..9745a6d 100644 --- a/conf/ifm.php +++ b/conf/ifm.php @@ -9,22 +9,32 @@ * main */ -error_reporting( E_ALL ); -ini_set( 'display_errors', 'OFF' ); +error_reporting(E_ALL); +ini_set('display_errors', 0); + +class IFMException extends Exception { + public $forUser = true; + public function __construct($message, $forUser = true, $code = 0, Exception $previous = null) { + $this->forUser = $forUser; + parent::__construct($message, $code, $previous); + } +} class IFM { - private $defaultconfig = array( + private $defaultconfig = [ // general config "auth" => 0, "auth_source" => 'inline;admin:$2y$10$0Bnm5L4wKFHRxJgNq.oZv.v7yXhkJZQvinJYR2p6X1zPvzyDRUVRC', + "auth_ignore_basic" => 0, "root_dir" => "", "root_public_url" => "", "tmp_dir" => "", "timezone" => "", - "forbiddenChars" => array(), + "forbiddenChars" => [], "dateLocale" => "en-US", "language" => "en", "selfoverwrite" => 0, + "session_name" => false, // api controls "ajaxrequest" => 1, @@ -42,7 +52,8 @@ class IFM { "zipnload" => 1, "createarchive" => 1, "search" => 1, - "pagination" => 0, + "paging" => 0, + "pageLength" => 50, // gui controls "showlastmodified" => 0, @@ -58,956 +69,49 @@ class IFM { "showrefresh" => 1, "forceproxy" => 0, "confirmoverwrite" => 1 - ); + ]; - private $config = array(); - private $templates = array(); - private $i18n = array(); + private $config = []; + private $templates = []; + private $i18n = []; public $mode = "standalone"; - public function __construct( $config=array() ) { + public function __construct($config=[]) { + // store initial working directory + $this->initialWD = getcwd(); // load the default config $this->config = $this->defaultconfig; // load config from environment variables - $this->config['auth'] = getenv('IFM_AUTH') !== false ? intval( getenv('IFM_AUTH') ) : $this->config['auth'] ; - $this->config['auth_source'] = getenv('IFM_AUTH_SOURCE') !== false ? getenv('IFM_AUTH_SOURCE') : $this->config['auth_source'] ; - $this->config['root_dir'] = getenv('IFM_ROOT_DIR') !== false ? getenv('IFM_ROOT_DIR') : $this->config['root_dir'] ; - $this->config['root_public_url'] = getenv('IFM_ROOT_PUBLIC_URL') !== false ? getenv('IFM_ROOT_PUBLIC_URL') : $this->config['root_public_url'] ; - $this->config['tmp_dir'] = getenv('IFM_TMP_DIR') !== false ? getenv('IFM_TMP_DIR') : $this->config['tmp_dir'] ; - $this->config['timezone'] = getenv('IFM_TIMEZONE') !== false ? getenv('IFM_TIMEZONE') : $this->config['timezone'] ; - $this->config['dateLocale'] = getenv('IFM_DATELOCALE') !== false ? getenv('IFM_DATELOCALE') : $this->config['dateLocale'] ; - $this->config['forbiddenChars'] = getenv('IFM_FORBIDDENCHARS') !== false ? str_split( getenv('IFM_FORBIDDENCHARS') ) : $this->config['forbiddenChars'] ; - $this->config['language'] = getenv('IFM_LANGUAGE') !== false ? getenv('IFM_LANGUAGE') : $this->config['language'] ; - $this->config['selfoverwrite'] = getenv('IFM_SELFOVERWRITE') !== false ? getenv('IFM_SELFOVERWRITE') : $this->config['selfoverwrite'] ; - $this->config['ajaxrequest'] = getenv('IFM_API_AJAXREQUEST') !== false ? intval( getenv('IFM_API_AJAXREQUEST') ) : $this->config['ajaxrequest'] ; - $this->config['chmod'] = getenv('IFM_API_CHMOD') !== false ? intval( getenv('IFM_API_CHMOD') ) : $this->config['chmod'] ; - $this->config['copymove'] = getenv('IFM_API_COPYMOVE') !== false ? intval( getenv('IFM_API_COPYMOVE') ) : $this->config['copymove'] ; - $this->config['createdir'] = getenv('IFM_API_CREATEDIR') !== false ? intval( getenv('IFM_API_CREATEDIR') ) : $this->config['createdir'] ; - $this->config['createfile'] = getenv('IFM_API_CREATEFILE') !== false ? intval( getenv('IFM_API_CREATEFILE') ) : $this->config['createfile'] ; - $this->config['edit'] = getenv('IFM_API_EDIT') !== false ? intval( getenv('IFM_API_EDIT') ) : $this->config['edit'] ; - $this->config['delete'] = getenv('IFM_API_DELETE') !== false ? intval( getenv('IFM_API_DELETE') ) : $this->config['delete'] ; - $this->config['download'] = getenv('IFM_API_DOWNLOAD') !== false ? intval( getenv('IFM_API_DOWNLOAD') ) : $this->config['download'] ; - $this->config['extract'] = getenv('IFM_API_EXTRACT') !== false ? intval( getenv('IFM_API_EXTRACT') ) : $this->config['extract'] ; - $this->config['upload'] = getenv('IFM_API_UPLOAD') !== false ? intval( getenv('IFM_API_UPLOAD') ) : $this->config['upload'] ; - $this->config['remoteupload'] = getenv('IFM_API_REMOTEUPLOAD') !== false ? intval( getenv('IFM_API_REMOTEUPLOAD') ) : $this->config['remoteupload'] ; - $this->config['rename'] = getenv('IFM_API_RENAME') !== false ? intval( getenv('IFM_API_RENAME') ) : $this->config['rename'] ; - $this->config['zipnload'] = getenv('IFM_API_ZIPNLOAD') !== false ? intval( getenv('IFM_API_ZIPNLOAD') ) : $this->config['zipnload'] ; - $this->config['createarchive'] = getenv('IFM_API_CREATEARCHIVE') !== false ? intval( getenv('IFM_API_CREATEARCHIVE') ) : $this->config['createarchive'] ; - $this->config['showlastmodified'] = getenv('IFM_GUI_SHOWLASTMODIFIED') !== false ? intval( getenv('IFM_GUI_SHOWLASTMODIFIED') ) : $this->config['showlastmodified'] ; - $this->config['showfilesize'] = getenv('IFM_GUI_SHOWFILESIZE') !== false ? intval( getenv('IFM_GUI_SHOWFILESIZE') ) : $this->config['showfilesize'] ; - $this->config['showowner'] = getenv('IFM_GUI_SHOWOWNER') !== false ? intval( getenv('IFM_GUI_SHOWOWNER') ) : $this->config['showowner'] ; - $this->config['showgroup'] = getenv('IFM_GUI_SHOWGROUP') !== false ? intval( getenv('IFM_GUI_SHOWGROUP') ) : $this->config['showgroup'] ; - $this->config['showpermissions'] = getenv('IFM_GUI_SHOWPERMISSIONS') !== false ? intval( getenv('IFM_GUI_SHOWPERMISSIONS') ) : $this->config['showpermissions'] ; - $this->config['showhtdocs'] = getenv('IFM_GUI_SHOWHTDOCS') !== false ? intval( getenv('IFM_GUI_SHOWHTDOCS') ) : $this->config['showhtdocs'] ; - $this->config['showhiddenfiles'] = getenv('IFM_GUI_SHOWHIDDENFILES') !== false ? intval( getenv('IFM_GUI_SHOWHIDDENFILES') ) : $this->config['showhiddenfiles'] ; - $this->config['showpath'] = getenv('IFM_GUI_SHOWPATH') !== false ? intval( getenv('IFM_GUI_SHOWPATH') ) : $this->config['showpath'] ; - $this->config['contextmenu'] = getenv('IFM_GUI_CONTEXTMENU') !== false ? intval( getenv('IFM_GUI_CONTEXTMENU') ) : $this->config['contextmenu'] ; - $this->config['search'] = getenv('IFM_API_SEARCH') !== false ? intval( getenv('IFM_API_SEARCH') ) : $this->config['search'] ; - $this->config['showrefresh'] = getenv('IFM_GUI_REFRESH') !== false ? intval( getenv('IFM_GUI_REFRESH') ) : $this->config['showrefresh'] ; - $this->config['forceproxy'] = getenv('IFM_GUI_FORCEPROXY') !== false ? intval( getenv('IFM_GUI_FORCEPROXY') ) : $this->config['forceproxy'] ; - $this->config['confirmoverwrite'] = getenv('IFM_GUI_CONFIRMOVERWRITE') !== false ? intval( getenv('IFM_GUI_CONFIRMOVERWRITE') ) : $this->config['confirmoverwrite'] ; - - // optional settings - if( getenv('IFM_SESSION_LIFETIME') !== false ) - $this->config['session_lifetime'] = getenv('IFM_SESSION_LIFETIME'); - if( getenv('IFM_FORCE_SESSION_LIFETIME') !== false ) - $this->config['session_lifetime'] = getenv('IFM_FORCE_SESSION_LIFETIME'); + foreach (array_keys($this->config) as $key) { + if (($value = getenv('IFM_' . strtoupper($key))) !== false) { + if (is_numeric($value)) + $value = intval($value); + $this->config[$key] = $value; + } + } // load config from passed array - $this->config = array_merge( $this->config, $config ); + $this->config = array_merge($this->config, $config); - // get list of ace includes - $this->config['ace_includes'] = <<<'f00bar' - -f00bar; - - // templates - $templates = array(); - $templates['app'] = <<<'f00bar' - -
-

{{i18n.upload_drop}}

-
-
-
- - - - - - {{#config.download}} - - {{/config.download}} - {{#config.showlastmodified}} - - {{/config.showlastmodified}} - {{#config.showfilesize}} - - {{/config.showfilesize}} - {{#config.showpermissions}} - - {{/config.showpermissions}} - {{#config.showowner}} - - {{/config.showowner}} - {{#config.showgroup}} - - {{/config.showgroup}} - - - - - -
{{i18n.filename}}{{i18n.last_modified}}{{i18n.size}}{{i18n.permissions}}{{i18n.owner}}{{i18n.group}}
-
-
-
-
-
{{i18n.footer}} v2.6.3
- {{i18n.github}} -
-
-
-
- -f00bar; - $templates['login'] = <<<'f00bar' - - - -f00bar; - $templates['filetable'] = <<<'f00bar' -{{#items}} - - {{#fixtop}} - - {{/fixtop}} - {{^fixtop}} - - {{/fixtop}} - - - - {{linkname}} - - - {{#config.download}} - - - - {{/config.download}} - {{#config.showlastmodified}} - {{lastmodified_hr}} - {{/config.showlastmodified}} - {{#config.showfilesize}} - {{size}} - {{/config.showfilesize}} - {{#config.showpermissions}} - - - - {{/config.showpermissions}} - {{#config.showowner}} - - {{owner}} - - {{/config.showowner}} - {{#config.showgroup}} - - {{group}} - - {{/config.showgroup}} - - {{#button}} - - - - {{/button}} - - -{{/items}} - -f00bar; - $templates['footer'] = <<<'f00bar' - - -f00bar; - $templates['task'] = <<<'f00bar' -
-
-
-
- {{name}} -
-
-
-
- -f00bar; - $templates['ajaxrequest'] = <<<'f00bar' -
- -
- -f00bar; - $templates['copymove'] = <<<'f00bar' -
-
- - -
-
- -f00bar; - $templates['createdir'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['createarchive'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['deletefile'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['extractfile'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['file'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['file_editoroptions'] = <<<'f00bar' -
-
-
- - -
-
- - -
-
-
-
- {{i18n.tab_size}} -
- -
- {{#ace_includes}} - - {{/ace_includes}} -
- -f00bar; - $templates['remoteupload'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['renamefile'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['search'] = <<<'f00bar' -
- -
- -f00bar; - $templates['searchresults'] = <<<'f00bar' -{{#items}} - - - - {{linkname}} ({{folder}}) - - - -{{/items}} -{{^items}} - - - No results found. - - -{{/items}} - -f00bar; - $templates['uploadfile'] = <<<'f00bar' -
- - -
- -f00bar; - $templates['uploadconfirmoverwrite'] = <<<'f00bar' -
- - -
- -f00bar; - $this->templates = $templates; - - $i18n = array(); - $i18n["ar"] = <<<'f00bar' -{ - "ajax_request": "AJAXطلب", - "archive_create_error": "تعذر أنشاء الأرشيف", - "archive_create_success": "تم إنشاء الأرشيف بنجاح", - "archive_invalid_format": "صيغة الأرشيف غير صحيحة", - "archivename": "اسم الأرشيف", - "cancel": "إلغاء", - "close": "إغلاق", - "copy": "نسخ", - "copy_error": "تعذر نسخ الملفات التالية", - "copy_success": "تم نسخ الملف / الملفات بنجاح", - "copylink": "نسخ الرابط", - "create_archive": "إنشاء أرشيف", - "data": "بيانات", - "delete": "حذف", - "directoryname": "اسم الدليل", - "download": "تحميل", - "edit": "تحرير ", - "editor_options": "خيارات المحرر", - "error": "خطأ ", - "extract": "استخراج", - "extract_error": "تعذر استخراج الملف", - "extract_filename": "استخراج الملف", - "extract_success": "تم استخراج الملف بنجاح", - "file_copy_to": "الى", - "file_delete_confirm": "هل تود حذف الملف التالي؟", - "file_delete_error": "تعذر حذف الملف / الملفات", - "file_delete_success": "تم حذف الملف / الملفات بنجاح", - "file_display_error": "لا يمكن عرض أو تحرير الملف", - "file_load_error": "تعذر تحميل الملف", - "file_new": "ملف جديد", - "file_no_permission": "ليس لديك صلاحية لإنشاء أو تحرير الملف", - "file_not_found": "تعذر العثور على الملف ", - "file_open_error": "تعذر فتح الملف", - "file_rename": "تعديل اسم الملف", - "file_rename_error": "تعذر تعديل اسم الملف", - "file_rename_success": "تم تعديل اسم الملف بنجاح", - "file_save_confirm": "هل تود حفظ الملف التالي؟", - "file_save_error": "تعذر إنشاء أو تحرير الملف ", - "file_save_success": "تم حفظ الملف بنجاح", - "file_upload_error": "تعذر رفع الملف", - "file_upload_success": "تم رفع الملف بنجاح", - "filename": "اسم الملف", - "filename_new": "اسم الملف الجديد", - "filename_slashes": "يجب ألا يحتوي اسم الملف على علامة ترقيم الشرطة المائلة", - "filter": "تصفية النتائج", - "folder_create_error": "تعذر إنشاء المجلد", - "folder_create_success": "تم إنشاء المجلد بنجاح", - "folder_new": "مجلد جديد", - "folder_not_found": "تعذر العثور على المجلد", - "folder_tree_load_error": "حدث خطأ أثناء البحث عن المجلد", - "footer": "IFM - improved file manager | ifm.php hidden |", - "general_error": "خطأ عام", - "github": "GitHub قم بزيارة المشروع على ", - "group": "مجموعة", - "invalid_action": "الإجراء غير صحيح", - "invalid_archive_format": "zip, tar, tar.gz, tar.bz2 صيغة الأرشيف غير صحيحة، الصيغ الممكنة هي", - "invalid_data": "بيانات غير صحيحة من الخادم", - "invalid_dir": "الدليل غير صحيح", - "invalid_filename": "اسم الملف غير صحيح", - "invalid_params": "المعامل غير صحيح", - "invalid_url": "العنوان غير صحيح", - "json_encode_error": "JSONتعذر الصياغة في ", - "last_modified": "آخر تعديل", - "load_config_error": "تعذر تحميل التكوين", - "load_template_error": "تعذر تحميل النماذج", - "load_text_error": "تعذر تحميل النصوص", - "login": "تسجيل الدخول", - "login_failed": "لم يتم تسجيل الدخول بنجاح", - "logout": "تسجيل الخروج", - "method": "طريقة", - "move": "نقل", - "move_error": "تعذر نقل الملفات التالية", - "move_success": "تم نقل الملف / الملفات بنجاح", - "nopermissions": "ليس لديك الصلاحية للقيام بذلك", - "options": "خيارات", - "owner": "المالك", - "password": "كلمة المرور", - "path_content": "محتوى", - "pattern_error_slashes": "يجب ألا يحتوي النمط على علامة ترقيم الشرطة المائلة ", - "permission_change_error": "تعذر تغيير الصلاحيات", - "permission_change_success": "تم تغيير الصلاحيات بنجاح", - "permission_parse_error": "تعذر تحليل الصلاحيات بنجاح", - "permissions": "صلاحيات", - "refresh": "تحديث", - "remaining_tasks": "لا يزال هناك مهام قائمة. هل تود إعادة التحميل؟", - "rename": "إعادة تسمية", - "rename_filename": "إعادة تسمية الملف", - "request": "طلب", - "response": "استجابة", - "save": "حفظ", - "save_wo_close": "حفظ بدون إغلاق", - "search": "بحث", - "search_pattern": "نمط", - "select_destination": "حدد الوجهة", - "size": "حجم", - "soft_tabs": "إضافة فراغ", - "tab_size": "حجم علامة التبويب", - "tasks": "مهام", - "toggle_nav": "تبديل التنقل", - "upload": "رفع", - "upload_drop": "قم بإسقاط الملف / الملفات للرفع", - "upload_file": "رفع ملف", - "upload_overwrite_hint": "سيتم استبدال الملف / الملفات التالية", - "upload_overwrite_confirm": "هل تريد الرفع على أية حال؟", - "upload_remote": "الرفع عن بعد", - "upload_remote_url": "عنوان الرفع عن بعد", - "username": "اسم المستخدم", - "word_wrap": "التفاف النص" -} -f00bar; -$i18n["ar"] = json_decode( $i18n["ar"], true ); -$i18n["de"] = <<<'f00bar' -{ - "ajax_request": "AJAX Request", - "archivename": "Name des Archivs", - "archive_create_success": "Das Archiv wurde erfolgreich erstellt.", - "archive_create_error": "Das Archiv konnte nicht erstellt werden.", - "archive_invalid_format": "Ungültiges Archivformat angegeben.", - "cancel": "Abbrechen", - "close": "Schließen", - "copy": "Kopieren", - "copylink": "Link kopieren", - "copy_error": "Folgende Dateien konnten nicht kopiert werden:", - "copy_success": "Datei(en) erfolgreich kopiert.", - "create_archive": "Archiv erstellen", - "data": "Daten", - "delete": "Löschen", - "directoryname": "Ordner Name", - "download": "Download", - "edit": "Bearbeiten", - "editor_options": "Editor Optionen", - "error": "Fehler:", - "extract": "Entpacken", - "extract_error": "Das Archiv konnte nicht entpackt werden.", - "extract_filename": "Folgende Datei entpacken -", - "extract_success": "Das Archiv wurde erfolgreich entpackt.", - "file_copy_to": "nach", - "file_delete_confirm": "Soll die folgende Datei wirklich gelöscht werden:", - "file_delete_error": "Folgende Dateien konnten nicht gelöscht werden:", - "file_delete_success": "Datei(en) erfolgreich gelöscht", - "file_display_error": "Die Datei kann nicht angezeigt oder geändert werden", - "file_new": "Neue Datei", - "file_load_error": "Der Inhalt der Datei konnte nicht geladen werden", - "file_open_error": "Die Datei konnte nicht geöffnet werden.", - "file_no_permission": "Sie haben keine Berechtigung diese Datei zu erstellen/bearbeiten.", - "file_not_found": "Die Datei wurde nicht gefunden, oder kann nicht geöffnet werden.", - "file_rename": "Datei umbenennen", - "file_rename_error": "Datei konnte nicht umbenannt werden: ", - "file_rename_success": "Datei erfolgreich umbenannt.", - "file_save_error": "Datei konnte nicht gespeichert werden.", - "file_save_success": "Datei erfolgreich gespeichert.", - "file_save_confirm": "Soll diese Datei wirklich gespeichert werden -", - "file_upload_error": "Datei konnte nicht hochgeladen werden.", - "file_upload_success": "Datei erfolgreich hochgeladen", - "filename": "Dateiname", - "filename_new": "Neuer Dateiname", - "filename_slashes": "Der Dateiname darf keine Schrägstriche enthalten.", - "filter": "Filtern", - "folder_create_error": "Verzeichnis konnte nicht angelegt werden.", - "folder_create_success": "Verzeichnis erfolgreich angelegt.", - "folder_new": "Neue Ordner", - "folder_not_found": "Das Verzeichnis wurde nicht gefunden.", - "folder_tree_load_error": "Fehler bei Laden des Verzeichnisbaums.", - "footer": "IFM - verbesserter file manager | ifm.php versteckt |", - "general_error": "Genereller Fehler aufgetreten: Keine oder unvollständige Antwort vom Server", - "github": "Besuche das Projekt auf GitHub", - "group": "Gruppe", - "invalid_action": "Fehlerhafte Aktion übergeben.", - "invalid_archive_format": "Ungültiges Archiv-Format. Möglich sind zip, tar, tar.gz oder tar.bz2.", - "invalid_data": "Fehlerhafte Daten vom Server erhalten.", - "invalid_dir": "Ungültiges Verzeichnis übergegeben.", - "invalid_filename": "Ungültiger Dateiname übergegeben.", - "invalid_params": "Ungültige Parameter übergegeben.", - "invalid_url": "Ungültige URL übergegeben.", - "json_encode_error": "Konnte die Antwort nicht als JSON formatieren:", - "last_modified": "Zuletzt geändert", - "load_config_error": "Konfiguration konnte nicht geladen werden.", - "load_template_error": "Vorlagen konnten nicht geladen werden.", - "load_text_error": "Texte konnten nicht geladen werden.", - "login": "Anmeldung", - "login_failed": "Anmeldung fehlgeschlagen.", - "logout": "Abmelden", - "method": "Methode", - "move": "Verschieben", - "move_error": "Folgende Dateien konnten nicht verschoben werden:", - "move_success": "Datei(en) erfolgreich verschoben.", - "nopermissions": "Sie haben nicht die nötige Berechtigung dafür.", - "options": "Optionen", - "owner": "Besitzer", - "password": "Passwort", - "path_content": "Inhalt von", - "pattern_error_slashes": "Das Muster darf keine Slashes enthalten.", - "permission_change_error": "Berechtigungen konnten nicht geändert werden.", - "permission_change_success": "Berechtigungen erfolgreich geändert.", - "permission_parse_error": "Berechtigungen konnten nicht geparst werden.", - "permissions": "Berechtigungen", - "refresh": "Auffrischen", - "rename": "Umbenennen", - "rename_filename": "Folgende Datei umbenennen -", - "request": "Anfrage", - "response": "Antwort", - "save": "Speichen", - "save_wo_close": "Speichen ohne schließen", - "search": "Suchen", - "search_pattern": "Muster", - "select_destination": "Zielort auswählen", - "size": "Größe", - "soft_tabs": "Leichte Tabulatoren", - "tab_size": "Tabulatoren Größe", - "tasks": "Aufgaben", - "remaining_tasks": "Es gibt noch laufende Prozesse. Wollen Sie wirklich neu laden?", - "toggle_nav": "Navigation umschalten", - "upload": "Hochladen", - "upload_drop": "Dateien zum hochladen hier ablegen", - "upload_file": "Datei hochladen", - "upload_overwrite_hint": "Die folgenden Dateien würden überschrieben:", - "upload_overwrite_confirm": "Sollen die Dateien dennoch hochgeladen werden?", - "upload_remote": "Hochladen von ausserhalb", - "upload_remote_url": "Entfernte URL zum hochladen", - "username": "Benutzername", - "word_wrap": "Zeilenumbruch" -} - -f00bar; -$i18n["de"] = json_decode( $i18n["de"], true ); -$i18n["en"] = <<<'f00bar' + $i18n = []; + $i18n["en"] = <<<'f00bar' { "ajax_request": "AJAX request", "archive_create_error": "Could not create archive.", - "archive_create_success": "Archive successfully created.", + "archive_create_success": "Archive created.", "archive_invalid_format": "Invalid archive format given.", "archivename": "Name of the archive", "cancel": "Cancel", "close": "Close", "copy": "Copy", "copy_error": "The following files could not be copied:", - "copy_success": "File(s) copied successfully.", + "copy_success": "Files copied.", "copylink": "Copy link", + "create": "Create", "create_archive": "Create archive", + "create_wo_close": "Create w/o close", "data": "Data", "delete": "Delete", "directoryname": "Directory Name", @@ -1017,41 +121,41 @@ $i18n["en"] = <<<'f00bar' "error": "Error:", "extract": "Extract", "extract_error": "Could not extract archive.", - "extract_filename": "Extract file - ", - "extract_success": "Archive extracted successfully.", + "extract_filename": "Extract file:", + "extract_success": "Archive extracted.", "file_copy_to": "to", - "file_delete_confirm": "Do you really want to delete the following file -", - "file_delete_error": "File(s) could not be deleted.", - "file_delete_success": "File(s) successfully deleted.", - "file_display_error": "This file can not be displayed or edited.", - "file_load_error": "Content could not be loaded.", + "file_delete_confirm": "Do you really want to delete the following file:", + "file_delete_error": "Could not delete files.", + "file_delete_success": "Files deleted.", + "file_display_error": "This file cannot be displayed or edited.", + "file_load_error": "Could not load content.", "file_new": "New file", "file_no_permission": "No permission to edit/create file.", - "file_not_found": "File was not found or could not be opened.", + "file_not_found": "Could either not find or open file.", "file_open_error": "Could not open the file.", "file_rename": "Rename File", - "file_rename_error": "File could not be renamed: ", - "file_rename_success": "File successfully renamed.", - "file_save_confirm": "Do you want to save the following file -", - "file_save_error": "File could not be saved.", - "file_save_success": "File was saved successfully.", - "file_upload_error": "File could not be uploaded.", - "file_upload_success": "File successfully uploaded.", + "file_rename_error": "File could not be renamed", + "file_rename_success": "File renamed.", + "file_save_confirm": "Do you want to save the following file:", + "file_save_error": "Could not save file.", + "file_save_success": "File saved.", + "file_upload_error": "Could not upload file.", + "file_upload_success": "File uploaded.", "filename": "Filename", "filename_new": "New Filename", - "filename_slashes": "The filename must not contain slashes.", + "filename_slashes": "Remove all slashes from the filename.", "filter": "Filter", - "folder_create_error": "Directory could not be created: ", - "folder_create_success": "Directory sucessfully created.", + "folder_create_error": "Could not create directory:", + "folder_create_success": "Directory created.", "folder_new": "New Folder", - "folder_not_found": "The directory could not be found.", - "folder_tree_load_error": "Error while fetching the folder tree.", + "folder_not_found": "Could not find the directory.", + "folder_tree_load_error": "Could not fetch folder tree.", "footer": "IFM - improved file manager | ifm.php hidden |", - "general_error": "General error occured: No or broken response.", + "general_error": "General error: No or broken response.", "github": "Visit the project on GitHub", "group": "Group", "invalid_action": "Invalid action given.", - "invalid_archive_format": "Invalid archive format given. Possible formats are zip, tar, tar.gz or tar.bz2.", + "invalid_archive_format": "Invalid archive format given. Possible formats are ZIP, TAR, tar.gz or tar.bz2.", "invalid_data": "Invalid data from server.", "invalid_dir": "Invalid directory given.", "invalid_filename": "Invalid filename given.", @@ -1068,25 +172,25 @@ $i18n["en"] = <<<'f00bar' "method": "Method", "move": "Move", "move_error": "The following files could not be moved:", - "move_success": "File(s) successfully moved.", - "nopermissions": "You don't have the permission to do that.", + "move_success": "Files moved.", + "nopermissions": "You lack the permissions to do that.", "options": "Options", "owner": "Owner", "password": "Password", - "path_content": "Content of", - "pattern_error_slashes": "Pattern must not contain slashes.", - "permission_change_error": "Permissions could not be changed: ", - "permission_change_success": "Permissions successfully changed.", - "permission_parse_error": "Permissions could not be parsed correctly.", + "path_content": "Current directory", + "pattern_error_slashes": "Pattern cannot contain slashes.", + "permission_change_error": "Could not change permissions:", + "permission_change_success": "Permissions changed.", + "permission_parse_error": "Could not parse permissions.", "permissions": "Permissions", "refresh": "Refresh", "remaining_tasks": "There are remaining tasks. Do you really want to reload?", "rename": "Rename", - "rename_filename": "Rename file -", + "rename_filename": "Rename file:", "request": "Request", "response": "Response", "save": "Save", - "save_wo_close": "Save w/o Close", + "save_wo_close": "Save without Closing", "search": "Search", "search_pattern": "Pattern", "select_destination": "Select Destination", @@ -1098,8 +202,8 @@ $i18n["en"] = <<<'f00bar' "upload": "Upload", "upload_drop": "Drop files to upload", "upload_file": "Upload File", - "upload_overwrite_hint": "The following files would be overwritten:", "upload_overwrite_confirm": "Upload anyway?", + "upload_overwrite_hint": "The following files will be overwritten:", "upload_remote": "Remote Upload", "upload_remote_url": "Remote Upload URL", "username": "Username", @@ -1108,353 +212,134 @@ $i18n["en"] = <<<'f00bar' f00bar; $i18n["en"] = json_decode( $i18n["en"], true ); -$i18n["fr"] = <<<'f00bar' +$i18n["en"] = <<<'f00bar' { - "ajax_request": "requête AJAX ", - "archivename": "Nom de l'archive", - "archive_create_success": "Archive créée avec succès.", - "archive_create_error": "Echec lors de la création de l'archive.", - "archive_invalid_format": "Le format de l'archive indiqué est invalide.", - "cancel": "Annuler", - "close": "Fermer", - "copy": "Copier", - "copylink": "Copier le lien", - "copy_error": "Les fichiers suivants n'ont pu être copiés :", - "copy_success": "Le(s) fichiers(s) a/ont été copié(s) avec succès.", - "create_archive": "Créer l'archive", - "data": "Données", - "delete": "Supprimer", - "directoryname": "Nom du dossier", - "download": "Téléchargement", - "edit": "Editer", - "editor_options": "Options de l'éditeur", - "error": "Erreur:", - "extract": "Extraire", - "extract_error": "Echec lors de l'extraction de l'archive.", - "extract_filename": "Extraire le fichier - ", - "extract_success": "Archive extraite avec succès.", - "file_copy_to": "vers", - "file_delete_confirm": "Voulez-vous vraiment supprimer le fichier -", - "file_delete_error": "Echec lors de la suppression des fichiers.", - "file_delete_success": "Les fichiers ont été supprimés avec succès.", - "file_display_error": "Ce fichier ne peut pas être affiché ni supprimé.", - "file_new": "Nouveau fichier", - "file_load_error": "Le contenu n'a pas pu être chargé.", - "file_open_error": "Impossible d'ouvrir le fichier.", - "file_no_permission": "Permissions insuffisantes pour éditer ou créer le fichier.", - "file_not_found": "Le fichier n'a pas été trouvé ou n'a pas pu être ouvert.", - "file_rename": "Renommer fichier", - "file_rename_error": "Le fichier n'a pas pu être renommé : ", - "file_rename_success": "Le fichier a été renommé avec succès.", - "file_save_error": "Le fichier n'a pas pu être enregistré.", - "file_save_success": "Le fichier a été enregistré avec succès.", - "file_save_confirm": "Voulez-vous enregistré le fichier -", - "file_upload_error": "Le fichier n'a pas pu être envoyé.", - "file_upload_success": "Le fichier a été envoyé avec succès.", - "filename": "Nom de fichier", - "filename_new": "Nouveau nom de fichier", - "filename_slashes": "Le Nom de fichier ne doit pas contenir de slash (/barre oblique/).", - "filter": "Filtrer", - "folder_create_error": "Le dossier n'a pas pu être créé : ", - "folder_create_success": "Le dossier n'a pas pu être créé avec succès.", - "folder_new": "Nouveau dossier", - "folder_not_found": "Dossier non trouvé.", - "folder_tree_load_error": "Error lors du chargement d le'arborescence.", + "ajax_request": "AJAX request", + "archive_create_error": "Could not create archive.", + "archive_create_success": "Archive created.", + "archive_invalid_format": "Invalid archive format given.", + "archivename": "Name of the archive", + "cancel": "Cancel", + "close": "Close", + "copy": "Copy", + "copy_error": "The following files could not be copied:", + "copy_success": "Files copied.", + "copylink": "Copy link", + "create": "Create", + "create_archive": "Create archive", + "create_wo_close": "Create w/o close", + "data": "Data", + "delete": "Delete", + "directoryname": "Directory Name", + "download": "Download", + "edit": "Edit", + "editor_options": "Editor Options", + "error": "Error:", + "extract": "Extract", + "extract_error": "Could not extract archive.", + "extract_filename": "Extract file:", + "extract_success": "Archive extracted.", + "file_copy_to": "to", + "file_delete_confirm": "Do you really want to delete the following file:", + "file_delete_error": "Could not delete files.", + "file_delete_success": "Files deleted.", + "file_display_error": "This file cannot be displayed or edited.", + "file_load_error": "Could not load content.", + "file_new": "New file", + "file_no_permission": "No permission to edit/create file.", + "file_not_found": "Could either not find or open file.", + "file_open_error": "Could not open the file.", + "file_rename": "Rename File", + "file_rename_error": "File could not be renamed", + "file_rename_success": "File renamed.", + "file_save_confirm": "Do you want to save the following file:", + "file_save_error": "Could not save file.", + "file_save_success": "File saved.", + "file_upload_error": "Could not upload file.", + "file_upload_success": "File uploaded.", + "filename": "Filename", + "filename_new": "New Filename", + "filename_slashes": "Remove all slashes from the filename.", + "filter": "Filter", + "folder_create_error": "Could not create directory:", + "folder_create_success": "Directory created.", + "folder_new": "New Folder", + "folder_not_found": "Could not find the directory.", + "folder_tree_load_error": "Could not fetch folder tree.", "footer": "IFM - improved file manager | ifm.php hidden |", - "general_error": "Erreur générale : pas de réponse, ou réponse incorrecte.", - "github": "Voir le projet sur GitHub", - "group": "Groupe", - "invalid_action": "Action demandée invalide.", - "invalid_archive_format": "Format d'archive invalide : les formats autorisés sont zip, tar, tar.gz ou tar.bz2.", - "invalid_data": "Données invalides reçues du serveur.", - "invalid_dir": "Le dossier indiqué est invalide.", - "invalid_filename": "Le nom de fichier indiqué est invalide.", - "invalid_params": "Le paramètre indiqué est invalide.", - "invalid_url": "L'URL indiquée est invalide.", - "json_encode_error": "Impossible de formater la réponse en JSON :", - "last_modified": "Dernière modification", - "load_config_error": "Impossible de charger la configuration.", - "load_template_error": "Impossible de charger les modèles.", - "load_text_error": "Impossible de charger les chaînes de textes.", - "login": "Connexion", - "login_failed": "Echec de connexion.", - "logout": "Déconnexion", - "method": "Méthode", - "move": "Déplacer", - "move_error": "Les fichiers suivants n'ont pu être déplacés :", - "move_success": "Fichiers déplacés avec succès.", - "nopermissions": "Vous n'avez pas les permissions pour faire cela.", + "general_error": "General error: No or broken response.", + "github": "Visit the project on GitHub", + "group": "Group", + "invalid_action": "Invalid action given.", + "invalid_archive_format": "Invalid archive format given. Possible formats are ZIP, TAR, tar.gz or tar.bz2.", + "invalid_data": "Invalid data from server.", + "invalid_dir": "Invalid directory given.", + "invalid_filename": "Invalid filename given.", + "invalid_params": "Invalid parameter given.", + "invalid_url": "Invalid URL given.", + "json_encode_error": "Could not format the response as JSON:", + "last_modified": "Last Modified", + "load_config_error": "Could not load configuration.", + "load_template_error": "Could not load templates.", + "load_text_error": "Could not load texts.", + "login": "Login", + "login_failed": "Login failed.", + "logout": "Log Off", + "method": "Method", + "move": "Move", + "move_error": "The following files could not be moved:", + "move_success": "Files moved.", + "nopermissions": "You lack the permissions to do that.", "options": "Options", - "owner": "Propriétaire", - "password": "Mot de passe", - "path_content": "Contenu de", - "pattern_error_slashes": "Le motif ne doit pas contenir de slashes.", - "permission_change_error": "Les permissions n'ont pu être changées : ", - "permission_change_success": "Permissions changées avec succès.", - "permission_parse_error": "Les permissions n'ont pu être interprétées correctement.", + "owner": "Owner", + "password": "Password", + "path_content": "Current directory", + "pattern_error_slashes": "Pattern cannot contain slashes.", + "permission_change_error": "Could not change permissions:", + "permission_change_success": "Permissions changed.", + "permission_parse_error": "Could not parse permissions.", "permissions": "Permissions", - "refresh": "Rafraîchir", - "rename": "Renommer", - "rename_filename": "Renommer fichier -", - "request": "Requête", - "response": "Réponse", - "save": "Enregistrer", - "save_wo_close": "Enregistrer sans fermer", - "search": "Recherche", - "search_pattern": "Motif", - "select_destination": "Seélectionner la destination", - "size": "Taille", - "soft_tabs": "Tabulations par espaces", - "tab_size": "Taille de tabulation", - "tasks": "Tâches", - "remaining_tasks": "Il reste des tâches en cours. Voulez-vous vraiment recharger la page ?", - "toggle_nav": "Basculer la navigation", - "upload": "Envoyer", - "upload_drop": "Glisser-déplacer les fichier pour les envoyer", - "upload_file": "Envoyer fichier", - "upload_remote": "Envoi distant", - "upload_remote_url": "URL pour l'envoi distant", - "username": "Nom d'utilisateur", - "word_wrap": "Revenir à la ligne" + "refresh": "Refresh", + "remaining_tasks": "There are remaining tasks. Do you really want to reload?", + "rename": "Rename", + "rename_filename": "Rename file:", + "request": "Request", + "response": "Response", + "save": "Save", + "save_wo_close": "Save without Closing", + "search": "Search", + "search_pattern": "Pattern", + "select_destination": "Select Destination", + "size": "Size", + "soft_tabs": "Soft Tabs", + "tab_size": "Tab Size", + "tasks": "Tasks", + "toggle_nav": "Toggle navigation", + "upload": "Upload", + "upload_drop": "Drop files to upload", + "upload_file": "Upload File", + "upload_overwrite_confirm": "Upload anyway?", + "upload_overwrite_hint": "The following files will be overwritten:", + "upload_remote": "Remote Upload", + "upload_remote_url": "Remote Upload URL", + "username": "Username", + "word_wrap": "Word Wrap" } f00bar; -$i18n["fr"] = json_decode( $i18n["fr"], true ); -$i18n["pt-br"] = <<<'f00bar' -{ - "ajax_request": "requisição AJAX", - "archivename": "Nome do arquivo compactado", - "archive_create_success": "Arquivo compactado com sucesso.", - "archive_create_error": "Não foi possível compactar o arquivo.", - "archive_invalid_format": "Formato do arquivo dado é inválido.", - "cancel": "Cancelar", - "close": "Fechar", - "copy": "Copiar", - "copylink": "Copiar endereço", - "copy_error": "Os seguintes arquivos não puderam ser copiados:", - "copy_success": "Arquivo(s) copiado(s) com sucesso.", - "create_archive": "Compactar", - "data": "Dados", - "delete": "Excluir", - "directoryname": "Nome do Diretório", - "download": "Baixar", - "edit": "Editar", - "editor_options": "Opções do Editor", - "error": "Erro:", - "extract": "Extrair", - "extract_error": "Não foi possível extrair o arquivo.", - "extract_filename": "Extrair arquivo - ", - "extract_success": "Arquivo extraído com sucesso.", - "file_copy_to": "para", - "file_delete_confirm": "Você tem certeza que quer excluir o seguinte arquivo -", - "file_delete_error": "Arquivo(s) não puderam/pôde ser excluído(s).", - "file_delete_success": "Arquivo(s) excluído(s) com sucesso.", - "file_display_error": "Este arquivo não pode ser exibido ou editado.", - "file_new": "Novo Arquivo", - "file_load_error": "Conteúdo não pôde ser carregado.", - "file_open_error": "Não foi possível abrir o arquivo.", - "file_no_permission": "Sem permissão para editar/criar o arquivo.", - "file_not_found": "Arquivo não foi encontrado ou não pôde ser aberto.", - "file_rename": "Renomear arquivo", - "file_rename_error": "Arquivo não pôde ser renomeado: ", - "file_rename_success": "Arquivo renomeado com sucesso.", - "file_save_error": "Não foi possível salvar o arquivo.", - "file_save_success": "Arquivo salvo com sucesso.", - "file_save_confirm": "Você quer salvar o seguinte arquivo -", - "file_upload_error": "Não foi possível enviar o arquivo.", - "file_upload_success": "Arquivo enviado com sucesso.", - "filename": "Nome do arquivo", - "filename_new": "Novo nome do arquivo", - "filename_slashes": "O nome do arquivo não deve ter barras.", - "filter": "Filtrar", - "folder_create_error": "Diretónio não pôde ser criado: ", - "folder_create_success": "Diretório criado com sucesso.", - "folder_new": "Novo Diretório", - "folder_not_found": "Não foi possível achar o diretório.", - "folder_tree_load_error": "Error durante a construção da árvore de diretórios.", - "footer": "IFM - improved file manager | ifm.php escondido |", - "general_error": "Erro genérico: Sem respsota ou resposta inválida.", - "github": "Visite o projeto no GitHub", - "group": "Grupo", - "invalid_action": "Ação inválida dada.", - "invalid_archive_format": "Formato de arquivo inválido dado. Formatos possíveis são zip, tar, tar.gz ou tar.bz2.", - "invalid_data": "Dados inválidos vindos do servidor.", - "invalid_dir": "Diretório inválido dado.", - "invalid_filename": "Nome do arquivo inválido dado.", - "invalid_params": "Parâmetro inválido dado.", - "invalid_url": "URL Inválida dada.", - "json_encode_error": "Não foi possível formatar a resposta como JSON:", - "last_modified": "Última Modificação", - "load_config_error": "Não foi possível carregar as configurações.", - "load_template_error": "Não foi possível carregar o template.", - "load_text_error": "Não foi possível carregar os textos.", - "login": "Logar", - "login_failed": "Login falhou.", - "logout": "Deslogar", - "method": "Método", - "move": "Mover", - "move_error": "Os seguintes arquivos não puderam ser movidos:", - "move_success": "Arquivo(s) movidos com sucesso.", - "nopermissions": "Você não tem permissão para fazer isto.", - "options": "Opções", - "owner": "Dono", - "password": "Senha", - "path_content": "Conteúdo de", - "pattern_error_slashes": "Padrão não deve conter barras.", - "permission_change_error": "Não foi possível alterar as permissões: ", - "permission_change_success": "Permissões alteradas com sucesso.", - "permission_parse_error": "Não foi possível mapear as permissões corretamente.", - "permissions": "Permissões", - "refresh": "Atualizar", - "rename": "Renomear", - "rename_filename": "Renomear arquivo -", - "request": "Requisição", - "response": "Resposta", - "save": "Salvar", - "save_wo_close": "Salvar sem Fechar", - "search": "Procurar", - "search_pattern": "Padrão", - "select_destination": "Selecione Destino", - "size": "Tamanho", - "soft_tabs": "Tabulação suave", - "tab_size": "Tamanho da tabulação", - "tasks": "Tarefas", - "remaining_tasks": "Existem tarefas remanescentes. Você realmente deseja recarregar?", - "toggle_nav": "Ativar/Desativar Navegação", - "upload": "Enviar", - "upload_drop": "Solte arquivo aqui para enviar", - "upload_file": "Enviar Arquivo", - "upload_remote": "Envio Remoto", - "upload_remote_url": "URL para Envio Remoto", - "username": "Nome de usuário", - "word_wrap": "Quebra de Linha" -} - -f00bar; -$i18n["pt-br"] = json_decode( $i18n["pt-br"], true ); -$i18n["ru"] = <<<'f00bar' -{ - "ajax_request": "AJAX запрос", - "archivename": "Название архива", - "archive_create_success": "Архив успешно создан.", - "archive_create_error": "Не удалось создать архив.", - "archive_invalid_format": "Указан неверный формат архива.", - "cancel": "Отмена", - "close": "Закрыть", - "copy": "Копировать", - "copylink": "Копировать ссылку", - "copy_error": "Не удалось скопировать следующие файлы:", - "copy_success": "Файл(ы) успешно скопированы.", - "create_archive": "Создать архив", - "data": "Данные", - "delete": "Удалить", - "directoryname": "Название каталога", - "download": "Скачать", - "edit": "Редактировать", - "editor_options": "Параметры редактора", - "error": "Ошибка:", - "extract": "Извлечь", - "extract_error": "Не удалось извлечь архив.", - "extract_filename": "Извлечь файл - ", - "extract_success": "Архив извлечен успешно.", - "file_copy_to": "в", - "file_delete_confirm": "Вы действительно хотите удалить следующий файл - ", - "file_delete_error": "Файл(ы) не может быть удалены.", - "file_delete_success": "Файл(ы) успешно удалены.", - "file_display_error": "Файл не может быть отображен или отредактирован.", - "file_new": "Новый файл", - "file_load_error": "Не удалось загрузить содержимое.", - "file_open_error": "Не удалось открыть файл.", - "file_no_permission": "Нет прав на редактирование/создание файла.", - "file_not_found": "Файл не найден или не может быть открыт.", - "file_rename": "Переименовать файл", - "file_rename_error": "Файл не может быть переименован: ", - "file_rename_success": "Файл успешно переименован.", - "file_save_error": "Не удалось сохранить файл.", - "file_save_success": "Файл успешно сохранен.", - "file_save_confirm": "Хотите сохранить следующий файл -", - "file_upload_error": "Не удалось загрузить файл.", - "file_upload_success": "Файл успешно загружен.", - "filename": "Имя файла", - "filename_new": "Новое имя файла", - "filename_slashes": "Имя файла не должно содержать косую черту.", - "filter": "Фильтр", - "folder_create_error": "Не удалось создать каталог: ", - "folder_create_success": "Каталог успешно сохранен.", - "folder_new": "Новый каталог", - "folder_not_found": "Каталог не найден.", - "folder_tree_load_error": "Ошибка при получении дерева папок.", - "footer": "IFM - improved file manager | ifm.php hidden |", - "general_error": "Ошибка: Отсутствующий или неверный ответ.", - "github": "Страница проекта на GitHub", - "group": "Группа", - "invalid_action": "Неверное действие.", - "invalid_archive_format": "Неверный формат архива. Допустимые форматы: zip, tar, tar.gz или tar.bz2.", - "invalid_data": "Неверные данные от сервера.", - "invalid_dir": "Неверный каталог.", - "invalid_filename": "Неверное имя файла.", - "invalid_params": "Неверный параметр.", - "invalid_url": "Неверный URL.", - "json_encode_error": "Не удалось представить ответ в виде JSON:", - "last_modified": "Изменено", - "load_config_error": "Ошибка загрузки конфигурации.", - "load_template_error": "Ошибка загрузки шаблона.", - "load_text_error": "Ошибка загрузки текста.", - "login": "Вход", - "login_failed": "Ошибка входа.", - "logout": "Выйти", - "method": "Метод", - "move": "Переместить", - "move_error": "Следующие файлы не могут быть перемещены:", - "move_success": "Файл(ы) успешно перемещены.", - "nopermissions": "Нет прав.", - "options": "Опции", - "owner": "Владелец", - "password": "Пароль", - "path_content": "Содержимое", - "pattern_error_slashes": "Шаблон не должен содержать косую черту.", - "permission_change_error": "Права не могут быть изменены: ", - "permission_change_success": "Права успешно изменены.", - "permission_parse_error": "Не удалось разобрать права.", - "permissions": "Права", - "refresh": "Обновить", - "rename": "Переименовать", - "rename_filename": "Переименовать файл -", - "request": "Запрос", - "response": "Ответ", - "save": "Сохранить и выйти", - "save_wo_close": "Сохранить", - "search": "Поиск", - "search_pattern": "Шаблон", - "select_destination": "Выберите назначение", - "size": "Размер", - "soft_tabs": "Пробелы вместо табуляции", - "tab_size": "Размер табов", - "tasks": "Задачи", - "remaining_tasks": "Есть оставшиеся задачи. Вы действительно хотите перезагрузить?", - "toggle_nav": "Переключить вид", - "upload": "Загрузить", - "upload_drop": "Перетащите файлы для загрузки", - "upload_file": "Загрузить файл", - "upload_remote": "Удаленная загрузка", - "upload_remote_url": "Удаленная загрузка по URL", - "username": "Имя пользователя", - "word_wrap": "Перенос строк" -} - -f00bar; -$i18n["ru"] = json_decode( $i18n["ru"], true ); +$i18n["en"] = json_decode( $i18n["en"], true ); $this->i18n = $i18n; - - if( in_array( $this->config['language'], array_keys( $this->i18n ) ) ) - // Merge english with the language in case of missing keys - $this->l = array_merge($this->i18n['en'], $this->i18n[$this->config['language']]); - else - $this->l = $this->i18n['en']; if ($this->config['timezone']) date_default_timezone_set($this->config['timezone']); + + if ($this->config['session_name']) + session_name($this->config['session_name']); + + // set cookie_path for SESSION to REQUEST_URI without QUERY_STRING + $cookie_path = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?') ?: strlen($_SERVER['REQUEST_URI'])); + session_set_cookie_params(0, $cookie_path); } /** @@ -1474,33 +359,36 @@ $i18n["ru"] = json_decode( $i18n["ru"], true ); $this->getJS(); } - public function getCSS() { - print ' - - - - - - - '; - } - public function getJS() { - echo <<<'f00bar' - -f00bar; - } +f00bar; + } public function getHTMLHeader() { print ' @@ -4388,166 +3399,840 @@ f00bar; print ''; } - /* - main functions + /** + * main functions */ - private function handleRequest() { - if( $_REQUEST["api"] == "getRealpath" ) { - if( isset( $_REQUEST["dir"] ) && $_REQUEST["dir"] != "" ) - $this->jsonResponse( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) ); - else - $this->jsonResponse( array( "realpath" => "" ) ); - } - elseif( $_REQUEST["api"] == "getFiles" ) { - if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) ) - $this->getFiles( $_REQUEST["dir"] ); - else - $this->getFiles( "" ); - } - elseif( $_REQUEST["api"] == "getConfig" ) { - $this->getConfig(); - } - elseif( $_REQUEST["api"] == "getFolders" ) { - $this->getFolders( $_REQUEST ); - } elseif( $_REQUEST["api"] == "getTemplates" ) { - $this->jsonResponse( $this->templates ); - } elseif( $_REQUEST["api"] == "getI18N" ) { - $this->jsonResponse( $this->l ); - } elseif( $_REQUEST["api"] == "logout" ) { - unset( $_SESSION['ifmauth'] ); - session_destroy(); - header( "Location: " . strtok( $_SERVER["REQUEST_URI"], '?' ) ); - exit( 0 ); - } else { - if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) ) { - $this->chDirIfNecessary( $_REQUEST['dir'] ); - switch( $_REQUEST["api"] ) { - case "createDir": $this->createDir( $_REQUEST["dir"], $_REQUEST["dirname"] ); break; - case "saveFile": $this->saveFile( $_REQUEST ); break; - case "getContent": $this->getContent( $_REQUEST ); break; - case "delete": $this->deleteFiles( $_REQUEST ); break; - case "rename": $this->renameFile( $_REQUEST ); break; - case "download": $this->downloadFile( $_REQUEST ); break; - case "extract": $this->extractFile( $_REQUEST ); break; - case "upload": $this->uploadFile( $_REQUEST ); break; - case "copyMove": $this->copyMove( $_REQUEST ); break; - case "changePermissions": $this->changePermissions( $_REQUEST ); break; - case "zipnload": $this->zipnload( $_REQUEST); break; - case "remoteUpload": $this->remoteUpload( $_REQUEST ); break; - case "searchItems": $this->searchItems( $_REQUEST ); break; - case "getFolderTree": $this->getFolderTree( $_REQUEST ); break; - case "createArchive": $this->createArchive( $_REQUEST ); break; - case "proxy": $this->downloadFile( $_REQUEST, false ); break; - default: - $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid api action given" ) ); - break; - } - } else { - print $this->jsonResponse( array( "status" => "ERROR", "message" => "Invalid working directory" ) ); - } - } - exit( 0 ); - } + public function run($mode="standalone") { + try { + if (!is_dir(realpath($this->config['root_dir'])) || !is_readable(realpath($this->config['root_dir']))) + throw new IFMException("Cannot access root_dir.", false); + + chdir(realpath($this->config['root_dir'])); - public function run( $mode="standalone" ) { - if ( $this->checkAuth() ) { - // go to our root_dir - if( ! is_dir( realpath( $this->config['root_dir'] ) ) || ! is_readable( realpath( $this->config['root_dir'] ) ) ) - die( "Cannot access root_dir."); - else - chdir( realpath( $this->config['root_dir'] ) ); $this->mode = $mode; - if( isset( $_REQUEST['api'] ) || $mode == "api" ) { - $this->handleRequest(); - } elseif( $mode == "standalone" ) { + if (isset($_REQUEST['api']) || $mode == "api") + $this->jsonResponse($this->dispatch()); + elseif ($mode == "standalone") $this->getApplication(); - } else { + else $this->getInlineApplication(); - } + } catch (IFMException $e) { + $this->jsonResponse(["status" => "ERROR", "message" => $e->getMessage()]); + } catch (Exception $e) { + $this->jsonResponse(["status" => "ERROR", "message" => $e->getMessage()]); } } - /* - api functions + private function dispatch() { + // APIs which do not need authentication + switch ($_REQUEST['api']) { + case "checkAuth": + if ($this->checkAuth()) + return ["status" => "OK", "message" => "Authenticated"]; + else + return ["status" => "ERROR", "message" => "Not authenticated"]; + case "getConfig": + return $this->getConfig(); + case "getTemplates": + return $this->getTemplates(); + case "getI18N": + return $this->getI18N($_REQUEST); + case "logout": + session_start(); + session_unset(); + header("Location: " . strtok($_SERVER["REQUEST_URI"], '?')); + exit; + } + + // check authentication + if (!$this->checkAuth()) + throw new IFMException("Not authenticated"); + + // api requests which work without a valid working directory + switch ($_REQUEST['api']) { + case "getRealpath": + if (isset($_REQUEST["dir"]) && $_REQUEST["dir"] != "") + return ["realpath" => $this->getValidDir($_REQUEST["dir"])]; + else + return ["realpath" => ""]; + case "getFiles": + if (isset($_REQUEST["dir"]) && $this->isPathValid($_REQUEST["dir"])) + return $this->getFiles($_REQUEST["dir"]); + else + return $this->getFiles(""); + case "getFolders": + return $this->getFolders($_REQUEST); + } + + // checking working directory + if (!isset($_REQUEST["dir"]) || !$this->isPathValid($_REQUEST["dir"])) + throw new IFMException($this->l("invalid_dir")); + + $this->chDirIfNecessary($_REQUEST['dir']); + switch ($_REQUEST["api"]) { + case "createDir": return $this->createDir($_REQUEST); + case "saveFile": return $this->saveFile($_REQUEST); + case "getContent": return $this->getContent($_REQUEST); + case "delete": return $this->deleteFiles($_REQUEST); + case "rename": return $this->renameFile($_REQUEST); + case "download": return $this->downloadFile($_REQUEST); + case "extract": return $this->extractFile($_REQUEST); + case "upload": return $this->uploadFile($_REQUEST); + case "copyMove": return $this->copyMove($_REQUEST); + case "changePermissions": return $this->changePermissions($_REQUEST); + case "zipnload": return $this->zipnload($_REQUEST); + case "remoteUpload": return $this->remoteUpload($_REQUEST); + case "searchItems": return $this->searchItems($_REQUEST); + case "getFolderTree": return $this->getFolderTree($_REQUEST); + case "createArchive": return $this->createArchive($_REQUEST); + case "proxy": return $this->downloadFile($_REQUEST, false); + default: + throw new IFMException($this->l("invalid_action")); + } + } + + /** + * api functions */ - - private function getFiles( $dir ) { - $this->chDirIfNecessary( $dir ); - - unset( $files ); unset( $dirs ); $files = array(); $dirs = array(); - - if( $handle = opendir( "." ) ) { - while( false !== ( $result = readdir( $handle ) ) ) { - if( $result == basename( $_SERVER['SCRIPT_NAME'] ) && $this->getScriptRoot() == getcwd() ) { } - elseif( ( $result == ".htaccess" || $result==".htpasswd" ) && $this->config['showhtdocs'] != 1 ) {} - elseif( $result == "." ) {} - elseif( $result != ".." && substr( $result, 0, 1 ) == "." && $this->config['showhiddenfiles'] != 1 ) {} - else { - $item = $this->getItemInformation( $result ); - if( $item['type'] == "dir" ) $dirs[] = $item; - else $files[] = $item; - } - } - closedir( $handle ); - } - usort( $dirs, array( $this, "sortByName" ) ); - usort( $files, array( $this, "sortByName" ) ); - - $this->jsonResponse( array_merge( $dirs, $files ) ); + private function getI18N($lang="en") { + if (in_array($lang, array_keys($this->i18n))) + return array_merge($this->i18n['en'], $this->i18n[$lang]); + else + return $this->i18n['en']; } - private function getItemInformation( $name ) { - $item = array(); + private function getTemplates() { + // templates + $templates = []; + $templates['app'] = <<<'f00bar' + +
+

{{i18n.upload_drop}}

+
+
+
+ + + + + + {{#config.download}} + + {{/config.download}} + {{#config.showlastmodified}} + + {{/config.showlastmodified}} + {{#config.showfilesize}} + + {{/config.showfilesize}} + {{#config.showpermissions}} + + {{/config.showpermissions}} + {{#config.showowner}} + + {{/config.showowner}} + {{#config.showgroup}} + + {{/config.showgroup}} + + + + + +
{{i18n.filename}}{{i18n.last_modified}}{{i18n.size}}{{i18n.permissions}}{{i18n.owner}}{{i18n.group}}
+
+
+
+
+
{{i18n.footer}} v4.0
+ {{i18n.github}} +
+
+
+
+ +f00bar; + $templates['login'] = <<<'f00bar' + + + + +f00bar; + $templates['filetable'] = <<<'f00bar' +{{#items}} + + {{#fixtop}} + + {{/fixtop}} + {{^fixtop}} + + {{/fixtop}} + + + + {{linkname}} + + + {{#config.download}} + + + + {{/config.download}} + {{#config.showlastmodified}} + {{lastmodified_hr}} + {{/config.showlastmodified}} + {{#config.showfilesize}} + {{size}} + {{/config.showfilesize}} + {{#config.showpermissions}} + + + + {{/config.showpermissions}} + {{#config.showowner}} + + {{owner}} + + {{/config.showowner}} + {{#config.showgroup}} + + {{group}} + + {{/config.showgroup}} + + {{#button}} + + + + {{/button}} + + +{{/items}} + +f00bar; + $templates['footer'] = <<<'f00bar' + + +f00bar; + $templates['task'] = <<<'f00bar' +
+
+
+
+ {{name}} +
+
+
+
+ +f00bar; + $templates['ajaxrequest'] = <<<'f00bar' +
+ +
+ +f00bar; + $templates['copymove'] = <<<'f00bar' +
+
+ + +
+
+ +f00bar; + $templates['createdir'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['createarchive'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['deletefile'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['extractfile'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['file'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['file_editoroptions'] = <<<'f00bar' +
+
+
+ + +
+
+ + +
+
+
+
+ {{i18n.tab_size}} +
+ +
+ {{#ace_includes}} + + {{/ace_includes}} +
+ +f00bar; + $templates['remoteupload'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['renamefile'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['search'] = <<<'f00bar' +
+ +
+ +f00bar; + $templates['searchresults'] = <<<'f00bar' +{{#items}} + + + + {{linkname}} ({{folder}}) + + + +{{/items}} +{{^items}} + + + No results found. + + +{{/items}} + +f00bar; + $templates['uploadfile'] = <<<'f00bar' +
+ + +
+ +f00bar; + $templates['uploadconfirmoverwrite'] = <<<'f00bar' +
+ + +
+ +f00bar; + return $templates; + } + + private function getFiles($dir) { + $this->chDirIfNecessary($dir); + + unset($files); unset($dirs); $files = []; $dirs = []; + + if ($handle = opendir(".")) { + while (false !== ($result = readdir($handle))) { + if ($result == basename($_SERVER['SCRIPT_NAME']) && getcwd() == $this->initialWD) + continue; + elseif (($result == ".htaccess" || $result==".htpasswd") && $this->config['showhtdocs'] != 1) + continue; + elseif ($result == ".") + continue; + elseif ($result != ".." && substr($result, 0, 1) == "." && $this->config['showhiddenfiles'] != 1) + continue; + else { + $item = $this->getItemInformation($result); + if ($item['type'] == "dir") + $dirs[] = $item; + else + $files[] = $item; + } + } + closedir($handle); + } + array_multisort(array_column($dirs, 'name'), SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $dirs); + array_multisort(array_column($files, 'name'), SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $files); + + return array_merge($dirs, $files); + } + + private function getItemInformation($name) { + $item = []; $item["name"] = $name; - if( is_dir( $name ) ) { + if (is_dir($name)) { $item["type"] = "dir"; - if( $name == ".." ) + if ($name == "..") $item["icon"] = "icon icon-up-open"; - else + else $item["icon"] = "icon icon-folder-empty"; } else { $item["type"] = "file"; - if( in_array( substr( $name, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) - $type = substr( $name, -6 ); - elseif( substr( $name, -8 ) == ".tar.bz2" ) + if (in_array(substr($name, -7), [".tar.gz", ".tar.xz"])) + $type = substr($name, -6); + elseif (substr($name, -8) == ".tar.bz2") $type = "tar.bz2"; else - $type = substr( strrchr( $name, "." ), 1 ); - $item["icon"] = $this->getTypeIcon( $type ); + $type = substr(strrchr($name, "."), 1); + $item["icon"] = $this->getTypeIcon($type); $item["ext"] = strtolower($type); - if( !$this->config['disable_mime_detection'] ) - $item["mime_type"] = mime_content_type( $name ); + if (!$this->config['disable_mime_detection']) + $item["mime_type"] = mime_content_type($name); } - if( $this->config['showlastmodified'] == 1 ) { $item["lastmodified"] = filemtime( $name ); } - if( $this->config['showfilesize'] == 1 ) { - if( $item['type'] == "dir" ) { + if ($this->config['showlastmodified'] == 1) + $item["lastmodified"] = filemtime($name); + if ($this->config['showfilesize'] == 1) { + if ($item['type'] == "dir") { $item['size_raw'] = 0; $item['size'] = ""; } else { - $item["size_raw"] = filesize( $name ); - if( $item["size_raw"] > 1073741824 ) $item["size"] = round( ( $item["size_raw"]/1073741824 ), 2 ) . " GB"; - elseif($item["size_raw"]>1048576)$item["size"] = round( ( $item["size_raw"]/1048576 ), 2 ) . " MB"; - elseif($item["size_raw"]>1024)$item["size"] = round( ( $item["size_raw"]/1024 ), 2 ) . " KB"; + $item["size_raw"] = filesize($name); + if ($item["size_raw"] > 1073741824) $item["size"] = round(($item["size_raw"]/1073741824 ), 2) . " GB"; + elseif($item["size_raw"]>1048576)$item["size"] = round(($item["size_raw"]/1048576), 2) . " MB"; + elseif($item["size_raw"]>1024)$item["size"] = round(($item["size_raw"]/1024), 2) . " KB"; else $item["size"] = $item["size_raw"] . " Byte"; } } - if( $this->config['showpermissions'] > 0 ) { - if( $this->config['showpermissions'] == 1 ) $item["fileperms"] = substr( decoct( fileperms( $name ) ), -3 ); - elseif( $this->config['showpermissions'] == 2 ) $item["fileperms"] = $this->filePermsDecode( fileperms( $name ) ); - if( $item["fileperms"] == "" ) $item["fileperms"] = " "; - $item["filepermmode"] = ( $this->config['showpermissions'] == 1 ) ? "short" : "long"; + if ($this->config['showpermissions'] > 0) { + if ($this->config['showpermissions'] == 1) + $item["fileperms"] = substr(decoct(fileperms($name)), -3); + elseif ($this->config['showpermissions'] == 2) + $item["fileperms"] = $this->filePermsDecode(fileperms($name)); + if ($item["fileperms"] == "") + $item["fileperms"] = " "; + $item["filepermmode"] = ($this->config['showpermissions'] == 1) ? "short" : "long"; } - if( $this->config['showowner'] == 1 ) { - if ( function_exists( "posix_getpwuid" ) && fileowner($name) !== false ) { - $ownerarr = posix_getpwuid( fileowner( $name ) ); + if ($this->config['showowner'] == 1) { + if (function_exists("posix_getpwuid") && fileowner($name) !== false) { + $ownerarr = posix_getpwuid(fileowner($name)); $item["owner"] = $ownerarr['name']; } else $item["owner"] = false; } - if( $this->config['showgroup'] == 1 ) { - if( function_exists( "posix_getgrgid" ) && filegroup( $name ) !== false ) { - $grouparr = posix_getgrgid( filegroup( $name ) ); + if ($this->config['showgroup'] == 1) { + if (function_exists("posix_getgrgid") && filegroup($name) !== false) { + $grouparr = posix_getgrgid(filegroup($name)); $item["group"] = $grouparr['name']; } else $item["group"] = false; } @@ -4556,530 +4241,518 @@ f00bar; private function getConfig() { $ret = $this->config; - $ret['inline'] = ( $this->mode == "inline" ) ? true : false; - $ret['isDocroot'] = ($this->getRootDir() == $this->getScriptRoot()); + $ret['inline'] = ($this->mode == "inline") ? true : false; + $ret['isDocroot'] = ($this->getRootDir() == $this->initialWD); - foreach (array("auth_source", "root_dir") as $field) { + foreach (["auth_source", "root_dir"] as $field) unset($ret[$field]); - } - $this->jsonResponse($ret); - } - private function getFolders( $d ) { - if( ! isset( $d['dir'] ) ) - $d['dir'] = $this->getRootDir(); - if( ! $this->isPathValid( $d['dir'] ) ) - echo "[]"; - else { - $ret = array(); - foreach( glob( $this->pathCombine( $d['dir'], "*" ), GLOB_ONLYDIR ) as $dir ) { - array_push( $ret, array( - "text" => htmlspecialchars( basename( $dir ) ), - "lazyLoad" => true, - "dataAttr" => array( "path" => $dir ) - )); - } - sort( $ret ); - if( $this->getScriptRoot() == realpath( $d['dir'] ) ) - $ret = array_merge( - array( - 0 => array( - "text" => "/ [root]", - "dataAttr" => array( "path" => $this->getRootDir() ) - ) - ), - $ret - ); - $this->jsonResponse( $ret ); - } - } - - private function searchItems( $d ) { - if( $this->config['search'] != 1 ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - return; - } - - if( strpos( $d['pattern'], '/' ) !== false ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['pattern_error_slashes'] ) ); - exit( 1 ); - } - try { - $results = $this->searchItemsRecursive( $d['pattern'] ); - $this->jsonResponse( $results ); - } catch( Exception $e ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error'] . " " . $e->getMessage() ) ); - } - } - - private function searchItemsRecursive( $pattern, $dir="" ) { - $items = array(); - $dir = $dir ? $dir : '.'; - foreach( glob( $this->pathCombine( $dir, $pattern ) ) as $result ) { - array_push( $items, $this->getItemInformation( $result ) ); - } - foreach( glob( $this->pathCombine( $dir, '*') , GLOB_ONLYDIR ) as $subdir ) { - $items = array_merge( $items, $this->searchItemsRecursive( $pattern, $subdir ) ); - } - return $items; - } - - private function getFolderTree( $d ) { - $this->jsonResponse( - array_merge( - array( - 0 => array( - "text" => "/ [root]", - "nodes" => array(), - "dataAttributes" => array( "path" => $this->getRootDir() ) - ) - ), - $this->getFolderTreeRecursive( $d['dir'] ) - ) - ); - } - - private function getFolderTreeRecursive( $start_dir ) { - $ret = array(); - $start_dir = realpath( $start_dir ); - if( $handle = opendir( $start_dir ) ) { - while (false !== ( $result = readdir( $handle ) ) ) { - if( is_dir( $this->pathCombine( $start_dir, $result ) ) && $result != "." && $result != ".." ) { - array_push( - $ret, - array( - "text" => htmlspecialchars( $result ), - "dataAttributes" => array( - "path" => $this->pathCombine( $start_dir, $result ) - ), - "nodes" => $this->getFolderTreeRecursive( $this->pathCombine( $start_dir, $result ) ) - ) - ); - } - } - } - sort( $ret ); return $ret; } - private function copyMove( $d ) { - if( $this->config['copymove'] != 1 ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - exit( 1 ); - } - if( ! isset( $d['destination'] ) || ! $this->isPathValid( realpath( $d['destination'] ) ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - exit( 1 ); - } - if( ! is_array( $d['filenames'] ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_params'] ) ); - exit( 1 ); - } - if( ! in_array( $d['action'], array( 'copy', 'move' ) ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_action'] ) ); - exit( 1 ); - } - $err = array(); $errFlag = -1; // -1 -> all errors; 0 -> at least some errors; 1 -> no errors - foreach( $d['filenames'] as $file ) { - if( ! file_exists( $file ) || $file == ".." || ! $this->isFilenameValid( $file ) ) { - array_push( $err, $file ); - } - if( $d['action'] == "copy" ) { - if( $this->xcopy( $file, $d['destination'] ) ) - $errFlag = 0; - else - array_push( $err, $file ); - } elseif( $d['action'] == "move" ) { - if( rename( $file, $this->pathCombine( $d['destination'], basename( $file ) ) ) ) - $errFlag = 0; - else - array_push( $err, $file ); - } - } - $action = ( $d['action'] == "copy" ? "copied" : "moved" ); - if( empty( $err ) ) { - $this->jsonResponse( array( "status" => "OK", "message" => ( $d['action'] == "copy" ? $this->l['copy_success'] : $this->l['move_success'] ), "errflag" => "1" ) ); - } + private function getFolders($d) { + if (!isset($d['dir'])) + $d['dir'] = $this->getRootDir(); + + if (!$this->isPathValid($d['dir'])) + return []; else { - $errmsg = ( $d['action'] == "copy" ? $this->l['copy_error'] : $this->l['move_error'] ) . "
    "; - foreach( $err as $item ) + $ret = []; + foreach (glob($this->pathCombine($d['dir'], "*"), GLOB_ONLYDIR) as $dir) { + array_push($ret, [ + "text" => htmlspecialchars(basename($dir)), + "lazyLoad" => true, + "dataAttr" => ["path" => $dir] + ]); + } + sort($ret); + if (realpath($d['dir']) == $this->initialWD) + $ret = array_merge( + [ + 0 => [ + "text" => "/ [root]", + "dataAttr" => ["path" => $this->getRootDir()] + ] + ], + $ret + ); + return $ret; + } + } + + private function searchItems($d) { + if ($this->config['search'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (strpos($d['pattern'], '/') !== false) + throw new IFMException($this->l('pattern_error_slashes')); + + $results = $this->searchItemsRecursive($d['pattern']); + return $results; + } + + private function searchItemsRecursive($pattern, $dir="") { + $items = []; + $dir = $dir ?? '.'; + + foreach (glob($this->pathCombine($dir, $pattern)) as $result) + array_push($items, $this->getItemInformation($result)); + + foreach (glob($this->pathCombine($dir, '*'), GLOB_ONLYDIR) as $subdir) + $items = array_merge($items, $this->searchItemsRecursive($pattern, $subdir)); + + return $items; + } + + private function getFolderTree($d) { + return array_merge( + [ + 0 => [ + "text" => "/ [root]", + "nodes" => [], + "dataAttributes" => ["path" => $this->getRootDir()] + ] + ], + $this->getFolderTreeRecursive($d['dir']) + ); + } + + private function getFolderTreeRecursive($start_dir) { + $ret = []; + $start_dir = realpath($start_dir); + if ($handle = opendir($start_dir)) { + while (false !== ($result = readdir($handle))) { + if (is_dir($this->pathCombine($start_dir, $result)) && $result != "." && $result != ".." ) { + array_push($ret, [ + "text" => htmlspecialchars($result), + "dataAttributes" => ["path" => $this->pathCombine($start_dir, $result)], + "nodes" => $this->getFolderTreeRecursive($this->pathCombine($start_dir, $result)) + ]); + } + } + } + sort($ret); + return $ret; + } + + private function copyMove($d) { + if ($this->config['copymove'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (!isset($d['destination']) || !$this->isPathValid(realpath($d['destination']))) + throw new IFMException($this->l('invalid_dir')); + + if (!is_array($d['filenames'])) + throw new IFMException($this->l('invalid_params')); + + if (!in_array($d['action'], ['copy', 'move'])) + throw new IFMException($this->l('invalid_action')); + + $err = []; $errFlag = -1; // -1 -> all errors; 0 -> at least some errors; 1 -> no errors + foreach ($d['filenames'] as $file) { + if (!file_exists($file) || $file == ".." || !$this->isFilenameValid($file)) { + array_push($err, $file); + } + if ($d['action'] == "copy") { + if ($this->xcopy($file, $d['destination'])) + $errFlag = 0; + else + array_push($err, $file); + } elseif ($d['action'] == "move") { + if (rename($file, $this->pathCombine($d['destination'], basename($file)))) + $errFlag = 0; + else + array_push($err, $file); + } + } + $action = ($d['action'] == "copy") ? "copied" : "moved"; + if (empty($err)) { + return [ + "status" => "OK", + "message" => ($d['action'] == "copy" ? $this->l('copy_success') : $this->l('move_success')), + "errflag" => "1" + ]; + } else { + $errmsg = ($d['action'] == "copy" ? $this->l('copy_error') : $this->l('move_error')) . "
      "; + foreach ($err as $item) $errmsg .= "
    • ".$item."
    • "; $errmsg .= "
    "; - $this->jsonResponse( array( "status" => "OK", "message" => $errmsg, "flag" => $errFlag ) ); + throw new IFMException($errmsg); } } // creates a directory - private function createDir($w, $dn) { - if( $this->config['createdir'] != 1 ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - exit( 1 ); - } - if( $dn == "" ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - elseif( ! $this->isFilenameValid( $dn ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - else { - if( @mkdir( $dn ) ) - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['folder_create_success'] ) ); - else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_create_error'] ) ); - } + private function createDir($d) { + if ($this->config['createdir'] != 1) + throw new IFMException($this->l('nopermissions')); + + if ($d['dirname'] == "" || !$this->isFilenameValid($d['dirname'])) + throw new IFMException($this->l('invalid_dir')); + + if (@mkdir($d['dirname'])) + return ["status" => "OK", "message" => $this->l('folder_create_success')]; + else + throw new IFMException($this->l('folder_create_error').". ".error_get_last()['message']); } // save a file - private function saveFile( $d ) { - if( ( file_exists( $this->pathCombine( $d['dir'], $d['filename'] ) ) && $this->config['edit'] != 1 ) || ( ! file_exists( $this->pathCombine( $d['dir'], $d['filename'] ) ) && $this->config['createfile'] != 1 ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - exit( 1 ); - } - if( isset( $d['filename'] ) && $this->isFilenameValid( $d['filename'] ) ) { - if( isset( $d['content'] ) ) { + private function saveFile($d) { + if ( + (file_exists($this->pathCombine($d['dir'], $d['filename'])) && $this->config['edit'] != 1 ) + || (!file_exists($this->pathCombine($d['dir'], $d['filename'])) && $this->config['createfile'] != 1) + ) + throw new IFMException($this->l('nopermissions')); + + if (isset($d['filename']) && $this->isFilenameValid($d['filename'])) { + if (isset($d['content'])) { // work around magic quotes - $content = get_magic_quotes_gpc() == 1 ? stripslashes( $d['content'] ) : $d['content']; - if( @file_put_contents( $d['filename'], $content ) !== false ) { - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_save_success'] ) ); - } else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_save_error'] ) ); + if((function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) + || (ini_get('magic_quotes_sybase') && (strtolower(ini_get('magic_quotes_sybase'))!="off")) ) { + $content = stripslashes($d['content']); + } else { + $content = $d['content']; + } + + if (@file_put_contents($d['filename'], $content) !== false) + return ["status" => "OK", "message" => $this->l('file_save_success')]; + else + throw new Exception($this->l('file_save_error')); } else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_save_error'] ) ); + throw new IFMException($this->l('file_save_error')); } else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); + throw new IFMException($this->l('invalid_filename')); } // gets the content of a file // notice: if the content is not JSON encodable it returns an error - private function getContent( array $d ) { - if( $this->config['edit'] != 1 ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['npermissions'] ) ); - else { - if( isset( $d['filename'] ) && $this->isFilenameAllowed( $d['filename'] ) && file_exists( $d['filename'] ) && is_readable( $d['filename'] ) ) { - $content = @file_get_contents( $d['filename'] ); - if( function_exists( "mb_check_encoding" ) && ! mb_check_encoding( $content, "UTF-8" ) ) - $content = utf8_encode( $content ); - $this->jsonResponse( array( "status" => "OK", "data" => array( "filename" => $d['filename'], "content" => $content ) ) ); - } else $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_not_found'] ) ); - } + private function getContent($d) { + if ($this->config['edit'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (isset($d['filename']) && $this->isFilenameAllowed($d['filename']) && file_exists($d['filename']) && is_readable($d['filename'])) { + $content = @file_get_contents($d['filename']); + if (function_exists("mb_check_encoding") && !mb_check_encoding($content, "UTF-8")) + $content = utf8_encode($content); + return ["status" => "OK", "data" => ["filename" => $d['filename'], "content" => $content]]; + } else + throw new IFMException($this->l('file_not_found')); } // deletes a bunch of files or directories - private function deleteFiles( array $d ) { - if( $this->config['delete'] != 1 ) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - else { - $err = array(); $errFLAG = -1; // -1 -> no files deleted; 0 -> at least some files deleted; 1 -> all files deleted - foreach( $d['filenames'] as $file ) { - if( $this->isFilenameAllowed( $file ) ) { - if( is_dir( $file ) ) { - $res = $this->rec_rmdir( $file ); - if( $res != 0 ) - array_push( $err, $file ); - else - $errFLAG = 0; - } else { - if( @unlink($file) ) - $errFLAG = 0; - else - array_push($err, $file); - } + private function deleteFiles($d) { + if ($this->config['delete'] != 1) + throw new IFMException($this->l('nopermissions')); + + $err = []; $errFLAG = -1; // -1 -> no files deleted; 0 -> at least some files deleted; 1 -> all files deleted + foreach ($d['filenames'] as $file) { + if ($this->isFilenameAllowed($file)) { + if (is_dir($file)) { + $res = $this->rec_rmdir($file); + if ($res != 0) + array_push($err, $file); + else + $errFLAG = 0; } else { - array_push( $err, $file ); + if (@unlink($file)) + $errFLAG = 0; + else + array_push($err, $file); } + } else { + array_push($err, $file); } - if( empty( $err ) ) { - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_delete_success'], "errflag" => "1" ) ); - } - else { - $errmsg = $this->l['file_delete_error'] . "
      "; - foreach($err as $item) - $errmsg .= "
    • ".$item."
    • "; - $errmsg .= "
    "; - $this->jsonResponse( array( "status" => "ERROR", "message" => $errmsg, "flag" => $errFLAG ) ); - } + } + if (empty($err)) + return ["status" => "OK", "message" => $this->l('file_delete_success'), "errflag" => "1"]; + else { + $errmsg = $this->l('file_delete_error') . "
      "; + foreach ($err as $item) + $errmsg .= "
    • ".$item."
    • "; + $errmsg .= "
    "; + throw new IFMException($errmsg); } } // renames a file - private function renameFile( array $d ) { - if( $this->config['rename'] != 1 ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - } elseif( ! $this->isFilenameValid( $d['filename'] ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - } elseif( ! $this->isFilenameValid( $d['newname'] ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - } else { - if( strpos( $d['newname'], '/' ) !== false ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['filename_slashes'] ) ); - elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['newname'], 0, 3) == ".ht" || substr( $d['filename'], 0, 3 ) == ".ht" ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['newname'], 0, 1) == "." || substr( $d['filename'], 0, 1 ) == "." ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - else { - if( @rename( $d['filename'], $d['newname'] ) ) - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_rename_success'] ) ); - else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_rename_error'] ) ); - } - } + private function renameFile(array $d) { + if ($this->config['rename'] != 1) + throw new IFMException($this->l('nopermissions')); + elseif (!$this->isFilenameValid($d['filename']) || !$this->isFilenameValid($d['newname'])) + throw new IFMException($this->l('invalid_filename')); + + if (@rename($d['filename'], $d['newname'])) + return ["status" => "OK", "message" => $this->l('file_rename_success')]; + else + throw new IFMException($this->l('file_rename_error')); } // provides a file for downloading - private function downloadFile( array $d, $forceDL=true ) { - if( $this->config['download'] != 1 ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - elseif( ! $this->isFilenameValid( $d['filename'] ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - elseif( $this->config['showhtdocs'] != 1 && ( substr( $d['filename'], 0, 3 ) == ".ht" || substr( $d['filename'],0,3 ) == ".ht" ) ) - $this->jsonResponse( array( "status" => "ERROR", "message"=> $this->l['nopermissions'] ) ); - elseif( $this->config['showhiddenfiles'] != 1 && ( substr( $d['filename'], 0, 1 ) == "." || substr( $d['filename'],0,1 ) == "." ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - else { - if( ! is_file( $d['filename' ] ) ) - http_response_code( 404 ); - else - $this->fileDownload( array( "file" => $d['filename'], "forceDL" => $forceDL ) ); - } + private function downloadFile(array $d, $forceDL=true) { + if ($this->config['download'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (!$this->isFilenameValid($d['filename'])) + throw new IFMException($this->l('invalid_filename')); + + if (!is_file($d['filename'])) + http_response_code(404); + else + $this->fileDownload(["file" => $d['filename'], "forceDL" => $forceDL]); } // extracts a zip-archive - private function extractFile( array $d ) { + private function extractFile(array $d) { $restoreIFM = false; $tmpSelfContent = null; $tmpSelfChecksum = null; - if( $this->config['extract'] != 1 ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - else { - if( ! file_exists( $d['filename'] ) ) { - $this->jsonResponse( array( "status" => "ERROR","message" => $this->l['invalid_filename'] ) ); - exit( 1 ); - } - if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" ) - $d['targetdir'] = "./"; - if( ! $this->isPathValid( $d['targetdir'] ) ) { - $this->jsonResponse( array( "status" => "ERROR","message" => $this->l['invalid_dir'] ) ); - exit( 1 ); - } - if( ! is_dir( $d['targetdir'] ) && ! mkdir( $d['targetdir'], 0777, true ) ) { - $this->jsonResponse( array( "status" => "ERROR","message" => $this->l['folder_create_error'] ) ); - exit( 1 ); - } - if( realpath( $d['targetdir'] ) == substr( $this->getScriptRoot(), 0, strlen( realpath( $d['targetdir'] ) ) ) ) { - $tmpSelfContent = tmpfile(); - fwrite( $tmpSelfContent, file_get_contents( __FILE__ ) ); - $tmpSelfChecksum = hash_file( "sha256", __FILE__ ); - $restoreIFM = true; - } - if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) { - if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) { - $this->jsonResponse( array( "status" => "ERROR","message" => $this->l['extract_error'] ) ); - } else { - $this->jsonResponse( array( "status" => "OK","message" => $this->l['extract_success'] ) ); - } - } else { - if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) { - $this->jsonResponse( array( "status" => "ERROR","message" => $this->l['extract_error'] ) ); - } else { - $this->jsonResponse( array( "status" => "OK","message" => $this->l['extract_success'] ) ); - } - } - if( $restoreIFM ) { - if( $tmpSelfChecksum != hash_file( "sha256", __FILE__ ) ) { - rewind( $tmpSelfContent ); - $fh = fopen( __FILE__, "w" ); - while( ! feof( $tmpSelfContent ) ) { - fwrite( $fh, fread( $tmpSelfContent, 8196 ) ); - } - fclose( $fh ); - } - fclose( $tmpSelfContent ); + if ($this->config['extract'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (!file_exists($d['filename'])) + throw new IFMException($this->l('invalid_filename')); + + if (!isset($d['targetdir']) || trim($d['targetdir']) == "") + $d['targetdir'] = "./"; + + if (!$this->isPathValid($d['targetdir'])) + throw new IFMException($this->l('invalid_dir')); + + if (!is_dir($d['targetdir']) && !mkdir($d['targetdir'], 0777, true)) + throw new IFMException($this->l('folder_create_error')); + + if (realpath($d['targetdir']) == substr($this->initialWD, 0, strlen(realpath($d['targetdir'])))) { + $tmpSelfContent = tmpfile(); + fwrite($tmpSelfContent, file_get_contents(__FILE__)); + $tmpSelfChecksum = hash_file("sha256", __FILE__); + $restoreIFM = true; + } + + if (strtolower(pathinfo($d['filename'], PATHINFO_EXTENSION) == "zip")) { + if (!IFMArchive::extractZip($d['filename'], $d['targetdir'])) + throw new IFMException($this->l('extract_error')); + else + return ["status" => "OK","message" => $this->l('extract_success')]; + } elseif ( + (strtolower(pathinfo($d['filename'], PATHINFO_EXTENSION)) == "tar") + || (strtolower(pathinfo(pathinfo($d['filename'], PATHINFO_FILENAME), PATHINFO_EXTENSION)) == "tar") + ) { + if (!IFMArchive::extractTar($d['filename'], $d['targetdir'])) + throw new IFMException($this->l('extract_error')); + else + return ["status" => "OK","message" => $this->l('extract_success')]; + } else { + throw new IFMException($this->l('archive_invalid_format')); + } + + if ($restoreIFM) { + if ($tmpSelfChecksum != hash_file("sha256", __FILE__)) { + rewind($tmpSelfContent); + $fh = fopen(__FILE__, "w"); + while (!feof($tmpSelfContent)) + fwrite($fh, fread($tmpSelfContent, 8196)); + fclose($fh); } + fclose($tmpSelfContent); } } // uploads a file - private function uploadFile( array $d ) { - if( $this->config['upload'] != 1 ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - elseif( !isset( $_FILES['file'] ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_upload_error'] ) ); - else { - $newfilename = ( isset( $d["newfilename"] ) && $d["newfilename"]!="" ) ? $d["newfilename"] : $_FILES['file']['name']; - if( ! $this->isFilenameValid( $newfilename ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - else { - if( $_FILES['file']['tmp_name'] ) { - if( is_writable( getcwd( ) ) ) { - if( move_uploaded_file( $_FILES['file']['tmp_name'], $newfilename ) ) - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_upload_success'], "cd" => $d['dir'] ) ); - else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_upload_error'] ) ); - } - else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_upload_error'] ) ); - } else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_not_found'] ) ); - } - } + private function uploadFile(array $d) { + if($this->config['upload'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (!isset($_FILES['file'])) + throw new IFMException($this->l('file_upload_error')); + + $newfilename = (isset($d["newfilename"]) && $d["newfilename"]!="") ? $d["newfilename"] : $_FILES['file']['name']; + if (!$this->isFilenameValid($newfilename)) + throw new IFMException($this->l('invalid_filename')); + + if ($_FILES['file']['tmp_name']) { + if (is_writable(getcwd())) { + if (move_uploaded_file($_FILES['file']['tmp_name'], $newfilename)) + return ["status" => "OK", "message" => $this->l('file_upload_success'), "cd" => $d['dir']]; + else + throw new IFMException($this->l('file_upload_error')); + } else + throw new IFMException($this->l('file_upload_error')); + } else + throw new IFMException($this->l('file_not_found')); } // change permissions of a file - private function changePermissions( array $d ) { - if( $this->config['chmod'] != 1 ) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - elseif( ! isset( $d["chmod"] )||$d['chmod']=="" ) $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['permission_parse_error'] ) ); - elseif( ! $this->isPathValid( $this->pathCombine( $d['dir'],$d['filename'] ) ) ) { $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); } - else { - $chmod = $d["chmod"]; $cmi = true; - if( ! is_numeric( $chmod ) ) { - $cmi = false; - $chmod = str_replace( " ","",$chmod ); - if( strlen( $chmod )==9 ) { - $cmi = true; - $arr = array( substr( $chmod,0,3 ),substr( $chmod,3,3 ),substr( $chmod,6,3 ) ); - $chtmp = "0"; - foreach( $arr as $right ) { - $rtmp = 0; - if( substr( $right,0,1 )=="r" ) $rtmp = $rtmp + 4; elseif( substr( $right,0,1 )<>"-" ) $cmi = false; - if( substr( $right,1,1 )=="w" ) $rtmp = $rtmp + 2; elseif( substr( $right,1,1 )<>"-" ) $cmi = false; - if( substr( $right,2,1 )=="x" ) $rtmp = $rtmp + 1; elseif( substr( $right,2,1 )<>"-" ) $cmi = false; - $chtmp = $chtmp . $rtmp; - } - $chmod = intval( $chtmp ); - } - } - else $chmod = "0" . $chmod; + private function changePermissions(array $d) { + if ($this->config['chmod'] != 1) + throw new IFMException($this->l('nopermissions')); - if( $cmi ) { - try { - chmod( $d["filename"], (int)octdec( $chmod ) ); - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['permission_change_success'] ) ); - } catch ( Exception $e ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['permission_change_error'] ) ); + if (!isset($d["chmod"]) || $d['chmod'] == "" ) + throw new IFMException($this->l('permission_parse_error')); + + if (!$this->isPathValid($this->pathCombine($d['dir'], $d['filename']))) + throw new IFMException($this->l('nopermissions')); + + $chmod = $d["chmod"]; $cmi = true; + if (!is_numeric($chmod)) { + $cmi = false; + $chmod = str_replace(" ", "", $chmod); + + if (strlen($chmod) == 9) { + $cmi = true; + $arr = [substr($chmod, 0, 3), substr($chmod, 3, 3), substr($chmod, 6, 3)]; + $chtmp = "0"; + foreach ($arr as $right) { + $rtmp = 0; + if (substr($right, 0, 1) == "r") $rtmp = $rtmp + 4; elseif (substr($right, 0, 1) <> "-") $cmi = false; + if (substr($right, 1, 1) == "w") $rtmp = $rtmp + 2; elseif (substr($right, 1, 1) <> "-") $cmi = false; + if (substr($right, 2, 1) == "x") $rtmp = $rtmp + 1; elseif (substr($right, 2, 1) <> "-") $cmi = false; + $chtmp = $chtmp . $rtmp; } + $chmod = intval($chtmp); } - else $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['permission_parse_error'] ) ); - } + } else + $chmod = "0" . $chmod; + + if ($cmi) { + try { + chmod($d["filename"], (int)octdec($chmod)); + return ["status" => "OK", "message" => $this->l('permission_change_success')]; + } catch (Exception $e) { + throw new IFMException($this->l('permission_change_error')); + } + } else + throw new IFMException($this->l('permission_parse_error')); } // zips a directory and provides it for downloading // it creates a temporary zip file in the current directory, so it has to be as much space free as the file size is - private function zipnload( array $d ) { - if( $this->config['zipnload'] != 1 ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermission'] ) ); - else { - if( ! file_exists( $d['filename'] ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['folder_not_found'] ) ); - elseif (!$this->isPathValid($d['filename'])) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_dir'] ) ); - elseif ($d['filename'] != "." && !$this->isFilenameValid($d['filename'])) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - else { - unset( $zip ); - if ($this->isAbsolutePath($this->config['tmp_dir'])) - $dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename - else - $dfile = $this->pathCombine( __DIR__, $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename + private function zipnload(array $d) { + if ($this->config['zipnload'] != 1) + throw new IFMException($this->l('nopermission')); - try { - IFMArchive::createZip(realpath($d['filename']), $dfile, array($this, 'isFilenameValid')); - if( $d['filename'] == "." ) { - if( getcwd() == $this->getScriptRoot() ) - $d['filename'] = "root"; - else - $d['filename'] = basename( getcwd() ); - } - $this->fileDownload( array( "file" => $dfile, "name" => $d['filename'] . ".zip", "forceDL" => true ) ); - } catch ( Exception $e ) { - echo $this->l['error'] . " " . $e->getMessage(); - } finally { - if( file_exists( $dfile ) ) @unlink( $dfile ); - } + if (!file_exists($d['filename'])) + throw new IFMException($this->l('folder_not_found')); + + if (!$this->isPathValid($d['filename'])) + throw new IFMException($this->l('invalid_dir')); + + if ($d['filename'] != "." && !$this->isFilenameValid($d['filename'])) + throw new IFMException($this->l('invalid_filename')); + + unset($zip); + if ($this->isAbsolutePath($this->config['tmp_dir'])) + $dfile = $this->pathCombine($this->config['tmp_dir'], uniqid("ifm-tmp-") . ".zip"); // temporary filename + else + $dfile = $this->pathCombine($this->initialWD, $this->config['tmp_dir'], uniqid("ifm-tmp-") . ".zip"); // temporary filename + + try { + IFMArchive::createZip(realpath($d['filename']), $dfile, [$this, 'isFilenameValid']); + if ($d['filename'] == ".") { + if (getcwd() == $this->getRootDir()) + $d['filename'] = "root"; + else + $d['filename'] = basename(getcwd()); } + $this->fileDownload(["file" => $dfile, "name" => $d['filename'] . ".zip", "forceDL" => true]); + } catch (Exception $e) { + throw new IFMException($this->l('error') . " " . $e->getMessage()); + } finally { + if (file_exists($dfile)) + @unlink($dfile); } } // uploads a file from an other server using the curl extention - private function remoteUpload( array $d ) { - if( $this->config['remoteupload'] != 1 ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - elseif( !isset( $d['method'] ) || !in_array( $d['method'], array( "curl", "file" ) ) ) - $this->jsonResponse( array( "status" => "error", "message" => $this->l['invalid_params'] ) ); - elseif( $d['method']=="curl" && $this->checkCurl( ) == false ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error']." cURL extention not installed." ) ); - elseif( $d['method']=="curl" && $this->checkCurl( ) == true ) { - $filename = ( isset( $d['filename'] )&&$d['filename']!="" )?$d['filename']:"curl_".uniqid( ); - $ch = curl_init( ); - if( $ch ) { - if( $this->isFilenameValid( $filename ) == false ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - elseif( filter_var( $d['url'], FILTER_VALIDATE_URL ) === false ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_url'] ) ); + private function remoteUpload(array $d) { + if ($this->config['remoteupload'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (!isset($d['method']) || !in_array($d['method'], ["curl", "file"])) + throw new IFMException($this->l('invalid_params')); + + if ($d['method'] == "curl" && $this->checkCurl() == false) + throw new IFMException($this->l('error')." cURL extention not installed."); + + if ($d['method'] == "curl" && $this->checkCurl() == true) { + $filename = (isset($d['filename']) && $d['filename'] != "") ? $d['filename'] : "curl_".uniqid(); + $ch = curl_init(); + if ($ch) { + if ($this->isFilenameValid($filename) == false) + throw new IFMException($this->l('invalid_filename')); + elseif (filter_var($d['url'], FILTER_VALIDATE_URL) === false) + throw new IFMException($this->l('invalid_url')); else { - $fp = fopen( $filename, "w" ); - if( $fp ) { - if( !curl_setopt( $ch, CURLOPT_URL, urldecode( $d['url'] ) ) || !curl_setopt( $ch, CURLOPT_FILE, $fp ) || !curl_setopt( $ch, CURLOPT_HEADER, 0 ) || !curl_exec( $ch ) ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error']." ".curl_error( $ch ) ) ); - else { - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_upload_success'] ) ); - } - curl_close( $ch ); - fclose( $fp ); - } else { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['file_open_error'] ) ); - } + $fp = fopen($filename, "w"); + if ($fp) { + if ( + !curl_setopt($ch, CURLOPT_URL, urldecode($d['url'])) + || !curl_setopt($ch, CURLOPT_FILE, $fp) + || !curl_setopt($ch, CURLOPT_HEADER, 0) + || !curl_exec($ch) + ) + throw new IFMException($this->l('error')." ".curl_error($ch)); + else + return ["status" => "OK", "message" => $this->l('file_upload_success')]; + curl_close($ch); + fclose($fp); + } else + throw new IFMException($this->l('file_open_error')); } - } else { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error']." curl init" ) ); - } - } - elseif( $d['method']=='file' ) { - $filename = ( isset( $d['filename'] ) && $d['filename']!="" ) ? $d['filename'] : "curl_".uniqid( ); - if( $this->isFilenameValid( $filename ) == false ) - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); + } else + throw new IFMException($this->l('error')." curl init"); + } elseif ($d['method'] == 'file') { + $filename = (isset($d['filename']) && $d['filename'] != "") ? $d['filename'] : "curl_".uniqid(); + if ($this->isFilenameValid($filename) == false) + throw new IFMException($this->l('invalid_filename')); else { try { - file_put_contents( $filename, file_get_contents( $d['url'] ) ); - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['file_upload_success'] ) ); - } catch( Exception $e ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['error'] . " " . $e->getMessage() ) ); + file_put_contents($filename, file_get_contents($d['url'])); + return ["status" => "OK", "message" => $this->l('file_upload_success')]; + } catch (Exception $e) { + throw new IFMException($this->l('error') . " " . $e->getMessage()); } } - } - else - $this->jsonResponse( array( "status" => "error", "message" => $this->l['invalid_params'] ) ); + } else + throw new IFMException($this->l('invalid_params')); } - private function createArchive( $d ) { - if( $this->config['createarchive'] != 1 ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['nopermissions'] ) ); - return false; - } - if( ! $this->isFilenameValid( $d['archivename'] ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - return false; - } - $filenames = array(); - foreach( $d['filenames'] as $file ) - if( ! $this->isFilenameValid( $file ) ) { - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['invalid_filename'] ) ); - exit( 1 ); - } else - array_push( $filenames, realpath( $file ) ); - switch( $d['format'] ) { + private function createArchive($d) { + if ($this->config['createarchive'] != 1) + throw new IFMException($this->l('nopermissions')); + + if (!$this->isFilenameValid($d['archivename'])) + throw new IFMException($this->l('invalid_filename')); + + $filenames = []; + foreach ($d['filenames'] as $file) + if (!$this->isFilenameValid($file)) + throw new IFMException($this->l('invalid_filename')); + else + array_push($filenames, realpath($file)); + + switch ($d['format']) { case "zip": - if( IFMArchive::createZip( $filenames, $d['archivename'] ) ) - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['archive_create_success'] ) ); + if (IFMArchive::createZip($filenames, $d['archivename'])) + return ["status" => "OK", "message" => $this->l('archive_create_success')]; else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['archive_create_error'] ) ); + throw new IFMException($this->l('archive_create_error')); break; case "tar": + $d['archivename'] = pathinfo($d['archivename'], PATHINFO_FILENAME); + if (IFMArchive::createTar($filenames, $d['archivename'], $d['format'])) + return ["status" => "OK", "message" => $this->l('archive_create_success')]; + else + throw new IFMException($this->l('archive_create_error')); + break; case "tar.gz": case "tar.bz2": - if( IFMArchive::createTar( $filenames, $d['archivename'], $d['format'] ) ) - $this->jsonResponse( array( "status" => "OK", "message" => $this->l['archive_create_success'] ) ); + $d['archivename'] = pathinfo(pathinfo($d['archivename'], PATHINFO_FILENAME), PATHINFO_FILENAME); + if (IFMArchive::createTar($filenames, $d['archivename'], $d['format'])) + return ["status" => "OK", "message" => $this->l('archive_create_success')]; else - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['archive_create_error'] ) ); + throw new IFMException($this->l('archive_create_error')); break; default: - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['archive_invalid_format'] ) ); + throw new IFMException($this->l('archive_invalid_format')); break; } } @@ -5088,155 +4761,151 @@ f00bar; help functions */ - private function log( $d ) { - file_put_contents( $this->pathCombine( $this->getRootDir(), "debug.ifm.log" ), ( is_array( $d ) ? print_r( $d, true ) . "\n" : $d . "\n" ), FILE_APPEND ); + private function l($str) { + if (isset($_REQUEST['lang']) + && in_array($_REQUEST['lang'], array_keys($this->i18n)) + && isset($this->i18n[$_REQUEST['lang']][$str])) + return $this->i18n[$_REQUEST['lang']][$str]; + else + return $this->i18n['en'][$str]; } - private function jsonResponse( $array ) { - $this->convertToUTF8( $array ); - $json = json_encode( $array ); - if( $json === false ) { - switch(json_last_error()) { - case JSON_ERROR_NONE: - echo ' - No errors'; - break; - case JSON_ERROR_DEPTH: - echo ' - Maximum stack depth exceeded'; - break; - case JSON_ERROR_STATE_MISMATCH: - echo ' - Underflow or the modes mismatch'; - break; - case JSON_ERROR_CTRL_CHAR: - echo ' - Unexpected control character found'; - break; - case JSON_ERROR_SYNTAX: - echo ' - Syntax error, malformed JSON'; - break; - case JSON_ERROR_UTF8: - echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; - break; - default: - echo ' - Unknown error'; - break; + private function log($d) { + file_put_contents($this->pathCombine($this->getRootDir(), "debug.ifm.log"), (is_array($d) ? print_r($d, true)."\n" : $d."\n"), FILE_APPEND); + } + + private function jsonResponse($array) { + $this->convertToUTF8($array); + $json = json_encode($array); + if ($json === false) { + switch (json_last_error()) { + case JSON_ERROR_NONE: + echo ' - No errors'; + break; + case JSON_ERROR_DEPTH: + echo ' - Maximum stack depth exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + echo ' - Underflow or the modes mismatch'; + break; + case JSON_ERROR_CTRL_CHAR: + echo ' - Unexpected control character found'; + break; + case JSON_ERROR_SYNTAX: + echo ' - Syntax error, malformed JSON'; + break; + case JSON_ERROR_UTF8: + echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + echo ' - Unknown error'; + break; } - $this->jsonResponse( array( "status" => "ERROR", "message" => $this->l['json_encode_error'] . " " . $err ) ); - } else { + throw new IFMException($this->l('json_encode_error')." ".$err); + } else echo $json; - } } - private function convertToUTF8( &$item ) { - if( is_array( $item ) ) - array_walk( - $item, - array( $this, 'convertToUTF8' ) - ); + private function convertToUTF8(&$item) { + if (is_array($item)) + array_walk($item, [$this, 'convertToUTF8']); else - if( function_exists( "mb_check_encoding" ) && ! mb_check_encoding( $item, "UTF-8" ) ) - $item = utf8_encode( $item ); + if (function_exists("mb_check_encoding") && !mb_check_encoding($item, "UTF-8")) + $item = utf8_encode($item); } - function checkAuth() { - if( $this->config['auth'] == 0 ) + private function checkAuth() { + if ($this->config['auth'] == 0) return true; - if( isset( $_SERVER['HTTP_X_IFM_AUTH'] ) && ! empty( $_SERVER['HTTP_X_IFM_AUTH'] ) ) { - $cred = explode( ":", base64_decode( str_replace( "Basic ", "", $_SERVER['HTTP_X_IFM_AUTH'] ) ) ); - if( count( $cred ) == 2 && $this->checkCredentials( $cred[0], $cred[1] ) ) + $credentials_header = $_SERVER['HTTP_X_IFM_AUTH'] ?? $_SERVER['HTTP_AUTHORIZATION'] ?? false; + if ($credentials_header && !$this->config['auth_ignore_basic']) { + $cred = explode(":", base64_decode(str_replace("Basic ", "", $credentials_header)), 2); + if (count($cred) == 2 && $this->checkCredentials($cred[0], $cred[1])) return true; } - if( session_status() !== PHP_SESSION_ACTIVE ) { - if( isset( $this->config['session_lifetime'] ) ) - ini_set( 'session.gc_maxlifetime', $this->config['session_lifetime'] ); - if( isset( $this->config['force_session_lifetime'] ) && $this->config['force_session_lifetime'] ) { - ini_set( 'session.gc_divisor', 1 ); - ini_set( 'session.gc_probability', 1 ); - } + if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); } - if( ! isset( $_SESSION['ifmauth'] ) || $_SESSION['ifmauth'] !== true ) { - $login_failed = false; - if( isset( $_POST["inputLogin"] ) && isset( $_POST["inputPassword"] ) ) { - if( $this->checkCredentials( $_POST["inputLogin"], $_POST["inputPassword"] ) ) { - $_SESSION['ifmauth'] = true; - } - else { - $_SESSION['ifmauth'] = false; - $login_failed = true; - } - } - - if( isset( $_SESSION['ifmauth'] ) && $_SESSION['ifmauth'] === true ) { - return true; - } else { - if( isset( $_POST["api"] ) ) { - if( $login_failed === true ) - $this->jsonResponse( array( "status"=>"ERROR", "message"=>"authentication failed" ) ); - else - $this->jsonResponse( array( "status"=>"ERROR", "message"=>"not authenticated" ) ); - } else { - $this->loginForm($login_failed); - } - return false; - } - } else { + if (isset($_SESSION['ifmauth']) && $_SESSION['ifmauth'] == true) return true; + + $login_failed = false; + if (isset($_POST["inputLogin"]) && isset($_POST["inputPassword"])) { + if ($this->checkCredentials($_POST["inputLogin"], $_POST["inputPassword"])) { + $_SESSION['ifmauth'] = true; + } else { + $_SESSION['ifmauth'] = false; + $login_failed = true; + } + } + + if (isset($_SESSION['ifmauth']) && $_SESSION['ifmauth'] === true) + return true; + else { + if ($login_failed === true) + throw new IFMException("Authentication failed: Wrong credentials", true); + else + throw new IFMException("Not authenticated" , true); } } - private function checkCredentials( $user, $pass ) { - list( $src, $srcopt ) = explode( ";", $this->config['auth_source'], 2 ); - switch( $src ) { + private function checkCredentials($user, $pass) { + list($src, $srcopt) = explode(";", $this->config['auth_source'], 2); + switch ($src) { case "inline": - list( $uname, $hash ) = explode( ":", $srcopt ); + list($uname, $hash) = explode(":", $srcopt); $htpasswd = new Htpasswd(); - return $htpasswd->verifyPassword( $pass, $hash ) ? ( $uname == $user ) : false; + return $htpasswd->verifyPassword($pass, $hash) ? ($uname == $user) : false; break; case "file": - if( @file_exists( $srcopt ) && @is_readable( $srcopt ) ) { - $htpasswd = new Htpasswd( $srcopt ); - return $htpasswd->verify( $user, $pass ); + if (@file_exists($srcopt) && @is_readable($srcopt)) { + $htpasswd = new Htpasswd($srcopt); + return $htpasswd->verify($user, $pass); } else { - trigger_error( "IFM: Fatal: Credential file does not exist or is not readable" ); + trigger_error("IFM: Fatal: Credential file does not exist or is not readable"); return false; } break; case "ldap": $authenticated = false; - $ldapopts = explode( ";", $srcopt ); - if( count( $ldapopts ) === 3 ) { - list( $ldap_server, $rootdn, $ufilter ) = explode( ";", $srcopt ); + $ldapopts = explode(";", $srcopt); + if (count($ldapopts) === 4) { + list($ldap_server, $basedn, $uuid, $ufilter) = explode(";", $srcopt); } else { - list( $ldap_server, $rootdn ) = explode( ";", $srcopt ); + list($ldap_server, $basedn) = explode(";", $srcopt); $ufilter = false; + $uuid = "uid"; } - $u = "uid=" . $user . "," . $rootdn; - if( ! $ds = ldap_connect( $ldap_server ) ) { - trigger_error( "Could not reach the ldap server.", E_USER_ERROR ); + $u = $uuid . "=" . $user . "," . $basedn; + if (!$ds = ldap_connect($ldap_server)) { + throw new IFMException("Could not reach the ldap server." , true); + //trigger_error("Could not reach the ldap server.", E_USER_ERROR); return false; } - ldap_set_option( $ds, LDAP_OPT_PROTOCOL_VERSION, 3 ); - if( $ds ) { - $ldbind = @ldap_bind( $ds, $u, $pass ); - if( $ldbind ) { - if( $ufilter ) { - if( ldap_count_entries( $ds, ldap_search( $ds, $rootdn, $ufilter ) ) > 0 ){ + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + if ($ds) { + $ldbind = @ldap_bind($ds, $u, $pass); + if ($ldbind) { + if ($ufilter) { + if (ldap_count_entries($ds, ldap_search($ds, $u, $ufilter)) == 1) { $authenticated = true; } else { - trigger_error( "User not allowed.", E_USER_ERROR ); + throw new IFMException("User not allowed." , true); + //trigger_error("User not allowed.", E_USER_ERROR); $authenticated = false; } - } else { + } else $authenticated = true; - } } else { - trigger_error( ldap_error( $ds ), E_USER_ERROR ); + throw new IFMException(ldap_error($ds) , true); + //trigger_error(ldap_error($ds), E_USER_ERROR); $authenticated = false; } - ldap_unbind( $ds ); + ldap_unbind($ds); } else $authenticated = false; return $authenticated; @@ -5245,105 +4914,90 @@ f00bar; return false; } - private function loginForm($loginFailed=false, $loginMessage="") { - $err = ""; - if( $loginFailed ) - $err = ''; - $this->getHTMLHeader(); - $html = str_replace( "{{error}}", $err, $this->templates['login'] ); - $html = str_replace( "{{i18n.username}}", $this->l['username'], $html ); - $html = str_replace( "{{i18n.password}}", $this->l['password'], $html ); - $html = str_replace( "{{i18n.login}}", $this->l['login'], $html ); - print $html; - $this->getHTMLFooter(); - } - - private function filePermsDecode( $perms ) { - $oct = str_split( strrev( decoct( $perms ) ), 1 ); - $masks = array( '---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx' ); + private function filePermsDecode($perms) { + $oct = str_split(strrev(decoct($perms)), 1); + $masks = ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx']; return( sprintf( '%s %s %s', - array_key_exists( $oct[ 2 ], $masks ) ? $masks[ $oct[ 2 ] ] : '###', - array_key_exists( $oct[ 1 ], $masks ) ? $masks[ $oct[ 1 ] ] : '###', - array_key_exists( $oct[ 0 ], $masks ) ? $masks[ $oct[ 0 ] ] : '###') + array_key_exists($oct[2], $masks) ? $masks[$oct[2]] : '###', + array_key_exists($oct[1], $masks) ? $masks[$oct[1]] : '###', + array_key_exists($oct[0], $masks) ? $masks[$oct[0]] : '###') ); } - private function isAbsolutePath( $path ) { - if( $path === null || $path === '' ) + private function isAbsolutePath($path) { + if ($path === null || $path === '') return false; - return $path[0] === DIRECTORY_SEPARATOR || preg_match('~\A[A-Z]:(?![^/\\\\])~i',$path) > 0; + return $path[0] === DIRECTORY_SEPARATOR || preg_match('~^[A-Z]:(?![^/\\\\])~i',$path) > 0; } private function getRootDir() { - if( $this->config['root_dir'] == "" ) - return realpath( $this->getScriptRoot() ); - elseif( $this->isAbsolutePath( $this->config['root_dir'] ) ) - return realpath( $this->config['root_dir'] ); + if ($this->config['root_dir'] == "") + return $this->initialWD; + elseif ($this->isAbsolutePath($this->config['root_dir'])) + return realpath($this->config['root_dir']); else - return realpath( $this->pathCombine( $this->getScriptRoot(), $this->config['root_dir'] ) ); + return realpath($this->pathCombine($this->initialWD, $this->config['root_dir'])); } - private function getScriptRoot() { - return ( defined( 'IFM_FILENAME' ) ? dirname( realpath( IFM_FILENAME ) ) : dirname( __FILE__ ) ); - } - - private function getValidDir( $dir ) { - if( ! $this->isPathValid( $dir ) || ! is_dir( $dir ) ) + private function getValidDir($dir) { + if (!$this->isPathValid($dir) || !is_dir($dir)) return ""; else { - $rpDir = realpath( $dir ); + $rpDir = realpath($dir); $rpConfig = $this->getRootDir(); - if( $rpConfig == "/" ) + if ($rpConfig == "/") return $rpDir; - elseif( $rpDir == $rpConfig ) + elseif ($rpDir == $rpConfig) return ""; else { - $part = substr( $rpDir, strlen( $rpConfig ) ); - $part = ( in_array( substr( $part, 0, 1 ), ["/", "\\"] ) ) ? substr( $part, 1 ) : $part; + $part = substr($rpDir, strlen($rpConfig)); + $part = (in_array(substr($part, 0, 1), ["/", "\\"])) ? substr($part, 1) : $part; return $part; } } } - private function isPathValid( $dir ) { + private function isPathValid($dir) { /** * This function is also used to check non-existent paths, but the PHP realpath function returns false for * nonexistent paths. Hence we need to check the path manually in the following lines. */ $tmp_d = $dir; - $tmp_missing_parts = array(); - while( realpath( $tmp_d ) === false ) { - $tmp_i = pathinfo( $tmp_d ); - array_push( $tmp_missing_parts, $tmp_i['filename'] ); - $tmp_d = dirname( $tmp_d ); - if( $tmp_d == dirname( $tmp_d ) ) break; + $tmp_missing_parts = []; + while (realpath($tmp_d) === false) { + $tmp_i = pathinfo($tmp_d, PATHINFO_FILENAME); + array_push($tmp_missing_parts, $tmp_i); + $tmp_d = dirname($tmp_d); + if ($tmp_d == dirname($tmp_d)) + break; } - $rpDir = $this->pathCombine( realpath( $tmp_d ), implode( "/", array_reverse( $tmp_missing_parts ) ) ); + $rpDir = $this->pathCombine(realpath($tmp_d), implode("/", array_reverse($tmp_missing_parts))); $rpConfig = $this->getRootDir(); - if( ! is_string( $rpDir ) || ! is_string( $rpConfig ) ) // can happen if open_basedir is in effect + if (!is_string($rpDir) || !is_string($rpConfig)) // can happen if open_basedir is in effect return false; - elseif( $rpDir == $rpConfig ) + elseif ($rpDir == $rpConfig) return true; - elseif( 0 === strpos( $rpDir, $rpConfig ) ) + elseif (!file_exists($rpDir)) + return false; + elseif (0 === strpos($rpDir, $rpConfig)) return true; else return false; } private function chDirIfNecessary($d) { - if( substr( getcwd(), strlen( $this->getScriptRoot() ) ) != $this->getValidDir($d) && !empty( $d ) ) { - chdir( $d ); - } + if (substr(getcwd(), strlen($this->getRootDir())) != $this->getValidDir($d) && !empty($d)) + chdir($d); } - private function getTypeIcon( $type ) { + private function getTypeIcon($type) { $type = strtolower($type); - switch( $type ) { + switch ($type) { case "aac": case "aiff": case "mid": case "mp3": case "wav": return 'icon icon-file-audio'; break; - case "ai": case "bmp": case "eps": case "tiff": case "gif": case "jpg": case "jpeg": case "png": case "psd": case "svg": return 'icon icon-file-image'; break; + case "ai": case "bmp": case "eps": case "tiff": case "gif": case "jpg": case "jpeg": case "png": case "psd": case "svg": case "webp": return 'icon icon-file-image'; break; case "avi": case "flv": case "mp4": case "mpg": case "mkv": case "mpeg": case "webm": case "wmv": case "mov": return 'icon icon-file-video'; break; case "c": case "cpp": case "css": case "dat": case "h": case "html": case "java": case "js": case "php": case "py": case "sql": case "xml": case "yml": case "json": return 'icon icon-file-code'; break; case "doc": case "docx": case "odf": case "odt": case "rtf": return 'icon icon-file-word'; break; @@ -5356,126 +5010,137 @@ f00bar; } } - private function rec_rmdir( $path ) { - if( !is_dir( $path ) ) { + private function rec_rmdir($path) { + if (!is_dir($path)) return -1; - } - $dir = @opendir( $path ); - if( !$dir ) { + + $dir = @opendir($path); + if (!$dir) return -2; + while (($entry = @readdir($dir)) !== false) { + if ($entry == '.' || $entry == '..') continue; + if (is_dir($path . '/' . $entry)) { + $res = $this->rec_rmdir($path.'/'.$entry); + if ($res == -1) { + @closedir($dir); + return -2; + } else if ($res == -2) { + @closedir($dir); + return -2; + } else if ($res == -3) { + @closedir($dir); + return -3; + } else if ($res != 0) { + @closedir($dir); + return -2; + } + } else if (is_file($path.'/'.$entry) || is_link($path.'/'.$entry)) { + $res = @unlink($path.'/'.$entry); + if (!$res) { + @closedir($dir); + return -2; + } + } else { + @closedir($dir); + return -3; + } } - while( ( $entry = @readdir( $dir ) ) !== false ) { - if( $entry == '.' || $entry == '..' ) continue; - if( is_dir( $path . '/' . $entry ) ) { - $res = $this->rec_rmdir( $path . '/' . $entry ); - if( $res == -1 ) { @closedir( $dir ); return -2; } - else if( $res == -2 ) { @closedir( $dir ); return -2; } - else if( $res == -3 ) { @closedir( $dir ); return -3; } - else if( $res != 0 ) { @closedir( $dir ); return -2; } - } else if( is_file( $path . '/' . $entry ) || is_link( $path . '/' . $entry ) ) { - $res = @unlink( $path . '/' . $entry ); - if( !$res ) { @closedir( $dir ); return -2; } - } else { @closedir( $dir ); return -3; } - } - @closedir( $dir ); - $res = @rmdir( $path ); - if( !$res ) { return -2; } + @closedir($dir); + $res = @rmdir($path); + if (!$res) + return -2; return 0; } - private function xcopy( $source, $dest ) { - $isDir = is_dir( $source ); - if( $isDir ) - $dest = $this->pathCombine( $dest, basename( $source ) ); - if( ! is_dir( $dest ) ) + private function xcopy($source, $dest) { + $isDir = is_dir($source); + if ($isDir) + $dest = $this->pathCombine($dest, basename($source)); + if (!is_dir($dest)) mkdir($dest, 0777, true); - if( is_file( $source ) ) - return copy( $source, $this->pathCombine( $dest, basename( $source ) ) ); + if (is_file($source)) + return copy($source, $this->pathCombine($dest, basename($source))); - chdir( $source ); - foreach( glob( '*' ) as $item ) - $this->xcopy( $item, $dest ); - chdir( '..' ); + chdir($source); + foreach (glob('*') as $item) + $this->xcopy($item, $dest); + chdir('..'); return true; } // combines two parts to a valid path private function pathCombine(...$parts) { $ret = ""; - foreach($parts as $part) + foreach ($parts as $part) if (trim($part) != "") - $ret .= (empty($ret)?rtrim($part,"/"):trim($part, '/'))."/"; + $ret .= (empty($ret) ? rtrim($part,"/") : trim($part, '/'))."/"; return rtrim($ret, "/"); } // check if filename is allowed - public function isFilenameValid( $f ) { - if( ! $this->isFilenameAllowed( $f ) ) + public function isFilenameValid($f) { + if (!$this->isFilenameAllowed($f)) return false; - if( strtoupper( substr( PHP_OS, 0, 3 ) ) == "WIN" ) { + + if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN") { // windows-specific limitations - foreach( array( '\\', '/', ':', '*', '?', '"', '<', '>', '|' ) as $char ) - if( strpos( $f, $char ) !== false ) + foreach (['\\', '/', ':', '*', '?', '"', '<', '>', '|'] as $char) + if (strpos($f, $char) !== false) return false; } else { // *nix-specific limitations - foreach( array( '/', '\0' ) as $char ) - if( strpos( $f, $char ) !== false ) + foreach (['/', '\0'] as $char) + if (strpos($f, $char) !== false) return false; } + // custom limitations - foreach( $this->config['forbiddenChars'] as $char ) - if( strpos( $f, $char ) !== false ) + foreach ($this->config['forbiddenChars'] as $char) + if (strpos($f, $char) !== false) return false; return true; } - private function isFilenameAllowed( $f ) { - if( $this->config['showhtdocs'] != 1 && substr( $f, 0, 3 ) == ".ht" ) + private function isFilenameAllowed($f) { + if ($this->config['showhtdocs'] != 1 && substr($f, 0, 3) == ".ht") return false; - elseif( $this->config['showhiddenfiles'] != 1 && substr( $f, 0, 1 ) == "." ) + elseif ($this->config['showhiddenfiles'] != 1 && substr($f, 0, 1) == ".") return false; - elseif( $this->config['selfoverwrite'] != 1 && getcwd() == $this->getScriptRoot() && $f == basename( __FILE__ ) ) + elseif ($this->config['selfoverwrite'] != 1 && getcwd() == $this->initialWD && $f == basename(__FILE__)) return false; else return true; } - // sorting function for file and dir arrays - private function sortByName( $a, $b ) { - if( strtolower( $a['name'] ) == strtolower( $b['name'] ) ) return 0; - return ( strtolower( $a['name'] ) < strtolower( $b['name'] ) ) ? -1 : 1; - } - // is cURL extention avaliable? private function checkCurl() { - if( !function_exists( "curl_init" ) || - !function_exists( "curl_setopt" ) || - !function_exists( "curl_exec" ) || - !function_exists( "curl_close" ) ) return false; - else return true; + if (!function_exists("curl_init") + || !function_exists("curl_setopt") + || !function_exists("curl_exec") + || !function_exists("curl_close") + ) + return false; + else + return true; } - private function fileDownload( array $options ) { - if( ! isset( $options['name'] ) || trim( $options['name'] ) == "" ) - $options['name'] = basename( $options['file'] ); + private function fileDownload(array $options) { + if (!isset($options['name']) || trim($options['name']) == "") + $options['name'] = basename($options['file']); - if( isset( $options['forceDL'] ) && $options['forceDL'] ) { + if (isset($options['forceDL']) && $options['forceDL']) { $content_type = "application/octet-stream"; - header( 'Content-Disposition: attachment; filename="' . $options['name'] . '"' ); - } else { - $content_type = mime_content_type( $options['file'] ); - } + header('Content-Disposition: attachment; filename="'.$options['name'].'"'); + } else + $content_type = mime_content_type($options['file']); - // This header was quite some time present, but I don't know why... - //header( 'Content-Description: File Transfer' ); - header( 'Content-Type: ' . $content_type ); - header( 'Expires: 0' ); - header( 'Cache-Control: must-revalidate' ); - header( 'Pragma: public' ); - header( 'Content-Length: ' . filesize( $options['file'] ) ); + header('Content-Type: '.$content_type); + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + header('Content-Length: '.filesize($options['file'])); - $file_stream = fopen( $options['file'], 'rb' ); + $file_stream = fopen($options['file'], 'rb'); $stdout_stream = fopen('php://output', 'wb'); stream_copy_to_stream($file_stream, $stdout_stream); @@ -5483,7 +5148,6 @@ f00bar; fclose($file_stream); fclose($stdout_stream); } - } /** @@ -5536,22 +5200,22 @@ class IFMArchive { /** * Create a zip file */ - public static function createZip($src, $out, $exclude_callback=null) { + public static function createZip($filenames, $archivename, $exclude_callback=null) { $a = new ZipArchive(); - $a->open($out, ZIPARCHIVE::CREATE); + $a->open($archivename, ZIPARCHIVE::CREATE); - if (!is_array($src)) - $src = array($src); + if (!is_array($filenames)) + $filenames = array($filenames); - foreach ($src as $s) - if (is_dir($s)) + foreach ($filenames as $f) + if (is_dir($f)) if (is_callable($exclude_callback)) - self::addFolder( $a, $s, null, $exclude_callback ); + self::addFolder( $a, $f, null, $exclude_callback ); else - self::addFolder( $a, $s ); - elseif (is_file($s)) - if (!is_callable($exclude_callback) || $exclude_callback($s)) - $a->addFile($s, substr($s, strlen(dirname($s)) + 1)); + self::addFolder( $a, $f ); + elseif (is_file($f)) + if (!is_callable($exclude_callback) || $exclude_callback($f)) + $a->addFile($f, pathinfo($f, PATHINFO_BASENAME)); try { return $a->close(); @@ -5579,28 +5243,28 @@ class IFMArchive { /** * Creates a tar archive */ - public static function createTar($src, $out, $t) { - $tmpf = substr($out, 0, strlen($out) - strlen($t)) . "tar"; + public static function createTar($filenames, $archivename, $format) { + $tmpf = $archivename . ".tar"; $a = new PharData($tmpf); - try { - if (!is_array($src)) - $src = array($src); + try { + if (!is_array($filenames)) + $filenames = array($filenames); - foreach ($src as $s) - if (is_dir($s)) - self::addFolder($a, $s); - elseif (is_file($s)) - $a->addFile($s, substr($s, strlen(dirname($s)) +1)); - switch ($t) { - case "tar.gz": - $a->compress(Phar::GZ); - @unlink($tmpf); - break; - case "tar.bz2": - $a->compress(Phar::BZ2); - @unlink($tmpf); - break; + foreach ($filenames as $f) + if (is_dir($f)) + self::addFolder($a, $f); + elseif (is_file($f)) + $a->addFile($f, pathinfo($f, PATHINFO_BASENAME)); + switch ($format) { + case "tar.gz": + $a->compress(Phar::GZ); + @unlink($tmpf); + break; + case "tar.bz2": + $a->compress(Phar::BZ2); + @unlink($tmpf); + break; } return true; } catch (Exception $e) { diff --git a/manifest.json b/manifest.json index 596b136..7e124ec 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "en": "Improved File Manager", "fr": "Gestionnaire de fichiers amélioré" }, - "version": "2.6.3~ynh3", + "version": "4.0.0~ynh1", "url": "https://github.com/misterunknown/ifm", "upstream": { "license": "MIT", @@ -20,12 +20,12 @@ "email": "" }, "requirements": { - "yunohost": ">= 4.3.0" + "yunohost": ">= 11.0.9" }, "multi_instance": true, "services": [ "nginx", - "php7.3-fpm" + "php8.0-fpm" ], "arguments": { "install" : [ diff --git a/scripts/_common.sh b/scripts/_common.sh index e760661..372bad3 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,7 +4,7 @@ # COMMON VARIABLES #================================================= -YNH_PHP_VERSION="7.3" +YNH_PHP_VERSION="8.0" pkg_dependencies="php${YNH_PHP_VERSION}-zip php${YNH_PHP_VERSION}-curl php${YNH_PHP_VERSION}-mbstring php${YNH_PHP_VERSION}-ldap php${YNH_PHP_VERSION}-json php${YNH_PHP_VERSION}-xml"