web-dev-qa-db-fra.com

Comment faire confiance à switch_to_blog ()?

Lorsque j’appelle switch_to_blog() avec un identifiant de blog, je ne sais pas si ce blog existe réellement. La fonction retourne toujours TRUE.

Cas de test:

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

Cela entraînera des erreurs de base de données qui seront exposées à l'utilisateur. Comment puis-je empêcher ça?

Cas d'utilisation dans le monde réel

J'étais le développeur principal de Multilingual Press . Lorsqu'un utilisateur traduit une publication, il obtient un écran comme celui-ci:

enter image description here

Maintenant ce qui suit peut arriver:

  1. Elle enregistre le message avec succès et continue de le traduire.
  2. Un autre utilisateur, un administrateur réseau, supprime le blog allemand alors qu'elle écrit.
  3. Elle clique à nouveau sur Save et obtient des erreurs de base de données.

Je veux éviter ce scénario. Comment puis-je vérifier rapidement si le blog cible existe? J'appelle switch_to_blog() très souvent dans plusieurs classes différentes, il faut donc que ce soit rapide.

18
fuxia

L’idée de @G.M. de mettre en cache le contrôle m’a amené à la fonction d’aide suivante. Je l’ai mis dans l’espace de noms global pour le rendre disponible partout.

La fonction ne dit rien sur le statut du blog, juste s'il existe et qu'il n'est pas marqué comme supprimé. La requête dans la base de données est très rapide (0,0001 seconde) et exécute une requête par identifiant de site, quelle que soit la fréquence d’appel de la fonction.

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 ] );
    }
}

Usage

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