AdvancedCustomFields / acf

Advanced Custom Fields
http://advancedcustomfields.com/
823 stars 168 forks source link

acf/location/rule_match not called from acf/ajax/check_screen request. #885

Open andyg2 opened 7 months ago

andyg2 commented 7 months ago

Describe the bug I'm filtering the rules matching via the acf/location/rule_match filter. This is working successfully when loading an existing post. Unfortunately this filter is not called when a user selects a category, which fires the acf/ajax/check_screen request.

To Reproduce Steps to reproduce the behavior:

  1. Create any rule based on a taxonomy ( WooCommerce product category )
  2. Create a new product
  3. Select any category > ajax is fired to check for applicable field sets.
  4. Applicable rules are not populated.

This is the filter function I'm using (working for existing products) - minimal version below.

/**
 * Filter ACF location rules to show fields for products in the subcategories of rule category.
 *
 * @param bool $match Whether the rule matches or not.
 * @param array $rule The ACF location rule.
 * @param array $options Additional options for the rule.
 * @return bool Whether the rule matches or not.
 */
function customize_acf_location_rules($match, $rule) {
  if (!is_admin() || !isset($rule['value'])) {
    return $match;
  }
  $match_cats = ['guns', 'gas', 'magazines'];
  foreach ($match_cats as $match_cat) {
    $target_rule = 'product_cat:' . $match_cat;

    // editing a product?
    if (defined('DOING_AJAX') && DOING_AJAX) {
      $is_correct_page = isset($_REQUEST['action']) && $_REQUEST['action'] = 'acf/ajax/check_screen';
    } else {
      $is_correct_page = isset($_REQUEST['post_type']) && $_REQUEST['post_type'] == 'product';
    }

    // include subcategories of ACF rule
    if ($rule['value'] ===  $target_rule && $is_correct_page) {
      $product_categories = wp_get_post_terms(get_the_ID(), 'product_cat', ['fields' => 'ids']);
      $focus_category = get_term_by('slug', $match_cat, 'product_cat');

      if ($focus_category) {
        $ancestor_category = $focus_category->term_id;
        $child_categories = get_term_children($ancestor_category, 'product_cat');
        if (in_array($ancestor_category, $product_categories) || array_intersect($product_categories, $child_categories)) {
          return true;
        }
      }
    }
  }
  return $match;
}
add_filter('acf/location/rule_match', 'customize_acf_location_rules', 10, 2);

For testing, this should supposedly stop the ajax request, showing the filter is not being called for ajax requests.

function customize_acf_location_rules($match, $rule) {
  // Exiting here should prevent the ajax request returning valid JSON, It doesn't

  exit;

}
add_filter('acf/location/rule_match', 'customize_acf_location_rules', 10, 2);

Expected behavior I would expect ajax requests to determine which field groups are applicable would be filtered through acf/location/rule_match. If this is intentional, I would appreciate an alternate method to filter the applicable field groups via Ajax

Code acf-export-2023-11-19.json

Version Information: