web-dev-qa-db-fra.com

WP_Query pour travailler avec la vue personnalisée

J'ai créé une base de données VIEW sur wp_posts qui sélectionne toutes ses colonnes et expose une colonne supplémentaire calculée (moyenne). Ainsi, ma vue est identique à wp_posts plus une colonne, que je souhaite utiliser pour le tri à un stade ultérieur.

  • Existe-t-il un moyen de lier WP_Query à cette vue?
  • En général, est-il possible de lier WP_Query à une table personnalisée contenant toutes les colonnes obligatoires de WP_Query?

Je peux obtenir des enregistrements avec $wpdb->get_results( _custom_query_here_ ), mais cela ne me permet pas d'utiliser les fonctionnalités de WP_Query.

P.S .: Je pensais que WP_Query::parse() était la réponse à ma curiosité, mais apparemment pas.

MODIFIER

Voici la requête VIEW:

CREATE VIEW `calculated_posts`
AS 
  SELECT *, 
         (SELECT Avg(CAST(`meta_value` as SIGNED))
          FROM   `wp_commentmeta` 
          WHERE  meta_key = 'rating' 
                 AND comment_id IN (SELECT comment_id 
                                    FROM   wp_comments 
                                    WHERE  comment_post_id = ID)) AS 
            rating_average 
  FROM   wp_posts;

Modifier 2:

De la solution fournie par @birgire, ici: https://wordpress.org/support/topic/changing-table-name-and-make-wordpress-still-working , j'ai utilisé le code suivant:

global $wpdb;
$wpdb->posts = 'calculated_posts';

WP_Query s'exécute correctement, mais je ne peux pas accéder au champ rating_average.

3
Annie

Utilisez une vue personnalisée dans l'interface frontale:

Vous pouvez essayer de modifier les requêtes SELECT dans le front-end avec le plugin (alpha) suivant:

<?php
/**
 * Plugin Name: wpdb - a custom SELECT view for the wp_posts table on the front-end
 * Version:     alpha
 */

! is_admin() && add_filter( 'query', function( $query ) {
    global $wpdb;
    $view = 'calculated_posts'; // <-- Edit to your needs.
    if( 'select' === mb_substr( strtolower( $query ) , 0, 6 ) )
        if( false !== mb_stripos( $query, $wpdb->posts ) )
            $query = str_ireplace( $wpdb->posts, $view, $query );

    return $query;
}, PHP_INT_MAX );

en utilisant le filtre query de la classe wpdb.

Nous ne voulons pas modifier les requêtes INSERT, UPDATE et DELETE.

Cela affectera uniquement les requêtes effectuées à partir de la classe native wpdb, mais pas par exemple les appels directs à MySQLi .

Notez qu'il est bien sûr possible que les plugins et les thèmes puissent contourner la classe native wpdb lors de la connexion à la base de données.

Il pourrait également y avoir des exemples de requêtes plus complexes, par exemple. combinaison de SELECT et INSERT. Le plugin ci-dessus pourrait être modifié pour s'adapter à ces cas.

Remarque : n'oubliez pas de faire une sauvegarde avant d'essayer.

Accéder au champ supplémentaire de la vue personnalisée:

Le champ supplémentaire rating_average devrait maintenant être disponible dans l'instance WP_Post, par exemple:

$post->rating_average

Nous pouvons également créer une balise de modèle personnalisé:

function get_the_rating_average()   
{
    $post = get_post();
    return ! empty( $post ) ? $post->rating_average : false;
}  

Ici, je ne fais que modifier la structure de la fonction get_the_ID().

La fonction d'affichage correspondante est:

function the_rating_average()   
{
    echo get_the_rating_average();
}  

Nous pouvons maintenant accéder facilement au champ supplémentaire de la boucle:

$q = new WP_Query( array( 'posts_per_page' => '5' ) );
while( $q->have_posts() ) : $q->the_post();
    the_title();
    the_rating_average();  #<-- displaying our extra field here
endwhile;

Il est également préférable d’utiliser un nom pour notre champ supplémentaire qui n’est pas déjà utilisé par les champs par défaut.

4
birgire