I'm using 'pre_get_posts' action to filter the media so authors only see those uploaded by them or other authors. I managed to get the right result in the media page with this code
add_action( 'pre_get_posts', 'coapp_restrict_media_library' );
function coapp_restrict_media_library( $query ) {
if( current_user_can('edit_pages') ) { return; }
$ids = get_users(array('role'=> 'author', 'fields' => 'ID'));
$query->set('author__in', $ids );
}
But it's not specific enought so it affect other query and break other part of my website. So I tried adding a condition like this so it can target only the right call.
add_action( 'pre_get_posts', 'coapp_restrict_media_library' );
function coapp_restrict_media_library( $query ) {
if( current_user_can('edit_pages') ) { return; }
$post_type = $query->get('post_type');
$array = ['acf-taxonomy','acf-post-type','acf-ui-options-page'];
error_log('pre_get_post'); //check if action is trigger
$ids = get_users(array('role'=> 'author', 'fields' => 'ID'));
if( in_array( $post_type, $array ) ){
error_log('change author in'); //check if condition is met
$query->set('author__in', $ids );
}
error_log( print_r($query, true) ); //check state of query at the end
}
With this code, I get all the media nothing is filtered and when I check the error_log I see the 'pre_get_post', the 'change author in' and the query array with the ids of the author in the author__in subarray. So the query is changed but the result aren't.
Anyone has any idea what could cause this behaviour ?
Extra note, I tried different condition (is_admin(), $_REQUEST['action'] != 'query-attachments', ...) but I always get the same result.
Viewing the media in grid or list view doesn't change anyting, neither does changing the priority of the function.
Also, I'm using ACF pro and filebird plugins so maybe they interfere somehow in my second example but not in the first ...
edit 1:
I've added the value of $ids to the code.
I want the media filter to be active in view and grid mode.
All the code I saw online only work for the grid worked never the list view.
edit 2:
So this get weirder, I tried the code that Richard posted and it work for the grid view but not the list view.
The strange part is that nothing is written in the error_log file, no 'change author in' or query array. I've added some other error_log lines and nothing is added to my debug file after this line of code if ( ! is_admin() || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] !== 'query-attachments' ) { return; }
could it interfere with the error_log() function ?
It does block something in the error_log function, I tried without it and all my debugging log are in the file.
edit 3:
I've manage to make it work like I wanted with this code
function coapp_restrict_media_library( $query ) {
// Avoid filtering queries for users with higher permissions
if ( current_user_can('edit_pages') ) {
return;
}
//get ids of all the author
$ids = get_users(array('role'=> 'author', 'fields' => 'ID'));
// Check if it's a media library request
$post_type = $query->get('post_type');
if ( $post_type === 'attachment' ) {
$query->set( 'author__in', $ids );
}
}
the post_type === 'attachment'
did the trick. I still don't understantd why it didn't work before since both code are changing the query but I've lost enought time on this problem.
I'm using 'pre_get_posts' action to filter the media so authors only see those uploaded by them or other authors. I managed to get the right result in the media page with this code
add_action( 'pre_get_posts', 'coapp_restrict_media_library' );
function coapp_restrict_media_library( $query ) {
if( current_user_can('edit_pages') ) { return; }
$ids = get_users(array('role'=> 'author', 'fields' => 'ID'));
$query->set('author__in', $ids );
}
But it's not specific enought so it affect other query and break other part of my website. So I tried adding a condition like this so it can target only the right call.
add_action( 'pre_get_posts', 'coapp_restrict_media_library' );
function coapp_restrict_media_library( $query ) {
if( current_user_can('edit_pages') ) { return; }
$post_type = $query->get('post_type');
$array = ['acf-taxonomy','acf-post-type','acf-ui-options-page'];
error_log('pre_get_post'); //check if action is trigger
$ids = get_users(array('role'=> 'author', 'fields' => 'ID'));
if( in_array( $post_type, $array ) ){
error_log('change author in'); //check if condition is met
$query->set('author__in', $ids );
}
error_log( print_r($query, true) ); //check state of query at the end
}
With this code, I get all the media nothing is filtered and when I check the error_log I see the 'pre_get_post', the 'change author in' and the query array with the ids of the author in the author__in subarray. So the query is changed but the result aren't.
Anyone has any idea what could cause this behaviour ?
Extra note, I tried different condition (is_admin(), $_REQUEST['action'] != 'query-attachments', ...) but I always get the same result.
Viewing the media in grid or list view doesn't change anyting, neither does changing the priority of the function.
Also, I'm using ACF pro and filebird plugins so maybe they interfere somehow in my second example but not in the first ...
edit 1:
I've added the value of $ids to the code.
I want the media filter to be active in view and grid mode.
All the code I saw online only work for the grid worked never the list view.
edit 2:
So this get weirder, I tried the code that Richard posted and it work for the grid view but not the list view.
The strange part is that nothing is written in the error_log file, no 'change author in' or query array. I've added some other error_log lines and nothing is added to my debug file after this line of code if ( ! is_admin() || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] !== 'query-attachments' ) { return; }
could it interfere with the error_log() function ?
It does block something in the error_log function, I tried without it and all my debugging log are in the file.
edit 3:
I've manage to make it work like I wanted with this code
function coapp_restrict_media_library( $query ) {
// Avoid filtering queries for users with higher permissions
if ( current_user_can('edit_pages') ) {
return;
}
//get ids of all the author
$ids = get_users(array('role'=> 'author', 'fields' => 'ID'));
// Check if it's a media library request
$post_type = $query->get('post_type');
if ( $post_type === 'attachment' ) {
$query->set( 'author__in', $ids );
}
}
the post_type === 'attachment'
did the trick. I still don't understantd why it didn't work before since both code are changing the query but I've lost enought time on this problem.
The issue seems to arise because the pre_get_posts
hook you're using to filter media library queries might be affecting other queries as well, and your filtering condition isn't targeting the exact query you're trying to modify. Here's a detailed breakdown and a solution:
pre_get_posts
filter applies only to the media library query.is_admin()
and Media-Specific Requests: Media library queries can have specific indicators, like is_admin()
and $_REQUEST['action'] == 'query-attachments'
.Here’s an improved version of your function to scope it correctly:
add_action( 'pre_get_posts', 'coapp_restrict_media_library' );
function coapp_restrict_media_library( $query ) {
// Only apply the filter in admin area for AJAX media library requests
if ( ! is_admin() || ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] !== 'query-attachments' ) {
return;
}
// Avoid filtering queries for users with higher permissions
if ( current_user_can('edit_pages') ) {
return;
}
// Check if it's a media library request
$post_type = $query->get('post_type');
if ( $post_type === 'attachment' ) {
error_log('change author__in'); // Debugging log
$query->set( 'author__in', [ get_current_user_id() ] ); // Replace $ids with current user ID for simplicity
}
error_log( print_r( $query, true ) ); // Debugging log
}
Explanation of Changes:
Targeting Media Library Requests:
$_REQUEST['action'] === 'query-attachments'
ensures this code only runs for media library AJAX requests.is_admin()
ensures the filter runs only in the WordPress admin panel.Scope to Attachments:
$post_type === 'attachment'
checks if the query is for the attachment
post type, which corresponds to media library queries.Replace $ids
with get_current_user_id()
:
$ids
was undefined in your code snippet. If you want to restrict media to the current user, you can use get_current_user_id()
.Error Logging:
error_log('change author__in');
and error_log( print_r( $query, true ) );
help debug the query.Debugging Steps:
Check Query Modification:
author__in
parameter is being set correctly in the query.Disable Plugins Temporarily:
Verify AJAX Request:
query-attachments
to ensure the AJAX request aligns with the condition.Possible Plugin Interference:
ACF Pro or FileBird:** These plugins might hook into pre_get_posts
or modify media library queries. If this is confirmed, you might need to prioritize your hook by adjusting the priority:
add_action( 'pre_get_posts', 'coapp_restrict_media_library', 20 );
Alternatively, check for conflicts in their documentation or support forums.
This code should address your issue by properly scoping the pre_get_posts
filter to the specific media library query. Let me know if further debugging is required!
$ids
but it's not being set anywhere. What should it be? – Pat J Commented Nov 29, 2024 at 0:14