0

I'm trying to filter pages in admin area by a custom field created with ACF.

I found a function here ( http://www.iamabdus.com/blog/wordpress/filter-custom-posts-by-custom-field/ ) and I adapted that code to my need.

When I click on "pages" the options load correctly, but when I click on "Filter" even if the filter work good, I receive a Warning: "Invalid argument supplied for foreach()". The var_dump($acf_field) return NULL.

I hope I explained the problem...

Here is the code:

add_action( 'restrict_manage_posts', 'wpse45436_admin_posts_filter_restrict_manage_posts' );

function wpse45436_admin_posts_filter_restrict_manage_posts(){
 $acf_field_name='field_5c65759c23c46';
 $acf_field=get_field_object($acf_field_name);
 var_dump($acf_field);
 $post_type_to_filter='page';
 $type = 'post';

 if (isset($_GET['post_type'])):
  $type = $_GET['post_type'];
 endif; // isset($_GET['post_type'])

 if ($post_type_to_filter == $type):
  foreach($acf_field['choices'] as $field_value => $field_label){
   $values[$field_label]=$field_value;
  }
  ?>
  <select name="custom_field_filter_value">
   <option value="">Filtra per tipo pagina</option>
   <?php $current_v = isset($_GET['custom_field_filter_value'])? $_GET['custom_field_filter_value']:'';
    foreach ($values as $label => $value) :
     printf(
      '<option value="%s"%s>%s</option>',
      $value,
      $value == $current_v? ' selected="selected"':'',
      $label
     );
    endforeach;
   ?>
  </select>
  <?php
 endif;
}

add_filter( 'parse_query', 'wpse45436_posts_filter' );
function wpse45436_posts_filter( $query ){
 global $pagenow;
 $type = 'post';
 if (isset($_GET['post_type'])):
  $type = $_GET['post_type'];
 endif;
 $query->query_vars['meta_value'] = $_GET['custom_field_filter_value'];
}
1

Try to use this code and modify the custom post name and meta key of acf and it will work.

add_action( 'restrict_manage_posts', 'wpse45436_admin_posts_filter_restrict_manage_posts' );
/**
 * First create the dropdown
/** Create the filter dropdown */
function wpse45436_admin_posts_filter_restrict_manage_posts(){
    $type = 'movies'; // change to custom post name.
    if (isset($_GET['movies'])) {
        $type = $_GET['movies'];
    }

    //only add filter to post type you want
    if ('movies' == $type){
        //change this to the list of values you want to show
        //in 'label' => 'value' format
        $values = array(
            'label' => 'value1', 
            'label1' => 'value2',
            'label2' => 'value3',
        );
        ?>
        <select name="ADMIN_FILTER_FIELD_VALUE">
        <option value=""><?php _e('Filter By ', 'wose45436'); ?></option>
        <?php
            $current_v = isset($_GET['ADMIN_FILTER_FIELD_VALUE'])? $_GET['ADMIN_FILTER_FIELD_VALUE']:'';
            foreach ($values as $label => $value) {
                printf
                    (
                        '<option value="%s"%s>%s</option>',
                        $value,
                        $value == $current_v? ' selected="selected"':'',
                        $label
                    );
                }
        ?>
        </select>
        <?php
    }
}


add_filter( 'parse_query', 'wpse45436_posts_filter' );
/**
 * if submitted filter by post meta

 * @return Void
 */
function wpse45436_posts_filter( $query ){
    global $pagenow;
    $type = 'movies'; // change to custom post name.
    if (isset($_GET['movies'])) {
        $type = $_GET['movies'];
    }
    if ( 'movies' == $type && is_admin() && $pagenow=='edit.php' && isset($_GET['ADMIN_FILTER_FIELD_VALUE']) && $_GET['ADMIN_FILTER_FIELD_VALUE'] != '') {
        $query->query_vars['meta_key'] = 'META_KEY'; // change to meta key created by acf.
        $query->query_vars['meta_value'] = $_GET['ADMIN_FILTER_FIELD_VALUE']; 
    }
}
  • When you copy the code from someone else's answer, you should at least mention it. – nmr Apr 5 at 14:17
0

So I tried Pawan's answer and while it did work, it was applying the filter all over the place, not to the custom post types I wanted. So I made a slight modification that should make this work:

public function filter_exhibitions($post_type, $which) {
  $target = 'exhibition'; // Created this target variable and removed the $_GET stuff

  if($post_type == $target) { // Test for correct post type
    $values = array(
      'Temporary' => 'temporary', // Add your own 'Label' => 'value' pairs here
      'Permanent' => 'permanent',
      'Online'      => 'online',
    );

    ?>
    <select name="ADMIN_FILTER_FIELD_VALUE">
      <option value=""><?php _e('All exhibition types', 'artlytical-media'); // Change this to the default null value display ?></option>
    <?php
    $current_v = isset($_GET['ADMIN_FILTER_FIELD_VALUE'])? $_GET['ADMIN_FILTER_FIELD_VALUE']:'';
    foreach ($values as $label => $value) {
      printf(
        '<option value="%s"%s>%s</option>',
        $value,
        $value == $current_v? ' selected="selected"':'',
        $label
      );
    }
    ?>
    </select>
    <?php
  }
}
add_action( 'restrict_manage_posts', 'filter_exhibitions' );

function exhibition_posts_filter($query){
  global $pagenow;

  if(is_admin()) {
    $type = $query->query['post_type'];
    $target = 'exhibition';

    if($type == $target &&
      $pagenow == 'edit.php' &&
      isset($_GET['ADMIN_FILTER_FIELD_VALUE']) &&
      $_GET['ADMIN_FILTER_FIELD_VALUE'] != '') {
      $query->query_vars['meta_key'] = 'exhibition_type'; // Change to meta key created by acf
      $query->query_vars['meta_value'] = $_GET['ADMIN_FILTER_FIELD_VALUE']; 
    }
  }
}

add_filter( 'parse_query', 'wpse45436_posts_filter' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.