wp_update_post make custom field values disappear (Wordpress) - wordpress

I'm trying to update the post content in one of my post through the wp_update_post function. I have read the documentation here: http://codex.wordpress.org/Function_Reference/wp_update_post
And if I get it right I just need to send the post ID and the post content I want to update with - just like in the example - and this should be the only thing that will change. Although my custom fields that I have attached to this post disappears, strange enough.
I have the following code that I pass on:
if(isset($_POST['submit'])){
$the_post = array();
$the_post['ID'] = $_POST['id'];
$the_post['post_content'] = $_POST['recension'];
// Update the post into the database
wp_update_post( $the_post );
}
How come this happen and how do I solve it?

This is because when you are updating the post the *wp_insert_post* function is used and there is "save_post"(1) action hook which is usually used for saving custom fields data.
The standard way to add/update post meta is something like this:
$post_meta['_mymeta'] = $_POST['_mymeta'];
// Add values of $events_meta as custom fields
foreach ($events_meta as $key => $value) { // Cycle through the $post_meta array!
if( $post->post_type == 'revision' ) return; // Don't store custom data twice
if($value && $value != get_post_meta($post->ID, $key, TRUE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value);
} elseif($value && get_post_meta($post_id, $key, TRUE) == "") { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value, TRUE);
}
if(!$value) delete_post_meta($post->ID, $key, get_post_meta($post->ID, $key, TRUE)); // Delete if blank
}
...as you can see it is checking for *$_POST* data and if it is empty or not set it updates your meta value with empty data or deletes it completely.
I suppose you should use database update function or some other API function to update post fields...for example this piece of code will update your post menu order:
$wpdb->update( $wpdb->posts, array( 'menu_order' => 5 ), array( 'ID' => $post->ID ) );
(1) Runs whenever a post or page is created or updated, which could be from an import, post/page edit form, xmlrpc, or post by email. Action function arguments: post ID.

To avoid that behavior set false as third parameter.
It deactivates the "after insert hooks".

Related

How to display a custom field in the dashboard posts list( replacing the title )

I'm using WordPress and I did create a custom post type with several custom fields ( using ACV, advanced custom fields )
I have hidden all the basic WordPress fields like title, content editor thumbnails, etc, etc so I leave just my custom fields for the creation of a new post.
Since the title is not filled at the creation of the post, I get a list of post with every title set as “auto draft”
The thing that I don't want obviously.
My question is simple :
Is it possible and if yes how to replace the title with one of my custom fields in the dashboard post list.
I searched everywhere but I couldn't find an answer.
Sorry for my English, it’s not my native tongue, I hope You understand what I basically want to do.
Thanks for your time to read my question.
Have a good day
I managed to find a solution myself.
Let us say that you have a custom post type named "test" with 3 custom fields named one, two and three. And you want to remove the title and the date, show the content of one, two, and three in the post list table.
First you have to create a function that removes the title and the date, and also creates the new columns.
function custom_columns($columns)
{
unset($columns['title']);
unset($columns['date']);
return array_merge(
$columns,
array(
'one' => __('One'),
'two' => __('Two'),
'three' => __('Three')
)
);
}
add_filter('manage_test_posts_columns', 'custom_columns');
Then you need to display the custom field content in the post list table:
function display_custom_columns($column, $post_id)
{
switch ($column) {
case 'one':
echo get_post_meta($post_id, 'one', true);
break;
case 'two':
echo get_post_meta($post_id, 'two', true);
break;
case 'three':
echo get_post_meta($post_id, 'three', true);
break;
}
}
add_action('manage_test_posts_custom_column', 'display_custom_columns', 10, 2);
Further reading
You can use wp_insert_post_data to accomplish the desired functionality. This action is triggered when a post is created or updated.
add_action( 'wp_insert_post_data', 'my_updated_title', 99, 1 );
function my_updated_title( $data ) {
// If this is just a revision, don't update title.
if ( wp_is_post_revision( $data['ID'] ) ) {
return;
}
// Set the post title to your custom field value
$data['post_title'] = get_field( 'your_acf_field', $data['ID'] );
// Return the updated post data
return $data;
}

WP REST API orderby meta_value

Need to be able to sort the results of a REST API custom post query by a meta value.
Having difficulty doing so.
I have made my post type available to the REST API and can order by the Date, Title, etc...
But when I try the Post Meta it doesn't work.
I have added the following code to try and enable the functionality but defaults to ordering by date.
function my_add_meta_vars ($current_vars) {
$current_vars = array_merge ($current_vars, array('meta_key', 'meta_value'));
return $current_vars;
}
add_filter ('query_vars', 'my_add_meta_vars');
add_filter ('rest_query_vars', 'my_add_meta_vars');
My REST API query is
mysite.com/wp-json/wp/v2/hh_equipment?filter[orderby]=meta_value_num&meta_key=equipment_price&order=desc
I have tried following the instructions here to no avail.
Running WordPress 4.8 and tried testing on 4.7 to no avail
I've got it working with the rest_' . $post_type . '_collection_params filter and rest_' . $post_type . '_query filter like so (change $post_type to needed post type slug):
// Add meta your meta field to the allowed values of the REST API orderby parameter
add_filter(
'rest_' . $post_type . '_collection_params',
function( $params ) {
$params['orderby']['enum'][] = 'YOUR_META_KEY';
return $params;
},
10,
1
);
// Manipulate query
add_filter(
'rest_' . $post_type . '_query',
function ( $args, $request ) {
$order_by = $request->get_param( 'orderby' );
if ( isset( $order_by ) && 'YOUR_META_KEY' === $order_by ) {
$args['meta_key'] = $order_by;
$args['orderby'] = 'meta_value'; // user 'meta_value_num' for numerical fields
}
return $args;
},
10,
2
);
The first filter adds your meta field to the possible values of the ordeby parameters, as by default REST API supports only: author, date, id, include, modified, parent, relevance, slug, include_slugs, title (check the ordeby param in the WP REST API handbook)
The second filter allows you to manipulate the query that returns the results when you have your meta key inside the orderby. Here we need to reset orderby to 'meta_value' or 'meta_value_num' (read more about this in WP Query class description) and set the meta key to your custom field key.
Refer below method,
I modified the existing routes to add a new args entry which validates the meta_key values which are permitted. No need to modify the rest query vars this way either.
add_filter('rest_endpoints', function ($routes) {
// I'm modifying multiple types here, you won't need the loop if you're just doing posts
foreach (['some', 'types'] as $type) {
if (!($route =& $routes['/wp/v2/' . $type])) {
continue;
}
// Allow ordering by my meta value
$route[0]['args']['orderby']['enum'][] = 'meta_value_num';
// Allow only the meta keys that I want
$route[0]['args']['meta_key'] = array(
'description' => 'The meta key to query.',
'type' => 'string',
'enum' => ['my_meta_key', 'another key'],
'validate_callback' => 'rest_validate_request_arg',
);
}
return $routes;
});
REF: https://github.com/WP-API/WP-API/issues/2308

Unable to save Query Vars with a post

I'm trying to save Query Vars to a post for later retrieval.
I'm using permalinks in this format: domain.com/%category%/%postname%/
Example:
I create a following page
domain.com/page-003/
I add Query Var called email to the page
add_query_arg('email', 'test#abc.com', 'domain.com/page-003/')
Now when I call
get_permalink($post_id);
I get
domain.com/page-003/
Instead of
domain.com/page-003/?email=test#abc.com
What am I missing? Aren't Query Vars saved with a post?
You want to save some meta data which you want to restore later on and add as query arg into the URL.
You need to first save it as post_meta like e.g. when you save post with that data. You use:
<?php update_post_meta(get_the_ID(), 'email_address', 'abc#mail.com'); ?>
More details: https://codex.wordpress.org/Function_Reference/update_post_meta
Then during the retrieval, you may hook into a HOOK early on like template_redirect or earlier of the post you can get post_meta to get the email and then add to query arg:
<?php $email = get_post_meta( get_the_ID(), 'email_address' ); ?>
Then
esc_url( add_query_arg( 'email', $email, get_permalink( get_the_ID() ) ) );
Something like that, code is untested, I just wrote here, you may please read detailed doc in codex for each function used above.
Update: How to update/fill Ninja form field from Meta Value:
add_filter( 'ninja_forms_render_default_value', 'wm_the_value' , 10 , 3);
function wm_the_value( $default_value, $field_type, $field_settings ) {
if( 'textbox' == $field_type && in_array('ref' , $field_settings)){
$default_value = get_post_meta(get_the_ID(),'_listing_mls', true);
}
return $default_value;
}
'ref' is field name in Ninja form.
'_listing_mls' is meta_key name from WP database.
Hope it works for you.

