The acf filter I linked to only works in the admin when editing and has no affect on the front of the site.
I think we are saying the same thing. Allow me to clarify. I want to modify the behavior of an ACF custom field of type ‘relationship’ on the admin side of WordPress when it populates in the target WordPress custom post type’s editor. I will handle how this data renders on the front end by coding the WordPress single-page template that I created for the custom post type. Does this clarify my goal?
Thank you, John, for providing a GitHub link to your work.
Thank you for the reply, John. My short-term goal is the latter (i.e., all selected products “are related to the manufacturer”). However, I plan to implement the former as well, which is to subselect a list of products from the manufacturer field.
While I appreciate having the “post-2-post-for-acf” plugin available, I want to avoid a solution that adds another plugin to my site. Interestingly, the link you presented for “acf/fields/relationship/quaery filter” reads like it can address both goals. Specifically,
// Restrict results to children of the current post only.
$args['post_parent'] = $post_id;
Yet, I am unsure if this ACF WP filter hook manifests within the custom post type’s editor window or only in the rendered HTML, which may be why you introduced the “post-2-post-for acf” plugin.
I would appreciate your thoughts on this. Thank you.
Thanks again, John, for your feedback. Yes, this reinforces your prior answer, but if I want both to update a post’s metadata via a post editor window AND update the post itself, how best would I do so?
For example, it would seem that I need to create a WP core “save_post” add_action, whereby its callback function invokes the ACF “acf/save_post” add_action. Given the latter requires its own callback function, is it a best practice to next an add_action and its callback function within the callback function of another add_action?
In other words, I understand the purpose of the “save_post” and “acf/save_post” add_actions, but how do I implement them together into a cohesive whole that follows best practices?
John, thanks again for your feedback. Perhaps you can point me in the right direction. Based upon your responses, the “acf/save_post” action does not respond to WordPress post creations/updates. Frankly, the ACF documentation is a bit confusing. I suppose its purpose is to enable one to update the relevant WordPress metadata table, among other WordPress metadata-specific tasks, whether updating the “standard” WP metadata tables or user-defined WP metadata tables.
Is this an accurate statement?
The detailed post I provided in this thread traces through a series of ACF-specific function calls that lead to WP metadata table row additions/modifications/deletions. For example, one such trace extends to the “meta.php” file contained in the WordPress “wp-includes” directory.
So, if the “acf/save_post” action is solely used to update a post’s metadata, for instance, metadata created via ACF, and if I want both to update a post’s metadata via a post editor window AND update the post itself, how best would I do so?
Thank you.
I appreciate the reply, John. Here is the full ‘acf/save_post’ description from :
Fires when saving the submitted $_POST data.
This action allows you to hook in before or after the $_POST data has been saved, making it useful to perform additional functionality when updating (emphasis mine) a post or other WP object.
Digging deeper, I ran a search for the the “acf/save_post” WordPress “add_action” action hook, which took me to the file “..\plugins\advanced-custom-fields\includes\acf-form-functions.php”. Here is a code excerpt from this file:
/**
* _acf_do_save_post
*
* Private function hooked into 'acf/save_post' to actually save the $_POST data.
* This allows developers to hook in before and after ACF has actually saved the data.
*
* @date 11/1/19
* @since 5.7.10
*
* @param int|string $post_id The post id.
* @return void
*/
function _acf_do_save_post( $post_id = 0 ) {
// Check and update $_POST data.
if( $_POST['acf'] ) {
acf_update_values( $_POST['acf'], $post_id );
}
}
// Run during generic action.
add_action( 'acf/save_post', '_acf_do_save_post' );
The “acf_update_values” function is located in the file “..\plugins\advanced-custom-fields\includes\acf-value-functions.php” in the following code excerpt:
/**
* acf_update_values
*
* Updates an array of values.
*
* @date 26/2/19
* @since 5.7.13
*
* @param array values The array of values.
* @param (int|string) $post_id The post id.
* @return void
*/
function acf_update_values( $values, $post_id ) {
// Loop over values.
foreach( $values as $key => $value ) {
// Get field.
$field = acf_get_field( $key );
// Update value.
if( $field ) {
acf_update_value( $value, $post_id, $field );
}
}
}
The “foreach” loop invokes the “acf_update_value” function that is located in the same PHP file. Here is its code excerpt:
/**
* acf_update_value
*
* Updates the value for a given field and post_id.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The new value.
* @param (int|string) $post_id The post id.
* @param array $field The field array.
* @return bool.
*/
function acf_update_value( $value, $post_id, $field ) {
// Allow filter to short-circuit update_value logic.
$check = apply_filters( "acf/pre_update_value", null, $value, $post_id, $field );
if( $check !== null ) {
return $check;
}
/**
* Filters the $value before it is updated.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The value to update.
* @param string $post_id The post ID for this value.
* @param array $field The field array.
* @param mixed $original The original value before modification.
*/
$value = apply_filters( "acf/update_value", $value, $post_id, $field, $value );
// Allow null to delete value.
if( $value === null ) {
return acf_delete_value( $post_id, $field );
}
// Update meta.
$return = acf_update_metadata( $post_id, $field['name'], $value );
// Update reference.
acf_update_metadata( $post_id, $field['name'], $field['key'], true );
// Delete stored data.
acf_flush_value_cache( $post_id, $field['name'] );
// Return update status.
return $return;
}
The relevant line of code is the “acf_update_metadata” statement located just below the “// Update reference.” comment. In the interest of reducing this post’s size:
The “acf_update_metadata” function is in the “..\acf-meta-functions.php” file. One of last code lines invokes the “update_metadata” function that is located in the “..\meta.php” file.
The “update_metadata” function includes the following “do_action”, which according to the code comments “fires immediately before updating a post’s metadata”:
do_action( "update_postmeta', $meta_id, $object_id, $meta_key, $meta_value' );
According to this sequence of function invocations, when I edit an ACF custom field in a post’s editor and then click the ‘Update’ button to update the post’s value in the WordPress database’s post table, this triggers a sequence of events that includes updating the WordPress post metadata table.
In actually, neither the post metadata table is update nor does
add_action('save_post', 'my_save_post');
appear to be invoked from
do_action( "update_postmeta', $meta_id, $object_id, $meta_key, $meta_value' );
Perhaps, I’ve missed something. Again, your feedback is appreciated.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.