Is it possible to update post meta from array in one call? - wordpress

Code snippet:
$save_dbarray = array(
'email' => 'email#email.se',
'adress' => 'adress'
);
//Save values from created array into db
foreach($save_dbarray as $meta_key=>$meta_value) {
update_post_meta($post_id, $meta_key, $meta_value);
}
Is there any way to optimize above code? In this simple scenario, it wouldn't matter, but If I have a large array then I guess it might be performance issues when updating?
I would like to do something like:
update_post_meta($post_id, $save_dbarray);
Is this possible?

While the other answers are creative solutions to your problem, they don't seem to address the actual issue or answer your question.
The Answer
No. WordPress's update_post_meta only works on one field at a time. Your best bet is to stick with the method you're using above, with the foreach loop. The other answers provide ways of storing that meta in a single field, which is probably fine for some but (as in my case) some need to query against those values, and having a serialized or JSON-encoded array doesn't cut it.
Unfortunately, WP provides no "bulk meta update" method, and if it did, it would likely be a foreach loop. You can always write a function to help make your code cleaner, at least:
<?php
function update_post_meta_array( $post_id, $meta ) {
if ( ! get_post( $post_id ) || ! is_array( $meta ) || empty( $meta ) ) {
return false;
}
foreach ( $meta as $meta_key => $meta_value ) {
update_post_meta( $post_id, $meta_key, $meta_value );
}
return true;
}

phatskat is correct in that there's no built-in way to do this and a foreach loop is required.
This is the most efficient I've found - wrote about it in a blog post as well:
add_action('init', 'bulk_update_post_meta_data');
function bulk_update_post_meta_data() {
$args = array(
'posts_per_page' => -1,
'post_type' => 'POSTTYPEHERE',
'suppress_filters' => true
);
$posts_array = get_posts( $args );
foreach($posts_array as $post_array) {
update_post_meta($post_array->ID, 'POSTMETAKEY', 'NEWVALUE');
}
}

Why not try with serialize() like this:
According to update_post_meta() documentation you can pass the $meta_value as array, that will be serialized into a string.
$save_dbarray = array(
'email' => 'email#email.se',
'adress' => 'adress'
);
update_post_meta($post_id, 'my_custom_fields', $save_dbarray);

Possible multiple value at a time you can your value genearte escaped_json
$escaped_json = '{"key":"value with \\"escaped quotes\\""}';
update_post_meta( $id, 'double_escaped_json', wp_slash($escaped_json) );

Related

Wordpress Insert post create tne meta key and meta value

I am creating wp_insert_post to create post from json, while creating post i need to create meta values i have tried both add_post_meta and update_post_meta no results Can anybody help
foreach ( $response->data as $single_data ) {
$post_title = $single_data->name;
$video_id = $single_data->uri;
$thumnbnail_url = $single_data->pictures->sizes[4]->link;
if (!post_exists($post_title)) { // Determine if a post exists based on title, content, and date
$post_id = wp_insert_post(array(
'post_type' => 'vimeo_videos',
'post_title' => $post_title,
'post_status' => 'publish',
));
}
$newPostID = wp_insert_post($post_id);
global $post;
add_post_meta( $post->ID, 'vimeo_video_thumnbnail_url_key', $thumnbnail_url, true );
update_post_meta( $newPostID, 'video_url_id', $video_id );
You're using wp_insert_post twice which does not make sense. The first wp_insert_post is correct and will return the $post_id of the created post upon success. However, your
$newPostID = wp_insert_post($post_id);
is totally wrong and will always store 0 as a result in $newPostID, regardless of whether the post existed beforehand or not since $post_id will never contain a valid post array. What you want is to get the ID of the existing post (which post_exists already returns if successful). Change your code like so:
$existingPostID = post_exists($post_title);
if (!$existingPostID) {
$existingPostID = wp_insert_post(array(
'post_type' => 'vimeo_videos',
'post_title' => $post_title,
'post_status' => 'publish',
));
}
if ($existingPostID) {
update_post_meta( $existingPostID, 'video_url_id', $video_id );
}
For insert new post used this syntax:
add_post_meta( int $post_id, string $meta_key, mixed $meta_value, bool $unique = false )

List all posts without at least one category assigned to them in admin

I am trying to allow the admin user to list out CPT that have not already had a category assigned to them (This is to enable them to quickly find posts that require a category and edit them)
I have this so far -
function function_name( $query ) {
global $post_type;
if ( is_admin() && $post_type == 'product' ) {
$query->set( 'cat', '' );
}
}
add_action( 'pre_get_posts', 'function_name' );
This does not work however. Can someone help point me in the right direction?
Thanks
I have achieved what I need this way, if anyone else comes up with this question -
$terms = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => false,
) );
$arr = array();
foreach ($terms as $term) {
$arr[] = '-'.$term->term_id;
}
$query->set( 'cat', $arr );
I am simply getting all category id's. looping through these and appending them to another array with a munis "-" value and passing them through to the query as an argument.

