Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filtering by ACF field #123

Closed
dominicgisler opened this issue Mar 29, 2017 · 32 comments
Closed

Filtering by ACF field #123

dominicgisler opened this issue Mar 29, 2017 · 32 comments

Comments

@dominicgisler
Copy link

dominicgisler commented Mar 29, 2017

Hello,

I'm using ACF to "categorize" my media items. With this plugin (v2.2.1 over wp-plugin-store) I'm able to see the custom field (acf->tag) in the wp-json-response.
How can I filter these values?

I'd like to to send a GET-Request just like this to get only specific media:
http://wordpress.dev/wp-json/wp/v2/media?tag=my-image-tag

I saw some examples with putting some code into functions.php, but I don't know which file I should change - it didn't work when I tried it.

On the other side I want to create media with this specific tag. So when I create media over the API, I want to set the ACF field value. How can I achieve this?

Sorry for this, maybe I'm just too stupid for this, but it's my first project with wordpress ^^

@jchiatt
Copy link

jchiatt commented Apr 1, 2017

I second this. What's the request structure needed to search by ACF field values?

For example, I have a Location custom post type. One of my ACF fields is 'City.'

What if I wanted to return all Location posts whose City value is 'New York' ?

I'd imagine this looking something like /acf/v3/locations?city=new%20york

But that didn't seem to work.

@airesvsg
Copy link
Owner

airesvsg commented Apr 5, 2017

Hi,
Thanks for using my plugin.

For both cases, use the filter below.

add_filter( 'rest_{type}_query', function( $args ) {
	$args['meta_query'] = array(
		array(
			'key'   => 'tag',
			'value' => esc_sql( $_GET['tag'] ),
		)
	);

	return $args;
} );

@TheBalco replace {type} to attachment
@jchiatt replace {type} to location

Thanks

@temsool
Copy link

temsool commented Apr 7, 2017

Is this solution work if I need this filter URL?

wp-json/acf/v3/project/?filter[paged]=' + $scope.page + '&filter[s]=' + $scope.searchKey + '&filter[posts_per_page]=' + $scope.postPerPage + '&filter[orderby]=date&filter[category_name]=' + $scope.selectedCat.slug + '&filter[tag]=' + $scope.selectedTag.slug + '&filter[meta_query][0][key]=start_date&filter[meta_query][0][value][0]=' + $scope.selectedDate.sDate + '&filter[meta_query][0][value][1]=' + $scope.selectedDate.eDate + '&filter[meta_query][0][compare]=BETWEEN&filter[meta_query][0][type]=DATE&filter[meta_key]=rating&filter[meta_value]=' + $scope.selectedRate.value'

@airesvsg
Copy link
Owner

Hi @amindiary,
That solutions works too.
Thanks

@GabeRivera
Copy link

Hi @airesvsg ,

