WP Manifestindependent plugin directory
manifest / media / simple-storage

Simple Storage

Moves WordPress media files to the Hosting Ukraine storage and back, with verification and serving from the storage.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/vitaliikaplia/simple-storage/archive/refs/heads/master.zip
Updates itself. It ships its own updater, so new versions appear under Dashboard → Updates.

WordPress-плагін, який переносить медіафайли сайту у сховище Хостинг Україна і повертає їх назад. Він звільняє диск хостингу, а медіатека WordPress лишається такою, як була: ті самі вкладення, метадані й посилання.

  • Індекс. Плагін рахує всі файли в теках років і місяців у uploads, тобто ті, що завантажені через Медіабібліотеку, і показує їхню кількість і розмір. Інші теки wp-content не чіпаються.

  • Перенесення в сховище однією кнопкою.

    • Файли копіюються, кожна копія перевіряється: розмір, а в суворому режимі (типово) ще й SHA-256 файлу, скачаного за публічною адресою.
    • Далі вмикається віддача зі сховища і перевіряється наскрізно, окремо для кожного розширення: пробний файл має відкритися за адресою сайту. Файли розширення, яке перевірку не пройшло, лишаються на сайті.
    • Лише після цього видаляються локальні копії, і перед кожним видаленням сховище ще раз підтверджує свою копію.
    • Прогрес видно на сторінці, задачу можна призупинити й продовжити.
  • Повернення однією кнопкою. Файли завантажуються назад, перевіряються й видаляються зі сховища. У результаті виходить звичайний WordPress з оригінальними часами зміни файлів.

  • Віддача на вибір:

    • «Прозорий проксі» зберігає адреси /wp-content/uploads/… незмінними. Файли віддає Apache (mod_proxy), якщо хостинг це дозволяє (плагін перевіряє це сам), або невеликий PHP-скрипт без WordPress.
    • «Напряму зі сховища» переписує посилання на сторінках на сховище чи свій піддомен, а старі адреси отримують 302.
  • Нові файли після перенесення їдуть у сховище наприкінці того самого запиту завантаження, разом із мініатюрами й WebP/AVIF-копіями теми; нарізки, які Timber чи тема роблять на переглядах сторінок, — наприкінці того запиту. Вони копіюються, перевіряються й зникають з диска в тому самому запиті (його ніколи не віддає кеш сторінок); лише з фоновим оптимізатором зображень (Smush, Imagify, EWWW, ShortPixel, Converter for Media тощо) локальні копії зникають за хвилину-дві, коли він закінчить (фільтр simple_storage_remove_at_request_end). Оптимізатор, що доходить до нових файлів лише за кілька хвилин через cron (WP-Optimize, оптимізація зображень LiteSpeed), застане їх уже в сховищі — його варто запускати до ввімкнення автоперенесення. WP-Cron для цього не потрібен: якщо його вимкнено, відкладену роботу плагін виконує сам наприкінці звичайних запитів, після відповіді відвідувачу. Видалення у WordPress видаляє файли й у сховищі, а теки, що там лишились порожніми (місяць, його підтеки, рік), плагін прибирає наприкінці того самого запиту — лише під блокуванням задач і лише коли порожнечу підтверджують і список теки, і сама тека, і індекс; теку сайту він не чіпає ніколи. Нове завантаження ніколи не займе ім'я файлу, який уже лежить лише в сховищі.

  • Редагування зображень. Кроп, поворот, масштаб і «Відновити оригінал» у класичному редакторі, а також кроп у блоці «Зображення» працюють і для файлів зі сховища: плагін на льоту повертає оригінал, а результат потім знову переїжджає в сховище.

  • Перенарізка мініатюр.

    • wp media regenerate і плагін Regenerate Thumbnails отримують оригінал зі сховища. Нові мініатюри замінюють старі в сховищі, а старі розміри, яких більше нема, видаляються й там (крім --skip-delete), але ніколи не оригінал і не файл іншого вкладення. Поки регенерація йде, автоперенесення чекає. З --only-missing мініатюри, що лежать лише в сховищі, для WP-CLI «відсутні», тож такі вкладення нарізаються повністю.
    • Ресайз Timber (|resize у Twig) бере готовий розмір зі сховища без оригіналу. Розмір, якого ще нема, нарізається у фоні з поверненого оригіналу, і обидва знову їдуть у сховище; доти сторінка отримує повнорозмірне зображення, як і без плагіна.
    • Разом із вкладенням зі сховища видаляються й похідні файли: розміри Timber і WebP/AVIF-копії поруч із зображенням (photo-jpg.webp).
  • Віддача, яка ще не працює, не зупиняє перемикання. «Перемкнути на сховище» для файлів, залитих туди вручну, нічого не видаляє, тож невдала перевірка віддачі нічого й не захищає: сайт перемикається, нові завантаження лишаються у WordPress, доки віддача не запрацює, а «Наступний крок» показує проблему першою й пропонує «Перевірити віддачу». Плагін сам називає причину: рядок uploads/.htaccess, який сервер не приймає (наприклад, Options … -ExecCGI), або правило, що забороняє PHP у теці plugins, — з готовим винятком для proxy.php.

  • Огляд. Угорі — звідки сайт віддає медіа, куди йдуть нові файли, і смуга, що показує, де лежать файли. Під нею — один «Наступний крок» із кнопкою: його плагін добирає за станом файлів і напрямом переїзду. Ще нижче — поточна задача. Картка «Переїзд» має два вигляди: «Покроково» й «Одним кліком». Біля кожного кроку коротко написано, що він зробить зараз. Технічні деталі віддачі сховано в «Розширене».

  • Покроковий переїзд в обидва боки — для перенесення вручну (FTP), частинами або коли файли лежать частково на хостингу, частково в сховищі. Картка «Покроково» має дві доріжки по три кроки:

    • До сховища: «Скопіювати все в сховище» → «Перемкнути на сховище» → «Видалити копії у WordPress».
    • До WordPress: «Скопіювати все у WordPress» → «Перемкнути на WordPress» → «Видалити копії в сховищі».
    • Копіювання нічого не видаляє. Файли, які вже лежать на іншому боці (залиті вручну), перевіряються, а не надсилаються вдруге.
    • Перемикання нічого не копіює. Спершу плагін перевіряє, що на потрібному боці є кожен файл сховища й медіатеки, і лише тоді змінює, звідки сайт віддає файли.
    • Видалення відбувається лише тоді, коли кожен файл має перевірену копію на іншому боці. Інакше не видаляється нічого, а задача називає, чого бракує.
    • Файли, повернуті вручну з новим часом зміни, плагін звіряє за SHA-256. Інший файл за тим самим шляхом лишається конфліктом імен.
    • Файли, які вже залито в сховище, поки їхні копії ще на хостингу, індекс показує окремим рядком: «з них у сховищі вже є файл із тим самим ім'ям, ще не перевірений». Копіями вони стають після перевірки вмісту. Її робить кнопка «Перевірити копії в сховищі» біля індексації (wp simple-storage verify), яка нічого не заливає, не видаляє й не перемикає; перевіряють їх і кроки «Скопіювати все в сховище», «Перемкнути на сховище» та «Видалити копії у WordPress».
  • Сайт, чиї файли не вміщаються на хостинг. Теки років і місяців можна залити в сховище самому (FTP). Кнопка «Перемкнути на сховище» звірить їх із медіатекою й покаже, скільки файлів знайдено, чого бракує і в чому не збігся розмір. Якщо все на місці, вона вмикає віддачу й автоперенесення; нічого не копіюється й не скачується. Файли, яких справді немає, можна прийняти кнопкою «Усе одно підключити». Те саме робить wp simple-storage adopt [--accept-missing]. Зворотний шлях: скачати теки зі сховища, залити на хостинг, натиснути «Перемкнути на WordPress», а згодом «Видалити копії в сховищі».

  • Що лишається поза сховищем. Сховище публічне, тому код і дані (PHP та інші скрипти, .sql, .log, .env тощо) не їдуть туди й не приїжджають звідти; задача каже, що саме пропустила. Вирішити інакше можна фільтром simple_storage_excluded_file. proxy.php файлів, які міг би виконати вебсервер, не віддає ніколи.

