fix(media-protection): allow undoing a protected file#3189
fix(media-protection): allow undoing a protected file#3189faisalahammad wants to merge 2 commits into
Conversation
Add ability to unprotect a media file by clearing the selected course or membership. The file is moved back to its original public location and all protection metadata is removed. - Record original public location in new meta key when a file is first protected so it can be restored later. - Add move_attachment_to_public_dir() mirroring the existing move to the protected dir, with conflict detection when a different file already exists at the original public path. - Route cleared product value through to the unprotect method in the classic attachment save path and the REST update_callback. - Enable clearing in the select2 in both classic and block editor UIs, show the original location, and warn the user before unprotecting. - Add a read-only REST field exposing the original location to the block editor. Fixes gocodebox#3018
|
The PHP 8.3 job hit a transient network error ( Maintainer can re-trigger the failed job when ready. I don't have the perms to do it from the fork. |
| // if the upload base directory has been customized. | ||
| $attached = get_post_meta( $attachment_id, '_wp_attached_file', true ); | ||
| if ( $attached ) { | ||
| $relative = ltrim( $attached, '/' ); |
There was a problem hiding this comment.
Are we sure this will always be correct, depending on the server config?
|
@faisalahammad Thanks for the PR! This is something I've wanted to add for a while. The UX is a little confusing, but might be close to the best we can do with the limitations on the media dialog. Clicking the "x" for the course immediately removes the restriction before the message is shown, as demo'ed in this video: CleanShot.2026-07-21.at.10.34.10.mp4If we show the warning/note about clearing will restore the file publicly, rather than showing the note about the original location, I think this would mostly solve things. Alternatively, a button to explicitly un-restrict the file (if possible) could work too. Thoughts? |
Summary
Adds ability to undo a protected media file by clearing the selected course or membership. The file moves back to its original public location, the protection metadata is removed, and the user sees a read-only note of the original location and a warning before unprotecting.
Fixes #3018
Changes
includes/class-llms-media-protector.phpAdded:
ORIGINAL_FILE_META_KEYconstant for storing the original public location.remove_authorization_meta_from_media_post()to clear auth meta and per-user cache.get_original_attached_file()to read the stored original path.Why: Need a recorded original path before protection so we can restore it, and need a clean way to clear the auth meta and the cached
is_authorized_to_viewresult for the current user.includes/admin/class-llms-admin-media-protection-attachment-settings.phpAdded:
move_attachment_to_public_dir(),store_original_attached_file(), andfiles_are_identical()helper.Changed:
move_attachment_to_protected_dir()now records the original_wp_attached_filebefore moving.attachment_fields_to_save()routes an empty product value through to the unprotect method.attachment_fields_to_edit()enablesallow_clearon the select2, shows the original location note, and renders the unprotect warning container.Why: Need a symmetric move-back method. The original path is recorded once so the unprotect method has a target. Conflict detection handles the case where a different file already exists at the original public location (returns
WP_Error).includes/class-llms-rest-fields.phpChanged:
_llms_media_protection_product_idupdate_callbacktreats an empty value as a request to unprotect and returnsWP_Erroron failure.Added: Read-only
_llms_media_protection_original_fileREST field exposing the original location.Why: The block editor needs to know the original location to render the note, and the REST path needs to honor the same "clear to unprotect" semantics as the classic save path. Backward compatibility preserved by keeping the existing field as a scalar integer.
src/js/admin-media-protection-block-protect.jsChanged:
data-allow_clear='true', send0when the select2 is cleared, display the original location and the unprotect warning, and wrap the change event listener with a cleanup so it does not leak across modal opens.assets/js/llms-admin-media-protection-attachment-settings.jsChanged: Toggle the unprotect warning visibility when the classic media modal select2 is cleared.
Testing
10 unit tests pass (19 assertions). PHPCS clean on all modified PHP files. CodeRabbit review addressed.
Test 1: Classic media library
Test 2: Block editor
Test 3: Conflict
WP_Errorso the UI can show the conflict message.