I'm sorry for what may be a stupid question, but here it goes. I'm not sure how to expand the above example for my use case. Currently the data structure I am getting back from the api, looks like this

  {
"id": 390,
"acf": {
    "SubStandard": {
        "ID": 74,
        "post_author": "1",
        "post_date": "2017-04-04 18:56:39",
        "post_date_gmt": "2017-04-04 18:56:39",
        "post_content": "",
        "post_title": "Inspection Of Indoor And Outdoor Play Areas And Equipment",
        "post_excerpt": "",
        "post_status": "publish",
        "comment_status": "closed",
        "ping_status": "closed",
        "post_password": "",
        "post_name": "inspection-of-indoor-and-outdoor-play-areas-and-equipment",
        "to_ping": "",
        "pinged": "",
        "post_modified": "2017-04-04 18:56:39",
        "post_modified_gmt": "2017-04-04 18:56:39",
        "post_content_filtered": "",
        "post_parent": 0,
        "guid": "http:\/\/localhost:8888\/childcare\/?post_type=substandards&p=74",
        "menu_order": 0,
        "post_type": "substandards",
        "post_mime_type": "",
        "comment_count": "0",
        "filter": "raw"
    },
    "Standard": {
        "ID": 38,
        "post_author": "1",
        "post_date": "2017-04-04 18:41:32",
        "post_date_gmt": "2017-04-04 18:41:32",
        "post_content": "",
        "post_title": "Play Area\/ Playgrounds and Transportation",
        "post_excerpt": "",
        "post_status": "publish",
        "comment_status": "closed",
        "ping_status": "closed",
        "post_password": "",
        "post_name": "play-area-playgrounds-and-transportation",
        "to_ping": "",
        "pinged": "",
        "post_modified": "2017-04-10 19:07:54",
        "post_modified_gmt": "2017-04-10 19:07:54",
        "post_content_filtered": "",
        "post_parent": 0,
        "guid": "http:\/\/localhost:8888\/childcare\/?post_type=standards&p=38",
        "menu_order": 0,
        "post_type": "standards",
        "post_mime_type": "",
        "comment_count": "0",
        "filter": "raw"
    },
    "State": {
        "ID": 32,
        "post_author": "1",
        "post_date": "2017-04-04 18:39:32",
        "post_date_gmt": "2017-04-04 18:39:32",
        "post_content": "",
        "post_title": "Georgia",
        "post_excerpt": "",
        "post_status": "publish",
        "comment_status": "closed",
        "ping_status": "closed",
        "post_password": "",
        "post_name": "georgia",
        "to_ping": "",
        "pinged": "",
        "post_modified": "2017-04-05 20:09:10",
        "post_modified_gmt": "2017-04-05 20:09:10",
        "post_content_filtered": "",
        "post_parent": 0,
        "guid": "http:\/\/localhost:8888\/childcare\/?post_type=states&p=32",
        "menu_order": 0,
        "post_type": "states",
        "post_mime_type": "",
        "comment_count": "0",
        "filter": "raw"
    },
    "Center": "Does Not Meet",
    "Home": "Does Not Meet",
    "CenterRecommendations": [{
        "recommendation": "According to the Bright from the Start state manual, Rules for Child Care Learning Centers, '(1) All indoor and outdoor furniture, activity materials, and equipment shall be used: (a) In a safe and appropriate manner by each Employee and child in attendance; and (b) In accordance with the manufacturer\u2019s instructions, recommendations, and intended use' (pg. 23, section: 591-1-1-.12 ). The state manual does not specify all the information stated in CFOC Basics Standard (e.g., inspected daily)."
    }, {
        "recommendation": "The state manual does not mention 'a) Missing or broken parts', 'b) Protusion of nuts and bolts', 'f) Visible cracks', 'g) Stability of non-anchored large party equipment (e.g., playhouses)', 'h) Wear and deterioration', 'i) Vandalism or trash'."
    }, {
        "recommendation": "According to the state manual, '(2) Equipment. All equipment and furniture shall be used only by the age-appropriate group of children. Equipment and furniture shall be: (d) Secured if equipment and furniture is of a weight or mass that could cause injury from tipping, falling, or being pulled or pushed over. Potentially unstable equipment and furniture that might injure a child if not secured include, but are not limited to, televisions, chests of drawers, bookcases, shelving, cabinets and fish tanks' (pg. 23, section: 591-1-1-.12 ). The state manual does not specify all the information stated in CFOC Basics Standard (e.g., stability of handholds)."
    }, {
        "recommendation": "The state manual does not mention this CFOC Basics Standard, 'Any problems should be corrected before the playground is used by children.'"
    }],
    "HomeRecommendations": [{
        "recommendation": "The state manual does not mention this CFOC Basics Standard, 'The indoor and outdoor play areas and equipment should be inspected daily for basic health and safety, including, but not limited to...'"
    }, {
        "recommendation": "The state manual does not mention 'a) Missing or broken parts', 'b) Protusion of nuts and bolts', 'f) Visible cracks', 'e) Stability of handholds', 'i) Vandalism or trash'"
    }, {
        "recommendation": "The state manual does not mention this CFOC Basics Standard, 'Any problems should be corrected before the playground is used by children.'"
    }],
    "CenterRecommendationsManua": [{
        "manual_name": "Bright from the Start state manual, Rules for Child Care Learning Centers",
        "manual_url": "http:\/\/decal.ga.gov\/documents\/attachments\/CCLCRulesandRegulations.pdf"
    }],
    "HomeRecommendationsManua": false,
    "Lists": false
}

},