Налаштування — у Медіафайли → Simple Storage. Кнопка «Перевірити віддачу» наново доводить віддачу й оновлює правила. Доступні також команди WP-CLI wp simple-storage status|test|index|verify|push|pull|adopt|resume|cancel|delivery, а для покрокового переїзду — copy storage|wordpress, switch storage|wordpress [--accept-missing] і delete-copies wordpress|storage; index --confirm-missing питає сховище про кожен записаний файл, якого немає в його списку, і забуває ті, яких воно вже не має.

Для тем і плагінів, які самі працюють з файлами:

  • simple_storage_ensure_local( $attachment_id_or_path_or_url ) повертає файл зі сховища на диск (потім він знову переїде в сховище);
  • simple_storage_file_exists( $path_or_url ) — заміна file_exists(), яка знає й файли в сховищі;
  • simple_storage_queue_offload( $path ) — файл, який код щойно записав (нарізка на перегляді сторінки), їде в сховище наприкінці запиту;
  • simple_storage_timber_resize( $url, $width, $height, $crop ) — Timber\ImageHelper::resize() для прямих викликів із PHP;
  • фільтр simple_storage_attachment_files додає файли, які тема тримає для вкладення поза його метаданими.

Потрібні WordPress 6.5+, PHP 8.1+ з cURL і сховище з користувачем веб-доступу (права «Читання», «Запис», «Вміст») та публічним «Читанням». Multisite не підтримується. Інший код, що сам читає файли з диска (file_exists(), генерація WebP-копій, вбудовування SVG), для файлів, що лежать лише в сховищі, їх не побачить — для нього є функції вище. Оновлення приходять через стандартний механізм WordPress з гілки master цього репозиторію. Інтерфейс англійською та українською.

Автор — Vitalii Kaplia. Ліцензія — GPL-2.0-or-later.