最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

filters - Hide Posts In Back-endAdmin Based On User's (Pseudo) Privileges Controlled by ACF

programmeradmin0浏览0评论

I'd like to disable access to posts in the back-end/Admin from a user that doesn't have the privilege to view those posts. This will function similar to the Author role however this "privilege" is controlled by an ACF User relationship field and not by a WP Core role or privilege.

One level of complexity deeper, the User relationship field is actually pointing to a parent/grouping custom post type that is then tied to the children post elements I'm attempting to filter. So rather than show just the posts that user has authored, it's also showing posts that others have authored but that they have been granted permission to manage. Let me explain this below...

Custom Post Type: Shoes [shoe]
Custom Post Type: Brands [brand]

  • Let's say you have a "shoe" called "Air Jordans" and you have a "brand" called "Nike".
  • So you create an ACF bidirectional relationship between "Air Jordan" and "Nike".
  • Now let's say you create a user on your site that you want to be able to edit all "Nike" shoes.
  • So you create an ACF User relationship field type in the "brand" post type, and you can assign multiple users to admin that brand.
  • So, when that user logs into the back-end and views all shoes, I want just Nikes shoes to show up and they will have the ability to edit all Nike shoes.

I've built out the logic to handle this on the front-end and it works perfect, and now I'd like to duplicate this on the back-end for filtering there as well. Here's what I built out on the front-end for reference:

$current_user = wp_get_current_user();

/* Get All Brands the Current User can Administer */
$brands_admin_args = array(
  'post_type'   => 'brand',
  'meta_query'  => array(
      array(
          'key'     => 'admins', // This is my ACF User field that tracks brand admins.
          'value'   => '"' . $current_user->ID . '"',
          'compare' => 'LIKE'
      ),
  ),
);
$brands_admin = get_posts($brands_admin_args);


/* Get All Shoes The User Can Administer Based On Each Brand They Can Administer*/
$approved_shoes_args = array(
  'post_type'       => 'shoe',
  'meta_query'      => array(
      'relation'    => 'OR'
  ),
);

foreach ($brands_admin as $ba) {
  array_push($approved_shoes_args['meta_query'], array(
      'key'       => 'shoe_brands', // This is my ACF Relationship field between Shoes and Brands 
      'value'     =>  '"' . $ba->ID . '"',
      'compare'   => 'LIKE'
  ));
}
$approved_shoes = new WP_Query($approved_shoes_args);

I'd like to disable access to posts in the back-end/Admin from a user that doesn't have the privilege to view those posts. This will function similar to the Author role however this "privilege" is controlled by an ACF User relationship field and not by a WP Core role or privilege.

One level of complexity deeper, the User relationship field is actually pointing to a parent/grouping custom post type that is then tied to the children post elements I'm attempting to filter. So rather than show just the posts that user has authored, it's also showing posts that others have authored but that they have been granted permission to manage. Let me explain this below...

Custom Post Type: Shoes [shoe]
Custom Post Type: Brands [brand]

  • Let's say you have a "shoe" called "Air Jordans" and you have a "brand" called "Nike".
  • So you create an ACF bidirectional relationship between "Air Jordan" and "Nike".
  • Now let's say you create a user on your site that you want to be able to edit all "Nike" shoes.
  • So you create an ACF User relationship field type in the "brand" post type, and you can assign multiple users to admin that brand.
  • So, when that user logs into the back-end and views all shoes, I want just Nikes shoes to show up and they will have the ability to edit all Nike shoes.

I've built out the logic to handle this on the front-end and it works perfect, and now I'd like to duplicate this on the back-end for filtering there as well. Here's what I built out on the front-end for reference:

$current_user = wp_get_current_user();

/* Get All Brands the Current User can Administer */
$brands_admin_args = array(
  'post_type'   => 'brand',
  'meta_query'  => array(
      array(
          'key'     => 'admins', // This is my ACF User field that tracks brand admins.
          'value'   => '"' . $current_user->ID . '"',
          'compare' => 'LIKE'
      ),
  ),
);
$brands_admin = get_posts($brands_admin_args);


/* Get All Shoes The User Can Administer Based On Each Brand They Can Administer*/
$approved_shoes_args = array(
  'post_type'       => 'shoe',
  'meta_query'      => array(
      'relation'    => 'OR'
  ),
);

foreach ($brands_admin as $ba) {
  array_push($approved_shoes_args['meta_query'], array(
      'key'       => 'shoe_brands', // This is my ACF Relationship field between Shoes and Brands 
      'value'     =>  '"' . $ba->ID . '"',
      'compare'   => 'LIKE'
  ));
}
$approved_shoes = new WP_Query($approved_shoes_args);
Share Improve this question asked May 21, 2019 at 13:52 Mike B.Mike B. 1692 silver badges8 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Your best bet is to use the pre_get_posts hook to adjust the query on the admin side.

Your logic is pretty complicated so I won't try to give you a working example but the snippet below will get you started. Basically, you want to be sure your in the admin and managing the main query.

Codex link

add_action( 'pre_get_posts', 'customize_admin_query' );

function customize_admin_query( $wp_query ) {
    if ( $wp_query->is_admin() && $wp_query->is_main_query() ) {
        // do your customizations in here.
    }
}

Taking @Welcher's suggestion of using pre_get_posts, I took my existing code and compiled the following to filter edit.php page for my custom post based on an ACF field granting the current user's access rights:

add_action( 'pre_get_posts', 'customize_products_for_admins' );
function customize_products_for_admins( $wp_query ) {

    if ( is_admin() && $wp_query->is_main_query() && current_user_can('editor') ) { // I know I need more conditional statements here

        $current_user = wp_get_current_user();

        /* Get All Brands the Current User can Administer */
        $brands_admin_args = array(
            'post_type'   => "brand",
            'meta_query'  => array(
                array(
                    'key'     => "admins",
                    'value'   => '"' . $current_user->ID . '"',
                    'compare' => "LIKE"
                ),
            ),
        );
        $brands_admin   = get_posts($brands_admin_args);

        /* Get All Shoes The User Can Administer Based On Each Brand They Can Administer */
        $approved_shoes_args = array(
            'meta_query'      => array(
                'relation'    => "OR"
            ),
        );

        foreach ($brands_admin as $ba) {
            array_push($approved_shoes_args['meta_query'], array(
                'key'       => "shoe_brands", // This is my ACF Relationship field between Shoes and Brands
                'value'     =>  '"' . $ba->ID . '"',
                'compare'   => "LIKE"
            ));
        }
        $wp_query->set('meta_query', $approved_shoes_args);
    }
}
发布评论

评论列表(0)

  1. 暂无评论