I would like to be able to filter by the value of acf.State.post_title. for example something like:

/childcare/wp-json/acf/v3/substandarddata/?filter[State]=Arizona?filterper_page=-1

Is this possible?

@danilopaulinodasilva
Copy link

danilopaulinodasilva commented Jan 22, 2018

How can I make it work with multiple filters? Like @jchiatt

In my case I have multiple fields like city, state, region code (array). I need to filter multiple fields.

I'm trying to /wp-json/wp/v2/posts/?city=SP&state=SP
And /wp-json/acf/v3/posts/?city=SP&state=SP

Have tried duplicate the function also pass an array in multiple points of it, nothing have worked. :/

@airesvsg
Copy link
Owner

airesvsg commented Jan 22, 2018

add_filter( 'rest_{type}_query', function( $args ) {
	$args   = array();
	$fields = array( 'city', 'state', 'region', 'code' );

	foreach ( $fields as $field ) {
		if ( isset( $_GET[ $field ] ) && ! empty( $_GET[ $field ] ) ) {
			$args['meta_query'][] = array(
				'key'   => $field,
				'value' => esc_sql( $_GET[ $field ] ),
			);
		}
	}

	return $args;
} );

@danilopaulinodasilva
Copy link

danilopaulinodasilva commented Jan 22, 2018

Não deu certo! hehe vou abrir um novo tópico, acho que estou quase na solução. Mais fácil, concorda?


It's not works! I'll open a new issue, I think a have a solution. It's ease, whats you think?

@tobalsan
Copy link

tobalsan commented Jun 7, 2018

I found the solution, it was actually that @airesvsg just forgot a bit of code in his latest code excerpt just above.

In the foreach loop, this line:

