ACF archive filter meta query foreach error

Hi, I’ve been having difficulty successfully implementing a filter on a custom post type archive page using Advanced Custom Fields. The query string loads as it should, and returns the correct results. However, it also returns a foreach error on the field choices, and the filter itself disappears. I’ve searched through the ACF and Themeco forums and had no success resolving the issue, and I’ve had a fellow developer look at it with no resolution. Here’s the code from functions.php:

$GLOBALS['my_query_filters'] = array( 
  'Room Type' => 'room_type',
  'Medium' => 'grow_medium', 
);

add_action('pre_get_posts', 'my_pre_get_posts');
function my_pre_get_posts( $query )
{
  if ( !is_admin() && is_post_type_archive('growdiaries') && (isset($_GET['room_type']) || isset($_GET['grow_medium'])) ) {

    $meta_query = $query->get('meta_query');

    foreach( $GLOBALS['my_query_filters'] as $key => $name ) {
    
    if( empty($_GET[ $name ]) ) {
      
      continue;
      
    }
    
    $value = explode(',', $_GET[ $name ]);
    
      $meta_query[] = array(
            'key'   => $name,
            'value'   => $value,
            'compare' => 'IN',
        );

        
  } 

  $query->set('meta_query', $meta_query);

}
  return;

}

And here's the relevant section from my archive-CPT.php:

 <div id="archive-filters" style="margin-bottom: 1em;padding-bottom:1em;border-bottom: 1px solid #e1e1e1;">
  <div><p class="details-p" style="text-align:left;margin-left:0 !important;border-bottom: 1px solid #e1e1e1;width:auto;">Filter By: </p></div>

  <?php foreach( $GLOBALS['my_query_filters'] as $key => $name ): 
  
  // get the field's settings without attempting to load a value
  $field = get_field_object($key, false, false);
  $choice_value = '';
  
  
  // set value if available
  if( isset($_GET[ $name ]) ) {
    
    $field['value'] = explode(',', $_GET[ $name ]);
    
  }
  
  
  // create filter
  ?>
  <div class="filter" data-filter="<?php echo $name; ?>">

<?php 
   $values = get_field($name);
   $field = get_field_object($name, false, false);
   $choices = $field['choices'];
?>


    <p class="details-p" style="text-align:left;margin-left:0 !important;"><?php echo $key; ?>
   
      <?php $values = isset($_GET[ $name ]) ? explode(',', $_GET[ $name ]) : array();
      foreach( $field['choices'] as $choice_value => $choice_label ): //invalid foreach argument here ?>
      <span style="text-transform: capitalize; margin: 0 0.2em;">| <?php echo $choice_label; ?></span>
          <input type="checkbox" value="<?php echo $choice_value ?>" <?php if( in_array($choice_value, $values) ): ?> checked="checked" <?php endif; ?> />
         
     
    <?php endforeach; ?>
    </p>
 </div>
     

  
<?php endforeach; ?>


</div>


<script type="text/javascript">

(function($) {
  
  // change
  $('#archive-filters').on('change', 'input[type="checkbox"]', function(){

    // vars
    var url = '<?php echo home_url('growdiaries'); ?>';
      args = {};
      
    
    // loop over filters
    $('#archive-filters .filter').each(function(){
      
      // vars
      var filter = $(this).data('filter'),
        vals = [];
      
      
      // find checked inputs
      $(this).find('input:checked').each(function(){
  
        vals.push( $(this).val() );
  
      });
      
      
      // append to args
      args[ filter ] = vals.join(',');
      
    });
    
    
    // update url
    url += '?';
    
    
    // loop over args
    $.each(args, function( name, value ){
      
      url += name + '=' + value + '&';
      
    });
    
    
    // remove last &
    url = url.slice(0, -1);
    
    
    // reload page
    window.location.replace( url );
    

  });

})(jQuery);
</script>

I’m not sure why my code isn’t formatting correctly, sorry about that… Any insight much appreciated!

Hi there,

Please consider this is a question about custom coding which uses the custom post type and the ACF Pro. Although we include the ACF Pro as an extension in our theme this particular request is way beyond our support scope.

Having said that I tried to check the code to find the possible problem with it and I could not. The only thing that I can suggest is that instead of using the $query->get I suggest that you use the standard functions of the ACF Pro to retrieve the information of the fields.

For more information please consult with the ACF Pro documentation:

Thank you for your understanding.

Thanks anyway! I’ll see if your tip leads me anywhere.

No problem.
We really appreciate for your understanding.

If anyone’s interested, I found a simple solution after days of searching. My query needed to include this code:

    if ( ! is_admin() && $query->is_main_query() ) {  }

So my final code in functions.php:

<?php 
    // array of filters (field key => field name)
    $GLOBALS['my_query_filters'] = array( 
            'field_59ee4cae33b83' => 'room_type',
            'field_59ee4ddd33b86' => 'grow_medium', 
            'field_59ee4e340ed47' => 'breeder',
            'field_59ee4e2a0ed46'  => 'strain_name'
    );

    add_action('pre_get_posts', 'my_pre_get_posts');

    function my_pre_get_posts( $query )
    {
        if ( !is_admin() && is_post_type_archive('growdiaries') && (isset($_GET['room_type']) || isset($_GET['grow_medium']) || isset($_GET['breeder']) || isset($_GET['strain_name'])) ) {
  
        //get original meta query
       $meta_query = $query->get('meta_query');

        if ( ! is_admin() && $query->is_main_query() ) { 
          
          // loop over filters
          foreach( $GLOBALS['my_query_filters'] as $key => $name ) {
    
                // continue if not found in url
                if( empty($_GET[ $name ]) ) {
                  continue;      
                }
    
                // get the value for this filter
                // eg: http://www.website.com/events?city=melbourne,sydney
                $value = explode(',', $_GET[ $name ]);
    

                // append meta query
              $meta_query[] = array(
                'key'   => $name,
                'value'   => $value,
                'compare' => 'IN',
             );

        
      } 

      //update the meta query args

      $query->set('meta_query', $meta_query);
    }
}
  //always return
  return;

}

Thanks for sharing your solution.

Much appreciated!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.