switch_to_blog()を信頼するにはどうすればよいですか?


18

switch_to_blog()ブログID を使用して電話をかけると、そのブログが実際に存在するかどうかわかりません。関数は常にを返しますTRUE

テストケース:

switch_to_blog( PHP_INT_MAX );
$post = get_post( 1 );
restore_current_blog();

これにより、ユーザーに公開されるデータベースエラーが発生します。どうすればそれを防ぐことができますか?

実世界のユースケース

私はMultilingual Pressの主任開発者でした。ユーザーが投稿を翻訳すると、次のような画面が表示されます。

ここに画像の説明を入力してください

これで、次のことが起こります。

  1. 彼女は投稿を正常に保存し、投稿の翻訳を続けます。
  2. 別のユーザーであるネットワーク管理者は、執筆中にドイツのブログを削除します。
  3. 彼女はもう一度保存を押し、データベースエラーを取得します。

私はそのシナリオを避けたいです。対象のブログが存在するかどうかをすばやく確認するにはどうすればよいですか?私はswitch_to_blog()非常に頻繁に複数の異なるクラスで呼び出すため、高速でなければなりません。


どの程度$wpdb->blogid;とフックwp_insert_post_data
JMau 14年

@JMau get_post()は単なる読み取りです。最後の保存から次の編集画面の再読み込みまでの間に長い一時停止が生じる場合があります。
FUXIA

5
wp_blogsテーブルのblog_idに対するリクエストごとのキャッシュされたSQLクエリ(削除済み= 0)
gmazzap

1
@GMSELECT blog_id FROM {$wpdb->blogs} WHERE site_id = %d AND public = '1' AND archived = '0' AND spam = '0' AND deleted = '0'
kaiser

@toscho 大声で考える ...がありますがwp_cache_switch_to_blog()、それは永続的なキャッシュでのみ役立ち、ページWPのデフォルトではありません。とにかく、ブログの存在を確認したい場所が本当に明確ではありません:誰かがブログを削除したり、別のブログを指す翻訳された投稿を書いたりするとき(同じコンテンツを別の言語で提供する)?
カイザー14年

回答:


10

チェックをキャッシュするという@GMのアイデアは、次のヘルパー関数につながりました。私はそれをどこでも利用できるようにグローバル名前空間に入れました。

この関数は、ブログのステータスについては何も言わず、単に存在し、削除済みとしてマークされていない場合のみです。データベースクエリは非常に高速(0.0001秒)で、関数が呼び出される頻度に関係なく、サイトIDごとに1つのクエリのみを実行します。

if ( ! function_exists( 'blog_exists' ) ) {

    /**
     * Checks if a blog exists and is not marked as deleted.
     *
     * @link   http://wordpress.stackexchange.com/q/138300/73
     * @param  int $blog_id
     * @param  int $site_id
     * @return bool
     */
    function blog_exists( $blog_id, $site_id = 0 ) {

        global $wpdb;
        static $cache = array ();

        $site_id = (int) $site_id;

        if ( 0 === $site_id )
            $site_id = get_current_site()->id;

        if ( empty ( $cache ) or empty ( $cache[ $site_id ] ) ) {

            if ( wp_is_large_network() ) // we do not test large sites.
                return TRUE;

            $query = "SELECT `blog_id` FROM $wpdb->blogs
                    WHERE site_id = $site_id AND deleted = 0";

            $result = $wpdb->get_col( $query );

            // Make sure the array is always filled with something.
            if ( empty ( $result ) )
                $cache[ $site_id ] = array ( 'do not check again' );
            else
                $cache[ $site_id ] = $result;
        }

        return in_array( $blog_id, $cache[ $site_id ] );
    }
}

使用法

if ( ! blog_exists( $blog_id ) )
    return new WP_Error( '410', "The blog with the id $blog_id has vanished." );

なぜ$wpdb->get_results+ wp_list_pluckのみの代わりに(int) $wpdb->get_var?しかし+1、と私は似た何かがコアswitch_to_blogであるべきだと思う...
gmazzap

@GM get_var()は結果を1つだけ返します。get_col()現在使用していますが、空の結果が再度フェッチされないようにしました。
FUXIA

ええと...クエリを今すぐ読んで、特定のサイトIDのすべてのブログIDを取得します。最初に読むと、一度に1つのブログID(関数に渡されたもの)しか取得できません...配列を確認してください方法が優れています。申し訳ありませんが、再び+1することはできません:)
gmazzap
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.