$args[] = array(

should be

$args['meta_query'][] = array(

The rest is fine.

All the necessary info about how to filter using custom fields for a custom post type API query is right here in the WordPress Codex: WP Meta Query class.

@bretmorris
Copy link

bretmorris commented Jun 28, 2018

Hey all,

I was having some issues with the snippets in this thread. This ended up working the best for me:

add_filter( 'rest_{type}_query', function( $args ) {

  $ignore = array('per_page', 'search', 'order', 'orderby', 'slug');

  foreach ( $_GET as $key => $value ) {
    if (!in_array($key, $ignore)) {
      $args['meta_query'][] = array(
        'key'   => $key,
        'value' => $value,
      );
    }
  }

  return $args;
});

The $ignore array is the query params that you do not want to include in the meta_query array.

@jeffceriello
Copy link

Hi all, I can't get any of this to work.

I have a date ACF and I need to access it via the rest API url. I have added @airesvsg code and changed $fields array with my field start_date but that breaks the json response. When I go to /wp-json/wp/v2/events Instead of showing my custom post type posts it shows the default posts post type.

Then I've tried @bretmorris solution but when I go to /wp-json/wp/v2/events/start_date=26%20March it shows a blank page.

What am I doing wrong?

@k8martian
Copy link

Hi, I added the code that you mentioned for specific query but now I can't get the list from the acf rest and also the wp rest.

Like /wp-json/wp/v2/books (not work anymore)
/wp-json/acf/v3/books (not work anymore)

This /wp-json/wp/v2/books?title=abc (this work)
/wp-json/acf/v3/books?title=abc (this work)

Can you please show me how to make both works?

@llino
Copy link

llino commented Aug 28, 2018

For anyone looking for a step by step guide, here's how to do it:

  1. go to your wordpress instalation and open wp-includes/functions.php
  2. add this code to the top:
add_filter( 'rest_user_query', function( $args ) {
        $fields = array( 'field1', 'field2', 'field3', 'field4' );

        foreach ( $fields as $field ) {
                if ( isset( $_GET[ $field ] ) && ! empty( $_GET[ $field ] ) ) {
                        $args['meta_query'][] = array(
                                'key'   => $field,
                                'value' => esc_sql( $_GET[ $field ] ),
                        );
                }
        }
        return $args; 
} );

now you can filter users with acf fields like this:
https://your.site.com/wp-json/wp/v2/users/?field1=value

Hope this helps.

@airesvsg
Copy link
Owner

Hi @llino,

Never edit your wp-includes/functions.php to paste a code.

You should paste the snippet of code in your functions.php of your current theme.

Thanks

@llino
Copy link

llino commented Sep 8, 2018

Ak, ok.

@juanfran1512
Copy link

add_filter( 'rest_{type}_query', function( $args ) {
	$args   = array();
	$fields = array( 'city', 'state', 'region', 'code' );

	foreach ( $fields as $field ) {
		if ( isset( $_GET[ $field ] ) && ! empty( $_GET[ $field ] ) ) {
			$args['meta_query'][] = array(
				'key'   => $field,
				'value' => esc_sql( $_GET[ $field ] ),
			);
		}
	}

	return $args;
} );

that bringsme a [ ] please you can help me?

@Sthefanny
Copy link

Sthefanny commented Sep 26, 2018

I have this data structure:

{
"id": 3910,
"acf": {
  "weekDay": "",
  "title": "Bebida Grátis na Compra de um Burger",
  "description": "Na compra de qualquer burger ganhe uma bebida. Na compra de qualquer burger 
  ganhe uma bebida. Na compra de qualquer burger ganhe uma bebida.",
  "priceBefore": "",
  "priceAfter": "",
  "image": {},
  "image_1": false,
  "image_2": false,
  "image_3": false,
  "": false,
  "active_coupon": true,
  "coupon_code": "AAA"
}
}

I applied this code to functions.php inside my theme:

add_filter( 'rest_post_query', function( $args ) {
$args = array();
$fields = array( 'city', 'state', 'region', 'code' );
foreach ( $fields as $field ) {
if ( isset( $_GET[ $field ] ) && ! empty( $_GET[ $field ] ) ) {
$args['meta_query'][] = array(
'key' => $field,
'value' => esc_sql( $_GET[ $field ] ),
);
}
}
return $args;
} );

I want to filter by active_coupon == true, so I try: http://site.com.br/wp-json/acf/v3/posts?active_coupon=true

But now it's returning an empty array: []

Can anyone help me?

@llino
Copy link

llino commented Sep 26, 2018

@juanfran1512

replace {type} with user, post, location, something else.

add_filter( 'rest_{type}_query', function( $args ) {
	$fields = array( 'city', 'state', 'region', 'code' );

	foreach ( $fields as $field ) {
		if ( isset( $_GET[ $field ] ) && ! empty( $_GET[ $field ] ) ) {
			$args['meta_query'][] = array(
				'key'   => $field,
				'value' => esc_sql( $_GET[ $field ] ),
			);
		}
	}

	return $args;
} );

@Sthefanny
Copy link

@llino I have the same problem as @juanfran1512 and I already replaced {type} with post. Can you help me?

@llino
Copy link

llino commented Sep 27, 2018

@Sthefanny
Try this:

add_filter( 'rest_post_query', function( $args ) {
	$fields = array( 'city', 'state', 'region', 'code' );
	
	foreach ( $fields as $field ) {
		if ( isset( $_GET[ $field ] ) && ! empty( $_GET[ $field ] ) ) {
			$args['meta_query'][] = array(
				'key' => $field,
				'value' => esc_sql( $_GET[ $field ] ),
			);
		}
	}

	return $args;
} );

@Sthefanny
Copy link

@llino Didn't work

@airesvsg
Copy link
Owner

@airesvsg
Copy link
Owner

airesvsg commented Oct 3, 2018

Hi @sthefany,

It's worked for you?? Let's me know.

Thanks

@Sthefanny
Copy link

Sthefanny commented Oct 5, 2018

@airesvsg No it didn't work. But I'm now using it with "WP REST Filter" plugin and I can do what I need
https://wordpress.org/plugins/wp-rest-filter/

@RaiBrightfox
Copy link

RaiBrightfox commented Jan 14, 2019

Hi @airesvsg,

In the project I'm working, I need to return if there're any value set in the field.

Something like this: /wp-json/wp/v2/posts?field=true

So doesn't matter what value is, since has something in the field it needs to return data from the search.

Can u help me?

@RaiBrightfox
Copy link

I've already found the solution :D
I just added 'compare' => '>=' in the meta_query
My search now is /wp-json/wp/v2/posts?field=1
So it brings all posts where the field is equals or greater than 1

@paulgarbas
Copy link

paulgarbas commented Feb 11, 2019

Hi @airesvsg ,

I need to filter by ACF field, which is an array. For a single value this code works:

add_filter( 'rest_{ type }_query', function( $args ) {
	
    $field = 'client';

	if ( isset( $_GET[ $field ] ) && ! empty( $_GET[$field] ) ) {
		$args['meta_query'][] = array(
			'key' => $field,
			'value' => esc_sql( $_GET[ $field ] ),
		);
	}

	return $args;
} );

But how can I filter all custom posts, when $field = 'client' is an array?

@geochanto
Copy link

I'm also running into problems with this... Tried every piece of code on this thread, and none worked all the way.

This one below sort of worked, but with issues:

add_filter( 'rest_product_query', function( $args ) {

    $ignore = array('per_page', 'search', 'order', 'orderby', 'slug');
  
    foreach ( $_GET as $key => $value ) {
      if (!in_array($key, $ignore)) {
        $args['meta_query'][] = array(
          'key'   => $key,
          'value' => $value,
        );
      }
    }
  
    return $args;
  });

This helped to filter by some ACF fields, but now I'm not able to access api pages like https://garrisoncollection1.dev/wp-json/wp/v2/product?page=2, which I need to do.

Any way to refactor this to still be able to use default wordpress API filters/search?

@geochanto
Copy link

Ahh, my misunderstanding. I realized I should add anything like that to the $ignore array. I added 'page', and it now works.

@ohtanya
Copy link

ohtanya commented Dec 24, 2019

@GabeRivera were you able to figure out the answer to your question? I'm also trying to figure out how to query nested fields, and all the answers here don't seem to be for that.

@fyllepo
Copy link

fyllepo commented Nov 17, 2020

Tried all the solutions here, like others, I got an empty acf: [] array for each post, heh! the filters work, just never returns the original posts ACF data anymore.

@Brunowilliang
Copy link

{
    "id": 116,
    "acf": {
      "name": "Amortecedor Fiat Toro 2015/...",
      "vippelCode": "00001",
      "refCode": "00002",
      "originalCode": "00003",
      "category": {
        "term_id": 29,
        "name": "Amortecedor",
        "slug": "amortecedor",
        "term_group": 0,
        "term_taxonomy_id": 29,
        "taxonomy": "Categorias",
        "description": "",
        "parent": 0,
        "count": 2,
        "filter": "raw"
      },
      "assembler": {
        "term_id": 32,
        "name": "Fiat",
        "slug": "fiat",
        "term_group": 0,
        "term_taxonomy_id": 32,
        "taxonomy": "Montadoras",
        "description": "",
        "parent": 0,
        "count": 2,
        "filter": "raw"
      },
      "info_1": "Diateiro",
      "info_2": "2.00 kg",
      "image": "http://catalogowebacf.local/wp-content/uploads/2020/05/par-amortecedor-dianteiro-traseiro-fiat-toro-20-18-cofap-D_NQ_NP_788067-MLB40622813730_012020-F.jpg"
    }
  },

Hello, I would like to filter all ACF data, how should I do this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests