Как я могу очистить встроенные кэши для YouTube в сообщениях по мере их загрузки


У меня есть сайт с множеством постов, сотни/тысячи из которых содержат встроенные видео на YouTube. Большинство использует формат по умолчанию [встраивать]youtube_url[встраивать], и фактический код встраивания хранится в полях oEmbed postmeta.

Я переключил сайт на HTTPS и новый домен, и теперь старые видео не отображаются, если я не сохраню запись повторно. Я не хочу повторно сохранять каждое сообщение по очевидным причинам, и я не хочу заходить в базу данных и вслепую удалять все oEmbed кэш сразу, это единственные другие варианты, которые я нашел во время поиска.

Что мне нужно, так это фильтр в системе oEmbed, который обновит кэш YouTube oEmbed по мере фактической загрузки сообщений, по сути, просто способ аннулирования кэшей во время загрузки сообщений.

В идеале это было бы применимо только к встраиваниям YouTube (хотя и было бы открыто для повторного использования) и позволило бы мне проверить дату публикации, чтобы избежать повторной выборки выходных данных для записей, созданных после переключения HTTPS.

Похоже, это то, что многим из нас нужно по многим причинам, так что, надеюсь, есть элегантный способ:)

Author: jerclarke, 2015-09-23

1 answers

Как запустить регенерацию встроенного кэша

Время кэширования по умолчанию составляет 24 часа, и мы можем настроить его с помощью фильтра oembed_ttl.

Но, как вы заметили, кэша с истекшим сроком действия недостаточно для запуска регенерации кэша.

Причина в этой строке в классе WP_Embed:

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

Таким образом, чтобы запустить регенерацию, нам нужно, чтобы как истекший срок действия кэш , так и свойство usecache объекта $wp_embed было false.

Когда мы сохраните запись, мы также выполняем вызов ajax для wp_ajax_oembed_cache(), который запускает метод WP_Embed::cache_oembed(). Этот метод временно устанавливает свойство usecache в значение false.

Пример #1

Мы можем принудительно восстановить кэш для кэша с истекшим сроком действия с помощью:

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

И мы можем дополнительно скорректировать время истечения до часа с помощью:

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

Обратите внимание, что при загрузке отдельных сообщений может возникнуть задержка из-за регенерации кэша. Вызов ajax может быть обходным решением. При таком подходе кэш всегда будет готов к повторному созданию, когда срок его действия истечет. В следующем примере мы попытаемся решить эту проблему, обновив ее только один раз.

Пример #2

Вот еще один подход к обновлению встроенного HTML-кода при загрузке одного сообщения, но только один раз.

Мы устанавливаем фиксированное время повторного кэширования (текущее), и когда загружается одна запись, мы сравниваем ее со временем последнего кэширования HTML-кода oEmbed.

Если последнее время кэширования было до повторного кэширования , затем нам нужно его регенерировать.

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 
             && ! did_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-cleaning
            do_action( 'wpse_do_cleanup' );
        }
    }
    return $ttl;
}, 10, 4 );

И тогда нам тоже может понадобиться это:

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

Надеюсь, вы сможете скорректировать это в соответствии с вашими потребностями.

 9
Author: birgire, 2020-01-18 14:19:13