Advanced Custom Fields repeater delete_post_meta hooks passing the wrong meta

I'm trying to run some additional functions when updating and deleting ACF custom post meta, ACF version 4.3.8. The ACF field type is a repeater with several rows. When I delete one of these rows, I'm getting the wrong $meta_key passed to my hook:
<?php
class My_Consultant_Save_Post {
function __construct() {
add_action( 'delete_post_meta', array ( $this, 'delete_consultant_meta_connections'), 10, 4 );
}
public function delete_consultant_meta_connections( $meta_id, $post_id, $meta_key, $_meta_value ) {
echo 'post_id';
var_dump($post_id);
echo 'meta_key';
var_dump($meta_key);
echo 'current value of meta, before deleting';
$current = get_post_meta($post_id, $meta_key);
var_dump($current);
die;
}
}
$my_consultant_update = new My_Consultant_Save_Post();
see delete_postmeta function, and the action delete_post_meta
actually it appears to be passing the $meta_key of the last row entry I have in the field group's repeater field, and definitely not one that I deleted from the front-end post editor's acf remove row button.
Any ideas why the hook is not returning the meta_key of the actual meta I tried to delete?

FeedWordPress - Save string as Custom Field

I am using the FeedWordPress plugin http://wordpress.org/extend/plugins/feedwordpress/ to pull posts from one site to another.
I have written a filter that after some help from Stack users successfully scans the $content and extracts the image URL into $new_content
define('FWPASTOPC_AUTHOR_NAME', 'radgeek');
add_filter(
/*hook=*/ 'syndicated_item_content',
/*function=*/ 'fwp_add_source_to_content',
/*order=*/ 10,
/*arguments=*/ 2
);
function fwp_add_source_to_content ($content, $post) {
// Use SyndicatedPost::author() to get author
// data in a convenient array
$content = $post->content();
// Authored by someone else
if( preg_match( '/<img[^>]+src\s*=\s*["\']?([^"\' ]+)[^>]*>/', $content, $matches ) ) {
$new_content .= 'URL IS '.$matches[0].'';
return $new_content;
}
else
{
}
}
What I wanted to do now was save this URL into a custom field instead of just returning it. Has anyone achieved anything similar?
So as I understand it, the plugin grabs content from external RSS feeds and creates them as posts in your website.
If this is the case, using your filter you should be able to grab the post ID within the $post variable.
So all you need is the add_post_meta() function to add a custom field to the specific post.
So including your code above it should look something like:
define('FWPASTOPC_AUTHOR_NAME', 'radgeek');
add_filter(
/*hook=*/ 'syndicated_item_content',
/*function=*/ 'fwp_add_source_to_content',
/*order=*/ 10,
/*arguments=*/ 2
);
function fwp_add_source_to_content ($content, $post) {
// Use SyndicatedPost::author() to get author
// data in a convenient array
$content = $post->content();
// Authored by someone else
if( preg_match( '/<img[^>]+src\s*=\s*["\']?([^"\' ]+)[^>]*>/', $content, $matches ) ) {
$new_content .= 'URL IS '.$matches[0].'';
//Add custom field with author info to post
add_post_meta($post->ID, 'post_author', $new_content);
return $new_content;
}
}

Resources