docs & release: add online instruction button, clean code comments, update documentation files and build docs/ package structure

This commit is contained in:
nertyog 2026-08-07 04:24:48 +03:00
parent faf03e20b7
commit c37d0c04b8
42 changed files with 3972 additions and 1089 deletions

3612
docs/instruction.html Normal file

File diff suppressed because one or more lines are too long

62
docs/instructions.txt Normal file
View File

@ -0,0 +1,62 @@
================================================================================
Image Optimizer [NAT]: Compress originals & remove unused images v1.2.0
================================================================================
Онлайн веб-інструкція / Онлайн веб-инструкция / Online Documentation:
http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html
--------------------------------------------------------------------------------
🇺🇦 УКРАЇНСЬКА МОВА (UKRAINIAN)
--------------------------------------------------------------------------------
ВСТАНОВЛЕННЯ МОДУЛЯ:
1. Розпакуйте архів.
2. Завантажте вміст папки upload/ у корінь вашого сайту по FTP.
3. Перейдіть в "Система" -> "Користувачі" -> "Групи користувачів", виберіть группу (Administrator) та встановіть галочки прав для: extension/module/img_opti (або module/img_opti для OC 2.0-2.2).
4. Перейдіть у "Модулі / Розширення", знайдіть "Image Optimizer [NAT]" та натисніть "Встановити", потім "Редагувати".
ФУНКЦІОНАЛ ТА ВКТАДКИ:
- Вкладка 1 (Інфо та статистика): Графік диска, накопичувальна статистика з бази даних сайту (враховує Оптимізацію, Очищення, Інструменти та Крон) з кнопкою [Скинути статистику], 100% експорт/імпорт налаштувань у JSON та кнопка переходу до Онлайн Інструкції.
- Вкладка 2 (Стиснення та Ресайз): Вибір движка (GD або Imagick з маркуванням дій), розмірів, якості WebP/JPG/PNG та вибір папок.
- Вкладка 3 (Очищення від сміття): Пошук невикористовуваних зображень, відправка у Карантин або остаточне видалення.
- Вкладка 4 (Формати & Захист): Захист від фейкових JPG на льоту (On-the-Fly Fake JPG Guard), WebP на льоту, SVG, Lazy Load.
- Вкладка 5 (Водяні знаки): Накладання водяних знаків (текст/фото) на льоту.
- Вкладка 6 (Заглушки): Автозаміна відсутніх фото товарів, категорій та брендів.
- Вкладка 7 (Інструменти & Крон): Санітайзер імен, конвертер CMYK у sRGB, виправлення чорних фонів, планувальник Cron.
--------------------------------------------------------------------------------
🇷🇺 РУССКИЙ ЯЗЫК (RUSSIAN)
--------------------------------------------------------------------------------
УСТАНОВКА МОДУЛЯ:
1. Распакуйте архив.
2. Загрузите содержимое папки upload/ в корень вашего сайта по FTP.
3. Перейдите в "Система" -> "Пользователи" -> "Группы пользователей", выберите группу (Administrator) и установите галочки прав для: extension/module/img_opti (или module/img_opti для OC 2.0-2.2).
4. Перейдите в "Модули / Расширения", найдите "Image Optimizer [NAT]", нажмите "Установить", затем "Редактировать".
ФУНКЦИОНАЛ И ВКЛАДКИ:
- Вкладка 1 (Инфо и статистика): График диска, накопительная статистика из базы данных сайта (учитывает Оптимизацию, Очистку, Инструменты и Крон) с кнопкой [Сбросить статистику], 100% экспорт/импорт настроек в JSON и кнопка перехода к Онлайн Инструкции.
- Вкладка 2 (Сжатие и Ресайз): Выбор движка (GD или Imagick с маркировкой действий), размеров, качества WebP/JPG/PNG и выбор папок.
- Вкладка 3 (Очистка от мусора): Поиск неиспользуемых изображений, отправка в Карантин или окончательное удаление.
- Вкладка 4 (Форматы & Защита): Защита от фейковых JPG на лету (On-the-Fly Fake JPG Guard), WebP на лету, SVG, Lazy Load.
- Вкладка 5 (Водяные знаки): Наложение водяных знаков (текст/фото) на лету.
- Вкладка 6 (Заглушки): Автозамена отсутствующих фото товаров, категорий и брендов.
- Вкладка 7 (Инструменты & Крон): Санитайзер имен, конвертер CMYK в sRGB, исправление черных фонов, планировщик Cron.
--------------------------------------------------------------------------------
🇬🇧 ENGLISH
--------------------------------------------------------------------------------
INSTALLATION:
1. Extract the archive.
2. Upload the contents of upload/ to your OpenCart root directory via FTP.
3. Go to System -> Users -> User Groups. Select Administrator and set Access/Modify permissions for extension/module/img_opti (or module/img_opti for OC 2.0-2.2).
4. Go to Extensions -> Modules, install "Image Optimizer [NAT]", and click Edit.
FEATURES & TABS:
- Tab 1 (Info & Stats): Disk chart, persistent DB stats with reset button, 100% full JSON settings export/import, online instruction link button.
- Tab 2 (Compression): GD / Imagick engine selection with labelled actions, batch resizing, WebP/JPG/PNG quality controls.
- Tab 3 (Cleaner): Smart search for unused catalog photos, safe quarantine and permanent deletion.
- Tab 4 (Formats & Guard): On-the-Fly Fake JPG Guard protection, WebP on-the-fly, SVG, Lazy Load.
- Tab 5 (Watermarks): On-the-fly image and text watermarks with position and opacity rules.
- Tab 6 (Placeholders): Fallback images for missing photos.
- Tab 7 (Tools & Cron): Name Sanitizer, CMYK to sRGB converter, Black BG repair, Cron background runner.

70
docs/readme.txt Normal file
View File

@ -0,0 +1,70 @@
================================================================================
Image Optimizer [NAT]: Compress originals & remove unused images v1.2.0
================================================================================
Thank you for purchasing our extension!
If you have any questions, feel free to contact us: info@nat.od.ua
Online Documentation: http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html
--------------------------------------------------------------------------------
TERMS & CONDITIONS (License & Support Policy)
--------------------------------------------------------------------------------
By purchasing and downloading this extension, you strictly agree to the following terms:
1. Single Domain License: One purchase allows you to install and use the extension on exactly one (1) live domain and one (1) local/test environment. You need a separate License Key for each additional live project.
2. License Activation: The module requires a License Key to function. Please email info@nat.od.ua with your Order ID and Domain Name after purchase to receive your key.
3. Support: We provide free technical support for bugs and standard installation issues. Support is available via email (info@nat.od.ua). Please allow up to 24-48 hours for a response.
4. Compatibility: The module is guaranteed to work on standard OpenCart / ocStore installations. We cannot guarantee out-of-the-box compatibility with heavily customized core files or third-party checkout/theme modules, though we will do our best to assist you.
5. Refund Policy: We offer a 100% refund if the extension is completely non-functional on a standard OpenCart setup and our support team is unable to fix it. We do not issue refunds for "change of mind" or if you have already requested and received a domain license key.
6. Distribution: The code is open-source, meaning you can modify it for your own needs. However, you may not resell, redistribute, share, or publish this extension in any form.
--------------------------------------------------------------------------------
INSTALLATION
--------------------------------------------------------------------------------
1. Extract the archive.
2. Upload the contents of the upload/ folder to your OpenCart root directory via FTP (no core files will be overwritten).
3. Go to OpenCart Admin -> System -> Users -> User Groups. Select your group (Administrator) and check both "Access" and "Modify" permissions for extension/module/img_opti (or module/img_opti on OC 2.0-2.2).
4. Go to Extensions -> Extensions -> Modules. Find "Image Optimizer [NAT]" and click the "Install" (green plus) button.
5. Click the "Edit" button to access the module panel.
--------------------------------------------------------------------------------
HOW TO USE (TABS & FEATURES)
--------------------------------------------------------------------------------
WARNING: Always create a full backup of your /image/catalog/ folder before running any optimizations or deletions!
TAB 1: INFO & STATS
- Disk Usage Chart: Renders a pie chart of folder sizes (Image Catalog, Cache, Trash). Supports manual hosting quota limit overrides and auto-update toggling on page open.
- Cumulative Database Stats: Displays total optimized files, total saved MB, and average savings percentage stored safely in site DB (accumulates across Optimization, Cleaner, Tools & Cron). Includes [Reset Statistics] button.
- Full Export / Import (JSON): Export and restore 100% of module settings (Cron tasks, watermark rules, placeholders, folder limits, format guards).
- Online Web-Instruction Button: Direct link to the complete web documentation at http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html.
TAB 2: OPTIMIZE & RESIZE (COMPRESSION)
1. Enter your License Key (Token) in the respective field.
2. Select target processing engine: GD (Standard) or Imagick (Advanced). Actions are explicitly labelled (GD / Imagick).
3. Select target folders inside image/catalog/.
4. Choose Mode: "Create a copy" (Safest) or "Replace originals".
5. Set maximum Width/Height and WebP/JPG/PNG quality settings.
6. Click "START OPTIMIZATION". Balanced 50/50 Pause & Stop UI controls allow full control during batch execution.
TAB 3: UNUSED IMAGES CLEANER (JUNK REMOVAL)
1. Select the folders to scan.
2. Click "FIND JUNK". The module compares physical files on disk with your Database and Theme files.
3. Review the detailed log of unused files.
4. Click "To Quarantine" to safely move junk files to image/catalog_trash/, or "Delete permanently" to wipe them from the server.
TAB 4: FORMATS (WEBP & FAKE JPG GUARD)
- On-the-Fly Fake JPG Guard: Detects PNG binary headers inside .jpg extensions and auto-converts or replaces them on-the-fly to eliminate black background glitches on the storefront.
- WebP "on-the-fly", SVG support, and progressive Lazy Load with blur-up.
TAB 5: WATERMARKS
- Dynamic Overlay rules: Set up watermarks (image or text) on-the-fly with position, transparency, angle, font, and category filters.
TAB 6: PLACEHOLDERS
- Renders fallback images for products, categories, or brands without images.
TAB 7: TOOLS (PRO) & CRON SCHEDULER
- Name Sanitizer, CMYK to sRGB Converter, Black Background Fixer.
- Cron background scheduler for continuous automated store optimization.

62
instructions.txt Normal file
View File

@ -0,0 +1,62 @@
================================================================================
Image Optimizer [NAT]: Compress originals & remove unused images v1.2.0
================================================================================
Онлайн веб-інструкція / Онлайн веб-инструкция / Online Documentation:
http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html
--------------------------------------------------------------------------------
🇺🇦 УКРАЇНСЬКА МОВА (UKRAINIAN)
--------------------------------------------------------------------------------
ВСТАНОВЛЕННЯ МОДУЛЯ:
1. Розпакуйте архів.
2. Завантажте вміст папки upload/ у корінь вашого сайту по FTP.
3. Перейдіть в "Система" -> "Користувачі" -> "Групи користувачів", виберіть группу (Administrator) та встановіть галочки прав для: extension/module/img_opti (або module/img_opti для OC 2.0-2.2).
4. Перейдіть у "Модулі / Розширення", знайдіть "Image Optimizer [NAT]" та натисніть "Встановити", потім "Редагувати".
ФУНКЦІОНАЛ ТА ВКТАДКИ:
- Вкладка 1 (Інфо та статистика): Графік диска, накопичувальна статистика з бази даних сайту (враховує Оптимізацію, Очищення, Інструменти та Крон) з кнопкою [Скинути статистику], 100% експорт/імпорт налаштувань у JSON та кнопка переходу до Онлайн Інструкції.
- Вкладка 2 (Стиснення та Ресайз): Вибір движка (GD або Imagick з маркуванням дій), розмірів, якості WebP/JPG/PNG та вибір папок.
- Вкладка 3 (Очищення від сміття): Пошук невикористовуваних зображень, відправка у Карантин або остаточне видалення.
- Вкладка 4 (Формати & Захист): Захист від фейкових JPG на льоту (On-the-Fly Fake JPG Guard), WebP на льоту, SVG, Lazy Load.
- Вкладка 5 (Водяні знаки): Накладання водяних знаків (текст/фото) на льоту.
- Вкладка 6 (Заглушки): Автозаміна відсутніх фото товарів, категорій та брендів.
- Вкладка 7 (Інструменти & Крон): Санітайзер імен, конвертер CMYK у sRGB, виправлення чорних фонів, планувальник Cron.
--------------------------------------------------------------------------------
🇷🇺 РУССКИЙ ЯЗЫК (RUSSIAN)
--------------------------------------------------------------------------------
УСТАНОВКА МОДУЛЯ:
1. Распакуйте архив.
2. Загрузите содержимое папки upload/ в корень вашего сайта по FTP.
3. Перейдите в "Система" -> "Пользователи" -> "Группы пользователей", выберите группу (Administrator) и установите галочки прав для: extension/module/img_opti (или module/img_opti для OC 2.0-2.2).
4. Перейдите в "Модули / Расширения", найдите "Image Optimizer [NAT]", нажмите "Установить", затем "Редактировать".
ФУНКЦИОНАЛ И ВКЛАДКИ:
- Вкладка 1 (Инфо и статистика): График диска, накопительная статистика из базы данных сайта (учитывает Оптимизацию, Очистку, Инструменты и Крон) с кнопкой [Сбросить статистику], 100% экспорт/импорт настроек в JSON и кнопка перехода к Онлайн Инструкции.
- Вкладка 2 (Сжатие и Ресайз): Выбор движка (GD или Imagick с маркировкой действий), размеров, качества WebP/JPG/PNG и выбор папок.
- Вкладка 3 (Очистка от мусора): Поиск неиспользуемых изображений, отправка в Карантин или окончательное удаление.
- Вкладка 4 (Форматы & Защита): Защита от фейковых JPG на лету (On-the-Fly Fake JPG Guard), WebP на лету, SVG, Lazy Load.
- Вкладка 5 (Водяные знаки): Наложение водяных знаков (текст/фото) на лету.
- Вкладка 6 (Заглушки): Автозамена отсутствующих фото товаров, категорий и брендов.
- Вкладка 7 (Инструменты & Крон): Санитайзер имен, конвертер CMYK в sRGB, исправление черных фонов, планировщик Cron.
--------------------------------------------------------------------------------
🇬🇧 ENGLISH
--------------------------------------------------------------------------------
INSTALLATION:
1. Extract the archive.
2. Upload the contents of upload/ to your OpenCart root directory via FTP.
3. Go to System -> Users -> User Groups. Select Administrator and set Access/Modify permissions for extension/module/img_opti (or module/img_opti for OC 2.0-2.2).
4. Go to Extensions -> Modules, install "Image Optimizer [NAT]", and click Edit.
FEATURES & TABS:
- Tab 1 (Info & Stats): Disk chart, persistent DB stats with reset button, 100% full JSON settings export/import, online instruction link button.
- Tab 2 (Compression): GD / Imagick engine selection with labelled actions, batch resizing, WebP/JPG/PNG quality controls.
- Tab 3 (Cleaner): Smart search for unused catalog photos, safe quarantine and permanent deletion.
- Tab 4 (Formats & Guard): On-the-Fly Fake JPG Guard protection, WebP on-the-fly, SVG, Lazy Load.
- Tab 5 (Watermarks): On-the-fly image and text watermarks with position and opacity rules.
- Tab 6 (Placeholders): Fallback images for missing photos.
- Tab 7 (Tools & Cron): Name Sanitizer, CMYK to sRGB converter, Black BG repair, Cron background runner.

View File

