filters - Why is the change in my query not taking into account

admin2025-01-07  3

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.

Share Improve this question edited Nov 29, 2024 at 16:59 Athone asked Nov 28, 2024 at 21:11 AthoneAthone 33 bronze badges 1
  • Your code uses $ids but it's not being set anywhere. What should it be? – Pat J Commented Nov 29, 2024 at 0:14
Add a comment  | 

1 Answer 1

Reset to default 0

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:

Key Points to Address:

  1. Scope the Query Correctly: Ensure your pre_get_posts filter applies only to the media library query.
  2. Verify is_admin() and Media-Specific Requests: Media library queries can have specific indicators, like is_admin() and $_REQUEST['action'] == 'query-attachments'.
  3. Plugins Interference: ACF Pro and FileBird might interfere by adding their custom hooks or modifying queries.

Updated Code

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:

  1. 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.
  2. Scope to Attachments:

    • The condition $post_type === 'attachment' checks if the query is for the attachment post type, which corresponds to media library queries.
  3. Replace $ids with get_current_user_id():

    • The original $ids was undefined in your code snippet. If you want to restrict media to the current user, you can use get_current_user_id().
  4. Error Logging:

    • Logs like error_log('change author__in'); and error_log( print_r( $query, true ) ); help debug the query.

Debugging Steps:

  1. Check Query Modification:

    • Use the error logs to ensure the author__in parameter is being set correctly in the query.
  2. Disable Plugins Temporarily:

    • Deactivate ACF Pro and FileBird temporarily to confirm whether they interfere with media queries.
  3. Verify AJAX Request:

    • Open the browser's developer tools, navigate to the "Network" tab, and check the request parameters for 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!

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736265461a1047.html

最新回复(0)