get submitted form's post_id from outside the loop PHP - php

I am working on an app that has a post form that matches up adoption mentors with mentees.
This is in Wordpress/PHP/MySQL/ACF (Advanced Custom Field).
After the form has been submitted, I am unable to get the post_id for that post so I can save the ACF field "title" for the screen that lists all the matches.
Do I need to retrieve that form's $post_id when I'm "outside the loop"? And how do I do that?
function match_post_title_auto( $post_id ) {
// get mentor & new mentee user array
$mentee = get_field('match_mentee', $post_id);
$mentor = get_field('match_mentor', $post_id);
$title = ' Mentor: ' . $mentor['display_name'] . ' and Mentee: ' . $mentee['display_name'];
$postdata = array(
'ID' => $post_id,
'post_title' => $title,
'post_type' => 'match'
);
wp_update_post( $postdata );
return $value;
}
var_dump($post_id); //returns NULL
//what do I put here to get that `post_id`? Thanks!
add_action('acf/save_post', 'match_post_title_auto', 10, 1);

The acf/save_post hook only passes the $post_id as single parameter. You have 3 parameters in your callback. https://www.advancedcustomfields.com/resources/acf-save_post/. Also, you need to have a priority higher than 10 to get the updated values from your post.
function match_post_title_auto( $post_id ) {
// do stuff
}
add_filter('acf/save_post', 'match_post_title_auto', 20 );

you are trying to catch the values by filter hook. Actually you need action hook and 1 parameter only. like this:
add_action('acf/save_post', 'match_post_title_auto', 10, 1);
Hope it will work.
for more information, check the standard documentation:
https://www.advancedcustomfields.com/resources/acf-save_post/

Related

Dinamically create a link using ACF (Advanced Custom Field) custom value

I'm trying to create a custom link based on a custom field, something like this:
<a href='htts://wa.me/55[acf field="phone-number"]?text=more%20text%here'>Whatsapp</a>
Maybe creating another shortcode loading de ACF field, but I don't know how do that.
I've tried do customized the following code, but without success:
function diwp_enclosed_shortcode_social_links($attr, $content){
$args = shortcode_atts( array(
'url' => '#',
'color' => '#F0F',
'textsize' => '16px'
), $attr );
$output = ''.$content.'';
return $output;
}
add_shortcode( 'enclosed_social_links', 'diwp_enclosed_shortcode_social_links' );
Hello as explained in the documentation you can load the acf field just by adding the id of the post it is associated with:
$value = get_field( "phone-number", 123 );
You can find the post id in the url on the edit post in the backend for example: https://your-url/wp-admin/post.php?post=161&action=edit
In that case we will get the phone-number from the post 161 and it should all be set, if the whole thing need to be done dynamically then we can just use get_field() because we should be in the page in which the field is saved.
Merry christmas!
I solved my problem with the following code:
function numero_whatsapp_dinamico( $attr ) {
$post_id = $attr['post_id'];
$phone_number = get_field( 'numero_de_whatsapp', $post_id );
$output = '<a class="botao-whatsapp-estabelecimento" href="https://wa.me/55' . $phone_number . '?text=more%20text%20here" ">Whatsapp</a>';
return $output;
}
add_shortcode( 'numero_whatsapp_estabelecimento', 'numero_whatsapp_dinamico' );
Hope It'll help someone else with the same problem.

How to automatically set post title according to custom meta fields

I want to automatically set my post title according to custom meta fields for example my custom meta fields have a Name of user I want the title of the post to be the Name of User hope you can help me with this
You can use WordPress' "save_post" hook to change the post title according to post meta whenever a post is saved. Lets say you fave a post meta field called "name_of_user" and you want to change the post title accordingly
add_action('save_post', 'wpse_update_post_title');
function wpse_update_post_title($post_id) {
// If this is just a revision, don't update the title yet.
if ( wp_is_post_revision( $post_id ) ) {
return;
}
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'wpse_update_post_title');
$user_name = get_post_meta( $post_id, 'name_of_user', true );
// Check if the meta for given key exists and then update the title
if($user_name) {
$slug = str_replace(' ', '-', strtolower($user_name))
$post_update = array(
'ID' => $post_id,
'post_title' => $user_name,
'post_name' => $slug // This swill update the url slug of the post too`enter code here`
);
wp_update_post( $post_update );
}
// re-hook this function
add_action('save_post', 'wpse_update_post_title');
}
The above code should go into your theme's functions.php file

WooCommerce pagination on single product pages - but only inside parent category

I would like to put pagination on each single product page in WooCommerce so that a user can move between products in that category easier than having to go back out to the main category page every time.
I know it's possible to use the standard WordPress pagination links like…
<?php previous_post_link('« %link'); ?>
<?php next_post_link('%link »'); ?>
This works if I want to page through all products, but I only want to page through products that are within the category I'm in. Does anyone know how I can limit this so products outside this category aren't included?
I've tried using the in_same_term parameter as mentioned in the WordPress codex to get the links only showing if the next/prev product is in the same category, but it's returning an integer for some reason. Here's the code I'm using…
<?php next_post_link( '%link', '%title', TRUE, '' ); ?>
This returns nothing at all even though it follows the Codex structure. I've also tried…
<?php next_post_link( '%link %title', TRUE, '' ); ?>
And this is what I'm getting in return…
1 %title
I'm stumped where to go next.
Here is a function that I have recently written that also does the job and is quite flexible
THE IDEA:
You first need to get the current post id, which I get through get_queried_object_id(). The post ID will be used to retrieve:
The post terms the post belongs to with wp_get_post_terms(). To speed things up, only the ID's of the terms will be returned. The first ID will be used (you can modify the code here to decide which term will be used if a post have more than one term) and this will be used to retrieve all the posts which has this certain term
The post ID's of the posts that is directly adjacent to this post to determine and retrieve the next and previous post from this one
All the info above will be used in a tax_query with get_posts to retrieve all the posts that shares the term from the current post. In the function, the default taxonomy is category and the post_type is set to any to get all the posts that has this specific term
Again, to make the code faster and to safe on resources, we only going to get the post ID's as this is all that is needed
Now comes the important parts of the code. We now need to determine the following:
The current position of the current post in the returned array of post ID's from the custom get_posts query. The function used here is array_search
If there is a post before or after this post (next or previous posts, the definitions are the same as for the build in functions next_post_link() and previous_post_link()), get the ID's of these posts
Use the ID's with get_post to retrieve the next and previous post's titles from the current post
Lastly will be to return the links. I have set messages if the current post is either the first or last post in the array and there are no next or previous post. You can decide what you want to do here, and for all that matters, the rest of the code
To make the code even faster and more efficient, I have made use of the Transient API which you can read further on. I have also used the transition_post_status action hook to hook a function to delete these transients whenever the post status of a post change. This includes new posts being published, post being updated and post deleted/undeleted
THE CODE:
Here is the code. This goes into your functions.php
function get_post_link( $taxonomy = 'category', $post_type = [ 'any' ] ) {
$id = get_queried_object_id(); // Get the current post ID
$transient_id = 'post_number_' . md5( $id . $taxonomy . implode( ',', $post_type ) ); //Create a unique transient id
if ( false === ( $links = get_transient( $transient_id ) ) ) {
// Get the terms a post belongs to
$terms = wp_get_post_terms( $id, $taxonomy, array( 'fields' => 'ids' ) );
// Use a tax_query to get all posts from the given term
// Just retrieve the ids to speed up the query
$post_args = [
'post_type' => $post_type,
'fields' => 'ids',
'posts_per_page' => -1,
'tax_query' => [
[
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $terms[0],
'include_children' => false,
],
],
];
// Get all the posts having the given term from all post types
$q = get_posts( $post_args );
//Get the current post position. Will be used to determine next/previous post
$current_post_position = array_search( $id, $q );
// Get the previous/older post ID
if ( array_key_exists( $current_post_position + 1 , $q ) ) {
$previous = $q[$current_post_position + 1];
}
// Get post title link to the previous post
if( isset( $previous ) ) {
$previous_post = get_post( $previous );
$previous_post_link = get_permalink( $previous );
$previous_title = '' . $previous_post->post_title . '</br>';
}
// Get the next/newer post ID
if ( array_key_exists( $current_post_position - 1 , $q ) ) {
$next = $q[$current_post_position - 1];
}
// Get post title link to the next post
if( isset( $next ) ) {
$next_post = get_post( $next );
$next_post_link = get_permalink( $next );
$next_title = '' . $next_post->post_title . '</br>';?><pre><?php var_dump($next_title); ?></pre><?php
}
// The returned post links
if( isset( $previous_title, $next_title ) ) {
$links = [
'previous_post' => $previous_title,
'next_post' => $next_title,
];
}elseif( !isset( $previous_title ) && $next_title ) {
$links = [
'previous_post' => 'You are currently viewing the newest post',
'next_post' => $next_title,
];
}elseif( $previous_title && !isset( $next_title ) ) {
$links = [
'previous_post' => $previous_title,
'next_post' => 'You are currently viewing the last post',
];
}
set_transient( $transient_id, $links, 7 * DAY_IN_SECONDS );
}
return (object)$links;
}
add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
{
global $wpdb;
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient%_post_number_%')" );
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient_timeout%_post_number_%')" );
}, 10, 3 );
HOW TO USE:
You can now use the code as follows in you single.php. The default taxonomy is category and post type is any. If your custom taxonomy is called mytax, you can use the code like this
if( function_exists( 'get_post_link' ) ) {
$post_links = get_post_link( 'mytax' );
echo $post_links->previous_post . '</br>' . $post_links->next_post;
}

Advanced Custom Fields - front-end form, save title from another field?

I am using WordPress's Advanced Custom Fields 5 plugin to create a front-end form. I would like to save the post title as one of the fields on my form. For example, one of my form fields is 'name' so I would like the post title to be 'John Smith'.
Looking at the ACF documentation it gives example code (copied below) where pre_save_post can be hooked into achieve this. Hoewver, I have included this function and the title still fails to save.
Any ideas what I am doing wrong?
Here is the code:
function my_pre_save_post( $post_id )
{
// check if this is to be a new post
if( $post_id != 'new' )
{
return $post_id
}
// Create a new post
$post = array(
'post_status' => 'draft' ,
'post_title' => $_POST['fields']['field_123'] ,
'post_type' => 'post' ,
);
// insert the post
$post_id = wp_insert_post( $post );
// return the new ID
return $post_id;
}
add_filter('acf/pre_save_post' , 'my_pre_save_post', 10, 1 );
I am using exactly the same method and it works fine.
Just a note that field_123 in your example is not the user defined field name in the wp back end but its actually the field name assigned in the meta_key value in the wp_postmeta table of you db.

Get custom fields values in filter on wp_insert_post_data

Hi all, thanks for reading.
Environment :
Wordpress + Advanced Custom Fields plugin
Problem :
I have searched for hours now and I can't seem to find the correct syntax to do the following:
When posting a new post, get custom field value in order to automatically replace the title of the post by that value. Example: I create a post and set '10am' in my 'time' custom field. The title of the post is automatically replaced by '10am'.
Example:
So I'm adding a filter with the following :
add_filter('wp_insert_post_data', 'change_title') ;
function change_title($data)
{
$time = XXX ; // How should I get this custom field value ?
$new_title = 'Topic created at'.$time ;
$data['post_title'] = $time ;
return $data;
}
It must be very simple but I have tried every function available on both WP and the plugin's documentations. I would be very thankful if anyone passing by gave me the solution.
Thanks in advance !
Tweak to Riadh's accepted answer (would add as a comment but haven't got enough rep yet):
As documented in the WordPress Codex wp_update_post includes the save_post hook so calling wp_update_post() inside the save_post hook creates an infinite loop. To avoid this, unhook then rehook your function like so:
add_action('save_post', 'change_title');
function change_title($post_id) {
$time = get_field('time',$post_id);
$post_title = 'Topic created at '. $time;
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'change_title');
// update the post, which calls save_post again
wp_update_post(array('ID' => $post_id, 'post_title' => $post_title));
// re-hook this function
add_action('save_post', 'change_title');
}
You can actually access the global $_POST variable for your field value , but i guess you can do it in a cleaner way by using the save_post action to update your post's title, eg:
add_action('save_post', 'change_title');
function change_title($post_id) {
$time = get_field('time',$post_id);
$post_title = 'Topic created at '. $time;
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'change_title');
// update the post, which calls save_post again
wp_update_post(array('ID' => $post_id, 'post_title' => $post_title));
// re-hook this function
add_action('save_post', 'change_title');
}
assuming that your ACF fieldname is "time".
Edit: Updated the answer as per Mark Chitty's answer.
You may try this
add_filter( 'wp_insert_post_data', 'change_title', '99', 2 );
function change_title($data , $postarr){
$custom_field = 'custom_filed_name';
$post_id = $postarr['ID'];
$time = get_post_meta( $post_id, $custom_field, true );
// Now you have the value, do whatever you want
}
Advanced Custom Fields creates a 'field key' for each custom field that is created. I was able to refer to this key value when trying to access the custom fields. The field key value can be found by viewing page source when viewing the post type within the Wordpress admin section.
Look for data-field-key. You will see a value similar to data-field-key="field_5847b00820f13" in the page source. Use this value when accessing the value in the $postarr argument in the wp_insert_post_data filter. The custom fields will be in a nested array named fields within the $postarr argument.
Alternatively, the field key value can be located by navigating to the Advanced Custom Fields / Export option from within the admin section. Once you are on the export page for Advanced Custom Fields, select the export to PHP option and you will see the value in the resulting PHP code.
In the example below, I am concatenating two Advanced Custom Fields and updating the post_title in the $data array returned from the function.
The result is that the post_title value will be saved to the database via the built in Wordpress save post logic.
add_filter('wp_insert_post_data', 'slb_set_title', '99', 2);
function slb_set_title ($data, $postarr){
if($data['post_type']==='slb_subscriber'){
$data['post_title'] = $postarr['fields']['field_5847b00820f13'] .' '.
$postarr['fields']['field_5847b03f20f14'];
}
return $data;
}

Categories