Support

Account

Forum Replies Created

  • This lightweight solution worked for me:

    
    function my_acf_render_field( $field ) {
    	if ( did_action('acf/render_field/key=field_508a263b40457') % 2 === 0 ) {
    		return;
    	}
    
    	echo '<p>Some extra HTML for the post object field</p>';
    }
    add_action( 'acf/render_field/key=field_508a263b40457', 'my_acf_render_field' );
    

    Using the modulus division operator, the function will bail early every 2nd execution.

  • 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;
    }
    
  • This is how I added support to limit the number of selectable checkboxes:

    
    acf.add_action('ready', function( $el ){
        var limit    = 4,
            selector = '.acf-field-573408b96dcd4 :checkbox',
            $boxes   = $(selector),
            limiter  = function () {
                if ($boxes.filter(':checked').length >= limit) {
                    // this.checked = false;
                    $boxes.not(':checked').attr('disabled', true).prop('disabled', true);
                } else {
                    $boxes.filter(':disabled').removeAttr('disabled').prop('disabled', false);
                }
            };
    
        if ($boxes.length) {
            limiter();
        }
    
        $(document).on('change.aqcpe.acf.careers', selector, limiter);
    });
    
  • Hi,


    @elliot
    I stumbled upon this forum thread in search of a Composer or Git version of ACF Pro. Currently, I’m managing a private manually synced Git repository of ACF Pro that I use as a Git submodule.

    For my next project, I’m leaning on using a Composer package-defined repository, as per this Gist.

    I was wondering if its possible to be added to this private repository. I like to use edge-versions of WordPress and plugins while a site is in development and due for launch after said packages are golden.

    My GitHub username is “mcaskill”.

    Thanks

  • Hi,

    I don’t know if we are sharing the same issue (and for me, the issue stretches further back than 5.2.5) but I’ve figured out mine.

    The Context:

    The project I’m currently working on uses Polylang for translations. Custom fields aren’t set to be translated, their data is synced manually.

    I have a post object setup to retrieve posts from two custom post types: partner and sponsor. These post types aren’t configured to be multilingual.

    The Issue:

    In acf_field_post_object::render_field(), if there’s a saved value, ACF will retrieve all posts matching the saved value (in order to pre-populate the rendered field).

    
    $posts = acf_get_posts(array(
    	'post__in' => $field['value']
    ));
    

    Unfortunately, this returns an empty array because acf_get_posts() will default to loading from all available post types. In my case, acf_get_post_types() returns: post, page, attachment, partner, and sponsor.

    And this is the key problem: post and page are configured to be multilingual. This triggers Polylang to add a condition to fetch posts in the current language which the non-multilingual post types can’t fulfill.

    First Solution:

    Require ACF to pass along the filtered list of post types:

    
    $posts = acf_get_posts(array(
    	'post__in' => $field['value'],
    	'post_type' => $field['post_type']
    ));
    

    The one downside of this is if the list of filtered post types changes (e.g., a post type is removed), it will affect any currently saved value assigned to that now-removed post type.

    Second Solution:

    Intercept Polylang before it adds that language condition to the WP_query. I accomplish this using a backtrace to figure out if the WP_query was called by acf_get_posts() by way of acf_field->render_field().

    **Updated 2015-05-21T17:22-05:00**

    
    add_action( 'pre_get_posts', function ( &$wp_query ) {
    	$is_acf_get_posts = (
    		   ( $e = new Exception )
    		&& ( $trace = $e->getTraceAsString() )
    		&& false !== strpos( $trace, 'acf_get_posts(Array)' )
    		&& (
    			   (   is_admin() && false !== strpos( $trace, '->render_field(Array)' ) )
    			|| ( ! is_admin() && false !== strpos( $trace, '->format_value(' ) )
    		)
    	);
    
    	if ( $is_acf_get_posts && pll_is_not_translated_post_type( $wp_query->get('post_type') ) ) {
    		pll_remove_language_query_var( $wp_query );
    	}
    }, 9 );
    
    function pll_is_not_translated_post_type( $post_type ) {
    	global $polylang;
    
    	if ( isset( $polylang ) ) {
    		$pll_post_types = $polylang->model->get_translated_post_types( false );
    
    		return ( is_array( $post_type ) && array_diff( $post_type, $pll_post_types ) || in_array( $post_type, $pll_post_types ) );
    	}
    
    	return false;
    }
    
    function pll_remove_language_query_var( &$query ) {
    	$qv = &$query->query_vars;
    
    	unset( $qv['lang'] );
    
    	if ( ! empty( $qv['tax_query'] ) ) {
    		foreach ( $qv['tax_query'] as $i => $tax_query ) {
    			if ( isset( $tax_query['taxonomy'] ) && 'language' === $tax_query['taxonomy'] ) {
    				unset( $qv['tax_query'][ $i ] );
    			}
    		}
    	}
    }
    

    I made this filter very verbose just to make sure the idea is understand. I’m using a much more compact version in my project. This function can also be easily translated to your multilingual-plugin flavour (e.g., WPML).

    Cheers,

Viewing 5 posts - 1 through 5 (of 5 total)