web-dev-qa-db-ja.com

カスタムビューで動作するWP_Query

wp_posts上に データベースVIEW を作成しました。これはすべての列を選択し、追加の計算列(平均)を公開します。だから私のビューはwp_postsに1つの列を加えたものにしたもので、後の段階でソートに使用したいものです。

  • そのビューにWP_Queryをバインドする方法はありますか?
  • 一般的に、WP_Queryのすべての必須列を持つカスタムテーブルにWP_Queryをバインドすることは可能ですか?

$wpdb->get_results( _custom_query_here_ )を使ってレコードを取得することはできますが、WP_Query機能を使うことはできません。

P.S .: WP_Query::parse()が私の好奇心に対する答えだと思ったが、どうやらそうではない。

編集

これが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;

編集2:

ここで@ birgireによって提供された解決策から: https://wordpress.org/support/topic/changing-table-name-and-make-wordpress-still-working 、次のコードを使用しました。

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

WP_Queryは正常に実行されましたが、フィールドrating_averageにアクセスできません。

3
Annie

フロントエンドでカスタムビューを使用します。

次の(alpha)プラグインを使ってフロントエンドのSELECTクエリを修正することができます。

<?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 );

queryクラスのwpdbフィルターを使用して。

INSERTUPDATE、およびDELETEクエリを変更したくありません。

これはネイティブのwpdbクラスから作られたクエリにのみ影響しますが、例えば直接MySQLiコールには影響しません。

データベースへの接続時に、プラグインとテーマがネイティブのwpdbクラスをバイパスする可能性があることにはもちろん注意してください。

より複雑なクエリの例もあります。 SELECTとINSERTの組み合わせ上記のプラグインはこれらの場合に合わせて修正することができます。

注意:試す前に必ずバックアップを取ってください。

カスタムビューの追加フィールドにアクセスする:

追加のrating_averageフィールドがWP_Postインスタンスで利用できるようになります。

$post->rating_average

カスタムテンプレートタグを作成することもできます。

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

ここではget_the_ID()関数の構造を修正しています。

対応する表示機能は次のとおりです。

function the_rating_average()   
{
    echo get_the_rating_average();
}  

ループ内の追加フィールドに簡単にアクセスできます。

$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;

追加フィールドには、デフォルトのフィールドではまだ使用されていない名前を使用することをお勧めします。

4
birgire