{"id":231653,"date":"2025-05-04T13:42:25","date_gmt":"2025-05-04T13:42:25","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/media-restriction\/"},"modified":"2026-05-21T18:59:38","modified_gmt":"2026-05-21T18:59:38","slug":"media-restriction","status":"publish","type":"plugin","link":"https:\/\/gl.wordpress.org\/plugins\/media-restriction\/","author":23283094,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.1.0","stable_tag":"2.1.0","tested":"7.0","requires":"5.0","requires_php":"7.4","requires_plugins":null,"header_name":"Media Restriction","header_author":"upluggit","header_description":"Restrict media library access based on user roles","assets_banners_color":"e8fa92","last_updated":"2026-05-21 18:59:38","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/upluggit\/media-restriction","header_author_uri":"https:\/\/upluggit.com\/","rating":0,"author_block_rating":0,"active_installs":40,"downloads":802,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"upluggit","date":"2025-05-04 13:41:59"},"1.0.1":{"tag":"1.0.1","author":"upluggit","date":"2025-05-04 16:45:32"},"1.0.2":{"tag":"1.0.2","author":"upluggit","date":"2025-05-05 17:38:16"},"1.0.3":{"tag":"1.0.3","author":"upluggit","date":"2025-05-05 18:25:32"},"2.0.0":{"tag":"2.0.0","author":"upluggit","date":"2026-05-10 06:30:03"},"2.1.0":{"tag":"2.1.0","author":"upluggit","date":"2026-05-21 18:59:38"}},"upgrade_notice":{"2.0.0":"<p>Major update. Deactivate and reactivate the plugin after upgrading \u2014 activation creates the Activity Log database table. All existing restriction settings are preserved.<\/p>","2.1.0":"<ul>\n<li>Compatible with WordPress 7.0<\/li>\n<\/ul>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3287965,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3287965,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3527585,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3527585,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.0.2","1.0.3","2.0.0","2.1.0"],"block_files":[],"assets_screenshots":{"screenshot-1.jpeg":{"filename":"screenshot-1.jpeg","revision":3287185,"resolution":"1","location":"assets","locale":"","width":1600,"height":1232},"screenshot-1.png":{"filename":"screenshot-1.png","revision":3527585,"resolution":"1","location":"assets","locale":"","width":862,"height":611}},"screenshots":{"1":"Media restrict settings page."}},"plugin_section":[],"plugin_tags":[8531,84,233,1505,1915],"plugin_category":[50,58],"plugin_contributors":[241778],"plugin_business_model":[],"class_list":["post-231653","plugin","type-plugin","status-publish","hentry","plugin_tags-activity-log","plugin_tags-media","plugin_tags-media-library","plugin_tags-restriction","plugin_tags-roles","plugin_category-media","plugin_category-user-management","plugin_contributors-upluggit","plugin_committers-upluggit"],"banners":{"banner":"https:\/\/ps.w.org\/media-restriction\/assets\/banner-772x250.png?rev=3527585","banner_2x":"https:\/\/ps.w.org\/media-restriction\/assets\/banner-1544x500.png?rev=3527585","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/media-restriction\/assets\/icon.svg?rev=3287965","icon":"https:\/\/ps.w.org\/media-restriction\/assets\/icon.svg?rev=3287965","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/media-restriction\/assets\/screenshot-1.png?rev=3527585","caption":"Media restrict settings page."}],"raw_content":"<!--section=description-->\n<p>Media Restriction is a lightweight and powerful WordPress plugin that gives site admins full control over who can see what in the Media Library. Restrict access by user role so that users only see their own uploads, exclude trusted individuals from the restriction, and keep a full audit trail of every upload, deletion, and library view \u2014 all from a clean, modern settings panel.<\/p>\n\n<p>Whether you manage a multi-author blog, an online course platform, a membership site, or a client project \u2014 Media Restriction ensures your media library stays tidy, private, and secure.<\/p>\n\n<p><strong>What makes v2.0.0 different:<\/strong>\nVersion 2.0.0 is a complete rebuild. The settings page has been redesigned with a tabbed interface and instant role toggles (no page reloads). A new Activity Log records every media event with user, file name, IP address, and timestamp. REST API protection closes the Gutenberg and headless bypass that most similar plugins miss entirely. And a critical bug affecting excluded users in the grid view has been resolved.<\/p>\n\n<h3>\ud83c\udf1f Features<\/h3>\n\n<p><strong>Core restriction<\/strong>\n\u2705 Restrict media library access by user role\n\u2705 Works in both grid view (media modal) and list view (Media Library screen)\n\u2705 Administrators always have full access \u2014 no configuration needed\n\u2705 Exclude specific users from restriction \u2014 grant bypass access to trusted individuals regardless of their role\n\u2705 REST API protection \u2014 \/wp\/v2\/media respects the same restriction rules, covering Gutenberg and headless setups<\/p>\n\n<p><strong>Settings &amp; admin<\/strong>\n\u2705 Modern tabbed settings page \u2014 Roles &amp; Users and Activity Log in one place\n\u2705 Instant role toggles \u2014 enable or disable restriction per role without a page reload\n\u2705 Live status badges on each role card showing user count and restriction state\n\u2705 Header summary showing how many roles are restricted and users excluded<\/p>\n\n<p><strong>Activity log<\/strong>\n\u2705 Tracks all upload, delete, and view events automatically\n\u2705 Records user, file name, IP address, and timestamp for every event\n\u2705 Displays the latest 30 entries in a clean admin table\n\u2705 One-click clear log with confirmation prompt<\/p>\n\n<p><strong>Compatibility &amp; clean code<\/strong>\n\u2705 Works with default WordPress roles and any custom roles (LMS, membership, WooCommerce, etc.)\n\u2705 Compatible with Gutenberg block editor, classic editor, and headless setups\n\u2705 Restricted users can still upload and manage their own files \u2014 restriction is visibility only\n\u2705 No impact on existing media files \u2014 the plugin never modifies or deletes files\n\u2705 Clean uninstall \u2014 removes all plugin options and database tables on deletion<\/p>\n\n<h3>\ud83e\udde0 Use Cases<\/h3>\n\n<p><strong>Online Learning Platforms (LMS):<\/strong>\nPrevent instructors from seeing or using each other's uploaded course files. Exclude trusted course managers so they retain full access.<\/p>\n\n<p><strong>Client Sites &amp; Freelancers:<\/strong>\nLimit clients to only their own media uploads, keeping your own assets private and the library uncluttered.<\/p>\n\n<p><strong>Multi-Author Blogs:<\/strong>\nEnsure each contributor only sees their own images and uploads. Exclude editors who need to manage all media.<\/p>\n\n<p><strong>Membership or Community Sites:<\/strong>\nAllow members to upload profile or content images but restrict them from browsing admin or other members' uploads.<\/p>\n\n<p><strong>Agencies &amp; Teams:<\/strong>\nGive designers and content editors restricted media access while allowing project leads or account managers full visibility.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20restrict%20media%20access%20for%20all%20user%20roles%3F\"><h3>Does this plugin restrict media access for all user roles?<\/h3><\/dt>\n<dd><p>Yes. You can restrict any user role on your site \u2014 including custom roles created by LMS, membership, WooCommerce, or user role editor plugins. Administrators are always exempt.<\/p><\/dd>\n<dt id=\"can%20i%20allow%20specific%20users%20to%20bypass%20the%20restriction%3F\"><h3>Can I allow specific users to bypass the restriction?<\/h3><\/dt>\n<dd><p>Yes. The Exclude Specific Users field lets you grant full media access to individual users even if their role is restricted. Changes take effect immediately.<\/p><\/dd>\n<dt id=\"does%20the%20restriction%20apply%20in%20the%20gutenberg%20block%20editor%3F\"><h3>Does the restriction apply in the Gutenberg block editor?<\/h3><\/dt>\n<dd><p>Yes. Version 2.0.0 adds REST API protection, which covers the \/wp\/v2\/media endpoint used by Gutenberg and headless WordPress setups. Previous versions only restricted the admin UI.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20support%20custom%20user%20roles%3F\"><h3>Does this plugin support custom user roles?<\/h3><\/dt>\n<dd><p>Yes. Media Restriction detects all registered roles automatically, including those added by third-party plugins.<\/p><\/dd>\n<dt id=\"will%20restricted%20users%20still%20be%20able%20to%20upload%20media%3F\"><h3>Will restricted users still be able to upload media?<\/h3><\/dt>\n<dd><p>Yes. Restriction only affects visibility \u2014 users can still upload and manage their own files. They simply cannot see files uploaded by other users.<\/p><\/dd>\n<dt id=\"does%20it%20affect%20existing%20media%20files%3F\"><h3>Does it affect existing media files?<\/h3><\/dt>\n<dd><p>No. The plugin only controls what is visible in the library. It never modifies, moves, or deletes any files.<\/p><\/dd>\n<dt id=\"what%20does%20the%20activity%20log%20track%3F\"><h3>What does the Activity Log track?<\/h3><\/dt>\n<dd><p>Every upload, deletion, and media library view is logged with the user's name, the file name or object, their IP address, and the date and time. Logs can be cleared by an administrator at any time.<\/p><\/dd>\n<dt id=\"will%20it%20conflict%20with%20other%20plugins%3F\"><h3>Will it conflict with other plugins?<\/h3><\/dt>\n<dd><p>Media Restriction is designed to be lightweight and conflict-free. It hooks into standard WordPress filters and does not modify the database schema beyond its own activity log table.<\/p><\/dd>\n<dt id=\"does%20it%20clean%20up%20after%20itself%20on%20uninstall%3F\"><h3>Does it clean up after itself on uninstall?<\/h3><\/dt>\n<dd><p>Yes. Uninstalling the plugin removes all saved options and drops the activity log database table completely.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Complete UI redesign \u2014 modern tabbed settings page with instant AJAX role toggles and live status badges<\/li>\n<li>New: Activity Log \u2014 tracks all upload, delete, and view events with user, file, IP, and timestamp<\/li>\n<li>New: REST API restriction \u2014 \/wp\/v2\/media endpoint now respects role-based restrictions<\/li>\n<li>Fixed: Excluded users were incorrectly restricted in the grid view (media modal) due to a type mismatch between stored user IDs (strings) and get_current_user_id() (integer)<\/li>\n<li>Fixed: WordPress core re-injects the author constraint after ajax_query_attachments_args \u2014 resolved via posts_where hook with unconditional strip for grid context<\/li>\n<li>Improved: Settings page now uses AJAX for both role toggles and excluded user saves \u2014 no full page reload required<\/li>\n<li>Requires PHP 7.4 or higher<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Removed extra tags<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Added GitHub Action<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Updated readme<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Restrict media library access by user role \u2014 with activity logging, and REST API protection.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/231653","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=231653"}],"author":[{"embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/upluggit"}],"wp:attachment":[{"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=231653"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=231653"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=231653"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=231653"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=231653"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/gl.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=231653"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}