@ -1,9 +1,10 @@
================================================================================
================================================================================
Image Optimizer [NAT]: Compress originals & remove unused images v1.2.0
================================================================================
Thank you for purchasing our extension!
If you have any questions, feel free to contact us: info@nat.od.ua
Online Documentation: http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html
--------------------------------------------------------------------------------
@ -16,15 +17,15 @@ By purchasing and downloading this extension, you strictly agree to the followin
3. Support: We provide free technical support for bugs and standard installation issues. Support is available via email (info@nat.od.ua). Please allow up to 24-48 hours for a response.
4. Compatibility: The module is guaranteed to work on standard OpenCart / ocStore installations. We cannot guarantee out-of-the-box compatibility with heavily customized core files or third-party checkout/theme modules, though we will do our best to assist you.
5. Refund Policy: We offer a 100% refund if the extension is completely non-functional on a standard OpenCart setup and our support team is unable to fix it. We do not issue refunds for "change of mind" or if you have already requested and received a domain license key.
6. Distribution: The code is open-source (no IonCube), meaning you can modify it for your own needs. However, you may not resell, redistribute, share, or publish this extension in any form.
6. Distribution: The code is open-source, meaning you can modify it for your own needs. However, you may not resell, redistribute, share, or publish this extension in any form.
--------------------------------------------------------------------------------
INSTALLATION
--------------------------------------------------------------------------------
1. Extract the archive.
2. Upload the contents of the `upload/` folder to your OpenCart root directory via FTP (no core files will be overwritten).
3. Go to OpenCart Admin -> System -> Users -> User Groups. Select your group (Administrator) and check both "Access" and "Modify" permissions for `extension/module/img_opti`.
2. Upload the contents of the upload/ folder to your OpenCart root directory via FTP (no core files will be overwritten).
3. Go to OpenCart Admin -> System -> Users -> User Groups. Select your group (Administrator) and check both "Access" and "Modify" permissions for extension/module/img_opti (or module/img_opti on OC 2.0-2.2).
4. Go to Extensions -> Extensions -> Modules. Find "Image Optimizer [NAT]" and click the "Install" (green plus) button.
5. Click the "Edit" button to access the module panel.
@ -32,73 +33,38 @@ INSTALLATION
--------------------------------------------------------------------------------
HOW TO USE (TABS & FEATURES)
--------------------------------------------------------------------------------
WARNING: Always create a full backup of your `/image/catalog/` folder before running any optimizations or deletions!
WARNING: Always create a full backup of your /image/catalog/ folder before running any optimizations or deletions!
TAB 1: INFO & STATS
- Disk Usage Chart: Renders a pie chart of folder sizes (Image Catalog, Cache, Trash). Supports manual hosting quota limit overrides and auto-update toggling on page open.
- Cumulative Stats: Displays total optimized files and total disk space saved.
- Cumulative Database Stats: Displays total optimized files, total saved MB, and average savings percentage stored safely in site DB (accumulates across Optimization, Cleaner, Tools & Cron). Includes [Reset Statistics] button.
- Full Export / Import (JSON): Export and restore 100% of module settings (Cron tasks, watermark rules, placeholders, folder limits, format guards).
- Online Web-Instruction Button: Direct link to the complete web documentation at http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html.
TAB 2: OPTIMIZE & RESIZE (COMPRESSION)
1. Enter your License Key (Token) in the respective field.
2. Select the target folders inside `image/catalog/` you want to process.
3. Choose the Mode: "Create a copy" (Safest) or "Replace originals".
4. Set your maximum Width/Height and WebP/JPG/PNG quality settings.
5. Click "START OPTIMIZATION". The module will process files in batches using AJAX without overloading your server.
2. Select target processing engine: GD (Standard) or Imagick (Advanced). Actions are explicitly labelled (GD / Imagick).
3. Select target folders inside image/catalog/.
4. Choose Mode: "Create a copy" (Safest) or "Replace originals".
5. Set maximum Width/Height and WebP/JPG/PNG quality settings.
6. Click "START OPTIMIZATION". Balanced 50/50 Pause & Stop UI controls allow full control during batch execution.
TAB 3: UNUSED IMAGES CLEANER (JUNK REMOVAL)
1. Select the folders to scan.
2. Click "FIND JUNK". The module compares physical files on disk with your Database and Theme files.
3. Review the detailed log of unused files.
4. Click "To Quarantine" to safely move the junk files to `image/catalog_trash/`, or "Delete permanently" to wipe them from the server.
5. You can easily restore files from Quarantine with one click if something goes wrong.
4. Click "To Quarantine" to safely move junk files to image/catalog_trash/, or "Delete permanently" to wipe them from the server.
TAB 4: WATERMARKS
- Dynamic Overlay rules: Set up watermarks (image or text) to overlay on category, brand, banner, or product images on-the-fly.
- Position, transparency, angle, font (TTF), size scaling, and category exclusion/inclusion filters are fully supported.
TAB 4: FORMATS (WEBP & FAKE JPG GUARD)
- On-the-Fly Fake JPG Guard: Detects PNG binary headers inside .jpg extensions and auto-converts or replaces them on-the-fly to eliminate black background glitches on the storefront.
- WebP "on-the-fly", SVG support, and progressive Lazy Load with blur-up.
TAB 5: PLACEHOLDERS
- Renders fallback images for products, categories, or brands that do not have an image assigned in the database, keeping the storefront look consistent.
TAB 5: WATERMARKS
- Dynamic Overlay rules: Set up watermarks (image or text) on-the-fly with position, transparency, angle, font, and category filters.
TAB 6: IMAGE FORMATS (🧪 BETA)
- WebP Support: Enable WebP on-the-fly delivery.
- SVG Support: Safe SVG rendering.
- Progressive Lazy Loading: Blur-up effect (loads micro-preview and fades/de-blurs smoothly as user scrolls).
- Fallback Image: Set global placeholder image for broken images.
TAB 6: PLACEHOLDERS
- Renders fallback images for products, categories, or brands without images.
TAB 7: TOOLS (PRO) (🧪 BETA)
- Filename Sanitizer: Clear names of cyrillic letters, spaces, and special symbols in file and directory paths.
- Broken DB Scanner: Finds and fixes database records referencing non-existent files.
- Broken Files Scanner: Scans the server to clean up corrupted or 0-byte images.
- Heavy Files: Find the largest images on disk and optimize them instantly.
- CMYK Converter: Convert color space of JPEG files from CMYK to sRGB for Apple iOS/Safari compatibility.
TAB 8: CRON (🧪 BETA)
- Configure automated background directory scans and image compression schedules using a Cron token.
--------------------------------------------------------------------------------
UNINSTALLATION
--------------------------------------------------------------------------------
1. Uninstall the module from the Extensions list in your OpenCart Admin.
2. Delete the module files from:
- admin/controller/extension/module/img_opti.php
- admin/language/*/extension/module/img_opti.php
- admin/view/template/extension/module/img_opti.twig
--------------------------------------------------------------------------------
🔥 CHECK OUT OUR OTHER OPENCART MODULES:
--------------------------------------------------------------------------------
Maximize your store's performance with our professional toolset:
• Catalog Optimizer [NAT]: Hide empty categories/brands, clear unused attributes/options.
• Domain Scanner [NAT]: Find and clean external links and images.
• Promo Top Bar [NAT]: Create interactive promo bars, marquees and header slideshows.
👉 View all our extensions here:
https://www.opencart.com/index.php?route=marketplace/extension&filter_member=nat.odua
================================================================================
Support info@nat.od.ua | All rights reserved.
TAB 7: TOOLS (PRO) & CRON SCHEDULER
- Name Sanitizer, CMYK to sRGB Converter, Black Background Fixer.
- Cron background scheduler for continuous automated store optimization.

View File

@ -2001,7 +2001,6 @@ class ControllerModuleImgOpti extends Controller {
$image = isset($this->request->post['module_img_opti_wm_image']) ? $this->request->post['module_img_opti_wm_image'] : '';
// Search for a real product image to act as a realistic preview background
$base_file = '';
$query_prod = $this->db->query("SELECT image FROM `" . DB_PREFIX . "product` WHERE image IS NOT NULL AND image != '' AND image LIKE 'catalog/%' LIMIT 1");
if ($query_prod->num_rows && is_file(DIR_IMAGE . $query_prod->row['image'])) {

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Compress Originals & Delete Junk';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Compress Originals & Delete Junk';
$_['text_extension'] = 'Extensions';
@ -539,14 +539,12 @@ $_['entry_disk_quota_total'] = 'Total Hosting Disk Space (GB)';
$_['entry_disk_quota_used'] = 'Total Hosting Used Disk Space (GB)';
$_['entry_auto_disk'] = 'Auto-update on page load';
// Cron Tasks
$_['entry_cron_task_name'] = 'Task Name';
$_['entry_cron_task_summary'] = 'Compression settings';
$_['button_add_cron_task'] = 'Add Cron Task';
$_['button_copy_cron_url'] = 'Copy URL';
$_['text_cron_recommended_url'] = 'Cron task execution URL:';
// Licensing
$_['text_license_required'] = 'License Key Required';
$_['text_license_required_desc'] = 'Please enter your license key to activate the module. All configuration and optimization features are locked until a valid key is provided.';
$_['entry_token_desc'] = 'Enter the activation token issued for your root domain. You can obtain it from your purchase page or by contacting support.';
@ -554,7 +552,6 @@ $_['button_activate'] = 'Activate Module';
$_['text_support'] = 'Technical Support';
$_['text_support_desc'] = 'If you don\'t have a key yet, or face issues, please provide your order ID and domain name.';
// New settings
$_['entry_wm_max_width'] = 'Watermark Max Width (px)';
$_['entry_wm_max_height'] = 'Watermark Max Height (px)';
$_['help_wm_max_width'] = 'If the source watermark image exceeds this width, it will be automatically scaled down. Set 0 or leave empty for default 800px.';
@ -563,3 +560,5 @@ $_['entry_disk_status'] = 'Enable Disk Space Scan & Graph';
$_['help_disk_status'] = 'If enabled, the module will periodically scan the image folder size and display a pie chart. Disable this on large sites to improve settings page load speed.';
$_['text_disk_settings_title'] = 'Disk Limits & Scanning Settings';
$_['button_online_instruction'] = 'Module Documentation (Online)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Compress Originals & Delete Junk';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Compress Originals & Delete Junk';
$_['text_extension'] = 'Extensions';
@ -536,9 +536,10 @@ $_['entry_disk_quota_total'] = 'Total Hosting Disk Space (GB)';
$_['entry_disk_quota_used'] = 'Total Hosting Used Disk Space (GB)';
$_['entry_auto_disk'] = 'Auto-update on page load';
// Cron Tasks
$_['entry_cron_task_name'] = 'Task Name';
$_['entry_cron_task_summary'] = 'Compression settings';
$_['button_add_cron_task'] = 'Add Cron Task';
$_['button_copy_cron_url'] = 'Copy URL';
$_['text_cron_recommended_url'] = 'Cron task execution URL:';
$_['button_online_instruction'] = 'Module Documentation (Online)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Сжатие оригиналов и удаление мусора';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Сжатие оригиналов и удаление мусора';
$_['text_extension'] = 'Расширения';
@ -539,14 +539,12 @@ $_['entry_disk_quota_total'] = 'Выделено диска на хостинг
$_['entry_disk_quota_used'] = 'Занято диска на хостинге всего (ГБ)';
$_['entry_auto_disk'] = 'Автообновление при входе';
// Cron Tasks
$_['entry_cron_task_name'] = 'Название задачи';
$_['entry_cron_task_summary'] = 'Параметры сжатия';
$_['button_add_cron_task'] = 'Добавить задачу';
$_['button_copy_cron_url'] = 'Копировать URL';
$_['text_cron_recommended_url'] = 'URL для запуска задачи крона:';
// Licensing
$_['text_license_required'] = 'Требуется лицензионный ключ';
$_['text_license_required_desc'] = 'Пожалуйста, введите лицензионный ключ для активации модуля. Все функции настроек и оптимизации заблокированы до ввода валидного ключа.';
$_['entry_token_desc'] = 'Введите токен активации, выданный для вашего основного домена. Вы можете получить его в личном кабинете на форуме или обратившись в поддержку.';
@ -554,7 +552,6 @@ $_['button_activate'] = 'Активировать модуль';
$_['text_support'] = 'Техническая поддержка';
$_['text_support_desc'] = 'Если у вас ещё нет ключа или возникли проблемы, пожалуйста, сообщите номер вашего заказа и домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. высота водяного знака (px)';
$_['help_wm_max_width'] = 'Если исходное изображение водяного знака превышает эту ширину, оно будет автоматически масштабировано. Укажите 0 или оставьте пустым для значения по умолчанию (800px).';
@ -563,3 +560,5 @@ $_['entry_disk_status'] = 'Включить сканирование диска
$_['help_disk_status'] = 'Если включено, модуль будет периодически сканировать объем папки картинок и отображать круговую диаграмму. Рекомендуется выключить на больших сайтах для ускорения загрузки панели.';
$_['text_disk_settings_title'] = 'Настройка лимитов и сканирования диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Сжатие оригиналов и удаление мусора';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Сжатие оригиналов и удаление мусора';
$_['text_extension'] = 'Расширения';
@ -539,14 +539,12 @@ $_['entry_disk_quota_total'] = 'Выделено диска на хостинг
$_['entry_disk_quota_used'] = 'Занято диска на хостинге всего (ГБ)';
$_['entry_auto_disk'] = 'Автообновление при входе';
// Cron Tasks
$_['entry_cron_task_name'] = 'Название задачи';
$_['entry_cron_task_summary'] = 'Параметры сжатия';
$_['button_add_cron_task'] = 'Добавить задачу';
$_['button_copy_cron_url'] = 'Копировать URL';
$_['text_cron_recommended_url'] = 'URL для запуска задачи крона:';
// Licensing
$_['text_license_required'] = 'Требуется лицензионный ключ';
$_['text_license_required_desc'] = 'Пожалуйста, введите лицензионный ключ для активации модуля. Все функции настроек и оптимизации заблокированы до ввода валидного ключа.';
$_['entry_token_desc'] = 'Введите токен активации, выданный для вашего основного домена. Вы можете получить его в личном кабинете на форуме или обратившись в поддержку.';
@ -554,7 +552,6 @@ $_['button_activate'] = 'Активировать модуль';
$_['text_support'] = 'Техническая поддержка';
$_['text_support_desc'] = 'Если у вас ещё нет ключа или возникли проблемы, пожалуйста, сообщите номер вашего заказа и домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. высота водяного знака (px)';
$_['help_wm_max_width'] = 'Если исходное изображение водяного знака превышает эту ширину, оно будет автоматически масштабировано. Укажите 0 или оставьте пустым для значения по умолчанию (800px).';
@ -563,3 +560,5 @@ $_['entry_disk_status'] = 'Включить сканирование диска
$_['help_disk_status'] = 'Если включено, модуль будет периодически сканировать объем папки картинок и отображать круговую диаграмму. Рекомендуется выключить на больших сайтах для ускорения загрузки панели.';
$_['text_disk_settings_title'] = 'Настройка лимитов и сканирования диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Сжатие оригиналов и удаление мусора';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Сжатие оригиналов и удаление мусора';
$_['text_extension'] = 'Расширения';
@ -539,14 +539,12 @@ $_['entry_disk_quota_total'] = 'Выделено диска на хостинг
$_['entry_disk_quota_used'] = 'Занято диска на хостинге всего (ГБ)';
$_['entry_auto_disk'] = 'Автообновление при входе';
// Cron Tasks
$_['entry_cron_task_name'] = 'Название задачи';
$_['entry_cron_task_summary'] = 'Параметры сжатия';
$_['button_add_cron_task'] = 'Добавить задачу';
$_['button_copy_cron_url'] = 'Копировать URL';
$_['text_cron_recommended_url'] = 'URL для запуска задачи крона:';
// Licensing
$_['text_license_required'] = 'Требуется лицензионный ключ';
$_['text_license_required_desc'] = 'Пожалуйста, введите лицензионный ключ для активации модуля. Все функции настроек и оптимизации заблокированы до ввода валидного ключа.';
$_['entry_token_desc'] = 'Введите токен активации, выданный для вашего основного домена. Вы можете получить его в личном кабинете на форуме или обратившись в поддержку.';
@ -554,7 +552,6 @@ $_['button_activate'] = 'Активировать модуль';
$_['text_support'] = 'Техническая поддержка';
$_['text_support_desc'] = 'Если у вас ещё нет ключа или возникли проблемы, пожалуйста, сообщите номер вашего заказа и домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. высота водяного знака (px)';
$_['help_wm_max_width'] = 'Если исходное изображение водяного знака превышает эту ширину, оно будет автоматически масштабировано. Укажите 0 или оставьте пустым для значения по умолчанию (800px).';
@ -563,3 +560,5 @@ $_['entry_disk_status'] = 'Включить сканирование диска
$_['help_disk_status'] = 'Если включено, модуль будет периодически сканировать объем папки картинок и отображать круговую диаграмму. Рекомендуется выключить на больших сайтах для ускорения загрузки панели.';
$_['text_disk_settings_title'] = 'Настройка лимитов и сканирования диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Сжатие оригиналов и удаление мусора';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Сжатие оригиналов и удаление мусора';
$_['text_extension'] = 'Расширения';
@ -539,14 +539,12 @@ $_['entry_disk_quota_total'] = 'Выделено диска на хостинг
$_['entry_disk_quota_used'] = 'Занято диска на хостинге всего (ГБ)';
$_['entry_auto_disk'] = 'Автообновление при входе';
// Cron Tasks
$_['entry_cron_task_name'] = 'Название задачи';
$_['entry_cron_task_summary'] = 'Параметры сжатия';
$_['button_add_cron_task'] = 'Добавить задачу';
$_['button_copy_cron_url'] = 'Копировать URL';
$_['text_cron_recommended_url'] = 'URL для запуска задачи крона:';
// Licensing
$_['text_license_required'] = 'Требуется лицензионный ключ';
$_['text_license_required_desc'] = 'Пожалуйста, введите лицензионный ключ для активации модуля. Все функции настроек и оптимизации заблокированы до ввода валидного ключа.';
$_['entry_token_desc'] = 'Введите токен активации, выданный для вашего основного домена. Вы можете получить его в личном кабинете на форуме или обратившись в поддержку.';
@ -554,7 +552,6 @@ $_['button_activate'] = 'Активировать модуль';
$_['text_support'] = 'Техническая поддержка';
$_['text_support_desc'] = 'Если у вас ещё нет ключа или возникли проблемы, пожалуйста, сообщите номер вашего заказа и домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. высота водяного знака (px)';
$_['help_wm_max_width'] = 'Если исходное изображение водяного знака превышает эту ширину, оно будет автоматически масштабировано. Укажите 0 или оставьте пустым для значения по умолчанию (800px).';
@ -562,3 +559,5 @@ $_['help_wm_max_height'] = 'Если исходное изображение в
$_['entry_disk_status'] = 'Включить сканирование диска и график';
$_['help_disk_status'] = 'Если включено, модуль будет периодически сканировать объем папки картинок и отображать круговую диаграмму. Рекомендуется выключить на больших сайтах для ускорения загрузки панели.';
$_['text_disk_settings_title'] = 'Настройка лимитов и сканирования диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Стиснення оригіналів та видалення сміття';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Стиснення оригіналів та видалення сміття';
$_['text_extension'] = 'Розширення';
@ -541,14 +541,12 @@ $_['entry_disk_quota_total'] = 'Виділено диска на хостинг
$_['entry_disk_quota_used'] = 'Зайнято диска на хостингу всього (ГБ)';
$_['entry_auto_disk'] = 'Автооновлення при вході';
// Cron Tasks
$_['entry_cron_task_name'] = 'Назва задачі';
$_['entry_cron_task_summary'] = 'Параметри стиснення';
$_['button_add_cron_task'] = 'Додати задачу';
$_['button_copy_cron_url'] = 'Копіювати URL';
$_['text_cron_recommended_url'] = 'URL для запуску задачі крону:';
// Licensing
$_['text_license_required'] = 'Необхідний ліцензійний ключ';
$_['text_license_required_desc'] = 'Будь ласка, введіть ліцензійний ключ для активації модуля. Усі функції налаштувань та оптимізації заблоковані до введення валідного ключа.';
$_['entry_token_desc'] = 'Введіть токен активації, виданий для вашого основного домену. Ви можете отримати його в особистому кабінеті на форумі або звернувшись у підтримку.';
@ -556,7 +554,6 @@ $_['button_activate'] = 'Активувати модуль';
$_['text_support'] = 'Технічна підтримка';
$_['text_support_desc'] = 'Якщо у вас ще немає ключа або виникли проблеми, будь ласка, повідомте номер вашого замовлення та домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. висота водяного знака (px)';
$_['help_wm_max_width'] = 'Якщо вихідне зображення водяного знака перевищує цю ширину, воно буде автоматично масштабоване. Вкажіть 0 або залиште порожнім для значення за замовчуванням (800px).';
@ -565,3 +562,5 @@ $_['entry_disk_status'] = 'Увімкнути сканування диска т
$_['help_disk_status'] = 'Якщо увімкнено, модуль періодично скануватиме обсяг папки картинок та відображатиме круговую діаграму. Рекомендується вимкнути на великих сайтах для прискорення завантаження панелі.';
$_['text_disk_settings_title'] = 'Налаштування лімітів та сканування диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Стиснення оригіналів та видалення сміття';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Стиснення оригіналів та видалення сміття';
$_['text_extension'] = 'Розширення';
@ -541,14 +541,12 @@ $_['entry_disk_quota_total'] = 'Виділено диска на хостинг
$_['entry_disk_quota_used'] = 'Зайнято диска на хостингу всього (ГБ)';
$_['entry_auto_disk'] = 'Автооновлення при вході';
// Cron Tasks
$_['entry_cron_task_name'] = 'Назва задачі';
$_['entry_cron_task_summary'] = 'Параметри стиснення';
$_['button_add_cron_task'] = 'Додати задачу';
$_['button_copy_cron_url'] = 'Копіювати URL';
$_['text_cron_recommended_url'] = 'URL для запуску задачі крону:';
// Licensing
$_['text_license_required'] = 'Необхідний ліцензійний ключ';
$_['text_license_required_desc'] = 'Будь ласка, введіть ліцензійний ключ для активації модуля. Усі функції налаштувань та оптимізації заблоковані до введення валідного ключа.';
$_['entry_token_desc'] = 'Введіть токен активації, виданий для вашого основного домену. Ви можете отримати його в особистому кабінеті на форумі або звернувшись у підтримку.';
@ -556,7 +554,6 @@ $_['button_activate'] = 'Активувати модуль';
$_['text_support'] = 'Технічна підтримка';
$_['text_support_desc'] = 'Якщо у вас ще немає ключа або виникли проблеми, будь ласка, повідомте номер вашого замовлення та домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. висота водяного знака (px)';
$_['help_wm_max_width'] = 'Якщо вихідне зображення водяного знака перевищує цю ширину, воно буде автоматично масштабоване. Вкажіть 0 або залиште порожнім для значення за замовчуванням (800px).';
@ -565,3 +562,5 @@ $_['entry_disk_status'] = 'Увімкнути сканування диска т
$_['help_disk_status'] = 'Якщо увімкнено, модуль періодично скануватиме обсяг папки картинок та відображатиме круговую діаграму. Рекомендується вимкнути на великих сайтах для прискорення завантаження панелі.';
$_['text_disk_settings_title'] = 'Налаштування лімітів та сканування диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Стиснення оригіналів та видалення сміття';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Стиснення оригіналів та видалення сміття';
$_['text_extension'] = 'Розширення';
@ -541,14 +541,12 @@ $_['entry_disk_quota_total'] = 'Виділено диска на хостинг
$_['entry_disk_quota_used'] = 'Зайнято диска на хостингу всього (ГБ)';
$_['entry_auto_disk'] = 'Автооновлення при вході';
// Cron Tasks
$_['entry_cron_task_name'] = 'Назва задачі';
$_['entry_cron_task_summary'] = 'Параметри стиснення';
$_['button_add_cron_task'] = 'Додати задачу';
$_['button_copy_cron_url'] = 'Копіювати URL';
$_['text_cron_recommended_url'] = 'URL для запуску задачі крону:';
// Licensing
$_['text_license_required'] = 'Необхідний ліцензійний ключ';
$_['text_license_required_desc'] = 'Будь ласка, введіть ліцензійний ключ для активації модуля. Усі функції налаштувань та оптимізації заблоковані до введення валідного ключа.';
$_['entry_token_desc'] = 'Введіть токен активації, виданий для вашого основного домену. Ви можете отримати його в особистому кабінеті на форумі або звернувшись у підтримку.';
@ -556,7 +554,6 @@ $_['button_activate'] = 'Активувати модуль';
$_['text_support'] = 'Технічна підтримка';
$_['text_support_desc'] = 'Якщо у вас ще немає ключа або виникли проблеми, будь ласка, повідомте номер вашого замовлення та домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. висота водяного знака (px)';
$_['help_wm_max_width'] = 'Якщо вихідне зображення водяного знака перевищує цю ширину, воно буде автоматично масштабоване. Вкажіть 0 або залиште порожнім для значення за замовчуванням (800px).';
@ -565,3 +562,5 @@ $_['entry_disk_status'] = 'Увімкнути сканування диска т
$_['help_disk_status'] = 'Якщо увімкнено, модуль періодично скануватиме обсяг папки картинок та відображатиме круговую діаграму. Рекомендується вимкнути на великих сайтах для прискорення завантаження панелі.';
$_['text_disk_settings_title'] = 'Налаштування лімітів та сканування диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Стиснення оригіналів та видалення сміття';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Стиснення оригіналів та видалення сміття';
$_['text_extension'] = 'Розширення';
@ -541,14 +541,12 @@ $_['entry_disk_quota_total'] = 'Виділено диска на хостинг
$_['entry_disk_quota_used'] = 'Зайнято диска на хостингу всього (ГБ)';
$_['entry_auto_disk'] = 'Автооновлення при вході';
// Cron Tasks
$_['entry_cron_task_name'] = 'Назва задачі';
$_['entry_cron_task_summary'] = 'Параметри стиснення';
$_['button_add_cron_task'] = 'Додати задачу';
$_['button_copy_cron_url'] = 'Копіювати URL';
$_['text_cron_recommended_url'] = 'URL для запуску задачі крону:';
// Licensing
$_['text_license_required'] = 'Необхідний ліцензійний ключ';
$_['text_license_required_desc'] = 'Будь ласка, введіть ліцензійний ключ для активації модуля. Усі функції налаштувань та оптимізації заблоковані до введення валідного ключа.';
$_['entry_token_desc'] = 'Введіть токен активації, виданий для вашого основного домену. Ви можете отримати його в особистому кабінеті на форумі або звернувшись у підтримку.';
@ -556,7 +554,6 @@ $_['button_activate'] = 'Активувати модуль';
$_['text_support'] = 'Технічна підтримка';
$_['text_support_desc'] = 'Якщо у вас ще немає ключа або виникли проблеми, будь ласка, повідомте номер вашого замовлення та домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. висота водяного знака (px)';
$_['help_wm_max_width'] = 'Якщо вихідне зображення водяного знака перевищує цю ширину, воно буде автоматично масштабоване. Вкажіть 0 або залиште порожнім для значення за замовчуванням (800px).';
@ -565,3 +562,5 @@ $_['entry_disk_status'] = 'Увімкнути сканування диска т
$_['help_disk_status'] = 'Якщо увімкнено, модуль періодично скануватиме обсяг папки картинок та відображатиме круговую діаграму. Рекомендується вимкнути на великих сайтах для прискорення завантаження панелі.';
$_['text_disk_settings_title'] = 'Налаштування лімітів та сканування диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -1,4 +1,4 @@
<?php
<?php
$_['heading_title_raw'] = 'Image Optimizer [NAT]: Стиснення оригіналів та видалення сміття';
$_['heading_title'] = '<b>Image Optimizer [NAT]:</b> Стиснення оригіналів та видалення сміття';
$_['text_extension'] = 'Розширення';
@ -539,14 +539,12 @@ $_['entry_disk_quota_total'] = 'Виділено диска на хостинг
$_['entry_disk_quota_used'] = 'Зайнято диска на хостингу всього (ГБ)';
$_['entry_auto_disk'] = 'Автооновлення при вході';
// Cron Tasks
$_['entry_cron_task_name'] = 'Назва задачі';
$_['entry_cron_task_summary'] = 'Параметри стиснення';
$_['button_add_cron_task'] = 'Додати задачу';
$_['button_copy_cron_url'] = 'Копіювати URL';
$_['text_cron_recommended_url'] = 'URL для запуску задачі крону:';
// Licensing
$_['text_license_required'] = 'Необхідний ліцензійний ключ';
$_['text_license_required_desc'] = 'Будь ласка, введіть ліцензійний ключ для активації модуля. Усі функції налаштувань та оптимізації заблоковані до введення валідного ключа.';
$_['entry_token_desc'] = 'Введіть токен активації, виданий для вашого основного домену. Ви можете отримати його в особистому кабінеті на форуме або звернувшись у підтримку.';
@ -554,7 +552,6 @@ $_['button_activate'] = 'Активувати модуль';
$_['text_support'] = 'Технічна підтримка';
$_['text_support_desc'] = 'Якщо у вас ще немає ключа або виникли проблеми, будь ласка, повідомте номер вашого замовлення та домен.';
// New settings
$_['entry_wm_max_width'] = 'Макс. ширина водяного знака (px)';
$_['entry_wm_max_height'] = 'Макс. висота водяного знака (px)';
$_['help_wm_max_width'] = 'Якщо вихідне зображення водяного знака перевищує цю ширину, воно буде автоматично масштабоване. Вкажіть 0 або залиште порожнім для значення за замовчуванням (800px).';
@ -562,3 +559,5 @@ $_['help_wm_max_height'] = 'Якщо вихідне зображення вод
$_['entry_disk_status'] = 'Увімкнути сканування диска та графік';
$_['help_disk_status'] = 'Якщо увімкнено, модуль періодично скануватиме обсяг папки картинок та відображатиме круговую діаграму. Рекомендується вимкнути на великих сайтах для прискорення завантаження панелі.';
$_['text_disk_settings_title'] = 'Налаштування лімітів та сканування диска';
$_['button_online_instruction'] = 'Инструкция к модулю (Онлайн)';

View File

@ -423,7 +423,6 @@ class ModelModuleImgOpti extends Model {
if ($size === 0) {
$is_broken = true;
} elseif ($size > 52428800) {
// Файл > 50MB — пропускаем GD-проверку во избежание OOM
$is_broken = false;
} else {
if (extension_loaded('imagick')) {

View File

@ -36,37 +36,6 @@
<div class="panel-body">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-module">
<?php if (!$is_licensed) { ?>
<div style="max-width: 600px; margin: 30px auto;">
<div class="panel panel-danger" style="border-radius: 6px; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
<div class="panel-heading" style="background-color: #d9534f; color: white; padding: 15px; border-top-left-radius: 5px; border-top-right-radius: 5px;">
<h3 class="panel-title" style="color: white; font-size: 16px; font-weight: bold;"><i class="fa fa-key"></i> <?php echo $text_license_required; ?></h3>
</div>
<div class="panel-body" style="padding: 25px;">
<div class="alert alert-danger" style="margin-bottom: 20px; font-size: 14px;">
<i class="fa fa-exclamation-triangle"></i> <?php echo $text_license_required_desc; ?>
</div>
<div class="form-group" style="margin-bottom: 20px;">
<label style="font-weight: bold; font-size: 14px; margin-bottom: 8px;"><?php echo $entry_token; ?></label>
<div style="font-size: 12px; color: #666; margin-bottom: 8px;"><?php echo $entry_token_desc; ?></div>
<div class="input-group">
<input type="text" name="module_img_opti_token" id="module_token" value="<?php echo $module_img_opti_token; ?>" class="form-control" placeholder="XXXX-XXXX-XXXX-XXXX" style="font-size: 16px; height: 46px; letter-spacing: 1px;">
<span class="input-group-btn">
<button type="submit" class="btn btn-primary" style="height: 46px; font-weight: bold; padding: 0 20px;"><i class="fa fa-refresh"></i> <?php echo $button_activate; ?></button>
</span>
</div>
</div>
<hr>
<h4 style="font-weight: bold; margin-bottom: 10px;"><i class="fa fa-envelope-o text-primary"></i> <?php echo $text_support; ?></h4>
<p style="font-size: 13px; color: #555; line-height: 1.5;"><?php echo $text_support_desc; ?></p>
<ul style="font-size: 13px; color: #555; padding-left: 20px; line-height: 1.8;">
<li>Email: <b>info@nat.od.ua</b></li>
<li>Gitea: <b>https://git.nat.od.ua</b></li>
</ul>
</div>
</div>
</div>
<?php } else { ?>
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-settings" data-toggle="tab"><i class="fa fa-cog"></i> <?php echo $tab_settings; ?></a></li>
<li><a href="#tab-optimize" data-toggle="tab"><i class="fa fa-compress"></i> <?php echo $tab_optimize; ?></a></li>
@ -126,51 +95,24 @@
</div>
</div>
<div class="panel-group" id="accordion-disk-settings" style="margin-top: 20px;">
<div class="panel panel-default" style="border: 1px solid #ddd; border-radius: 4px;">
<div class="panel-heading" style="background-color: #f5f5f5; padding: 10px 15px;">
<h4 class="panel-title">
<a data-toggle="collapse" parent="#accordion-disk-settings" href="#collapse-disk-settings" style="display: block; text-decoration: none; font-weight: bold; color: #2980b9;">
<i class="fa fa-chevron-down"></i> <?php echo $text_disk_settings_title; ?>
</a>
</h4>
<fieldset style="margin-top: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 4px; background: #fff;">
<legend style="width: auto; padding: 0 10px; font-size: 16px; border: none; font-weight: bold; color: #2980b9;"><?php echo $text_disk_quota_legend; ?></legend>
<div class="alert alert-info" style="margin-bottom: 15px;"><?php echo $text_disk_quota_desc; ?></div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label"><?php echo $entry_disk_quota_total; ?></label>
<input type="number" name="module_img_opti_disk_quota_total" value="<?php echo $module_img_opti_disk_quota_total; ?>" class="form-control" placeholder="20" step="0.1" min="0" />
</div>
</div>
<div id="collapse-disk-settings" class="panel-collapse collapse">
<div class="panel-body" style="background: #fff; padding: 20px;">
<div class="row">
<div class="col-sm-12">
<div class="form-group" style="background: #f8f9fa; padding: 15px; border-radius: 4px; border: 1px solid #dee2e6; margin-bottom: 20px;">
<label style="font-weight: bold; cursor: pointer; margin-bottom: 0;">
<input type="checkbox" name="module_img_opti_disk_status" value="1" <?php if (isset($module_img_opti_disk_status) && $module_img_opti_disk_status) { ?>checked="checked"<?php } ?> style="vertical-align: middle; margin-top: -2px; margin-right: 6px;" />
<?php echo $entry_disk_status; ?>
</label>
<div style="font-size: 11px; color: #888; margin-top: 5px;"><?php echo $help_disk_status; ?></div>
</div>
</div>
</div>
<fieldset style="border: 1px solid #eee; padding: 15px; border-radius: 4px; background: #fafafa;">
<legend style="width: auto; padding: 0 10px; font-size: 14px; border: none; font-weight: bold; color: #7f8c8d; margin-bottom: 10px;"><?php echo $text_disk_quota_legend; ?></legend>
<div class="alert alert-info" style="margin-bottom: 15px; font-size: 12px;"><?php echo $text_disk_quota_desc; ?></div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label"><?php echo $entry_disk_quota_total; ?></label>
<input type="number" name="module_img_opti_disk_quota_total" value="<?php echo $module_img_opti_disk_quota_total; ?>" class="form-control" placeholder="20" step="0.1" min="0" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label"><?php echo $entry_disk_quota_used; ?></label>
<input type="number" name="module_img_opti_disk_quota_used" value="<?php echo $module_img_opti_disk_quota_used; ?>" class="form-control" placeholder="7.1" step="0.01" min="0" />
</div>
</div>
</div>
</fieldset>
<div class="col-md-6">
<div class="form-group">
<label class="control-label"><?php echo $entry_disk_quota_used; ?></label>
<input type="number" name="module_img_opti_disk_quota_used" value="<?php echo $module_img_opti_disk_quota_used; ?>" class="form-control" placeholder="7.1" step="0.01" min="0" />
</div>
</div>
</div>
</div>
</fieldset>
<fieldset style="margin-top: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 4px; background: #fff;">
<legend style="width: auto; padding: 0 10px; font-size: 16px; border: none; font-weight: bold; color: #2980b9;"><?php echo $text_folder_rules_title; ?></legend>
@ -264,22 +206,25 @@
<button type="button" id="btn-reset-stats" class="btn btn-xs btn-danger pull-right" style="margin-top:-2px;" title="<?php echo $text_reset_stats; ?>"><i class="fa fa-trash"></i></button>
</div>
<div class="panel-body" style="padding:15px;">
<div class="row" style="text-align:center;">
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_total_files_opt; ?></div>
<div id="cs-files" style="font-size:26px; font-weight:bold; color:#2c3e50;">&mdash;</div>
</div>
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_total_saved; ?></div>
<div id="cs-saved" style="font-size:26px; font-weight:bold; color:#27ae60;">&mdash;</div>
</div>
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_avg_saving_pct; ?></div>
<div id="cs-pct" style="font-size:26px; font-weight:bold; color:#e67e22;">&mdash;</div>
</div>
</div>
<hr style="margin:12px 0;">
<div style="font-size:12px; color:#777; text-align:center;"><?php echo $text_stats_hint; ?></div>
<div class="row" style="text-align:center;">
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_total_files_opt; ?></div>
<div id="cs-files" style="font-size:26px; font-weight:bold; color:#2c3e50;"><?php echo isset($stats_files) ? $stats_files : '0'; ?></div>
</div>
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_total_saved; ?></div>
<div id="cs-saved" style="font-size:26px; font-weight:bold; color:#27ae60;"><?php echo isset($stats_saved_mb) ? $stats_saved_mb : '0.00'; ?> MB</div>
</div>
<div class="col-xs-4">
<div style="font-size:11px; color:#666; text-transform:uppercase; letter-spacing:1px;"><?php echo $text_avg_saving_pct; ?></div>
<div id="cs-pct" style="font-size:26px; font-weight:bold; color:#e67e22;"><?php echo isset($stats_avg_pct) ? $stats_avg_pct : '0.0'; ?>%</div>
</div>
</div>
<hr style="margin:12px 0;">
<div style="font-size:12px; color:#777; text-align:center; display: flex; justify-content: space-between; align-items: center;">
<span><i class="fa fa-database"></i> <?php echo $text_stats_hint; ?></span>
<button type="button" id="btn-reset-stats" class="btn btn-default btn-xs" style="color:#c0392b; border-color:#e74c3c;" title="<?php echo $text_reset_stats; ?>"><i class="fa fa-trash-o"></i> <?php echo $text_reset_stats; ?></button>
</div>
</div>
</div>
<div class="panel panel-default" style="border-color:#8e44ad;">
@ -444,17 +389,17 @@
</div>
</div>
<div class="row" style="display: flex; flex-wrap: wrap; margin-left: -5px; margin-right: -5px;">
<div class="col-sm-10 col-xs-9" id="block-start" style="padding-left: 5px; padding-right: 5px;">
<div class="row">
<div class="col-sm-10" id="block-start">
<button type="button" id="btn-start" class="btn btn-primary btn-lg btn-block" <?php echo !$gd_enabled ? 'disabled' : ''; ?>><i class="fa fa-play"></i> <?php echo $button_start; ?></button>
</div>
<div class="col-sm-2" id="block-reset-cache" style="padding-left: 5px; padding-right: 5px;">
<div class="col-sm-2" id="block-reset-cache">
<button type="button" id="btn-reset-cache" class="btn btn-default btn-lg btn-block" title="<?php echo $text_reset_cache_hint; ?>"><i class="fa fa-eraser"></i></button>
</div>
<div class="col-sm-6 col-xs-6" id="block-pause" style="display:none; padding-left: 5px; padding-right: 5px;">
<div class="col-sm-6" id="block-pause" style="display:none;">
<button type="button" id="btn-pause" class="btn btn-warning btn-lg btn-block"><i class="fa fa-pause"></i> <?php echo $button_pause; ?></button>
</div>
<div class="col-sm-6" id="block-stop" style="display:none; padding-left: 5px; padding-right: 5px;">
<div class="col-sm-6" id="block-stop" style="display:none;">
<button type="button" id="btn-stop" class="btn btn-danger btn-lg btn-block"><i class="fa fa-stop"></i> <?php echo $button_stop; ?></button>
</div>
</div>
@ -648,6 +593,29 @@
</div>
</div>
<div class="row" style="margin-top: 20px;">
<div class="col-md-12">
<div style="background: #fffdf5; padding: 16px; border: 1px solid #f39c12; border-radius: 6px;">
<div class="checkbox" style="margin-top: 0; margin-bottom: 8px;">
<label style="font-weight: bold; font-size: 14px; color: #d35400;">
<input type="checkbox" name="module_img_opti_auto_fake_jpg_guard" id="chk-auto-fake-jpg" value="1" <?php if (isset($module_img_opti_auto_fake_jpg_guard) && $module_img_opti_auto_fake_jpg_guard) { ?>checked="checked"<?php } ?>>
<i class="fa fa-shield"></i> <?php echo $entry_auto_fake_jpg_guard; ?>
</label>
</div>
<div style="font-size: 12px; color: #666; line-height: 1.4; margin-bottom: 10px;">
<?php echo $help_auto_fake_jpg_guard; ?>
</div>
<div id="fake-jpg-mode-box" style="<?php if (empty($module_img_opti_auto_fake_jpg_guard)) { ?>display: none;<?php } ?> margin-top: 10px; padding-top: 10px; border-top: 1px dashed #f0c36d; max-width: 600px;">
<label style="font-weight: bold; color: #333; font-size: 13px; margin-bottom: 5px;"><?php echo $entry_fake_jpg_mode; ?></label>
<select name="module_img_opti_fake_jpg_mode" class="form-control input-sm">
<option value="jpg" <?php if (empty($module_img_opti_fake_jpg_mode) || $module_img_opti_fake_jpg_mode == 'jpg') { ?>selected="selected"<?php } ?>><?php echo $text_fake_jpg_mode_jpg; ?></option>
<option value="png" <?php if (isset($module_img_opti_fake_jpg_mode) && $module_img_opti_fake_jpg_mode == 'png') { ?>selected="selected"<?php } ?>><?php echo $text_fake_jpg_mode_png; ?></option>
</select>
</div>
</div>
</div>
</div>
<div class="row" style="margin-top: 20px;">
<div class="col-md-4">
<div class="checkbox" style="background: #fffdf5; padding: 15px; border: 1px solid #f39c12; border-radius: 6px; min-height: 150px; margin-top: 0; margin-bottom: 0;">
@ -731,30 +699,18 @@
<div id="tool-ui-watermark" class="tool-ui-block" style="display: none;">
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label class="control-label"><?php echo $entry_wm_status; ?></label>
<select name="module_img_opti_wm_status" class="form-control">
<option value="1" <?php if (isset($module_img_opti_wm_status) && $module_img_opti_wm_status) { ?>selected="selected"<?php } ?>><?php echo $text_enabled; ?></option>
<option value="0" <?php if (!isset($module_img_opti_wm_status) || !$module_img_opti_wm_status) { ?>selected="selected"<?php } ?>><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label class="control-label" title="<?php echo $help_wm_max_width; ?>"><?php echo $entry_wm_max_width; ?></label>
<input type="number" name="module_img_opti_wm_max_width" value="<?php echo $module_img_opti_wm_max_width; ?>" class="form-control" placeholder="800" min="0" />
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<label class="control-label" title="<?php echo $help_wm_max_height; ?>"><?php echo $entry_wm_max_height; ?></label>
<input type="number" name="module_img_opti_wm_max_height" value="<?php echo $module_img_opti_wm_max_height; ?>" class="form-control" placeholder="800" min="0" />
</div>
</div>
<div class="col-sm-4" style="padding-top: 23px;">
<button type="button" id="btn-clear-cache-wm" class="btn btn-warning btn-block" data-loading-text="<i class='fa fa-spinner fa-spin'></i> Cleaning..."><i class="fa fa-eraser"></i> <?php echo $button_clear_cache_wm; ?></button>
</div>
<div class="col-sm-8">
<div class="form-group">
<label class="control-label"><?php echo $entry_wm_status; ?></label>
<select name="module_img_opti_wm_status" class="form-control">
<option value="1" <?php if (isset($module_img_opti_wm_status) && $module_img_opti_wm_status) { ?>selected="selected"<?php } ?>><?php echo $text_enabled; ?></option>
<option value="0" <?php if (!isset($module_img_opti_wm_status) || !$module_img_opti_wm_status) { ?>selected="selected"<?php } ?>><?php echo $text_disabled; ?></option>
</select>
</div>
</div>
<div class="col-sm-4" style="padding-top: 23px;">
<button type="button" id="btn-clear-cache-wm" class="btn btn-warning btn-block" data-loading-text="<i class='fa fa-spinner fa-spin'></i> Cleaning..."><i class="fa fa-eraser"></i> <?php echo $button_clear_cache_wm; ?></button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
@ -992,6 +948,11 @@
<h3 style="margin-top: 0; color: #2c3e50;"><i class="fa fa-rocket"></i> <?php echo $text_promo_title; ?></h3>
<p style="color: #333;"><?php echo $text_promo_desc; ?></p>
<p style="color: #333;"><?php echo $text_support; ?> <a href="mailto:info@nat.od.ua">info@nat.od.ua</a></p>
<div style="margin-top: 15px; margin-bottom: 5px;">
<a href="http://oc3-demo.nat.od.ua/instructions/image_optimizer_nat_instruction.html" target="_blank" class="btn btn-primary btn-lg" style="border-radius: 6px; font-weight: bold; background: linear-gradient(135deg, #2980b9, #3498db); border: none; box-shadow: 0 4px 12px rgba(41, 128, 185, 0.3);">
<i class="fa fa-book"></i> <?php echo $button_online_instruction; ?>
</a>
</div>
</div>
<div class="row">
@ -1074,7 +1035,6 @@
</div>
</div>
<?php } ?>
</form>
</div>
@ -1940,10 +1900,10 @@ $(document).ready(function() {
html += ' <td><small>' + foldersList + '</small></td>';
html += ' <td><small>' + qualityInfo + '</small></td>';
html += ' <td class="text-center">' + statusText + '</td>';
html += ' <td class="text-right" style="white-space: normal; min-width: 250px;">';
html += ' <button type="button" class="btn btn-default btn-xs btn-copy-task-url" data-url="' + taskUrl.replace(/&amp;/g, '&') + '" title="<?php echo $button_copy_cron_url; ?>" style="margin: 2px 0 2px 5px;"><i class="fa fa-copy"></i> <?php echo $button_copy_cron_url; ?></button>';
html += ' <button type="button" class="btn btn-primary btn-xs btn-edit-cron-task" data-index="' + index + '" style="margin: 2px 0 2px 5px;"><i class="fa fa-pencil"></i> <?php echo $button_edit; ?></button>';
html += ' <button type="button" class="btn btn-danger btn-xs btn-delete-cron-task" data-index="' + index + '" style="margin: 2px 0 2px 5px;"><i class="fa fa-trash"></i> <?php echo $button_delete; ?></button>';
html += ' <td class="text-right">';
html += ' <button type="button" class="btn btn-default btn-xs btn-copy-task-url" data-url="' + taskUrl.replace(/&amp;/g, '&') + '" title="<?php echo $button_copy_cron_url; ?>"><i class="fa fa-copy"></i> <?php echo $button_copy_cron_url; ?></button>';
html += ' <button type="button" class="btn btn-primary btn-xs btn-edit-cron-task" data-index="' + index + '" style="margin-left:5px;"><i class="fa fa-pencil"></i> <?php echo $button_edit; ?></button>';
html += ' <button type="button" class="btn btn-danger btn-xs btn-delete-cron-task" data-index="' + index + '" style="margin-left:5px;"><i class="fa fa-trash"></i> <?php echo $button_delete; ?></button>';
html += ' </td>';
html += '</tr>';
});
@ -3242,17 +3202,8 @@ $('#import-settings-file').on('change', function() {
// ============ PERSIST ACTIVE TAB ============
$(document).ready(function() {
var activeTab = localStorage.getItem('nat_active_tab_img_opti');
var $tabLinks = $('.nav-tabs').first().find('a[data-toggle="tab"]');
var tabExists = false;
if (activeTab) {
var $targetTab = $('.nav-tabs').first().find('a[href="' + activeTab + '"]');
if ($targetTab.length > 0) {
$targetTab.tab('show');
tabExists = true;
}
}
if (!tabExists && $tabLinks.length > 0) {
$tabLinks.first().tab('show');
$('.nav-tabs').first().find('a[href="' + activeTab + '"]').tab('show');
}
$('.nav-tabs').first().on('shown.bs.tab', 'a[data-toggle="tab"]', function(e) {
localStorage.setItem('nat_active_tab_img_opti', $(e.target).attr('href'));

View File

@ -1,4 +1,4 @@
<?php
<?php
if (!defined('DIR_APPLICATION')) { exit; }
class ControllerModuleImgOptiCron extends Controller {

View File

@ -1,4 +1,4 @@
<?php
<?php
if (!defined('DIR_APPLICATION')) { exit; }
class ModelModuleImgOpti extends Model {

View File

@ -1,4 +1,4 @@
<?php
<?php
define('ELFINDER_PHP_ROOT_PATH', dirname(__FILE__));

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder - file manager for web.
@ -464,7 +464,6 @@ class elFinder
*/
private static $seekableUrlFps = array();
// Errors messages
const ERROR_ACCESS_DENIED = 'errAccess';
const ERROR_ARC_MAXSIZE = 'errArcMaxSize';
const ERROR_ARC_SYMLINKS = 'errArcSymlinks';
@ -540,7 +539,6 @@ class elFinder
*/
public function __construct($opts)
{
// set default_charset
if (version_compare(PHP_VERSION, '5.6', '>=')) {
if (($_val = ini_get('iconv.internal_encoding')) && strtoupper($_val) !== 'UTF-8') {
ini_set('iconv.internal_encoding', '');
@ -561,7 +559,6 @@ class elFinder
}
ini_set('default_charset', 'UTF-8');
// define accept constant of server commands path
!defined('ELFINDER_TAR_PATH') && define('ELFINDER_TAR_PATH', 'tar');
!defined('ELFINDER_GZIP_PATH') && define('ELFINDER_GZIP_PATH', 'gzip');
!defined('ELFINDER_BZIP2_PATH') && define('ELFINDER_BZIP2_PATH', 'bzip2');
@ -579,29 +576,21 @@ class elFinder
!defined('ELFINDER_DISABLE_ZIPEDITOR') && define('ELFINDER_DISABLE_ZIPEDITOR', false);
// enable(true)/disable(false) handling postscript on ImageMagick
// Should be `false` as long as there is a Ghostscript vulnerability
// see https://artifex.com/news/ghostscript-security-resolved/
!defined('ELFINDER_IMAGEMAGICK_PS') && define('ELFINDER_IMAGEMAGICK_PS', false);
// for backward compat
$this->version = (string)self::$ApiVersion;
// set error handler of WARNING, NOTICE
$errLevel = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_RECOVERABLE_ERROR;
if (defined('E_DEPRECATED')) {
$errLevel |= E_DEPRECATED | E_USER_DEPRECATED;
}
set_error_handler('elFinder::phpErrorHandler', $errLevel);
// Associative array of file pointers to close at the end of script: ['temp file pointer' => true]
$GLOBALS['elFinderTempFps'] = array();
// Associative array of files to delete at the end of script: ['temp file path' => true]
$GLOBALS['elFinderTempFiles'] = array();
// regist Shutdown function
register_shutdown_function(array('elFinder', 'onShutdown'));
// convert PATH_INFO to GET query
if (!empty($_SERVER['PATH_INFO'])) {
$_ps = explode('/', trim($_SERVER['PATH_INFO'], '/'));
if (!isset($_GET['cmd'])) {
@ -622,15 +611,12 @@ class elFinder
}
}
// set elFinder instance
elFinder::$instance = $this;
// setup debug mode
$this->debug = (isset($opts['debug']) && $opts['debug'] ? true : false);
if ($this->debug) {
error_reporting(defined('ELFINDER_DEBUG_ERRORLEVEL') ? ELFINDER_DEBUG_ERRORLEVEL : -1);
ini_set('display_errors', '1');
// clear output buffer and stop output filters
while (ob_get_level() && ob_end_clean()) {
}
}
@ -639,7 +625,6 @@ class elFinder
include_once dirname(__FILE__) . '/elFinderSessionInterface.php';
}
// session handler
if (!empty($opts['session']) && $opts['session'] instanceof elFinderSessionInterface) {
$this->session = $opts['session'];
} else {
@ -655,16 +640,13 @@ class elFinder
}
$this->session = new elFinderSession($sessionOpts);
}
// try session start | restart
$this->session->start();
// 'netmount' added to handle requests synchronously on unmount
$sessionUseCmds = array('netmount');
if (isset($opts['sessionUseCmds']) && is_array($opts['sessionUseCmds'])) {
$sessionUseCmds = array_merge($sessionUseCmds, $opts['sessionUseCmds']);
}
// set self::$volumesCnt by HTTP header "X-elFinder-VolumesCntStart"
if (isset($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']) && ($volumesCntStart = intval($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']))) {
self::$volumesCnt = $volumesCntStart;
}
@ -710,41 +692,31 @@ class elFinder
$this->itemLockExpire = intval($opts['itemLockExpire']);
}
// deprecated settings
$this->netVolumesSessionKey = !empty($opts['netVolumesSessionKey']) ? $opts['netVolumesSessionKey'] : 'elFinderNetVolumes';
self::$sessionCacheKey = !empty($opts['sessionCacheKey']) ? $opts['sessionCacheKey'] : 'elFinderCaches';
// check session cache
$_optsMD5 = md5(json_encode($opts['roots']));
if ($this->session->get('_optsMD5') !== $_optsMD5) {
$this->session->set('_optsMD5', $_optsMD5);
}
// setlocale and global locale regists to elFinder::locale
self::$locale = !empty($opts['locale']) ? $opts['locale'] : (substr(PHP_OS, 0, 3) === 'WIN' ? 'C' : 'en_US.UTF-8');
if (false === setlocale(LC_ALL, self::$locale)) {
self::$locale = setlocale(LC_ALL, '0');
}
// set defaultMimefile
elFinder::$defaultMimefile = isset($opts['defaultMimefile']) ? $opts['defaultMimefile'] : '';
// set memoryLimitGD
elFinder::$memoryLimitGD = isset($opts['memoryLimitGD']) ? $opts['memoryLimitGD'] : 0;
// set flag of throwErrorOnExec
// `true` need `try{}` block for `$connector->run();`
$this->throwErrorOnExec = !empty($opts['throwErrorOnExec']);
// set archivers
elFinder::$archivers = isset($opts['archivers']) && is_array($opts['archivers']) ? $opts['archivers'] : array();
// set utf8Encoder
if (isset($opts['utf8Encoder']) && is_callable($opts['utf8Encoder'])) {
$this->utf8Encoder = $opts['utf8Encoder'];
}
// bind events listeners
if (!empty($opts['bind']) && is_array($opts['bind'])) {
$_req = $_SERVER["REQUEST_METHOD"] == 'POST' ? $_POST : $_GET;
$_reqCmd = isset($_req['cmd']) ? $_req['cmd'] : '';
@ -754,7 +726,6 @@ class elFinder
$doRegist = ($_reqCmd && in_array($_reqCmd, array_map('self::getCmdOfBind', explode(' ', $cmd))));
}
if ($doRegist) {
// for backward compatibility
if (!is_array($handlers)) {
$handlers = array($handlers);
} else {
@ -785,16 +756,13 @@ class elFinder
$opts['roots'] = array();
}
// try to enable elFinderVolumeFlysystemZipArchiveNetmount to zip editing
if (empty(elFinder::$netDrivers['ziparchive'])) {
elFinder::$netDrivers['ziparchive'] = 'FlysystemZipArchiveNetmount';
}
// check for net volumes stored in session
$netVolumes = $this->getNetVolumes();
foreach ($netVolumes as $key => $root) {
if (!isset($root['id'])) {
// given fixed unique id
if (!$root['id'] = $this->getNetVolumeUniqueId($netVolumes)) {
$this->mountErrors[] = 'Netmount Driver "' . $root['driver'] . '" : Could\'t given volume id.';
continue;
@ -804,25 +772,21 @@ class elFinder
$opts['roots'][$key] = $root;
}
// "mount" volumes
foreach ($opts['roots'] as $i => $o) {
$class = 'elFinderVolume' . (isset($o['driver']) ? $o['driver'] : '');
if (class_exists($class)) {
/* @var elFinderVolumeDriver $volume */
$volume = new $class();
try {
if ($this->maxArcFilesSize && (empty($o['maxArcFilesSize']) || $this->maxArcFilesSize < $o['maxArcFilesSize'])) {
$o['maxArcFilesSize'] = $this->maxArcFilesSize;
}
// pass session handler
$volume->setSession($this->session);
if (!$this->default) {
$volume->setNeedOnline(true);
}
if ($volume->mount($o)) {
// unique volume id (ends on "_") - used as prefix to files hash
$id = $volume->id();
$this->volumes[$id] = $volume;
@ -849,10 +813,8 @@ class elFinder
}
}
// if at least one readable volume - ii desu >_<
$this->loaded = !empty($this->default);
// restore error handler for now
restore_error_handler();
}
@ -1067,10 +1029,8 @@ class elFinder
**/
public function exec($cmd, $args)
{
// set error handler of WARNING, NOTICE
set_error_handler('elFinder::phpErrorHandler', E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE);
// set current request args
self::$currentArgs = $args;
if (!$this->loaded) {
@ -1085,16 +1045,13 @@ class elFinder
return array('error' => $this->error(self::ERROR_UNKNOWN_CMD));
}
// check request id
$args['reqid'] = preg_replace('[^0-9a-fA-F]', '', !empty($args['reqid']) ? $args['reqid'] : (!empty($_SERVER['HTTP_X_ELFINDERREQID']) ? $_SERVER['HTTP_X_ELFINDERREQID'] : ''));
// to abort this request
if ($cmd === 'abort') {
$this->abort($args);
return array('error' => 0);
}
// make flag file and set self::$abortCheckFile
if ($args['reqid']) {
$this->abort(array('makeFile' => $args['reqid']));
}
@ -1105,10 +1062,8 @@ class elFinder
}
}
// regist shutdown function as fallback
register_shutdown_function(array($this, 'itemAutoUnlock'));
// detect destination dirHash and volume
$dstVolume = false;
$dst = !empty($args['target']) ? $args['target'] : (!empty($args['dst']) ? $args['dst'] : '');
if ($dst) {
@ -1122,14 +1077,12 @@ class elFinder
$dst = '';
}
} else if ($cmd === 'open') {
// for initial open without args `target`
$dstVolume = $this->default;
$dst = $dstVolume->defaultPath();
}
$result = null;
// call pre handlers for this command
$args['sessionCloseEarlier'] = isset($this->sessionUseCmds[$cmd]) ? false : $this->sessionCloseEarlier;
if (!empty($this->listeners[$cmd . '.pre'])) {
foreach ($this->listeners[$cmd . '.pre'] as $handler) {
@ -1152,15 +1105,12 @@ class elFinder
}
}
// unlock session data for multiple access
if ($this->sessionCloseEarlier && $args['sessionCloseEarlier']) {
$this->session->close();
// deprecated property
elFinder::$sessionClosed = true;
}
if (substr(PHP_OS, 0, 3) === 'WIN') {
// set time out
elFinder::extendTimeLimit(300);
}
@ -1180,7 +1130,6 @@ class elFinder
}
}
// check change dstDir
$changeDst = false;
if ($dst && $dstVolume && (!empty($result['added']) || !empty($result['removed']))) {
$changeDst = true;
@ -1210,7 +1159,6 @@ class elFinder
$volume->resetResultStat();
}
// dstDir is changed
if ($changeDst) {
if ($dstDir = $dstVolume->dir($dst)) {
if (!isset($result['changed'])) {
@ -1220,17 +1168,14 @@ class elFinder
}
}
// call handlers for this command
if (!empty($this->listeners[$cmd])) {
foreach ($this->listeners[$cmd] as $handler) {
if (call_user_func_array($handler, array($cmd, &$result, $args, $this, $dstVolume))) {
// handler return true to force sync client after command completed
$result['sync'] = true;
}
}
}
// replace removed files info with removed files hashes
if (!empty($result['removed'])) {
$removed = array();
foreach ($result['removed'] as $file) {
@ -1238,15 +1183,12 @@ class elFinder
}
$result['removed'] = array_unique($removed);
}
// remove hidden files and filter files by mimetypes
if (!empty($result['added'])) {
$result['added'] = $this->filter($result['added']);
}
// remove hidden files and filter files by mimetypes
if (!empty($result['changed'])) {
$result['changed'] = $this->filter($result['changed']);
}
// add toasts
if ($this->toastMessages) {
$result['toasts'] = array_merge(((isset($result['toasts']) && is_array($result['toasts']))? $result['toasts'] : array()), $this->toastMessages);
}
@ -1267,7 +1209,6 @@ class elFinder
}
}
// remove sesstion var 'urlContentSaveIds'
if ($this->removeContentSaveIds) {
$urlContentSaveIds = $this->session->get('urlContentSaveIds', array());
foreach (array_keys($this->removeContentSaveIds) as $contentSaveId) {
@ -1287,10 +1228,8 @@ class elFinder
$volume->umount();
}
// unlock locked items
$this->itemAutoUnlock();
// custom data
if ($this->customData !== null) {
$result['customData'] = $this->customData ? json_encode($this->customData) : '';
}
@ -1456,7 +1395,6 @@ class elFinder
$key = strtolower($name);
if (!isset($this->plugins[$key])) {
$class = 'elFinderPlugin' . $name;
// to try auto load
if (!class_exists($class)) {
$p_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'plugin.php';
if (is_file($p_file)) {
@ -1472,9 +1410,6 @@ class elFinder
return $this->plugins[$key];
}
/***************************************************************************/
/* commands */
/***************************************************************************/
/**
* Normalize error messages
@ -1541,10 +1476,8 @@ class elFinder
}
}
/* @var elFinderVolumeDriver $volume */
$volume = new $class();
// pass session handler
$volume->setSession($this->session);
$volume->setNeedOnline(true);
@ -1566,13 +1499,11 @@ class elFinder
$netVolumes = $this->getNetVolumes();
if (!isset($options['id'])) {
// given fixed unique id
if (!$options['id'] = $this->getNetVolumeUniqueId($netVolumes)) {
return array('error' => $this->error(self::ERROR_NETMOUNT, $args['host'], 'Could\'t given volume id.'));
}
}
// load additional volume root options
if (!empty($this->optionsNetVolumes['*'])) {
$options = array_merge($this->optionsNetVolumes['*'], $options);
}
@ -1586,7 +1517,6 @@ class elFinder
$options['netkey'] = $key;
if (!isset($netVolumes[$key]) && $volume->mount($options)) {
// call post-process function of netmount
if (is_callable(array($volume, 'postNetmount'))) {
$volume->postNetmount($options);
}
@ -1630,9 +1560,6 @@ class elFinder
$hash = $init ? 'default folder' : '#' . $target;
$compare = '';
// on init request we can get invalid dir hash -
// dir which can not be opened now, but remembered by client,
// so open default dir
if ((!$cwd || !$cwd['read']) && $init) {
$volume = $this->default;
$target = $volume->defaultPath();
@ -1648,7 +1575,6 @@ class elFinder
$files = array();
// get current working directory files list
if (($ls = $volume->scandir($cwd['hash'])) === false) {
return array('error' => $this->error(self::ERROR_OPEN, $cwd['name'], $volume->error()));
}
@ -1657,14 +1583,12 @@ class elFinder
$cwd = $volume->dir($target);
}
// get other volume root
if ($tree) {
foreach ($this->volumes as $id => $v) {
$files[] = $v->file($v->root());
}
}
// long polling mode
if ($args['compare']) {
$sleep = max(1, (int)$volume->getOption('lsPlSleep'));
$standby = (int)$volume->getOption('plStandby');
@ -1840,7 +1764,6 @@ class elFinder
$CriOS = isset($_SERVER['HTTP_USER_AGENT'])? (strpos($_SERVER['HTTP_USER_AGENT'], 'CriOS') !== false) : false;
if (!$download) {
//1st: Return array contains download archive file info
$error = array(self::ERROR_ARCHIVE);
if (($volume = $this->volume($targets[0])) !== false) {
if ($dlres = $volume->zipdl($targets)) {
@ -1867,10 +1790,7 @@ class elFinder
}
return array('error' => $error);
} else {
// 2nd: Return array contains opened file session key, root itself and required headers
// Detect Chrome on iOS
// It has access twice on downloading
$CriOSinit = false;
if ($CriOS) {
$accept = isset($_SERVER['HTTP_ACCEPT'])? $_SERVER['HTTP_ACCEPT'] : '';
@ -1878,15 +1798,12 @@ class elFinder
$CriOSinit = true;
}
}
// data check
if (count($targets) !== 4 || ($volume = $this->volume($targets[0])) == false || !($file = $CriOS? $targets[1] : $this->session->get('zipdl' . $targets[1]))) {
return array('error' => 'File not found', 'header' => $h404, 'raw' => true);
}
$path = $volume->getTempPath() . DIRECTORY_SEPARATOR . basename($file);
// remove session data of "zipdl..."
$this->session->remove('zipdl' . $targets[1]);
if (!$CriOSinit) {
// register auto delete on shutdown
$GLOBALS['elFinderTempFiles'][$path] = true;
}
if ($volume->commandDisabled('zipdl')) {
@ -1895,7 +1812,6 @@ class elFinder
if (!is_readable($path) || !is_writable($path)) {
return array('error' => 'File not found', 'header' => $h404, 'raw' => true);
}
// for HTTP headers
$name = $targets[2];
$mime = $targets[3];
@ -1926,7 +1842,6 @@ class elFinder
'Connection: close'
)
);
// add cache control headers
if ($cacheHeaders = $volume->getOption('cacheHeaders')) {
$result['header'] = array_merge($result['header'], $cacheHeaders);
}
@ -1949,7 +1864,6 @@ class elFinder
$target = $args['target'];
$download = !empty($args['download']);
$onetime = !empty($args['onetime']);
//$h304 = 'HTTP/1.1 304 Not Modified';
$h403 = 'HTTP/1.0 403 Access Denied';
$a403 = array('error' => 'Access Denied', 'header' => $h403, 'raw' => true);
$h404 = 'HTTP/1.0 404 Not Found';
@ -2002,10 +1916,8 @@ class elFinder
}
}
// check aborted by user
elFinder::checkAborted();
// allow change MIME type by 'file.pre' callback functions
$mime = isset($args['mime']) ? $args['mime'] : $file['mime'];
if ($download || $onetime) {
$disp = 'attachment';
@ -2059,12 +1971,10 @@ class elFinder
);
if (!$onetime) {
// add cache control headers
if ($cacheHeaders = $volume->getOption('cacheHeaders')) {
$result['header'] = array_merge($result['header'], $cacheHeaders);
}
// check 'xsendfile'
$xsendfile = $volume->getOption('xsendfile');
$path = null;
if ($xsendfile) {
@ -2087,7 +1997,6 @@ class elFinder
}
}
// add "Content-Location" if file has url data
if (isset($file['url']) && $file['url'] && $file['url'] != 1) {
$result['header'][] = 'Content-Location: ' . $file['url'];
}
@ -2282,7 +2191,6 @@ class elFinder
}
if ($query) {
// batch rename
$splits = elFinder::splitFileExtention($query);
if ($splits[1] && $splits[0] === '*') {
$type = 'extention';
@ -2475,7 +2383,6 @@ class elFinder
*/
protected function editor($args = array())
{
/* @var elFinderEditor $editor */
$name = $args['name'];
if (is_array($name)) {
$res = array();
@ -2547,27 +2454,21 @@ class elFinder
if (preg_match('~^(?:ht|f)tps?://[-_.!\~*\'()a-z0-9;/?:\@&=+\$,%#\*\[\]]+~i', $url)) {
$info = parse_url($url);
$host = trim(strtolower($info['host']), '.');
// do not support IPv6 address
if (preg_match('/^\[.*\]$/', $host)) {
return false;
}
// do not support non dot host
if (strpos($host, '.') === false) {
return false;
}
// do not support URL-encoded host
if (strpos($host, '%') !== false) {
return false;
}
// disallow including "localhost" and "localdomain"
if (preg_match('/\b(?:localhost|localdomain)\b/', $host)) {
return false;
}
// wildcard DNS (e.g xip.io)
if (preg_match('/0x[0-9a-f]+|[0-9]+(?:\.(?:0x[0-9a-f]+|[0-9]+)){1,3}/', $host)) {
$host = gethostbyname($host);
}
// check IPv4 local loopback, private network and link local
if (preg_match('/^0x[0-9a-f]+|[0-9]+(?:\.(?:0x[0-9a-f]+|[0-9]+)){1,3}$/', $host, $m)) {
$long = (int)sprintf('%u', ip2long($host));
if (!$long) {
@ -2583,9 +2484,7 @@ class elFinder
return false;
}
}
// dose not support 'user' and 'pass' for security reasons
$url = $info['scheme'].'://'.$host.(!empty($info['port'])? (':'.$info['port']) : '').$info['path'].(!empty($info['query'])? ('?'.$info['query']) : '').(!empty($info['fragment'])? ('#'.$info['fragment']) : '');
// check by URL upload filter
if ($this->urlUploadFilter && is_callable($this->urlUploadFilter)) {
if (!call_user_func_array($this->urlUploadFilter, array($url, $this))) {
return false;
@ -2664,16 +2563,13 @@ class elFinder
$arr = parse_url($url);
if (!$arr) {
// Bad request
return false;
}
if ($arr['scheme'] === 'https') {
$ssl = 'ssl://';
}
// query
$arr['query'] = isset($arr['query']) ? '?' . $arr['query'] : '';
// port
$port = isset($arr['port']) ? $arr['port'] : '';
$arr['port'] = $port ? $port : ($ssl ? 443 : 80);
@ -2736,7 +2632,6 @@ class elFinder
$rc = (int)$rccd[1];
$ret = false;
// Redirect
switch ($rc) {
case 307: // Temporary Redirect
case 303: // See Other
@ -2748,10 +2643,8 @@ class elFinder
$url = trim($matches[1]);
if (!preg_match('/^https?:\//', $url)) { // no scheme
if ($url[0] != '/') { // Relative path
// to Absolute path
$url = substr($url_path, 0, strrpos($url_path, '/')) . '/' . $url;
}
// add sheme,host
$url = $url_base . $url;
}
if ($_url === $url) {
@ -2809,7 +2702,6 @@ class elFinder
protected function parse_data_scheme($str, $extTable, $args = null)
{
$data = $name = $mime = '';
// Scheme 'data://' require `allow_url_fopen` and `allow_url_include`
if ($fp = fopen('data://' . substr($str, 5), 'rb')) {
if ($data = stream_get_contents($fp)) {
$meta = stream_get_meta_data($fp);
@ -2824,7 +2716,6 @@ class elFinder
}
if ($data) {
$ext = ($mime && isset($extTable[$mime])) ? '.' . $extTable[$mime] : '';
// Set name if name eq 'image.png' and $args has 'name' array, e.g. clipboard data
if (is_array($args['name']) && isset($args['name'][0])) {
$name = $args['name'][0];
if ($ext) {
@ -2887,7 +2778,6 @@ class elFinder
$mime = trim($mime[0]);
if (in_array($mime, array('application/x-empty', 'inode/x-empty'))) {
// finfo return this mime for empty files
$mime = 'text/plain';
} elseif ($mime == 'application/x-zip') {
// http://elrte.org/redmine/issues/163
@ -3022,7 +2912,6 @@ class elFinder
*/
private function checkChunkedFile($tmpname, $chunk, $cid, $tempDir, $volume = null)
{
/* @var elFinderVolumeDriver $volume */
if (preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m)) {
$fname = $m[1];
$encname = md5($cid . '_' . $fname);
@ -3030,7 +2919,6 @@ class elFinder
$clast = intval($m[3]);
if (is_null($tmpname)) {
ignore_user_abort(true);
// chunked file upload fail
foreach (glob($base . '*') as $cf) {
unlink($cf);
}
@ -3048,12 +2936,10 @@ class elFinder
$tmpExists = is_file($tmp);
if (!$tmpExists) {
// check upload max size
$uploadMaxSize = $volume ? $volume->getUploadMaxSize() : 0;
if ($uploadMaxSize > 0 && $size > $uploadMaxSize) {
return array(self::ERROR_UPLOAD_FILE_SIZE, false);
}
// make temp file
$ok = false;
if ($fp = fopen($tmp, 'wb')) {
flock($fp, LOCK_EX);
@ -3067,7 +2953,6 @@ class elFinder
return array(self::ERROR_UPLOAD_TEMP, false);
}
} else {
// wait until makeing temp file (for anothor session)
$cnt = 1200; // Time limit 120 sec
while (!is_file($base) && --$cnt) {
usleep(100000); // wait 100ms
@ -3077,12 +2962,10 @@ class elFinder
}
}
// check size info
if ($len != $csize || $start + $len > $size || ($tmpExists && $size != filesize($tmp))) {
return array(self::ERROR_UPLOAD_TEMP, false);
}
// write chunk data
$src = fopen($tmpname, 'rb');
$fp = fopen($tmp, 'cb');
fseek($fp, $start);
@ -3091,7 +2974,6 @@ class elFinder
fclose($src);
try {
// to check connection is aborted
elFinder::checkAborted();
} catch (elFinderAbortException $e) {
unlink($tmpname);
@ -3104,16 +2986,13 @@ class elFinder
return array(self::ERROR_UPLOAD_TEMP, false);
}
// write counts
file_put_contents($base, "\0", FILE_APPEND | LOCK_EX);
if (filesize($base) >= $clast + 1) {
// Completion
unlink($base);
return array($tmp, $fname);
}
} else {
// old way
$part = $base . $m[2];
if (move_uploaded_file($tmpname, $part)) {
chmod($part, 0600);
@ -3182,7 +3061,6 @@ class elFinder
return array_merge(array('error' => $this->error(self::ERROR_UPLOAD, self::ERROR_TRGDIR_NOT_FOUND, '#' . $target)), $header);
}
// check $chunk
if (strpos($chunk, '/') !== false || strpos($chunk, '\\') !== false) {
return array('error' => $this->error(self::ERROR_UPLOAD));
}
@ -3205,14 +3083,12 @@ class elFinder
$this->itemLock($target);
// file extentions table by MIME
$extTable = array_flip(array_unique($volume->getMimeTable()));
if (empty($files)) {
if (isset($args['upload']) && is_array($args['upload']) && ($tempDir = $this->getTempDir($volume->getTempPath()))) {
$names = array();
foreach ($args['upload'] as $i => $url) {
// check chunked file upload commit
if ($chunk) {
if ($url === 'chunkfail' && $args['mimes'] === 'chunkfail') {
$this->checkChunkedFile(null, $chunk, $cid, $tempDir);
@ -3234,13 +3110,11 @@ class elFinder
$GLOBALS['elFinderTempFiles'][$tmpfname] = true;
$_name = '';
// check is data:
if (substr($url, 0, 5) === 'data:') {
list($data, $args['name'][$i]) = $this->parse_data_scheme($url, $extTable, $args);
} else {
$fp = fopen($tmpfname, 'wb');
if ($data = $this->get_remote_contents($url, 30, 5, 'Mozilla/5.0', $fp)) {
// to check connection is aborted
try {
elFinder::checkAborted();
} catch(elFinderAbortException $e) {
@ -3248,7 +3122,6 @@ class elFinder
throw $e;
}
$_name = preg_replace('~^.*?([^/#?]+)(?:\?.*)?(?:#.*)?$~', '$1', rawurldecode($url));
// Check `Content-Disposition` response header
if (($headers = get_headers($url, true)) && !empty($headers['Content-Disposition'])) {
if (preg_match('/filename\*=(?:([a-zA-Z0-9_-]+?)\'\')"?([a-z0-9_.~%-]+)"?/i', $headers['Content-Disposition'], $m)) {
$_name = rawurldecode($m[2]);
@ -3294,7 +3167,6 @@ class elFinder
$files['tmp_name'][$i] = $tmpfname;
$files['name'][$i] = $_name;
$files['error'][$i] = 0;
// set to auto rename
$volume->setUploadOverwrite(false);
} else {
unlink($tmpfname);
@ -3342,12 +3214,10 @@ class elFinder
}
return $result;
} else {
// for form clipboard with Google Chrome or Opera
$name = 'image.png';
}
}
// Set name if name eq 'image.png' and $args has 'name' array, e.g. clipboard data
if (strtolower(substr($name, 0, 5)) === 'image' && is_array($args['name']) && isset($args['name'][$i])) {
$type = $files['type'][$i];
$name = $args['name'][$i];
@ -3358,7 +3228,6 @@ class elFinder
$name .= $ext;
}
// do hook function 'upload.presave'
try {
$this->trigger('upload.presave', array(&$thash, &$name, $tmpname, $this, $volume), $errors);
} catch (elFinderTriggerException $e) {
@ -3370,7 +3239,6 @@ class elFinder
clearstatcache();
if ($mtime && is_file($tmpname)) {
// for keep timestamp option in the LocalFileSystem volume
touch($tmpname, $mtime);
}
@ -3391,7 +3259,6 @@ class elFinder
if (!isset($addedDirs[$thash])) {
$addedDirs[$thash] = true;
$result['added'][] = $dir;
// to support multi-level directory creation
$_phash = isset($dir['phash']) ? $dir['phash'] : null;
while ($_phash && !isset($addedDirs[$_phash]) && $_phash !== $target) {
if ($_dir = $volume->dir($_phash)) {
@ -3409,7 +3276,6 @@ class elFinder
}
} else {
$_target = $target;
// file rename for backup
if (isset($renames[$name])) {
$dir = $volume->realpath($_target);
if (isset($hashes[$name])) {
@ -3601,7 +3467,6 @@ class elFinder
$enc = '';
if ($content !== '') {
if (!$args['conv'] || $args['conv'] == '1') {
// detect encoding
if (function_exists('mb_detect_encoding')) {
if ($enc = mb_detect_encoding($content, mb_detect_order(), true)) {
$encu = strtoupper($enc);
@ -3620,7 +3485,6 @@ class elFinder
$enc = 'unknown';
}
}
// call callbacks 'get.detectencoding'
if (!empty($this->listeners['get.detectencoding'])) {
foreach ($this->listeners['get.detectencoding'] as $handler) {
call_user_func_array($handler, array('get', &$enc, array_merge($args, array('content' => $content)), $this, $volume));
@ -3701,7 +3565,6 @@ class elFinder
'content' => $content
);
// add cache control headers
if ($cacheHeaders = $volume->getOption('cacheHeaders')) {
$res['header'] = array_merge($res['header'], $cacheHeaders);
}
@ -3734,7 +3597,6 @@ class elFinder
if ($encoding === 'scheme') {
if (preg_match('~^https?://~i', $args['content'])) {
/** @var resource $fp */
$fp = $this->get_remote_contents($args['content'], 30, 5, 'Mozilla/5.0', $volume->tmpfile());
if (!$fp) {
return array('error' => self::ERROR_SAVE, $args['content'], self::ERROR_FILE_NOT_FOUND);
@ -3886,7 +3748,6 @@ class elFinder
{
$files = array();
$compare = null;
// long polling mode
if ($args['compare'] && count($args['targets']) === 1) {
$compare = intval($args['compare']);
$hash = $args['targets'][0];
@ -4084,7 +3945,6 @@ var go = function() {
}
}
} catch(e) {
// for CORS
w.postMessage && w.postMessage(JSON.stringify({bind:\'' . $bind . '\',data:' . $json . '}), \'' . $origin . '\');
}
close();
@ -4206,9 +4066,6 @@ var go = function() {
return $proc;
}
/***************************************************************************/
/* utils */
/***************************************************************************/
/**
* Return root - file's owner
@ -4497,9 +4354,6 @@ var go = function() {
return utf8_encode($str);
}
/***************************************************************************/
/* static utils */
/***************************************************************************/
/**
* Return full version of API that this connector supports all functions
@ -4925,11 +4779,9 @@ var go = function() {
fputs($stream, join("\r\n", $sends) . "\r\n");
while (($res = trim(fgets($stream))) !== '') {
// find redirect
if (preg_match('/^Location: (.+)$/i', $res, $m)) {
$data['url'] = $m[1];
}
// fetch cookie
if (strpos($res, 'Set-Cookie:') === 0) {
$domain = $url['host'];
if (preg_match('/^Set-Cookie:(.+)(?:domain=\s*([^ ;]+))?/i', $res, $c1)) {
@ -4941,7 +4793,6 @@ var go = function() {
}
}
}
// is seekable url
if (preg_match('/^(Accept-Ranges|Content-Range): bytes/i', $res)) {
elFinder::$seekableUrlFps[(int)$stream] = true;
}
@ -5031,7 +4882,6 @@ var go = function() {
if ($file = self::$abortCheckFile) {
(version_compare(PHP_VERSION, '5.3.0') >= 0) ? clearstatcache(true, $file) : clearstatcache();
if (!is_file($file)) {
// GC (expire 12h)
list($ptn) = explode('elfreq', $file);
self::GlobGC($ptn . 'elfreq*', 43200);
return true;
@ -5155,10 +5005,8 @@ var go = function() {
$except = null;
$ret = stream_select($read, $write, $except, 1);
if ($ret === false) {
// error
break;
} else if ($ret === 0) {
// timeout
continue;
} else {
foreach ($read as $sock) {
@ -5186,9 +5034,6 @@ var go = function() {
}
/***************************************************************************/
/* callbacks */
/***************************************************************************/
/**
* Get command name of binded "commandName.subName"

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* Default elFinder connector
@ -74,7 +74,6 @@ class elFinderConnector
$src = $isPost ? array_merge($_GET, $_POST) : $_GET;
$maxInputVars = (!$src || isset($src['targets'])) ? ini_get('max_input_vars') : null;
if ((!$src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) {
// for max_input_vars and supports IE XDomainRequest()
$parts = explode('&', $rawPostData);
if (!$src || $maxInputVars < count($parts)) {
$src = array();
@ -117,17 +116,14 @@ class elFinderConnector
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
}
// telepat_mode: on
if (!$cmd && $isPost) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
}
// telepat_mode: off
if (!$this->elFinder->commandExists($cmd)) {
$this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
}
// collect required arguments to exec command
$hasFiles = false;
foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
if ($name === 'FILES') {
@ -159,12 +155,8 @@ class elFinderConnector
try {
$this->output($this->elFinder->exec($cmd, $args));
} catch (elFinderAbortException $e) {
// connection aborted
// unlock session data for multiple access
$this->elFinder->getSession()->close();
// HTTP response code
header('HTTP/1.0 204 No Content');
// clear output buffer
while (ob_get_level() && ob_end_clean()) {
}
exit();
@ -192,9 +184,7 @@ class elFinderConnector
*/
protected function output(array $data)
{
// unlock session data for multiple access
$this->elFinder->getSession()->close();
// client disconnect should abort
ignore_user_abort(false);
if ($this->header) {
@ -202,15 +192,12 @@ class elFinderConnector
}
if (isset($data['pointer'])) {
// set time limit to 0
elFinder::extendTimeLimit(0);
// send optional header
if (!empty($data['header'])) {
self::sendHeader($data['header']);
}
// clear output buffer
while (ob_get_level() && ob_end_clean()) {
}
@ -245,7 +232,6 @@ class elFinderConnector
header('Content-Length: ' . $psize);
header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
// Apache mod_xsendfile dose not support range request
if (isset($data['info']['xsendfile']) && strtolower($data['info']['xsendfile']) === 'x-sendfile') {
if (function_exists('header_remove')) {
header_remove($data['info']['xsendfile']);
@ -278,7 +264,6 @@ class elFinderConnector
if ($sendData) {
if ($toEnd || elFinder::isSeekableUrl($fp)) {
// PHP < 5.6 has a bug of fpassthru
// see https://bugs.php.net/bug.php?id=66736
if (version_compare(PHP_VERSION, '5.6', '<')) {
file_put_contents('php://output', $fp);
@ -352,7 +337,6 @@ class elFinderConnector
*/
public static function outputJson($data)
{
// send header
$header = isset($data['header']) ? $data['header'] : self::$contentType;
self::sendHeader($header);
@ -367,7 +351,6 @@ class elFinderConnector
$out = json_encode($data);
}
// clear output buffer
while (ob_get_level() && ob_end_clean()) {
}

View File

@ -1,4 +1,4 @@
<?php
<?php
use League\Flysystem\Filesystem;
use League\Flysystem\Adapter\Local;
@ -53,7 +53,6 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
if ($this->options['icon'] === true) {
unset($this->options['icon']);
}
// enable command archive
$this->options['useRemoteArchive'] = true;
}
return $res;
@ -316,7 +315,6 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
$service = new \Google_Service_Drive($client);
// If path is not set, use the root
if (!isset($opts['path']) || $opts['path'] === '') {
$opts['path'] = 'root';
}
@ -344,7 +342,6 @@ class elFinderVolumeFlysystemGoogleDriveNetmount extends ExtDriver
}
if ($res = parent::mount($opts)) {
// update access_token of session data
if ($creds) {
$netVolumes = $this->session->get('netvolume');
$netVolumes[$this->netMountKey]['access_token'] = array_merge($netVolumes[$this->netMountKey]['access_token'], $creds);

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder Plugin Abstract
@ -51,7 +51,6 @@ class elFinderPlugin
return false;
}
// check post var 'contentSaveId' to disable this plugin
if ($elfinder && !empty($opts['disableWithContentSaveId'])) {
$session = $elfinder->getSession();
$urlContentSaveIds = $session->get('urlContentSaveIds', array());
@ -64,7 +63,6 @@ class elFinderPlugin
}
if (isset($opts['onDropWith']) && !is_null($opts['onDropWith'])) {
// plugin disabled by default, enabled only if given key is pressed
if (isset($_REQUEST['dropWith']) && $_REQUEST['dropWith']) {
$onDropWith = $opts['onDropWith'];
$action = (int)$_REQUEST['dropWith'];
@ -82,7 +80,6 @@ class elFinderPlugin
}
if (isset($opts['offDropWith']) && !is_null($opts['offDropWith']) && isset($_REQUEST['dropWith'])) {
// plugin enabled by default, disabled only if given key is pressed
$offDropWith = $opts['offDropWith'];
$action = (int)$_REQUEST['dropWith'];
if (!is_array($offDropWith)) {

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder - file manager for web.
@ -126,7 +126,6 @@ class elFinderSession implements elFinderSessionInterface
{
set_error_handler(array($this, 'session_start_error'), E_NOTICE | E_WARNING);
// apache2 SAPI has a bug of session cookie register
// see https://bugs.php.net/bug.php?id=75554
// see https://github.com/php/php-src/pull/3231
if ($this->fixCookieRegist === true) {
@ -223,7 +222,6 @@ class elFinderSession implements elFinderSessionInterface
{
if ($this->started) {
if ($this->fixCookieRegist === true) {
// regist cookie only once for apache2 SAPI
$cParm = session_get_cookie_params();
if ($this->opts['cookieParams'] && is_array($this->opts['cookieParams'])) {
$cParm = array_merge($cParm, $this->opts['cookieParams']);

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder - file manager for web.

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* Simple elFinder driver for BoxDrive
@ -114,9 +114,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
$this->options['mimeDetect'] = 'internal';
}
/*********************************************************************/
/* ORIGINAL FUNCTIONS */
/*********************************************************************/
/**
* Get Parent ID, Item ID, Parent Path as an array from path.
@ -189,7 +186,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
);
curl_setopt_array($curl, array(
// General options.
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $fields,
@ -238,7 +234,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
if ($aTokenFile && is_file($aTokenFile)) {
$lock = $aTokenFile . '.lock';
if (file_exists($lock)) {
// Probably updating on other instance
return true;
}
touch($lock);
@ -257,7 +252,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
$curl = curl_init();
curl_setopt_array($curl, array(
// General options.
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true, // i am sending post data
CURLOPT_POSTFIELDS => http_build_query($postData),
@ -303,8 +297,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
file_put_contents($aTokenFile, json_encode($token), LOCK_EX);
$this->options['accessToken'] = $json;
} else if (!empty($this->options['netkey'])) {
// OAuth2 refresh token can be used only once,
// so update it if it is the same as the token file
if ($aTokenFile && is_file($aTokenFile)) {
if ($_token = json_decode(file_get_contents($aTokenFile))) {
if ($_token->data->refresh_token === $refresh_token) {
@ -313,7 +305,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
}
}
$this->options['accessToken'] = $json;
// update session value
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'accessToken', $json);
$this->session->set('BoxTokens', $token);
} else {
@ -338,7 +329,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
$curl = curl_init();
$defaultOptions = array(
// General options.
CURLOPT_RETURNTRANSFER => true,
);
@ -436,7 +426,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
throw new \Exception($errmsg);
}
// make catch
if ($decodeOrParent && $decodeOrParent !== true) {
$raws = null;
if (isset($decoded->entries)) {
@ -610,7 +599,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
CURLOPT_CUSTOMREQUEST => 'DELETE',
));
//unlink or delete File or Folder in the Parent
$this->_bd_curlExec($curl);
} catch (Exception $e) {
return $this->setError('Box error: ' . $e->getMessage());
@ -652,9 +640,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
return (empty($this->token->initialToken)? md5($this->options['client_id'] . (!empty($this->token->data->refresh_token)? $this->token->data->refresh_token : $this->token->data->access_token)) : $this->token->initialToken);
}
/*********************************************************************/
/* OVERRIDE FUNCTIONS */
/*********************************************************************/
/**
* Prepare
@ -702,7 +687,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
if ($code) {
try {
if (!empty($options['id'])) {
// Obtain the token using the code received by the Box.com API
$this->session->set('BoxTokens',
$this->_bd_obtainAccessToken($options['client_id'], $options['client_secret'], $code));
@ -876,9 +860,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
return $res;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
@ -908,7 +889,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
throw new Exception('Required option `accessToken` is invalid JSON.');
}
// make net mount key
if (empty($this->options['netkey'])) {
$this->netMountKey = $this->_bd_getInitialToken();
} else {
@ -929,7 +909,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
}
}
} else if (is_file($this->aTokenFile)) {
// If the refresh token is the same as the permanent volume
$this->token = json_decode(file_get_contents($this->aTokenFile));
}
}
@ -947,13 +926,11 @@ class elFinderVolumeBox extends elFinderVolumeDriver
if ($error) {
if (empty($this->options['netkey']) && $this->tmbPrefix) {
// for delete thumbnail
$this->netunmount(null, null);
}
return false;
}
// normalize root path
if ($this->options['path'] == 'root') {
$this->options['path'] = '/';
}
@ -977,13 +954,10 @@ class elFinderVolumeBox extends elFinderVolumeDriver
$this->rootName = $this->options['alias'];
// This driver dose not support `syncChkAsTs`
$this->options['syncChkAsTs'] = false;
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
// enable command archive
$this->options['useRemoteArchive'] = true;
return true;
@ -999,15 +973,11 @@ class elFinderVolumeBox extends elFinderVolumeDriver
{
parent::configure();
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
}
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection.
@ -1032,9 +1002,7 @@ class elFinderVolumeBox extends elFinderVolumeDriver
{
list(, $name, $parent) = $this->_bd_splitPath($path);
// We can not use it because the search of Box.com there is a time lag.
// ref. https://docs.box.com/reference#searching-for-content
// > Note: If an item is added to Box then it becomes accessible through the search endpoint after ten minutes.
/***
* $url = self::API_URL.'/search?limit=1&offset=0&content_types=name&ancestor_folder_ids='.rawurlencode($pid)
@ -1048,7 +1016,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
$phash = $this->encode($parent);
// do not recursive search
$searchExDirReg = $this->options['searchExDirReg'];
$this->options['searchExDirReg'] = '/.*/';
$search = $this->search($name, array(), $phash);
@ -1199,9 +1166,7 @@ class elFinderVolumeBox extends elFinderVolumeDriver
$name = $this->tmbname($stat);
$tmb = $this->tmbPath . DIRECTORY_SEPARATOR . $name;
// copy image into tmbPath so some drivers does not store files on local fs
if (!$data = $this->_bd_getThumbnail($path)) {
// try get full contents as fallback
if (!$data = $this->_getContents($path)) {
return false;
}
@ -1217,13 +1182,11 @@ class elFinderVolumeBox extends elFinderVolumeDriver
}
$result = true;
/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png');
} else {
if ($this->options['tmbCrop']) {
/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize)) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
}
@ -1299,7 +1262,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
return parent::getContentUrl($hash, $options);
}
if (!empty($options['temporary'])) {
// try make temporary file
$url = parent::getContentUrl($hash, $options);
if ($url) {
return $url;
@ -1319,7 +1281,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
CURLOPT_POSTFIELDS => json_encode($params),
));
$res = $this->_bd_curlExec($curl, true, array(
// The data is sent as JSON as per Box documentation.
'Content-Type: application/json',
));
@ -1331,7 +1292,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
return '';
}
/*********************** paths/urls *************************/
/**
* Return parent directory path.
@ -1452,7 +1412,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
return $path == $parent || strpos($path, $parent . '/') === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -1544,7 +1503,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -1581,7 +1539,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
'headers' => array('Authorization: Bearer ' . $this->token->data->access_token),
);
// to support range request
if (func_num_args() > 2) {
$opts = func_get_arg(2);
} else {
@ -1614,7 +1571,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
}
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed.
@ -1639,7 +1595,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
CURLOPT_POSTFIELDS => json_encode($params),
));
//create the Folder in the Parent
$folder = $this->_bd_curlExec($curl, $path);
return $this->_joinPath($path, $folder->id);
@ -1689,7 +1644,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
protected function _copy($source, $targetDir, $name)
{
try {
//Set the Parent id
list(, $parentId) = $this->_bd_splitPath($targetDir);
list(, $srcId) = $this->_bd_splitPath($source);
@ -1707,7 +1661,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
CURLOPT_POSTFIELDS => json_encode($data),
));
//copy File in the Parent
$result = $this->_bd_curlExec($curl, $targetDir);
if (isset($result->id)) {
@ -1738,14 +1691,11 @@ class elFinderVolumeBox extends elFinderVolumeDriver
protected function _move($source, $targetDir, $name)
{
try {
//moving and renaming a file or directory
//Set new Parent and remove old parent
list(, $parentId) = $this->_bd_splitPath($targetDir);
list(, $itemId) = $this->_bd_splitPath($source);
$srcItem = $this->_bd_getRawItem($source);
//rename or move file or folder in destination target
$properties = array('name' => $name, 'parent' => array('id' => $parentId));
$type = ($srcItem->type === 'folder') ? 'folders' : 'files';
@ -1759,7 +1709,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
));
$result = $this->_bd_curlExec($curl, $targetDir, array(
// The data is sent as JSON as per Box documentation.
'Content-Type: application/json',
));
@ -1830,10 +1779,8 @@ class elFinderVolumeBox extends elFinderVolumeDriver
}
try {
//Create or Update a file
$metaDatas = stream_get_meta_data($fp);
$tmpFilePath = isset($metaDatas['uri']) ? $metaDatas['uri'] : '';
// remote contents
if (!$tmpFilePath || empty($metaDatas['seekable'])) {
$tmpHandle = $this->tmpfile();
stream_copy_to_stream($fp, $tmpHandle);
@ -1842,11 +1789,9 @@ class elFinderVolumeBox extends elFinderVolumeDriver
}
if ($itemId === '') {
//upload or create new file in destination target
$properties = array('name' => $name, 'parent' => array('id' => $parentId));
$url = self::UPLOAD_URL . '/files/content';
} else {
//update existing file in destination target
$properties = array('name' => $name);
$url = self::UPLOAD_URL . '/files/' . $itemId . '/content';
}
@ -1924,7 +1869,6 @@ class elFinderVolumeBox extends elFinderVolumeDriver
**/
protected function _checkArchivers()
{
// die('Not yet implemented. (_checkArchivers)');
return array();
}

View File

@ -1,4 +1,4 @@
<?php
<?php
elFinder::$netDrivers['dropbox'] = 'Dropbox';
@ -85,11 +85,9 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
*/
public function __construct() {
// check with composer
$this->dropbox_phpFound = class_exists('Dropbox_API');
if (! $this->dropbox_phpFound) {
// check with pear
if (include_once 'Dropbox/autoload.php') {
$this->dropbox_phpFound = in_array('Dropbox_autoload', spl_autoload_functions());
}
@ -148,7 +146,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
$this->oauth = new Dropbox_OAuth_PHP($options['consumerKey'], $options['consumerSecret']);
} else {
if (! class_exists('HTTP_OAuth_Consumer')) {
// We're going to try to load in manually
include 'HTTP/OAuth/Consumer.php';
}
if (class_exists('HTTP_OAuth_Consumer', false)) {
@ -164,7 +161,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
if ($options['pass'] === 'init') {
$html = '';
if ($sessionToken = $this->session->get('DropboxTokens')) {
// token check
try {
list(, $accessToken, $accessTokenSecret) = $sessionToken;
$this->oauth->setToken($accessToken, $accessTokenSecret);
@ -179,7 +175,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
}
}
if (! $html) {
// get customdata
$cdata = '';
$innerKeys = array('cmd', 'host', 'options', 'pass', 'protocol', 'user');
$this->ARGS = $_SERVER['REQUEST_METHOD'] === 'POST'? $_POST : $_GET;
@ -259,9 +254,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return true;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
@ -287,7 +279,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
$this->options['metaCachePath'] = ELFINDER_DROPBOX_META_CACHE_PATH;
}
// make net mount key
$this->netMountKey = md5(join('-', array('dropbox', $this->options['path'])));
if (! $this->oauth) {
@ -298,7 +289,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
$this->oauth = new Dropbox_OAuth_PHP($this->options['consumerKey'], $this->options['consumerSecret']);
} else {
if (! class_exists('HTTP_OAuth_Consumer')) {
// We're going to try to load in manually
include 'HTTP/OAuth/Consumer.php';
}
if (class_exists('HTTP_OAuth_Consumer', false)) {
@ -312,7 +302,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return $this->setError('OAuth extension not loaded.');
}
// normalize root path
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
if (empty($this->options['alias'])) {
@ -329,7 +318,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return $this->setError('Dropbox error: '.$e->getMessage());
}
// user
if (empty($this->options['dropboxUid'])) {
try {
$res = $this->dropbox->getAccountInfo();
@ -368,13 +356,10 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return $this->setError('Cache dirctory (metaCachePath or tmp) is require.');
}
// setup PDO
if (! $this->options['PDO_DSN']) {
$this->options['PDO_DSN'] = 'sqlite:'.$this->metaCache.DIRECTORY_SEPARATOR.'.elFinder_dropbox_db_'.md5($this->dropboxUid.$this->options['consumerSecret']);
}
// DataBase table name
$this->DB_TableName = $this->options['PDO_DBName'];
// DataBase check or make table
try {
$this->DB = new PDO($this->options['PDO_DSN'], $this->options['PDO_User'], $this->options['PDO_Pass'], $this->options['PDO_Options']);
if (! $this->checkDB()) {
@ -397,10 +382,8 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
$this->options['syncChkAsTs'] = true;
}
if ($this->options['syncChkAsTs']) {
// 'tsPlSleep' minmum 5 sec
$this->options['tsPlSleep'] = max(5, $this->options['tsPlSleep']);
} else {
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
}
@ -429,10 +412,8 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
private function checkDB() {
$res = $this->query('SELECT * FROM sqlite_master WHERE type=\'table\' AND name=\''.$this->DB_TableName.'\'');
if ($res && isset($_REQUEST['init'])) {
// check is index(nameidx) UNIQUE?
$chk = $this->query('SELECT sql FROM sqlite_master WHERE type=\'index\' and name=\'nameidx\'');
if (!$chk || strpos(strtoupper($chk[0]), 'UNIQUE') === false) {
// remake
$this->DB->exec('DROP TABLE '.$this->DB_TableName);
$res = false;
}
@ -490,9 +471,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
. ', isdir=' . ($dat['is_dir']? 1 : 0)
. ' where path='.$this->DB->quote(strtolower($this->_dirname($path))).' and fname='.$this->DB->quote(strtolower($this->_basename($path))));
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection
@ -575,7 +553,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
}
} while (! empty($_info['has_more']));
// update time stamp of parent holder
foreach ($ptimes as $_p => $_t) {
if ($praw = $this->getDBdat($_p)) {
$_update = false;
@ -791,7 +768,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
$name = $this->tmbname($stat);
$tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$name;
// copy image into tmbPath so some drivers does not store files on local fs
if (! $data = $this->getThumbnail($path, $this->options['getTmbSize'])) {
return false;
}
@ -807,7 +783,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return false;
}
/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );
@ -815,7 +790,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
if ($this->options['tmbCrop']) {
/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize) ) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
}
@ -958,7 +932,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return $res;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path
@ -1051,7 +1024,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return $path == $parent || strpos($path, $parent.'/') === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -1072,7 +1044,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
* @author Dmitry (dio) Levashov
**/
protected function _stat($path) {
//if (!empty($this->ARGS['reload']) && isset($this->ARGS['target']) && strpos($this->ARGS['target'], $this->id) === 0) {
if ($this->isMyReload()) {
$this->deltaCheck();
}
@ -1121,7 +1092,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -1195,7 +1165,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
}
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed
@ -1392,7 +1361,6 @@ class elFinderVolumeDropbox extends elFinderVolumeDriver {
* @return array
**/
protected function _checkArchivers() {
// die('Not yet implemented. (_checkArchivers)');
return array();
}

View File

@ -1,4 +1,4 @@
<?php
<?php
use Kunnu\Dropbox\Dropbox;
use Kunnu\Dropbox\DropboxApp;
@ -72,8 +72,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
'rootCssClass' => 'elfinder-navbar-root-dropbox',
'publishPermission' => [
'requested_visibility' => 'public',
//'link_password' => '',
//'expires' => '',
],
'getThumbSize' => 'medium', // Available sizes: 'thumb', 'small', 'medium', 'large', 'huge'
];
@ -81,9 +79,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
$this->options['mimeDetect'] = 'internal';
}
/*********************************************************************/
/* ORIGINAL FUNCTIONS */
/*********************************************************************/
/**
* Get Parent ID, Item ID, Parent Path as an array from path.
@ -151,7 +146,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
$stat = [];
$isFolder = false;
if ($raw === true) {
// root folder
$isFolder = true;
$stat['name'] = '';
$stat['iid'] = '0';
@ -262,9 +256,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return isset($res['oauth2_token']) ? $res['oauth2_token'] : false;
}
/*********************************************************************/
/* EXTENDED FUNCTIONS */
/*********************************************************************/
/**
* Prepare
@ -483,9 +474,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return true;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare Dropbox connection
@ -518,7 +506,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
}
try {
// make net mount key for network mount
$aToken = $this->options['access_token'];
$this->netMountKey = md5($aToken . '-' . $this->options['path']);
@ -526,7 +513,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
if ($this->needOnline && !$this->service) {
$app = new DropboxApp($this->options['app_key'], $this->options['app_secret'], $aToken);
$this->service = new Dropbox($app);
// to check access_token
$this->service->getCurrentAccount();
}
} catch (DropboxClientException $e) {
@ -543,7 +529,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return $this->setError($errors);
}
// normalize root path
$this->options['path'] = strtolower($this->options['path']);
if ($this->options['path'] == 'root') {
$this->options['path'] = '/';
@ -569,13 +554,10 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
$this->tmp = $tmp;
}
// This driver dose not support `syncChkAsTs`
$this->options['syncChkAsTs'] = false;
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
// enable command archive
$this->options['useRemoteArchive'] = true;
return true;
@ -591,19 +573,14 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
{
parent::configure();
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
}
if ($this->isMyReload()) {
//$this->_db_getDirectoryData(false);
}
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection.
@ -664,7 +641,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
protected function doSearch($path, $q, $mimes)
{
if (!empty($this->doSearchCurrentQuery['matchMethod']) || $mimes) {
// has custom match method or mimes, use elFinderVolumeDriver::doSearch()
return parent::doSearch($path, $q, $mimes);
}
@ -790,7 +766,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
$name = $this->tmbname($stat);
$tmb = $this->tmbPath . DIRECTORY_SEPARATOR . $name;
// copy image into tmbPath so some drivers does not store files on local fs
if (!$data = $this->_db_getThumbnail($path)) {
return false;
}
@ -806,13 +781,11 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
$result = true;
/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png');
} else {
if ($this->options['tmbCrop']) {
/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize)) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
}
@ -875,7 +848,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return parent::getContentUrl($hash, $options);
}
if (!empty($options['temporary'])) {
// try make temporary file
$url = parent::getContentUrl($hash, $options);
if ($url) {
return $url;
@ -933,7 +905,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return $res;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path.
@ -1055,7 +1026,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return $path == $parent || strpos($path, $parent . '/') === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -1150,7 +1120,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -1187,7 +1156,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
'headers' => array('Authorization: Bearer ' . $access_token),
);
// to support range request
if (func_num_args() > 2) {
$opts = func_get_arg(2);
} else {
@ -1218,7 +1186,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
is_resource($fp) && fclose($fp);
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed.
@ -1421,7 +1388,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
$name = '';
$stat = $this->stat($path);
if ($stat) {
// keep real name
$path = $this->_dirname($path);
$name = $stat['name'];
}
@ -1439,7 +1405,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
**/
protected function _checkArchivers()
{
// die('Not yet implemented. (_checkArchivers)');
return [];
}
@ -1466,7 +1431,6 @@ class elFinderVolumeDropbox2 extends elFinderVolumeDriver
protected function _unpack($path, $arc)
{
die('Not yet implemented. (_unpack)');
//return false;
}
/**

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* Simple elFinder driver for FTP
@ -149,9 +149,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return $options;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
@ -176,21 +173,18 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$this->options['path'] = '/';
}
// make ney mount key
$this->netMountKey = md5(join('-', array('ftp', $this->options['host'], $this->options['port'], $this->options['path'], $this->options['user'])));
if (!function_exists('ftp_connect')) {
return $this->setError('FTP extension not loaded.');
}
// remove protocol from host
$scheme = parse_url($this->options['host'], PHP_URL_SCHEME);
if ($scheme) {
$this->options['host'] = substr($this->options['host'], strlen($scheme) + 3);
}
// normalize root path
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
if (empty($this->options['alias'])) {
@ -236,7 +230,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$this->tmp = $tmp;
}
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
}
@ -251,7 +244,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$this->disabled[] = 'extract';
}
// echo $this->tmp;
}
@ -279,7 +271,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return $this->setError('Unable to login into ' . $this->options['host'] . $withSSL);
}
// try switch utf8 mode
if ($this->encoding) {
ftp_raw($this->connect, 'OPTS UTF8 OFF');
} else {
@ -290,11 +281,8 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$this->isPureFtpd = stripos(implode(' ', $help), 'Pure-FTPd') !== false;
if (!$this->isPureFtpd) {
// switch off extended passive mode - may be usefull for some servers
// this command, for pure-ftpd, doesn't work and takes a timeout in some pure-ftpd versions
ftp_raw($this->connect, 'epsv4 off');
}
// enter passive mode if required
$pasv = ($this->options['mode'] == 'passive');
if (!ftp_pasv($this->connect, $pasv)) {
if ($pasv) {
@ -302,14 +290,12 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
}
}
// enter root folder
if (!ftp_chdir($this->connect, $this->root)
|| $this->root != ftp_pwd($this->connect)) {
$this->umount();
return $this->setError('Unable to open root folder.');
}
// check for MLST support
$features = ftp_raw($this->connect, 'FEAT');
if (!is_array($features)) {
$this->umount();
@ -348,9 +334,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return $res;
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection
@ -405,7 +388,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
if (preg_match('|(.+)\-\>(.+)|', $name, $m)) {
$name = trim($m[1]);
// check recursive processing
if ($this->cacheDirTarget && $this->_joinPath($base, $name) !== $this->cacheDirTarget) {
return array();
}
@ -426,7 +408,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
}
if (is_numeric($info[5]) && !$info[6] && !$info[7]) {
// by normalizeRawWindows()
$stat['ts'] = $info[5];
} else {
$stat['ts'] = strtotime($info[5] . ' ' . $info[6] . ' ' . $info[7]);
@ -445,12 +426,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$stat['owner'] = $info[2];
$stat['group'] = $info[3];
$stat['perm'] = substr($info[0], 1);
//
// if not exists owner in LS ftp ==> isowner = true
// if is defined as option : 'owner' => true isowner = true
//
// if exist owner in LS ftp and 'owner' => False isowner = result of owner(file) == user(logged with ftp)
//
$stat['isowner'] = isset($stat['owner']) ? ($this->options['owner'] ? true : ($stat['owner'] == $this->options['user'])) : true;
}
@ -552,7 +527,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
foreach ($list as $stat) {
$p = $prefix . $stat['name'];
if (isset($stat['target'])) {
// stat later
$targets[$stat['name']] = $stat['target'];
} else {
$stat = $this->updateCache($p, $stat);
@ -564,7 +538,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
}
}
}
// stat link targets
foreach ($targets as $name => $target) {
$stat = array();
$stat['name'] = $name;
@ -630,7 +603,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return strpos($this->mimetype($path), 'text/') === 0 ? FTP_ASCII : FTP_BINARY;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path
@ -688,7 +660,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
if (empty($path)) {
$path = '.';
}
// path must be start with /
$path = preg_replace('|^\.\/?|', $this->separator, $path);
$path = preg_replace('/^([^\/])/', "/$1", $path);
@ -746,7 +717,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
if (strpos($path, $this->root) === 0) {
return ltrim(substr($path, strlen($this->root)), $this->separator);
} else {
// for link
return $path;
}
}
@ -766,7 +736,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return $this->root;
} else {
if ($path[0] === $this->separator) {
// for link
return $path;
} else {
return $this->_joinPath($this->root, $path);
@ -801,7 +770,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return $path == $parent || strpos($path, rtrim($parent, $this->separator) . $this->separator) === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -893,7 +861,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$stat = $this->convEncIn(isset($this->cache[$outPath]) ? $this->cache[$outPath] : array());
if (!$this->mounted) {
// dispose incomplete cache made by calling `stat` by 'startPath' option
$this->cache = array();
}
return $stat;
@ -957,7 +924,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return array();
}
// do not use MLST to get stat of symlink
if ($stat['mime'] === 'symlink') {
$this->MLSTsupprt = false;
$res = $this->_stat($path);
@ -1005,11 +971,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
}
$stat['perm'] = trim($stat['perm']);
//
// if not exists owner in LS ftp ==> isowner = true
// if is defined as option : 'owner' => true isowner = true
//
// if exist owner in LS ftp and 'owner' => False isowner = result of owner(file) == user(logged with ftp)
$owner_computed = isset($stat['owner']) ? ($this->options['owner'] ? true : ($stat['owner'] == $this->options['user'])) : true;
@ -1083,7 +1044,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -1120,7 +1080,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
*/
protected function _fopen($path, $mode = 'rb')
{
// try ftp stream wrapper
if ($this->options['mode'] === 'passive' && ini_get('allow_url_fopen')) {
$url = ($this->isFTPS ? 'ftps' : 'ftp') . '://' . $this->options['user'] . ':' . $this->options['pass'] . '@' . $this->options['host'] . ':' . $this->options['port'] . $path;
if (strtolower($mode[0]) === 'w') {
@ -1171,7 +1130,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
}
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed
@ -1423,7 +1381,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$localPath = $dir . DIRECTORY_SEPARATOR . $basename;
if (!ftp_get($this->connect, $localPath, $path, FTP_BINARY)) {
//cleanup
$this->rmdirRecursive($dir);
return false;
}
@ -1432,7 +1389,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$this->archiveSize = 0;
// find symlinks and check extracted items
$checkRes = $this->checkExtractItems($dir);
if ($checkRes['symlinks']) {
$this->rmdirRecursive($dir);
@ -1447,13 +1403,11 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$filesToProcess = self::listFilesInDirectory($dir, true);
// no files - extract error ?
if (empty($filesToProcess)) {
$this->rmdirRecursive($dir);
return false;
}
// check max files size
if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
$this->rmdirRecursive($dir);
return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
@ -1461,14 +1415,11 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
$extractTo = $this->extractToNewdir; // 'auto', ture or false
// archive contains one item - extract in archive dir
$name = '';
$src = $dir . DIRECTORY_SEPARATOR . $filesToProcess[0];
if (($extractTo === 'auto' || !$extractTo) && count($filesToProcess) === 1 && is_file($src)) {
$name = $filesToProcess[0];
} else if ($extractTo === 'auto' || $extractTo) {
// for several files - create new directory
// create unique name for directory
$src = $dir;
$splits = elFinder::splitFileExtention(basename($path));
$name = $splits[0];
@ -1570,7 +1521,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
*/
protected function _archive($dir, $files, $name, $arc)
{
// get current directory
$cwd = getcwd();
$tmpDir = $this->tempDir();
@ -1578,9 +1528,7 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
return false;
}
//download data
if (!$this->ftp_download_files($dir, $files, $tmpDir)) {
//cleanup
$this->rmdirRecursive($tmpDir);
return false;
}
@ -1593,7 +1541,6 @@ class elFinderVolumeFTP extends elFinderVolumeDriver
}
}
//cleanup
if (!$this->rmdirRecursive($tmpDir)) {
return false;
}

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* Simple elFinder driver for GoogleDrive
@ -138,9 +138,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$this->options['mimeDetect'] = 'internal';
}
/*********************************************************************/
/* ORIGINAL FUNCTIONS */
/*********************************************************************/
/**
* Get Parent ID, Item ID, Parent Path as an array from path.
@ -330,7 +327,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$root = '';
if ($this->root === '/') {
// get root id
if ($res = $this->_gd_getFile('/', 'id')) {
$root = $res->getId();
}
@ -593,7 +589,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$byteCount = 0;
$giantChunk = '';
while (!feof($handle)) {
// fread will never return more than 8192 bytes if the stream is read buffered and it does not represent a plain file
$chunk = fread($handle, 8192);
$byteCount += strlen($chunk);
$giantChunk .= $chunk;
@ -605,9 +600,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return $giantChunk;
}
/*********************************************************************/
/* EXTENDED FUNCTIONS */
/*********************************************************************/
/**
* Prepare
@ -865,9 +857,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return empty($srcFile) ? false : $this->_gd_parseRaw($srcFile[0]);
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
@ -909,7 +898,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
if (!$serviceAccountConfig) {
$aTokenFile = '';
if ($this->options['refresh_token']) {
// permanent mount
$aToken = $this->options['refresh_token'];
$this->options['access_token'] = '';
$tmp = elFinder::getStaticVar('commonTempPath');
@ -923,7 +911,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
}
}
} else {
// make net mount key for network mount
if (is_array($this->options['access_token'])) {
$aToken = !empty($this->options['access_token']['refresh_token'])
? $this->options['access_token']['refresh_token']
@ -997,7 +984,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return $this->setError($errors);
}
// normalize root path
if ($this->options['path'] == 'root') {
$this->options['path'] = '/';
}
@ -1028,10 +1014,8 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$this->tmp = $tmp;
}
// This driver dose not support `syncChkAsTs`
$this->options['syncChkAsTs'] = false;
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
if ($this->options['useGoogleTmb']) {
@ -1039,7 +1023,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$this->options['tmbPath'] = '';
}
// enable command archive
$this->options['useRemoteArchive'] = true;
return true;
@ -1054,7 +1037,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
{
parent::configure();
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
}
@ -1064,9 +1046,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
}
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection.
@ -1136,7 +1115,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
protected function doSearch($path, $q, $mimes)
{
if (!empty($this->doSearchCurrentQuery['matchMethod'])) {
// has custom match method use elFinderVolumeDriver::doSearch()
return parent::doSearch($path, $q, $mimes);
}
@ -1310,7 +1288,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$name = $this->tmbname($stat);
$tmb = $this->tmbPath . DIRECTORY_SEPARATOR . $name;
// copy image into tmbPath so some drivers does not store files on local fs
if (!$data = $this->_gd_getThumbnail($path)) {
return false;
}
@ -1326,13 +1303,11 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return false;
}
/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png');
} else {
if ($this->options['tmbCrop']) {
/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize)) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
}
@ -1387,7 +1362,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return parent::getContentUrl($hash, $options);
}
if (!empty($options['temporary'])) {
// try make temporary file
$url = parent::getContentUrl($hash, $options);
if ($url) {
return $url;
@ -1421,7 +1395,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return $res;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path.
@ -1548,7 +1521,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return $path == $parent || strpos($path, $parent . '/') === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -1646,7 +1618,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -1697,7 +1668,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
'headers' => array('Authorization: Bearer ' . $access_token),
);
// to support range request
if (func_num_args() > 2) {
$opts = func_get_arg(2);
} else {
@ -1732,7 +1702,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
}
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed.
@ -1755,7 +1724,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$file->setMimeType(self::DIRMIME);
$file->setParents([$parentId]);
//create the Folder in the Parent
$obj = $this->service->files->create($file);
if ($obj instanceof Google_Service_Drive_DriveFile) {
@ -1818,7 +1786,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
$file = new \Google_Service_Drive_DriveFile();
$file->setName($name);
//Set the Parent id
list(, $parentId) = $this->_gd_splitPath($targetDir);
$file->setParents([$parentId]);
@ -1850,11 +1817,9 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
list($removeParents, $itemId) = $this->_gd_splitPath($source);
$target = $this->_normpath($targetDir . '/' . $itemId);
try {
//moving and renaming a file or directory
$files = new \Google_Service_Drive_DriveFile();
$files->setName($name);
//Set new Parent and remove old parent
list(, $addParents) = $this->_gd_splitPath($targetDir);
$opts = ['addParents' => $addParents, 'removeParents' => $removeParents];
@ -1976,7 +1941,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
}
}
// set chunk size (max: 100MB)
$chunkSizeBytes = 100 * 1024 * 1024;
if ($size > 0) {
$memory = elFinder::getIniBytes('memory_limit');
@ -1987,7 +1951,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
if ($size > $chunkSizeBytes) {
$client = $this->client;
// Call the API with the media upload, defer so it doesn't immediately return.
$client->setDefer(true);
if ($mode === 'insert') {
$request = $this->service->files->create($file, [
@ -1999,22 +1962,14 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
]);
}
// Create a media file upload to represent our upload process.
$media = new Google_Http_MediaFileUpload($client, $request, $mime, null, true, $chunkSizeBytes);
$media->setFileSize($size);
// Upload the various chunks. $status will be false until the process is
// complete.
$status = false;
while (!$status && !feof($fp)) {
elFinder::checkAborted();
// read until you get $chunkSizeBytes from TESTFILE
// fread will never return more than 8192 bytes if the stream is read buffered and it does not represent a plain file
// An example of a read buffered file is when reading from a URL
$chunk = $this->_gd_readFileChunk($fp, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
// The final value of $status will be the data from the API for the object
// that has been uploaded.
if ($status !== false) {
$obj = $status;
}
@ -2099,7 +2054,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
**/
protected function _checkArchivers()
{
// die('Not yet implemented. (_checkArchivers)');
return [];
}
@ -2126,7 +2080,6 @@ class elFinderVolumeGoogleDrive extends elFinderVolumeDriver
protected function _unpack($path, $arc)
{
die('Not yet implemented. (_unpack)');
//return false;
}
/**

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder driver for Volume Group.
@ -47,11 +47,7 @@ class elFinderVolumeGroup extends elFinderVolumeDriver
);
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/*********************** paths/urls *************************/
/**
* @inheritdoc
@ -119,7 +115,6 @@ class elFinderVolumeGroup extends elFinderVolumeDriver
/***************** file stat ********************/
/**
* {@inheritDoc}
@ -156,7 +151,6 @@ class elFinderVolumeGroup extends elFinderVolumeDriver
{
return false;
}
/******************** file/dir content *********************/
/**
* {@inheritDoc}
@ -190,7 +184,6 @@ class elFinderVolumeGroup extends elFinderVolumeDriver
return true;
}
/******************** file/dir manipulations *************************/
/**
* {@inheritDoc}

View File

@ -1,6 +1,5 @@
<?php
<?php
// Implement similar functionality in PHP 5.2 or 5.3
// http://php.net/manual/class.recursivecallbackfilteriterator.php#110974
if (!class_exists('RecursiveCallbackFilterIterator', false)) {
class RecursiveCallbackFilterIterator extends RecursiveFilterIterator
@ -84,9 +83,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$this->options['statCorrector'] = null; // callable to correct stat data `function(&$stat, $path, $statOwner, $volumeDriveInstance){}`
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare driver before mount volume.
@ -96,14 +92,12 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
**/
protected function init()
{
// Normalize directory separator for windows
if (DIRECTORY_SEPARATOR !== '/') {
foreach (array('path', 'tmbPath', 'tmpPath', 'quarantine') as $key) {
if (!empty($this->options[$key])) {
$this->options[$key] = str_replace('/', DIRECTORY_SEPARATOR, $this->options[$key]);
}
}
// PHP >= 7.1 Supports UTF-8 path on Windows
if (version_compare(PHP_VERSION, '7.1', '>=')) {
$this->options['encoding'] = '';
$this->options['locale'] = '';
@ -112,7 +106,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
if (!$cwd = getcwd()) {
return $this->setError('elFinder LocalVolumeDriver requires a result of getcwd().');
}
// detect systemRoot
if (!isset($this->options['systemRoot'])) {
if ($cwd[0] === DIRECTORY_SEPARATOR || $this->root[0] === DIRECTORY_SEPARATOR) {
$this->systemRoot = DIRECTORY_SEPARATOR;
@ -133,7 +126,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
if (is_null($this->options['syncCheckFunc'])) {
$this->options['syncCheckFunc'] = array($this, 'localFileSystemInotify');
}
// check 'statCorrector'
if (empty($this->options['statCorrector']) || !is_callable($this->options['statCorrector'])) {
$this->options['statCorrector'] = null;
}
@ -153,7 +145,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$hiddens = array();
$root = $this->stat($this->root);
// check thumbnails path
if (!empty($this->options['tmbPath'])) {
if (strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false) {
$hiddens['tmb'] = $this->options['tmbPath'];
@ -162,7 +153,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$this->options['tmbPath'] = $this->_normpath($this->options['tmbPath']);
}
}
// check temp path
if (!empty($this->options['tmpPath'])) {
if (strpos($this->options['tmpPath'], DIRECTORY_SEPARATOR) === false) {
$hiddens['temp'] = $this->options['tmpPath'];
@ -171,7 +161,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$this->options['tmpPath'] = $this->_normpath($this->options['tmpPath']);
}
}
// check quarantine path
if (!empty($this->options['quarantine'])) {
if (strpos($this->options['quarantine'], DIRECTORY_SEPARATOR) === false) {
$hiddens['quarantine'] = $this->options['quarantine'];
@ -183,12 +172,10 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
parent::configure();
// check tmbPath
if (!$this->tmbPath && isset($hiddens['tmb'])) {
unset($hiddens['tmb']);
}
// if no thumbnails url - try detect it
if ($root['read'] && !$this->tmbURL && $this->URL) {
if (strpos($this->tmbPath, $this->root) === 0) {
$this->tmbURL = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root) + 1));
@ -198,7 +185,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
}
}
// set $this->tmp by options['tmpPath']
$this->tmp = '';
if (!empty($this->options['tmpPath'])) {
if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], $this->options['dirMode'], true)) && is_writable($this->options['tmpPath'])) {
@ -213,7 +199,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$this->tmp = $tmp;
}
// check quarantine dir
$this->quarantine = '';
if (!empty($this->options['quarantine'])) {
if ((is_dir($this->options['quarantine']) || mkdir($this->options['quarantine'], $this->options['dirMode'], true)) && is_writable($this->options['quarantine'])) {
@ -283,31 +268,22 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$cmd = $inotifywait . ' ' . escapeshellarg($path) . ' -t ' . $standby . ' -e moved_to,moved_from,move,close_write,delete,delete_self';
$this->procExec($cmd, $o, $r);
if ($r === 0) {
// changed
clearstatcache();
if (file_exists($path)) {
$mtime = filemtime($path); // error on busy?
return $mtime ? $mtime : time();
} else {
// target was removed
return 0;
}
} else if ($r === 2) {
// not changed (timeout)
return $compare;
}
// error
// cache to $_SESSION
$this->sessionCache['localFileSystemInotify_disable'] = true;
$this->session->set($this->id, $this->sessionCache);
return false;
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/*********************** paths/urls *************************/
/**
* Return parent directory path
@ -431,7 +407,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
if (strpos($path, $this->root) === 0) {
return ltrim(substr($path, strlen($this->root)), DIRECTORY_SEPARATOR);
} else {
// for link
return $path;
}
}
@ -495,7 +470,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
/***************** file stat ********************/
/**
* Return stat for given path.
@ -524,7 +498,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
return $stat;
}
//Verifies the given path is the root or is inside the root. Prevents directory traveral.
if (!$this->_inpath($path, $this->root)) {
return $stat;
}
@ -576,7 +549,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
if (!isset($stat['mime'])) {
$stat['mime'] = $dir ? 'directory' : $this->mimetype($path);
}
//logical rights first
$stat['read'] = ($linkreadable || $readable) ? null : false;
$stat['write'] = is_writable($path) ? null : false;
@ -709,7 +681,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
? $s[0] . 'x' . $s[1]
: false;
}
/******************** file/dir content *********************/
/**
* Return symlink target file
@ -817,7 +788,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$stat = array_merge($stat, $this->getOwnerStat($uid, $gid));
}
//logical rights first
$stat['read'] = ($linkreadable || $file->isReadable()) ? null : false;
$stat['write'] = $file->isWritable() ? null : false;
$stat['locked'] = $dirWritable ? null : true;
@ -876,7 +846,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
return (is_resource($fp) && fclose($fp));
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed
@ -1029,7 +998,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
if (($isCmdCopy || !rename($uri, $path)) && !copy($uri, $path)) {
return false;
}
// keep timestamp on upload
if ($mtime && $this->ARGS['cmd'] === 'upload') {
touch($path, isset($this->options['keepTimestamp']['upload']) ? $mtime : time());
}
@ -1133,38 +1101,32 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
return false;
}
// insurance unexpected shutdown
register_shutdown_function(array($this, 'rmdirRecursive'), realpath($dir));
chmod($dir, 0777);
// copy in quarantine
if (!is_readable($path) || ($archive && !copy($path, $archive))) {
return false;
}
// extract in quarantine
try {
$this->unpackArchive($path, $arc, $archive ? true : $dir);
} catch(Exception $e) {
return $this->setError($e->getMessage());
}
// get files list
try {
$ls = self::localScandir($dir);
} catch (Exception $e) {
return false;
}
// no files - extract error ?
if (empty($ls)) {
return false;
}
$this->archiveSize = 0;
// find symlinks and check extracted items
$checkRes = $this->checkExtractItems($dir);
if ($checkRes['symlinks']) {
self::localRmdirRecursive($dir);
@ -1177,7 +1139,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
}
}
// check max files size
if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
$this->delTree($dir);
return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
@ -1185,14 +1146,11 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
$extractTo = $this->extractToNewdir; // 'auto', ture or false
// archive contains one item - extract in archive dir
$name = '';
$src = $dir . DIRECTORY_SEPARATOR . $ls[0];
if (($extractTo === 'auto' || !$extractTo) && count($ls) === 1 && is_file($src)) {
$name = $ls[0];
} else if ($extractTo === 'auto' || $extractTo) {
// for several files - create new directory
// create unique name for directory
$src = $dir;
$splits = elFinder::splitFileExtention(basename($path));
$name = $splits[0];
@ -1228,7 +1186,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
return (is_array($result) || file_exists($result)) ? $result : false;
}
//TODO: Add return statement here
return false;
}
@ -1250,7 +1207,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
return $this->makeArchive($dir, $files, $name, $arc);
}
/******************** Over write functions *************************/
/**
* File path of local server side work file path
@ -1291,12 +1247,10 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
protected function isNameExists($path)
{
$exists = file_exists($this->convEncIn($path));
// restore locale
$this->convEncOut();
return $exists ? $this->stat($path) : false;
}
/******************** Over write (Optimized) functions *************************/
/**
* Recursive files search
@ -1313,7 +1267,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
protected function doSearch($path, $q, $mimes)
{
if (!empty($this->doSearchCurrentQuery['matchMethod']) || $this->encoding || !class_exists('FilesystemIterator', false)) {
// has custom match method or non UTF-8, use elFinderVolumeDriver::doSearch()
return parent::doSearch($path, $q, $mimes);
}
@ -1400,8 +1353,6 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver
public function localFileSystemSearchIteratorFilter($file, $key, $iterator)
{
/* @var FilesystemIterator $file */
/* @var RecursiveDirectoryIterator $iterator */
$name = $file->getFilename();
if ($this->doSearchCurrentQuery['excludes']) {
foreach ($this->doSearchCurrentQuery['excludes'] as $exclude) {

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* Simple elFinder driver for MySQL.
@ -86,9 +86,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
$this->options['mimeDetect'] = 'internal';
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare driver before mount volume.
@ -144,10 +141,8 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
$this->updateCache($this->options['path'], $this->_stat($this->options['path']));
// enable command archive
$this->options['useRemoteArchive'] = true;
// check isLocalhost
$this->isLocalhost = $this->options['isLocalhost'] || $this->options['host'] === 'localhost' || $this->options['host'] === '127.0.0.1' || $this->options['host'] === '::1';
return true;
@ -178,7 +173,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
$this->tmpPath = $tmp;
}
// fallback of $this->tmp
if (!$this->tmpPath && $this->tmbPathWritable) {
$this->tmpPath = $this->tmbPath;
}
@ -246,13 +240,9 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
{
$sql = 'INSERT INTO %s (`parent_id`, `name`, `size`, `mtime`, `mime`, `content`, `read`, `write`, `locked`, `hidden`, `width`, `height`) VALUES (\'%s\', \'%s\', 0, %d, \'%s\', \'\', \'%d\', \'%d\', \'%d\', \'%d\', 0, 0)';
$sql = sprintf($sql, $this->tbf, $path, $this->db->real_escape_string($name), time(), $mime, $this->defaults['read'], $this->defaults['write'], $this->defaults['locked'], $this->defaults['hidden']);
// echo $sql;
return $this->query($sql) && $this->db->affected_rows > 0;
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Cache dir contents
@ -357,7 +347,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
protected function doSearch($path, $q, $mimes)
{
if (!empty($this->doSearchCurrentQuery['matchMethod'])) {
// has custom match method use elFinderVolumeDriver::doSearch()
return parent::doSearch($path, $q, $mimes);
}
@ -444,7 +433,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
}
/*********************** paths/urls *************************/
/**
* Return parent directory path
@ -570,7 +558,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
: in_array($parent, $this->getParents($path));
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -655,7 +642,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
return ($stat = $this->stat($path)) && isset($stat['width']) && isset($stat['height']) ? $stat['width'] . 'x' . $stat['height'] : '';
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -720,7 +706,6 @@ class elFinderVolumeMySQL extends elFinderVolumeDriver
}
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* Simple elFinder driver for OneDrive
@ -118,9 +118,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$this->options['mimeDetect'] = 'internal';
}
/*********************************************************************/
/* ORIGINAL FUNCTIONS */
/*********************************************************************/
/**
* Obtains a new access token from OAuth. This token is valid for one hour.
@ -164,7 +161,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
);
curl_setopt_array($curl, array(
// General options.
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $fields,
@ -234,7 +230,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$curl = curl_init();
curl_setopt_array($curl, array(
// General options.
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true, // i am sending post data
CURLOPT_POSTFIELDS => 'client_id=' . urlencode($this->options['client_id'])
@ -287,8 +282,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
file_put_contents($this->aTokenFile, json_encode($token));
$this->options['accessToken'] = $json;
} else if (!empty($this->options['netkey'])) {
// OAuth2 refresh token can be used only once,
// so update it if it is the same as the token file
$aTokenFile = $this->_od_getATokenFile();
if ($aTokenFile && is_file($aTokenFile)) {
if ($_token = json_decode(file_get_contents($aTokenFile))) {
@ -298,7 +291,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
}
}
$this->options['accessToken'] = $json;
// update session value
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'accessToken', $this->options['accessToken']);
$this->session->set('OneDriveTokens', $token);
} else {
@ -349,7 +341,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$curl = curl_init($url);
$defaultOptions = array(
// General options.
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
@ -556,7 +547,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
throw new Exception('Data can not be acquired from the source.');
}
// create upload session
if ($itemId) {
$url = self::API_URL . $itemId . '/createUploadSession';
} else {
@ -713,9 +703,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return (empty($this->token->initialToken)? md5($this->options['client_id'] . (!empty($this->token->data->refresh_token)? $this->token->data->refresh_token : $this->token->data->access_token)) : $this->token->initialToken);
}
/*********************************************************************/
/* OVERRIDE FUNCTIONS */
/*********************************************************************/
/**
* Prepare
@ -763,7 +750,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
if ($code) {
try {
if (!empty($options['id'])) {
// Obtain the token using the code received by the OneDrive API
$this->session->set('OneDriveTokens',
$this->_od_obtainAccessToken($options['client_id'], $options['client_secret'], $code, $options['id']));
@ -843,7 +829,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$this->session->set('OneDriveTokens', (object)array('token' => null));
$offline = '';
// Gets a log in URL with sufficient privileges from the OneDrive API
if (!empty($options['offline'])) {
$offline = ' offline_access';
}
@ -949,9 +934,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return $res;
}
/*********************************************************************/
/* INIT AND CONFIGURE */
/*********************************************************************/
/**
* Prepare FTP connection
@ -981,7 +963,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
throw new Exception('Required option `accessToken` is invalid JSON.');
}
// make net mount key
if (empty($this->options['netkey'])) {
$this->netMountKey = $this->_od_getInitialToken();
} else {
@ -1002,7 +983,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
}
}
} else if (is_file($this->aTokenFile)) {
// If the refresh token is the same as the permanent volume
$this->token = json_decode(file_get_contents($this->aTokenFile));
}
}
@ -1024,13 +1004,11 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
if ($error) {
if (empty($this->options['netkey']) && $this->tmbPrefix) {
// for delete thumbnail
$this->netunmount(null, null);
}
return false;
}
// normalize root path
if ($this->options['path'] == 'root') {
$this->options['path'] = '/';
}
@ -1053,10 +1031,8 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$this->rootName = $this->options['alias'];
// This driver dose not support `syncChkAsTs`
$this->options['syncChkAsTs'] = false;
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
$this->queryOptions = array(
@ -1071,7 +1047,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$this->queryOptions['query']['expand'] = 'thumbnails(select=small)';
}
// enable command archive
$this->options['useRemoteArchive'] = true;
return true;
@ -1086,15 +1061,11 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
{
parent::configure();
// fallback of $this->tmp
if (!$this->tmp && $this->tmbPathWritable) {
$this->tmp = $this->tmbPath;
}
}
/*********************************************************************/
/* FS API */
/*********************************************************************/
/**
* Close opened connection.
@ -1268,7 +1239,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$name = $this->tmbname($stat);
$tmb = $this->tmbPath . DIRECTORY_SEPARATOR . $name;
// copy image into tmbPath so some drivers does not store files on local fs
if (!$data = $this->_od_getThumbnail($path)) {
return false;
}
@ -1284,13 +1254,11 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return false;
}
/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png');
} else {
if ($this->options['tmbCrop']) {
/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize)) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
}
@ -1344,7 +1312,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return parent::getContentUrl($hash, $options);
}
if (!empty($options['temporary'])) {
// try make temporary file
$url = parent::getContentUrl($hash, $options);
if ($url) {
return $url;
@ -1384,7 +1351,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return $res;
}
/*********************** paths/urls *************************/
/**
* Return parent directory path.
@ -1505,7 +1471,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return $path == $parent || strpos($path, $parent . '/') === 0;
}
/***************** file stat ********************/
/**
* Return stat for given path.
* Stat contains following fields:
@ -1577,7 +1542,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return '';
}
//$cache = $this->_od_getFileRaw($path);
if (func_num_args() > 2) {
$args = func_get_arg(2);
} else {
@ -1632,7 +1596,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
return $ret;
}
/******************** file/dir content *********************/
/**
* Return files list in directory.
@ -1669,7 +1632,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
'headers' => array('Authorization: Bearer ' . $this->token->data->access_token),
);
// to support range request
if (func_num_args() > 2) {
$opts = func_get_arg(2);
} else {
@ -1701,7 +1663,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
}
}
/******************** file/dir manipulations *************************/
/**
* Create dir and return created dir path or false on failed.
@ -1734,7 +1695,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
CURLOPT_POSTFIELDS => json_encode($data),
));
//create the Folder in the Parent
$result = curl_exec($curl);
curl_close($curl);
$folder = json_decode($result);
@ -1788,7 +1748,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
$path = $this->_joinPath($targetDir, $name);
try {
//Set the Parent id
list(, $parentId) = $this->_od_splitPath($targetDir);
list(, $itemId) = $this->_od_splitPath($source);
@ -1926,7 +1885,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
CURLOPT_CUSTOMREQUEST => 'DELETE',
));
//unlink or delete File or Folder in the Parent
$result = curl_exec($curl);
curl_close($curl);
} catch (Exception $e) {
@ -1994,7 +1952,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
}
try {
// for unseekable file pointer
if (!elFinder::isSeekableStream($fp)) {
if ($tfp = tmpfile()) {
if (stream_copy_to_stream($fp, $tfp, $size? $size : -1) !== false) {
@ -2004,7 +1961,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
}
}
//Create or Update a file
if ($itemId === '') {
$url = self::API_URL . $parentId . ':/' . rawurlencode($name) . ':/content';
} else {
@ -2017,14 +1973,12 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
CURLOPT_PUT => true,
CURLOPT_INFILE => $fp,
);
// Size
if ($size !== null) {
$options[CURLOPT_INFILESIZE] = $size;
}
curl_setopt_array($curl, $options);
//create or update File in the Target
$file = json_decode(curl_exec($curl));
curl_close($curl);
@ -2088,7 +2042,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
**/
protected function _checkArchivers()
{
// die('Not yet implemented. (_checkArchivers)');
return array();
}
@ -2115,7 +2068,6 @@ class elFinderVolumeOneDrive extends elFinderVolumeDriver
protected function _unpack($path, $arc)
{
die('Not yet implemented. (_unpack)');
//return false;
}
/**

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder driver for trash bin at local filesystem.
@ -19,10 +19,8 @@ class elFinderVolumeTrash extends elFinderVolumeLocalFileSystem
public function __construct()
{
parent::__construct();
// original option of the Trash
$this->options['lockEverything'] = false; // Lock all items in the trash to disable delete, move, rename.
// common options as the volume driver
$this->options['alias'] = 'Trash';
$this->options['quarantine'] = '';
$this->options['rootCssClass'] = 'elfinder-navbar-root-trash';
@ -43,7 +41,6 @@ class elFinderVolumeTrash extends elFinderVolumeLocalFileSystem
);
array_unshift($opts['attributes'], $attr);
}
// force set `copyJoin` to true
$opts['copyJoin'] = true;
return parent::mount($opts);

View File

@ -1,4 +1,4 @@
<?php
<?php
/**
* elFinder driver for trash bin at MySQL Database
@ -19,10 +19,8 @@ class elFinderVolumeTrashMySQL extends elFinderVolumeMySQL
public function __construct()
{
parent::__construct();
// original option of the Trash
$this->options['lockEverything'] = false; // Lock all items in the trash to disable delete, move, rename.
// common options as the volume driver
$this->options['alias'] = 'Trash';
$this->options['quarantine'] = '';
$this->options['rootCssClass'] = 'elfinder-navbar-root-trash';
@ -43,7 +41,6 @@ class elFinderVolumeTrashMySQL extends elFinderVolumeMySQL
);
array_unshift($opts['attributes'], $attr);
}
// force set `copyJoin` to true
$opts['copyJoin'] = true;
return parent::mount($opts);

View File

@ -1,38 +1,8 @@
<?php
//Module: True File Manager by Sitecreator
//Version (Версия): 1.3.1
<?php
//Developer of this module (Разработчик): Malyutin R. A. (Малютин Р. А.), Developer Website: https://sitecreator.ru 2019-2021(c)
//All rights reserved. (с)
//Все права защищены. (с)
//The copyright for this module belongs to Mr. Malyutin R. A.
//Авторские права на данный модуль принадлежат господину Малютину Р. А.
//Запрещается распространение данного программного продукта без разрешения автора.
//Distribution of this software product without the permission of the author is prohibited.
//
//Данное программное обеспечение предоставляется на основе простой неисключительной лицензии.
//Данное программное обеспечение распространяется по общепринятому принципу "как есть" без предоставления каких-либо гарантий в явной или неявной форме.
//Разработчик не гарантирует пригодность данного программного обеспечения для особых целей.
//Ни при каких обстоятельствах разработчик не несет ответственности за любой ущерб, который может возникнуть в результате использования данного программного обеспечения.
//This software is provided based on a simple, non-exclusive license.
//This software is distributed on a generally accepted “as is” basis without any warranty, expressed or implied.
//The developer does not guarantee the suitability of this software for special purposes.
//Under no circumstances shall the developer be liable for any damage that may result from the use of this software.
//
//
//
//
//This software uses freely distributed software of 3 parties, namely the following software:
//Данное программное обеспечение использует в своем составе свободно распространяемое программное обеспечение 3-х сторон, а именно следующий софт:
//
//jquery ver. 3.4.1 (JavaScript library), Developer Website: https://jquery.com/
//jquery ui ver. 1.12.1 (JavaScript library), Developer Website: https://jqueryui.com/
//elFinder ver. 2.1.49, Developer Website: https://jqueryui.com/
//
//На указанное выше программное обеспечение третьих лиц распространяется авторское право, принадлежащее соответственно этим третьим лицам.
//Подробнее об этих авторских правах можно прочитать на соответствующих вебсайтах разработчиков. Адреса соответствующих вебсайтов указаны выше.
//
//The above third-party software is copyrighted by these third parties, respectively.
//You can read more about these copyrights on their respective developer websites. The addresses of the respective websites are indicated above.
class ControllerCommonFileManager extends ControllerCommonFileManager__ {
@ -47,28 +17,24 @@ class ControllerCommonFileManager extends ControllerCommonFileManager__ {
if($oc30) $data['token'] = $this->session->data['user_token']; // opencart 3
else $data['token'] = $this->session->data['token'];
// Return the target ID for the file manager to set the value
if (isset($this->request->get['target'])) {
$data['target'] = $this->request->get['target'];
} else {
$data['target'] = '';
}
// CKEditor
if (isset($this->request->get['cke'])) {
$data['cke'] = $this->request->get['cke'];
} else {
$data['cke'] = '';
}
// summernote_id
if (isset($this->request->get['summernote_id'])) {
$data['summernote_id'] = $this->request->get['summernote_id'];
} else {
$data['summernote_id'] = '';
}
// Return the thumbnail for the file manager to show a thumbnail
if (isset($this->request->get['thumb'])) {
$data['thumb'] = $this->request->get['thumb'];
} else {