=== KDA Custom Upload Structure ===
Contributors: deniskey
Tags: uploads, upload folder, media, post type, migration
Requires at least: 5.8
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.3.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Store uploads outside wp-content in a custom folder, organized by post type. Includes a migration tool for existing media.

== Description ==

= English =

**Custom Upload Structure** lets you store uploaded files outside the standard
`wp-content/uploads` directory — for example in `assets/public/` at the site
root — and organize them the way you want.

Features:

* **Custom upload location.** Store all media in any folder relative to the
  site root instead of `wp-content/uploads`.
* **Organize by post type.** Files are placed into subfolders named after the
  post type they belong to (e.g. `assets/public/films/`). Unattached files go
  into a configurable "others" subfolder.
* **Year / month folders.** Keep the default WordPress year/month structure
  inside your custom folder.
* **Transliteration.** Convert Cyrillic and other non-Latin file names to
  Latin characters on upload (e.g. a Cyrillic file name is converted to its
  Latin equivalent).
* **Post ID prefix.** Optionally prefix each file name with the ID of the post
  it is uploaded to (e.g. post 42 → `42-photo.jpg`). Off by default.
* **Migration tool.** Move existing media between the default folder and your
  custom structure (and back) without breaking the Media Library. Includes a
  dry run, optional replacement of old URLs inside post content, and a retry
  mode for failed items.
* **Safety.** The upload folder is protected with an `index.php` stub, file
  permissions are normalized, and a full backup is required before any move.

All behaviour is controlled from **Settings → Upload Structure**.

== Installation ==

1. Upload the `kda-custom-upload-structure` folder to `/wp-content/plugins/`.
2. Activate the plugin through the "Plugins" menu in WordPress.
3. Go to **Settings → Upload Structure**, enable the plugin and set your
   custom upload folder path (e.g. `/assets/public/`).
4. Save the settings. The folder will be created automatically.

== Frequently Asked Questions ==

= Does the plugin move my existing files? =

No, not automatically. Use the **Migration** tab on the settings page to move
existing media between the default folder and your custom structure. Always
make a full backup first.

= Can I revert to the default uploads folder? =

Yes. Disable the plugin and use the reverse migration on the **Migration** tab
to move files back into `wp-content/uploads`.

== Screenshots ==

1. General settings: custom path, organization options and current directory info.
2. Migration tab: forward, reverse and retry tools with a dry run.

== Changelog ==

= 1.3.0 =

* Fixed plugin version constant so asset cache-busting matches the release.
* Centralized upload-base computation and shared helper methods across plugin core, admin and migrator.
* Migration now also replaces old URLs inside postmeta (serialization-safe).
* Improved migration rollback: when moving a generated image size fails, the whole item is rolled back cleanly.
* Fixed file-permissions and image-size filters to run only when the plugin is enabled.
* Sanitized `$_REQUEST['post_id']` upload context inputs.
* Added migration-status reset when a run gets stuck (closed tab).
* Added `uninstall.php` cleanup for plugin options and transients.
* Minor accessibility improvements on settings tabs.

= 1.2.0 =

* Migration is now processed in chunks with a progress bar and automatic resume, avoiding AJAX timeouts on large media libraries.
* Added "migration in progress" indicator when reopening the page during a run.
* Added free disk space check before starting a migration and rollback of the current chunk on a rename error.
* Added "rename files on move" option (applies post ID prefix and transliteration to existing files).
* Added multisite per-site subfolder support.
* Added folder structure preview on the settings page.
* Empty subfolders are cleaned up automatically after a reverse migration.
* Security: capability check on post ID prefix, error logging in directory creation, nonce verification on the classic migration endpoint.

= 1.1.0 =

* Added "Add post ID to file name" option (off by default).
* Reverse migration now updates image URLs inside post content.
* JavaScript migration handlers rewired so forward, reverse and retry buttons work.
* Removed hardcoded fallback folder name; the "others" folder is taken from settings.

= 1.0.0 =

* Initial release.

== Upgrade Notice ==

= 1.1.0 =

Adds post ID filename prefix and fixes reverse-migration content URL replacement.
