web-dev-qa-db-fra.com

Comment effacer les caches oEmbed pour YouTube dans les publications au fur et à mesure de leur chargement

J'ai un site avec des tonnes de messages postés par centaines/milliers de personnes qui incluent des vidéos YouTube. La plupart utilisent le format par défaut [embed] youtube_url [embed] et le code incorporé réel est stocké dans les champs postmeta oEmbed.

J'ai basculé le site vers HTTPS et un nouveau domaine, et maintenant les anciennes vidéos ne s'affichent que si je réenregistre le message. Je ne souhaite pas réenregistrer tous les messages pour des raisons évidentes, ni dans la base de données pour supprimer aveuglément tous les caches oEmbed à la fois, qui sont les seules autres options que j'ai trouvées lors de la recherche.

Ce que je veux, c’est un filtre sur le système oEmbed qui mettra à jour les caches oEmbed de YouTube au fur et à mesure que les messages sont chargés, c’est simplement un moyen de les invalider pendant le chargement des articles.

Dans l'idéal, il ne s'appliquerait qu'aux inserts YouTube (bien que pouvant être réutilisé) et me permettrait de vérifier la date du message pour éviter de récupérer à nouveau la sortie oEmbed pour les messages créés après le commutateur HTTPS.

On dirait que c'est une chose dont beaucoup d'entre nous ont besoin pour de nombreuses raisons, alors espérons qu'il existe un moyen élégant :)

5
jerclarke

Comment déclencher une régénération de cache oembed

La durée de cache par défaut est de 24 heures et nous pouvons l’ajuster avec le filtre oembed_ttl.

Mais comme vous l'avez remarqué, cache expiré n'est pas suffisant pour déclencher une régénération de cache.

La raison en est cette ligne dans la classe WP_Embed:

if ( $this->usecache || $cached_recently ) {

aussi, pour déclencher une régénération, il faut que la propriété expired cache et / usecache de l’objet $wp_embed soit false.

Lorsque nous sauvegardons une publication, nous effectuons également un appel ajax à wp_ajax_oembed_cache() qui exécute la méthode WP_Embed::cache_oembed(). Cette méthode définit temporairement la propriété usecache sur false.

Exemple 1

Nous pouvons forcer une régénération de cache pour un cache expiré avec:

add_action( 'template_redirect', function()
{    
    if( is_single() )
        $GLOBALS['wp_embed']->cache_oembed( get_queried_object_id() );  
});

et nous pouvons encore ajuster le délai d’expiration à une heure avec:

add_filter( 'oembed_ttl', function( $ttl )
{
    return HOUR_IN_SECONDS; // Adjust to your needs
} );

Notez que nous pouvons rencontrer un retard lors du chargement des publications uniques, en raison de la régénération du cache. Un appel ajax pourrait être une solution de contournement. Avec cette approche, le cache sera toujours prêt pour la régénération, une fois expiré. Dans l'exemple suivant, nous essayons de résoudre ce problème en l'actualisant une seule fois.

Exemple n ° 2

Voici une autre approche sur la façon d'actualiser le HTML oEmbed, lors de chargements de publication uniques, mais une seule fois.

Nous définissons un recache time (actuel) fixe et, lorsqu'un seul article est chargé, nous le comparons à l'heure à laquelle le HTML oEmbed a été mis en cache pour la dernière fois.

Si la dernière heure de cache est antérieure à recache time, nous devons le régénérer.

add_filter( 'oembed_ttl', function( $ttl, $url, $attr, $post_ID )
{
    // Only do this on single posts
    if( is_single() )
    {
        // Oembeds cached before this time, will be recached:
        $recache_time  = '2015-09-23 23:26:00';     // <-- Set this to the current time.

        // Get the time when oEmbed HTML was last cached (based on the WP_Embed class)
        $key_suffix    = md5( $url . serialize( $attr ) );
        $cachekey_time = '_oembed_time_' . $key_suffix;
        $cache_time    = get_post_meta( $post_ID, $cachekey_time, true );

        // Get the cached HTML 
        $cachekey      = '_oembed_' . $key_suffix;
        $cache_html    = get_post_meta( $post_ID, $cachekey, true );

        // Check if we need to regenerate the oEmbed HTML:
        if(     
                $cache_time < strtotime( $recache_time )     // cache time check
             && false !== strpos( $cache_html, 'youtube' )   // contains "youtube" stuff 
             && ! do_action( 'wpse_do_cleanup' )             // let's just run this once 
             && 1 === $GLOBALS['wp_embed']->usecache
        ) {
            // What we need to skip the oembed cache part
            $GLOBALS['wp_embed']->usecache = 0; 
            $ttl = 0;               
            // House-cleanoing
            do_action( 'wpse_do_cleanup' );
        }
    }
    return $ttl;
}, 10, 4 );

et alors nous pourrions aussi avoir besoin de celui-ci:

// Set the usecache attribute back to 1.
add_filter( 'embed_oembed_discover', function( $discover )
{
    if( 1 === did_action( 'wpse_do_cleanup' ) )
        $GLOBALS['wp_embed']->usecache = 1;
    return $discover;
} );

J'espère que vous pourrez adapter cela à vos besoins.

6
birgire