Як я можу довіряти switch_to_blog ()?


18

Коли я дзвоню switch_to_blog()з ідентифікатором щоденника, я не знаю, чи існує цей блог. Функція повертається завжди TRUE.

Тестовий випадок:

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

Це призведе до помилок бази даних, які піддаються користувачеві. Як я можу запобігти цьому?

Справа використання реального світу

Я був провідним розробником багатомовної преси . Коли користувач перекладає публікацію, вона отримує такий екран:

введіть тут опис зображення

Тепер може статися таке:

  1. Вона успішно зберігає публікацію та продовжує перекладати публікацію.
  2. Інший користувач, адміністратор мережі, видаляє німецький блог, поки вона пише.
  3. Вона знову потрапляє на збереження та отримує помилки бази даних.

Я хочу уникнути цього сценарію. Як я можу швидко перевірити, чи існує цільовий блог? Я дзвоню switch_to_blog()дуже часто в декілька різних класів, тому це повинно бути швидким.


Як щодо $wpdb->blogid;гачка wp_insert_post_data?
JMau

@JMau get_post()- це просто читання. Між останнім збереженням та наступним завантаженням екрана редагування може бути довга пауза.
fuxia

5
Запит на кеш SQL запиту для blog_id у таблиці wp_blogs (де видалено = 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. У будь-якому випадку, мені не зовсім зрозуміло, де ви хочете перевірити існування блогу: коли хтось видаляє блог або коли хтось намагається написати перекладений пост, який вказує на інший блог (живлення того ж вмісту іншою мовою)?
кайзер

Відповіді:


10

@ Ідея GM про кешування чека привела мене до наступної функції помічника. Я помістив його в глобальний простір імен, щоб він був доступний всюди.

Функція нічого не говорить про стан блогу, лише якщо він існує і не позначений як видалений. Запит на базу даних дуже швидкий (0,0001 секунди) і виконує лише один запит на ідентифікатор сайту, незалежно від того, як часто функція викликається.

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, і я думаю, що щось подібне має бути в core switch_to_blog ...
gmazzap

@GM get_var()повертає лише один результат. Я використовував get_col()зараз, і я переконався, що порожній результат знову не з’явиться.
фуксія

Ну добре ... Я краще прочитайте запит зараз, ви отримуєте всі ідентифікатори блогу для конкретного ідентифікатора сайту, спочатку прочитайте, я повинен отримати лише один ідентифікатор блогу (той, який перейшов у функцію) ... впевнений масив шлях краще. Вибачте, знову не можливо +1:
gmazzap
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.