=== Devenia Replace Media ===
Contributors: basicus
Tags: replace media, replace image, media library, attachments, cache busting
Requires at least: 5.7
Tested up to: 7.1
Stable tag: 1.8.1
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Correct the file your pages already use. Keep the same attachment, its descriptive text and WordPress media relationships.

== Description ==

Replace an existing WordPress attachment without creating another Media Library item or selecting a new attachment on every page.

= Correct one shared source =

A product photograph appears on a product page and two articles. If it needs correcting everywhere, open the existing Media Library item and choose Replace File. The pages continue to use the same attachment ID.

If one page must keep the old photograph, upload a separate attachment instead. Replacement changes a shared source; it does not create a per-page variation.

= What is preserved =

* The attachment ID and WordPress relationships that refer to it.
* The attachment title, caption, description and alt text. Review that text when the replacement changes its meaning.
* The existing file path used for the replacement. WordPress image processing may generate a different full-size image when it scales, rotates or converts an image. Check the resulting URL and existing links.

WordPress regenerates attachment metadata and available image sizes. A smaller replacement may not recreate an old thumbnail size. Fixed thumbnail URLs in page HTML, CSS, external messages or exported pages are not rewritten automatically.

= Where to find Replace File =

Use the Media Library list, Edit Media screen or supported WordPress media dialogs. Elementor attachment details provide another entry point when Elementor is active. The normal Media Library workflow does not require Elementor or an AI client.

= Prepare the replacement =

Save a separate copy of the old file if you may need it again. Replacement does not provide a permanent revision history or an Undo button.

Prefer the same file format and prepare dimensions suitable for every placement. Although an allowed replacement type updates the recorded MIME type, a web server can infer the served type from the retained filename extension. A different format under an old extension is not a dependable conversion workflow.

= Check caches and published pages =

A changing v parameter is added to attachment and responsive image URLs produced through the supported WordPress filters. Each replacement gets a newer value, including repeated edits in the same second.

This does not purge every browser, page cache or CDN. Hard-coded URLs are not rewritten. Check representative pages and direct download links; clear the relevant cache or rebuild exported pages when needed.

= Automation abilities =

When WordPress Abilities API is available, two operations are registered:

* media/replace-from-url requires attachment_id and url. The HTTP or HTTPS source must pass WordPress URL validation.
* media/replace-base64 requires attachment_id, filename and base64. A base64 data URI is accepted. The decoded file must be no larger than 20 MiB; server request limits can be lower.

The account must have upload_files and permission to edit the selected attachment. Both operations use the same replacement function as the editor. A successful response includes the attachment ID, URL, MIME type, dimensions, version and message. A failed ability returns success: false with a message.

An MCP client needs a compatible connection to WordPress Abilities API. Automation is optional; replacing files through the Media Library works without it.

Read the [product guide](https://devenia.com/plugins/replace-media/) and WordPress documentation for [image-size generation](https://developer.wordpress.org/reference/functions/wp_create_image_subsizes/).

== Installation ==

1. Download the [plugin ZIP](https://downloads.devenia.com/devenia-replace-media.zip).
2. Open Plugins > Add New > Upload Plugin in WordPress.
3. Upload the ZIP and activate Devenia Replace Media.
4. Open the existing attachment and choose Replace File.
5. Upload the corrected file and check its pages, images and direct links.

WordPress 5.7 or later, PHP 7.4 or later, and a writable upload directory are required. The account must be able to upload files and edit the selected attachment.

== Frequently Asked Questions ==

= Should I replace the attachment or upload another file? =

Replace it when the correction belongs in every use of that attachment. Upload a separate attachment when some pages must keep the old content.

= Are titles, captions and alt text rewritten? =

No. They remain attached to the same item. Review and edit them if the replacement changes what the file shows or means.

= Will every old thumbnail link still work? =

Not necessarily. WordPress generates sizes from the new dimensions and current settings. A smaller file may not recreate an old size. Check fixed thumbnail URLs separately.

= Can I undo a replacement? =

There is no permanent file history or Undo button. Save a separate copy before replacing a file you may need later.

= Why can I still see the old file? =

The version parameter only helps when a URL passes through supported WordPress filters and the cache distinguishes it. Refresh the page and check the relevant browser, page cache, CDN or exported page.

== Screenshots ==

1. Replace File action in the Media Library list.
2. Replace File action in attachment details.
3. Replacement upload form.

== Changelog ==

= 1.8.1 =
* Fixed: Every replacement gets a newer cache revision, including rapid edits and clock adjustments.
* Updated: Guidance on shared attachments, image processing, file formats and cache limits.

= 1.8.0 =
* Added: media/replace-from-url and media/replace-base64 abilities.
* Improved: Editor uploads and automation use the same replacement function.

= 1.7.5 =
* Fixed: Replace File button injection in Media Library grid/details view on newer WordPress admin markup
* Improved: More robust attachment ID detection across WP media frames and DOM
* Fixed: Media Library grid view details modal now detects attachment ID via `?item=<ID>`
* Improved: Cache busting now also applies to responsive image `srcset` and works across repeated replacements
* Improved: After replacement, Media Library refresh behavior is more reliable
* Improved: Safer file replacement flow (staged write + rollback) and stricter permissions check

= 1.7.4 =
* Added: Replace File button on Edit Media screen

= 1.7.3 =
* Fixed: Use wp_add_inline_script() and wp_print_inline_script_tag() instead of raw script tags
* Fixed: Added nonce verification for GET requests to replacement page
* Fixed: Wrapped require_once calls with function_exists checks
* Fixed: Improved file upload validation with is_uploaded_file(), sanitize_file_name(), and sanitize_mime_type()
* Added: User capability check (upload_files) in replacement function
* Improved: Better code documentation and WordPress Coding Standards compliance

= 1.7.2 =
* Changed slug to devenia-replace-media (WordPress.org requirement)

= 1.7.1 =
* Fixed text domain to match plugin slug

= 1.7 =
* Fixed nonce verification warnings in file upload handling
* Improved input validation for WordPress.org Plugin Check compliance
* Shortened short description to meet 150 character limit

= 1.6 =
* Uses WordPress Filesystem API for all file operations
* Improved security and WordPress.org compatibility

= 1.5 =
* Added automatic cache busting - URLs now include version parameter after replacement
* Helps caches fetch updated files without manual cache clearing

= 1.4 =
* Added support for Elementor gallery editor
* Uses `elementor/editor/footer` hook for proper script loading

= 1.3 =
* Changed script loading method for better compatibility

= 1.2 =
* Improved attachment ID detection in media modals

= 1.1 =
* Added JavaScript injection for media modal support

= 1.0 =
* Initial release
* Replace files from Media Library list view
* Preserve metadata and regenerate thumbnails

== Upgrade Notice ==

= 1.8.1 =
Keeps cache revisions distinct across repeated replacements. Check pages and direct links after updating a shared file.