Change publish date from meta date when publish post

When the post is publish, I want the publish date as the same as the date in the meta data, imic_sermon_date.
Here's my code. The problem is that it get stuck when publishing a post.
function update_sermon_date ($post_id) {
//automatically change publish date to sermon date when publish/save a postfunction update_sermon_date ($post_id) {
$sermon_date = get_post_meta($post_id, 'imic_sermon_date', true);
$mypost = array (
'ID' => $post_id,
'post_date' => $sermon_date);
wp_update_post( $mypost );
}
add_action ('save_post', 'update_sermon_date');
Can someone help me with this?
Thanks.
After searching online, I've fixed my code.
The code basically will only update when the post is edited. I added remove_action and add_action in order to prevent the code from running an endless loop.
****//automatically change publish date to sermon date when publish/save a post
function update_sermon_date () {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if ( !current_user_can('edit_post', $post_id) )
return;
$sermon_date = get_post_meta(get_the_ID(), 'imic_sermon_date', true);
$mypost = array (
'ID' => get_the_ID(),
'post_title' => $sermon_date,
'post_date' => $sermon_date,
'post_date_gmt' => $sermon_date);
if ( ! (wp_is_post_revision($post_id) || wp_is_post_autosave ( $post_id) ) ) {
remove_action('edit_post','update_sermon_date');
wp_update_post( $mypost );
add_action ('edit_post', 'update_sermon_date');
}
}
add_action ('edit_post', 'update_sermon_date');****

$wp_query and WP_QUERY - same arguments, different results

I spend this whole day trying to figure out a problem with a combination of a custom query and custom post types. This is my last resort...
The setting
I wrote a plugin that introduces some custom post types to my WordPress. To display them in the main query I hooked them into the query like this:
function add_cpt_to_query( $query ) {
*some code...*
// add custom post types to query
if ( !( is_admin() || is_post_type_archive() || is_page() ) && $query->is_main_query() ) {
$query->set('post_type', array_merge( array('post'), $cpt ) );
}
}
add_action('pre_get_posts','add_cpt_to_query');
In my theme on the other hand I setup ajax pagination like this:
function setup_pagination() {
global $wp_query;
$max_pages = $wp_query->max_num_pages;
$current_page = ( $wp_query->paged > 1 ) ? $wp_query->paged : 1;
$ajaxurl = admin_url( 'admin-ajax.php' );
wp_register_script( 'ajax-pagination', get_template_directory_uri() .'/js/dummy.js', array('jquery'), '', true);
wp_localize_script( 'ajax-pagination', 'ajaxpagination', array(
'max_pages' => $max_pages,
'current_page' => $current_page,
'ajaxurl' => $ajaxurl,
'query_vars' => $wp_query->query_vars
));
wp_enqueue_script( 'ajax-pagination' );
}
add_action( 'wp_enqueue_scripts', 'setup_pagination' );
function pagination() {
$query = $_POST['query_vars'];
$query['paged'] = $_POST['next_page'];
/*
$query = array(
'paged' => 2,
'post_type' => array('post', 'custom_post_type_1', 'custom_post_type_2' )
);
*/
$posts = new WP_Query( $query );
$GLOBALS['wp_query'] = $posts;
// Start the loop.
while ( have_posts() ) : the_post();
?>
*some code...*
<?php endwhile;
die();
}
add_action( 'wp_ajax_nopriv_ajax_pagination', 'pagination' );
add_action( 'wp_ajax_ajax_pagination', 'pagination' );
and the script part:
$.ajax({
url: ajaxpagination.ajaxurl,
type: 'post',
data: {
action: 'ajax_pagination',
query_vars: ajaxpagination.query_vars,
next_page: parseInt(ajaxpagination.current_page) + 1
}
});
The problem
If I pass the query_vars array I get from $wp_query with the altered 'paged' value back to WP_QUERY, it returns the wrong set of posts. It looks like, that WP_QUERY does not account for the cpts in the loop. Though these cpts are mentioned in the 'post_type' of the query_vars array and thereby passed along to the new WP_QUERY.
When I manually set 'post_type' and only pass this argument, it works as intended. The aspect that blows my mind is, that the resulting query_vars used in the ajax call to WP_QUERY are exactly the same, but only when I manually set 'post_type' the pagination works as it should.
I dont know if this was a somewhat understandable explanation, but I'm thankful for every idea that could help me out. Big THX!
Ok... I got it now.
I made a mistake in wp_localize_script(). The query_vars should be a json-string, I on the other hand just passed the array itself. My code above has to be altered in two lines:
function mk_setup_pagination() {
...
wp_localize_script( 'ajax-pagination', 'ajaxpagination', array(
...
'query_vars' => json_encode($wp_query->query_vars) <- convert to json-string
));
...
}
function mk_pagination() {
$query = json_decode( stripslashes( $_POST['query_vars'] ) , true); <- convert json-string to array
...
Works like a charm now. :)
btw: the code is based on a tutorial by wpmudev.org: Loading WordPress Posts Dynamically With AJAX

