Advanced Custom Field checkbox query not working - php

I am using an Advanced Custom Field to allocate a custom field to posts.
This field is then used by a filtering system to filter posts using a custom query (via the pre_get_posts action). The other query arguments are working fine, except for the one which relies on ACF’s field.
The current query arguments of the field’s meta_query have been constructed according to the ACF documentation for the field (hence the quotation marks surrounding the value).
Can anyone advise me as to where this is going wrong? The query doesn’t seem to return any posts based on the values I am passing to the query.
Query arguments:
$courses = get_query_var('courses');
if ($courses) {
$query->set('meta_query', array(
array(
'key' => 'course_check',
'value' => '"'.$courses.'"', //i.e mdia-403
'compare' => 'LIKE'
),
)
);
}

ACF stores checkbox values in array, that's the reason your code is not working.
See working example here:
https://support.advancedcustomfields.com/forums/topic/wp_query-using-meta_query-for-an-acf-checkbox-field/

Found the cause of this issue by print_r’ing the entire query and inspecting what was actually going on - had done this a number of times, but overlooked the following detail:
The issue here wasn’t actually due to the checkbox meta_query, but a conflict between the get_query_var term (‘courses’) and a custom taxonomy whose slug is also ‘courses’.
When the query was executed, the query seemed to be querying for posts associated with both the custom taxonomy and the selected checkbox value, yielding no results.
Renaming the name attr to something other than courses then reconfiguring the registered query var and meta_query fixed this issue.

Related

Trying to populate custom fields in Wordpress from WP database

