Support

Account

Home Forums General Issues oEmbed Cache Reply To: oEmbed Cache

  • Unfortunately, a call is made each time.

    Looking at acf_field_oembed::wp_oembed_get(), the field type relies primarily on WordPress’ wp_oembed_get(). That function does not support caching.

    If wp_oembed_get() fails, then the field type will try with WP_Embed::shortcode() which does support caching (internally uses wp_oembed_get() :p ).

    I’ve come up with two solutions.

    1. Skip format value

    
    $url   = get_field('oembed', false, false);
    $embed = $wp_embed->shortcode([ 'width' => 640, 'height' => 390 ], $url);
    

    2. Via ACF Filters

    The solution I implemented:

    
    /** Disables acf_field_oembed::format_value() */
    add_action( 'acf/init', function () {
        $field_type = acf_get_field_type('oembed');
        remove_filter( 'acf/format_value/type=oembed', [ $field_type, 'format_value' ] );
    }, 1 );
    
    /** Fetch the cached oEmbed HTML; Replaces the original method */
    add_filter( 'acf/format_value/type=oembed', function ( $value, $post_id, $field ) {
        if ( ! empty( $value ) ) {
            $value = acf_oembed_get( $value, $post_id, $field );
        }
    
        return $value;
    }, 10, 3 );
    
    /** Cache the oEmbed HTML */
    add_filter( 'acf/update_value/type=oembed', function ( $value, $post_id, $field ) {
        if ( ! empty( $value ) ) {
            // Warm the cache
            acf_oembed_get( $value, $post_id, $field );
        }
    
        return $value;
    }, 10, 3 );
    
    /**
     * Attempts to fetch the embed HTML for a provided URL using oEmbed.
     *
     * Checks for a cached result (stored as custom post or in the post meta).
     *
     * @see  \WP_Embed::shortcode()
     *
     * @param  mixed   $value   The URL to cache.
     * @param  integer $post_id The post ID to save against.
     * @param  array   $field   The field structure.
     * @return string|null The embed HTML on success, otherwise the original URL.
     */
    function acf_oembed_get( $value, $post_id, $field )
    {
        if ( empty( $value ) ) {
            return $value;
        }
    
        global $wp_embed;
    
        $attr = [
            'width'  => $field['width'],
            'height' => $field['height'],
        ];
    
        remove_filter('embed_oembed_html', 'Roots\\Soil\\CleanUp\\embed_wrap');
    
        $html = $wp_embed->shortcode($attr, $value);
    
        add_filter('embed_oembed_html', 'Roots\\Soil\\CleanUp\\embed_wrap');
    
        if ( $html ) {
            return $html;
        }
    
        return $value;
    }