web-dev-qa-db-ja.com

ネットワーク内の複数のサイトから投稿を問い合わせる

私は私が追い求めている解決策のまわりで踊るいくつかの質問があることを認識していますが、私は私が何か特別なことを探していると信じています。

これは実際には二部構成の質問です。

1)私の目標はワードプレスをネットワーク(マルチサイト)モードで動作させることであり、私は本質的に特定のサイトを一緒に「グループ化」する方法を見つけようとしています。私は "マルチネットワーク"プラグインを知っていますが、これがこれに対する最善のアプローチであるかどうか私は質問しますか?ここで重要なのは、特定のユーザーが自分のサブネットワーク内でサイトを追加/編集できるようにすることです。

2)これはこの記事の重要な問題です...私は私がサイトのこの「サブネットワーク」の中から本質的に記事を問い合わせることを可能にするであろう最善のアプローチを知りたいのですが。したがって、たとえば、このサブネットワーク内に10のサイトがあり、それぞれが "news"というカスタム投稿タイプ内に投稿を作成した場合、たとえば、この10のコレクションから最近公開された10の投稿を表示できます。サイト.

注:私は複数のサブネットワークを作成することができるという能力が必要です。それは今度は最新の「ニュース」のクエリが正しいグループに属するものからの投稿しか表示できないことを意味します。

最後に - 私はこのようなことを行うための解決策が存在することを認識していますが、私はデータベース負荷/クエリの最小量を必要とする両方のケースで最良のアプローチを探しています。余分な肥大化を引き起こすプラグインをインストールするのではなく、私のfunctions.phpファイルのコードを通してこれをしたいと思います。

私はどんな提案にも非常に寛容で、どんな反応にも感謝します。

8

私はあなたがむしろプラグインをインストールしたくないと言ったことを知っていますが、それはまさにこの状況であなたがやりたいことです。テーマのfunctions.phpファイルにコードを配置するには、サブネットワーク内のすべてのサイトで同じテーマを使用するか、同じファイルの複数のコピーを維持する必要があります。その一方で、機能をカプセル化するための簡単なプラグインを作成し、それをネットワーク上で 有効にして 、すぐに使用可能な機能を1つのファイルだけで維持することができます。これは実際にあなたのfunctions.phpファイルに依存するよりもless肥大化するでしょう。

ここで覚えておくべきことは、あなたがあなたの投稿を見つけるかカスタムクエリを実行するためにネットワーク上の各サイトをループする必要があるということです。もう少し複雑ですが、ブログごとに異なるクエリではなく単一のクエリを実行するため、2番目のルーチンを選択します。

基本的には次のことを行う必要があります。

  1. ネットワーク/サブネットワーク内のすべてのブログIDのリストを取得します。 Vanillaインストールを使用している場合、これは wp_blogs テーブルにあります。単純なSELECTクエリを実行して配列を読み込むだけで、ループして各ブログをメインクエリに追加できます。
  2. 各ブログを大きなクエリに追加するループを作成します。あなたは一緒にテーブルをJOINingし、(blog_idから)wp_blogs、(post_idから)wp_BLOG_posts、そしてカスタム分類法に基づいて検索する必要があります。

私が言ったように、それは簡単な解決策ではありません(SQLステートメントはvery複雑になるでしょう、そして私は今それをハックする時間がありません)。すべての作業を行う単一のステートメント.

代わりに...

  1. ブログIDのリストを取得してそれを配列に格納します。
  2. ネットワーク内の各ブログを検索し、一致(特定の分類用語を使用した投稿)を別のアレイに追加することで、アレイを繰り返します。

別の方法では、ネットワーク内のブログごとに個別のクエリを実行する必要があります。あなたのネットワークが10-20サイトであれば、これはそれほど問題ではありません。ネットワークが200〜500サイトの場合、パフォーマンスの問題が発生することが予想されます。

また、可能であれば、クエリの結果をキャッシュする必要があります。それが複数のページロードで実行されている場合(つまり、ネットワーク上で共有されているサイドバーウィジェットの場合)、取得する新しいデータがあるときにのみクエリを実行します。それ以外の場合は、キャッシュされた結果を処理して、ネットワークの速度を落とさないようにします。

7
EAMann

私は同様の問題を抱えていました。私はコメントでソートされたすべてのネットワークサイトにわたる投稿のリストを入手する必要がありました(最も人気のある投稿を表示するため)。これが私が使った機能です。

基本は、ネットワーク内のすべてのブログIDのリストを最初に取得することです。次に、blog_id、ID、およびcomment_count列を含む結果を取得する、大きな単一のクエリ(UNIONを使用してすべての行を結合し、見苦しいJOINを必要としない)を作成します。それを使って、get_blog_post()を使って各投稿の詳細情報を取得します。

何が起こっているのかを確認するためにさまざまな時点で使用できるデバッグ行がいくつかあります。

function txx_top_posts_mu( $howMany = 10 ) {
global $wpdb;
global $table_prefix;

// get an array of the table names that our posts will be in
// we do this by first getting all of our blog ids and then forming the name of the 
// table and putting it into an array
$rows = $wpdb->get_results( "SELECT blog_id from $wpdb->blogs WHERE
    public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0';" );
if ( $rows ) :
    $blogPostTableNames = array();
    foreach ( $rows as $row ) :
        $blogPostTableNames[$row->blog_id] = $wpdb->get_blog_prefix( $row->blog_id ) . 'posts';
    endforeach;
    //print_r($blogPostTableNames);

    // now we need to do a query to get all the posts from all our blogs
    // ordered by the number of comments and with limits applied
    if ( count( $blogPostTableNames ) > 0 ) :
        $query = '';
        $i = 0;
        foreach ( $blogPostTableNames as $blogId => $tableName ) :
            if ( $i > 0 ) :
                $query.= ' UNION ';
            endif;
            $query.= " SELECT ID, comment_count, $blogId as `blog_id` FROM $tableName ";
            $i++;
        endforeach;
        $query.= " ORDER BY comment_count DESC LIMIT 0,$howMany;";
        //echo $query;
        $rows = $wpdb->get_results( $query );

        // now we need to get each of our posts into an array and return them
        if ( $rows ) :
            $posts = array();
            foreach ( $rows as $row ) :
                $posts[] = get_blog_post( $row->blog_id, $row->ID );
            endforeach;
            //print_r($posts);
            return $posts;
        endif;
    endif;
endif;
return false;

}

1
user3967