I'm trying to populate a custom field, let's say 'field_123' (in this case from ACF plugin) with data from a Wordpress database table (which is coming from an API), let's say 'house' > 'square_metres'.
Posts (cpt) are already showing the main content 'out of the box' but I would want to add some more database tables to populate other custom fields. (which I then can use later on on different grids in visual composer)
I started with something but then realized soon enough I wasn't gonna solve the problem myself..
global $wpdb;
$new_value = $_POST['acf']['field_123'];
$wpdb->update(
"house",
array(
"square_metres" => $new_value,
),
array( '%s' )
);
}
add_action('acf/save_post', 'update_field', 1);```
Someone any suggestions? Or a push in the right direction? Perhaps there are smarter/easier ways to achieve this.
Thanks!
Is it all on the same DB? "house" is an existing table? what's it's name on the database? are you sure you didn't call it "wp_house"? in that case you are missing $wpdb->prefix."house" as the table name.
That last row of "add_action" is confusing me, what were you exactly trying to do? With that code, if the "house" table exist, you whould be able to populate its square_metres value with what you have in $new_value just fine (be careful, you didn't specify any WHERE clause, you are going to update ALL the rows in a single shot, dunno if this was intentional).
Is your post missing a piece of code?

Update a post's taxonomy when a specific acf_form() is updated

I'm currently building a parent admissions portal for a school. Pupils are created as a custom post type (pupil) when a user (parent) signs up – the parent is the author of each pupil post. These pupil posts have a custom taxonomy named status which determines if the pupil's admission forms have been submitted and reviewed. I'm using acf_form() to create the admission forms that display on the frontend and are filled in by the parent user. Each pupil currently has 6 ACF field groups (6 forms). I'm getting the keys of these field groups and looping through them with a foreach loop to display 6 individual acf_form() forms for each of the field groups.
When a pupil post is created, it's status is automatically set to "in progress" i.e. the parent is filling out the forms.
What I want
When a user updates one specific form/field group of the 6, I want the pupil's status taxonomy to be changed from "in progress" to "submitted". To explain further, this form is the final form the user/parent needs to complete and so once they press the acf_form() update button, the taxonomy should be updated.
So essentially...
I'm looking for a way to hook into the action of saving an acf_form(), doing a check to see if the form that was updated was a specific form (by the field group key?) and then updating the status taxonomy of the post that the form was submitted on.
What I've tried
I've tried using ACF's pre_save_post filter and save_post action but I can't figure out a way to check which field group was saved as those two functions just give me the $post_id. I simply added the code from the ACF Docs and tried to print_r() / echo the data from the functions to see if there was any way for me to check the field group key, but nothing is being printed on the page when I update the acf_form().
So...
Does anyone know how I can hook into that action properly and get the correct data that will allow me to do the checks that I want?
I found a way to do what I'm looking for but I feel like it isn't a very good or robust way to do it so I'm still open to suggestions/advice.
The code:
function my_acf_save_post( $post_id ) {
$keys_of_specific_field_group = array(
'field_5ce2970bc9fbd' => '',
'field_5ce29741c9fbe' => '',
'field_5ce297c7c9fc1' => '',
'field_5ce297ddc9fc2' => '',
'field_5ce297fac9fc3' => '',
'field_5ce2980ec9fc4' => '',
'field_5ce29874c9fc5' => '',
'_validate_email' => ''
);
if ( $_POST['acf'] === $keys_of_specific_field_group ) {
wp_set_post_terms($post_id, array(21), 'status');
}
}
add_action('acf/save_post', 'my_acf_save_post', 1);
Basically I am just checking if the field keys returned from $_POST['acf'] match the field keys of the fields in the specific form I want to check, and if they do I am updating the post's status taxonomy (array(21) is the ID of the 'submitted' term I want to set).
Hopefully there's a nicer/better way to do this as if any fields are added to the field group I will have to manually update the code.

Implement custom search by term name(s) in wordpress

I have implemented normal search functionality in simple pages using php and MySQL where I get result rows by mysqli_fetch_array. There I could have any numbers of variable with AND or OR relationship and it will retrieve results from the db.
Now I am trying to do this in WordPress.
I have seen solutions where one uses WP_query to search by term names. How do I achieve this AND and OR variables in my search query.
For example, my query is like select all post title where term name like 'search keyword' AND term slug like 'hi'.
I have created a view terms_and_posts table from merging terms and posts tables using taxonomy relationship, with columns custom term name, custom term slug, post title, post content, post status, and post type.
Do I need a merged table or it can be achieved by modifying WP_Query?
I do not want to resort to using plugins as I am very new to WordPress, and I prefer not to use plugins as long as I can help it.

How can I modify the value of an Advanced Custom Fields Post Object field via PHP?

I'm working on creating an import script to migrate data from an Excel spreadsheet that a client is providing, and converting each row into a WordPress post. So far, I've got the posts being created and all custom fields being filled in properly...except for one.
One of the fields is Associated Parts. I'd like to use the Post Object for this field, but I can't seem to find any documentation on the formatting to use in order to assign a post object (or preferably multiple objects) to this field's value via my PHP script.
The following is an example of some code that I'm using to populate the "specifications" repeater field that has two sub fields, label and value.
$field_key = 'field_53ef95cead820';
$value = get_field($field_key, $postID);
foreach($specs as $spec):
$specArray = explode(':',$spec);
if($specArray[0] && $specArray[1]):
$value[] = array("label" => $specArray[0], "value" => $specArray[1]);
endif;
++$i;
endforeach;
update_field( $field_key, $value, $postID );
To modify the associated parts field, should I set it up as a repeater like this and then create some sort of array to populate it, or should I use the multi select option and still pass some sort of an array to it. I'm happy to go either route, I just need some way to get those fields in there.
It's impossible to add associate products (other posts) during the initial import due to the fact that while you are importing the first product into WordPress, it's associated parts have not yet been created. For this reason I had to run two imports of the spreadsheet into WordPress.
On the first import, it created all the posts and added all of the non-relational custom fields as they appeared in the spreadsheet. I setup the script the print the post ID's of the imported products in a table format that allowed me to easily copy and paste all of the ID's at once from the script output back into a "Product ID" field in the spreadsheet. The script checks for the existence of a product ID and this field is what will determine if it is creating a new post/product or updating an existing one.
Once all the products had been imported and their respect ID's were added to the spreadsheet, we began the second import. We used the exact same spreadsheet with the only difference being that now it had the WordPress ID's added to a column.
1. if($product['Associated Parts']):
2. $assParts = explode('|',$product['Associated Parts']);
3. unset($assIDs);
4. foreach($assParts as $assPart):
5. unset($assID);
6. if($assPart):
7. $assID = get_page_by_title( $assPart , 'OBJECT' , 'product' );
8. $assIDs[] = $assID->ID;
9. endif;
10. endforeach;
11. $assIDs = array_filter($assIDs);
12. update_field( 'field_542c5dc44272e' , $assIDs , $product['Page ID'] );
13. endif;
Breakdown of the code line by line:
I check to see if this product has any associated parts assigned to it.
I convert the pipe separated list of associated parts into an array.
I unset the array that we will be using to store the array of post ID's. I do this so that the associated parts from the first product are not still stored in the array when we begin processing the second product.
I begin looping through the array of associated parts. Each item in this array contains the title of the associated part. In order for this to work, the titles must be spelled, formatted and in all other ways identical to the title of the WordPress post.
Same as 3, only now it's for this particular associated part.
This line was added to ensure that I wasn't searching for an associated part if that item of the array was an empty string.
I retrieve the WordPress post item that matches the title of this particular associated item.
I add the ID of the associated product to a numeric array.
Close the if statement on line 6.
End the associated products loop.
Filter out any empty strings or null values from our array of post ID's.
We pass the the numeric array containing the post ID's into the Advanced Custom Fields "update_field()" function. The first parameter is the unique field key of the Post Object custom field. The second parameter is the array of associated products ID's. The third parameter is the ID of the product we are editing.
Close the if statement on line 1.
I had to guess as to the format I needed to use for the value of the field. At first, I tried passing in an array of Post Objects and that didn't work. In the WordPress post editor, I inspected the code and saw that the value of their input field (when another post was selected) was that posts ID. After switching to a numeric array containing the Posts' ID's, the update_field() function accepted them perfectly without incident.
We're done.

How to use a relationship in the where parameter when finding records using the pods framework?

my question has to do with the pods framework plugin for wordpress sites. I am using pods version 2.2 and have been having trouble with the where parameter in the find() function.
I'd be suprised if I am the first person to encounter this problem but I have searched extensively and haven't found anyone providing an answer (or question at that).
Anyway, I'll give an example to highlight my problem.
Say I have a Bands Pod and a Records Pod and these two pods have a bi-directional multi-select relationship between them (that is, an n to n relationship). Hence a band can have numerous records and a record can have multiple bands. Further, the relationship exists between the fields BandsPod('records') and RecordsPod('bands').
Now, I can retrieve all records in the records pod like so (note the where is commented out):
$pods = pods('records');
$params = array(
'select' => 't.*',
'limit' => -1
//,'where' => '???'
);
$pods->find($params);
Then do whatever I want with them, e.g. template(), fetch(), etc.
My trouble occurs when I want to filter by band. What should my where statement be if I want to retrieve all records by band with id 1?
My view is that it should be something like this:
$params = array(
'select' => 't.*',
'limit' => -1,
'where' => '1 IN bands.id'
);
$pods->find($params);
However, this does not work (not that I especially expected it to).
It would also be desirable to know how this would work for filtering by multiple bands. E.g.
'where' => '(1, 2) IN bands.id'
As I said before, I've been trying to get this to work for some time and with little joy. I have managed to get it working but in a very ugly way. I.e.
Get bands from Bands Pod with relevant band ids,
Collect all ids of records from the bands pod records field,
Write params for Records Pod
Use the ids in the where statement to check they match with t.id,
$pods->find(); //where $pods=pods('records');
Thanks in advance for taking the time to read this and any answers you may give.
Cheers,
Joe
N.B. I know about the filters() function and it does not do what I'm after. I'd like stuff specifically for the where statement please.
You would want:
'where' => 'bands.id IN ( 1, 2 )'
If your bands are a custom post type, it would be:
'where' => 'bands.ID IN ( 1, 2 )'

Categories