WordPress update_post_meta is returning odd results

Problems with WordPress update_post_meta.
I have a function that should be updating _gravity_form_data. It works, but it is adding extra data for some reason. Here's the function:
Here is the function:
function wpufe_gravity_custom_video( $post_id ) {
if (isset( $_POST['custom_video'])) {
$custom_video = 'a:13:{s:2:"id";s:1:"2";s:13:"display_title";b:0;s:19:"display_description";b:0;s:25:"disable_woocommerce_price";s:2:"no";s:12:"price_before";s:0:"";s:11:"price_after";s:0:"";s:20:"disable_calculations";s:3:"yes";s:22:"disable_label_subtotal";s:2:"no";s:21:"disable_label_options";s:2:"no";s:19:"disable_label_total";s:2:"no";s:14:"label_subtotal";s:8:"Subtotal";s:13:"label_options";s:7:"Options";s:11:"label_total";s:5:"Total";}';
update_post_meta( $post_id, '_gravity_form_data', $custom_video );
}
}
add_action( 'wpuf_add_post_after_insert', 'wpufe_gravity_custom_video' );
add_action( 'wpuf_edit_post_after_update', 'wpufe_gravity_custom_video' );
It SHOULD be making _gravity_form_data have this content:
a:13:{s:2:"id";s:1:"2";s:13:"display_title";b:0;s:19:"display_description";b:0;s:25:"disable_woocommerce_price";s:2:"no";s:12:"price_before";s:0:"";s:11:"price_after";s:0:"";s:20:"disable_calculations";s:3:"yes";s:22:"disable_label_subtotal";s:2:"no";s:21:"disable_label_options";s:2:"no";s:19:"disable_label_total";s:2:"no";s:14:"label_subtotal";s:8:"Subtotal";s:13:"label_options";s:7:"Options";s:11:"label_total";s:5:"Total";}
Yet when it updates the _gravity_form_data field, its output is:
s:429:"a:13:{s:2:"id";s:1:"2";s:13:"display_title";b:0;s:19:"display_description";b:0;s:25:"disable_woocommerce_price";s:2:"no";s:12:"price_before";s:0:"";s:11:"price_after";s:0:"";s:20:"disable_calculations";s:3:"yes";s:22:"disable_label_subtotal";s:2:"no";s:21:"disable_label_options";s:2:"no";s:19:"disable_label_total";s:2:"no";s:14:"label_subtotal";s:8:"Subtotal";s:13:"label_options";s:7:"Options";s:11:"label_total";s:5:"Total";}";
Why is it adding the s:429:" in the beginning and then the extra "; at the end? And most importantly, how do I fix it? :)
Thanks so much!
UPDATE: Was suggested to serialize the data, so I did:
function wpufe_gravity_custom_video( $post_id ) {
if (isset( $_POST['custom_video'])) {
$gubcustom_video = array('id' => 2, 'display_title' => '', 'display_description' => '', 'disable_woocommerce_price' => 'no', 'price_before' => '', 'price_after' => '', 'disable_calculations' => 'yes', 'disable_label_subtotal' => 'no', 'disable_label_option' => 'no', 'disable_label_total' => 'no', 'label_subtotal' => 'Subtotal', 'label_options' => 'Options', 'label_total' => 'Total');
$gubvideodata = serialize($gubcustom_video);
update_post_meta( $post_id, '_gravity_form_data', $gubvideodata );
}
}
add_action( 'wpuf_add_post_after_insert', 'wpufe_gravity_custom_video' );
add_action( 'wpuf_edit_post_after_update', 'wpufe_gravity_custom_video' );
...and still get the incorrect data posted to mysql.
Is there a way to just insert that string I need to insert? That's all I want to do, is update the database with that text.
I can do this in phpMySql easily, just copy and paste the text and it works like a champ. That's the solution I'm hoping for. Thanks again!
It looks like a serialized array that you are trying to insert manually but you should insert it by serializing it using serialize function, for example:
$custom_video = array('id' => 2, 'display_title' => '');
$data = serialize($custom_video);
update_post_meta( $post_id, '_gravity_form_data', $data );
Also, try using following hook:
add_action( 'save_post', 'save_meta_data' );
function save_meta_data($post_id)
{
$custom_video = array('id' => 2, 'display_title' => '');
$data = serialize($custom_video);
update_post_meta( $post_id, '_gravity_form_data', $data );
}
Problem solved. WP User Frontend Pro was setting the meta key with its own value of "1", causing it to re-serialize the serialized string. Problem solved by removing the WPUF meta key and just leaving the field.

Resources