web-dev-qa-db-fra.com

Comment ajouter des publications au résultat wp_query?

J'ai 2 groupes d'utilisateurs: auteurs et clients

Les auteurs peuvent publier des publications et spécifier dans metabox le client correspondant à ces publications.

Le client peut publier des messages et les afficher, les modifier, créés par auteurs pour eux.

Problème:

Dans wp-admin sur l'écran des messages ( wp-admin/edit.php ), je dois afficher:

if Auteur : uniquement les messages de l'auteur

if Client : publications du client et publications où la méta-valeur est l'identifiant du client

if admins : tous les messages

I'v a ajouté pre_get_posts filter pour ne filtrer que les publications d'auteurs:


/**
 * Show only author posts, but all for admins
**/
function m7_24_ee_posts_for_current_author( $query ) {

    if( $query->is_admin && 'post' == $query->query_vars['post_type'] && ! current_user_can( 'administrator' ) ) {
        global $user_ID;
        $query->set( 'author',  $user_ID );
        if( current_user_can( 'client' ) ) {
            $query->set( 'meta_key', 'client' );
            $query->set( 'meta_value', $user_ID );
        }
    }
    return $query;
}
add_filter( 'pre_get_posts', 'm7_24_ee_posts_for_current_author' );

Mais le problème est que les champs meta_key et author agissent comme AND, mais j'ai besoin qu'ils soient "OU". ou l'auteur est $ user_ID ou meta_value est $ user_ID

S'il n'y a pas de solution facile à ces problèmes, il est possible de résoudre 2 requêtes (1 avec l'auteur et 2 avec la méta-valeur), mais le problème est que je ne sais pas quel crochet dois-je utiliser pour les lier, car pre_get_posts est enflammé trop tôt.

Voici un hack pour la requête principale post dans wp-admin qui devrait faire l'affaire:

/**
 * Modification of the wp-admin main (post) query: 
 *     If current user has the "client" role then 
 *     show client's posts OR posts where the "client" meta value is the client id.
 *
 * @see http://wordpress.stackexchange.com/a/173967/26350
 */

function wpse_pre_get_posts( $q )
{
    if( is_admin()
        && $q->is_main_query()
        && 'post' === $q->get( 'post_type' ) 
        && ! current_user_can( 'administrator' )  
    ) 
    {
        $q->set( 'author',  get_current_user_id() );
        if( current_user_can( 'client' ) ) 
        {
            $q->set( 'author',  null );
            $q->set( 'meta_key', 'client' );
            $q->set( 'meta_value', get_current_user_id() );
            add_filter( 'posts_where', 'wpse_posts_where' );
        }
    }
    return $query;
}
add_filter( 'pre_get_posts', 'wpse_pre_get_posts' );

où le rappel pour le filtre posts_where est défini comme suit:

function wpse_posts_where( $where )
{
    global $wpdb;
    remove_filter( current_filter(), __FUNCTION__ );
    return str_ireplace(
        "{$wpdb->postmeta}.meta_key",
        sprintf( 
            "{$wpdb->posts}.post_author = %d 
             OR {$wpdb->postmeta}.meta_key", 
            get_current_user_id() 
        ),
        $where
    );
}

où je suppose qu'il y a non d'autres méta requêtes sur la requête principale post dans wp-admin. Si ce n'est pas le cas, vous devriez pouvoir l'affiner davantage.

1
birgire