Unable saving an associative array using add_post_meta() function - php

I need to run an encryption function on each member of an associative array prior to it being saved to wp_postmeta table. My form allows dynamic add/delete of rows. I've been trying to get this to work using array_walk().
This is how the form is configured:
<input type="text" id="z_my_data[][username]" name="z_my_data[0][username]">
<input type="text" id="z_my_data[][password]" name="z_my_data[0][password]">
This is ran on the 'save_post` action:
// Save encrypted data to post meta
if (isset($_POST['z_my_data'])) {
// Get posted form variables
$my_data = $_POST['z_my_data'];
// Encrypt each member of each row
for ($i = 0; $i < count($my_data); $i++) {
$cryptKey = $this->cryptKey;
array_walk($my_data[strval($i)], create_function('&$val', 'global $cryptKey; $val = Crypto::encrypt($val, $cryptKey);'));
}
if ( ! add_post_meta( $post_id, '_my_data', $my_data, true ) ) {
update_post_meta( $post_id, '_my_data', $my_data);
}
} else {
delete_post_meta( $post_id, '_my_data' );
}
I can see that the data is being encrypted. Here is a print_r($my_data) after the for loop:
Array
(
[0] => Array
(
[username] => ®ØåÛâÏ0…"ë°?mˤÙ
[password] => xSFç„L¶·3z˜'J0ÖRÅÎj
)
)
But the post meta key is not created and no error is generated. The meta key doesn't exist in the postmeta table, yet add_post_meta() returns false and the key/value is never added.
Does anyone see what I'm doing wrong?
I'm not sure how to tell, but I think the [0] is a named key and not an index key. I say that because I can create more than one and delete the [0] element and the single element remaining still shows [1] using print_r.

In your if ( ! add_post_meta( $post_id, '_my_data', $my_data, true ) ) { you are using add_post_meta() function and last argument is set to true.
It should be false instead, because you are inserting an array and NOT a string.
For this reason your if statement is not working properly.
Instead, your code should be (as add_post_meta last argument default value is false):
if ( ! add_post_meta( $post_id, '_my_data', $my_data ) ) {
update_post_meta( $post_id, '_my_data', $my_data );
}
Alternatively, you could also use this:
if ( ( !empty( get_post_meta( $post_id, '_my_data' ) ) ) {
update_post_meta( $post_id, '_my_data', $my_data );
}
References:
WordPress Code Reference - add_post_meta
WordPress Code Reference - update_post_meta
WordPress Code Reference - get_post_meta

Related

Create a function which replaces a mysql value if it isn't empty?

I have two keys in the database called background-video-lengthand slide_duration. The one called background-video-lengthis not always set, when it is not, it is NULL. If it is anything but NULL I want to transfer the value from background-video-length to slide_durationand replace whatever is set in this one.
And another thing, slide_durationisn't always there, when it is empty it is removed, so it must be created if background-video-length value contains anything. If background-video-length is NULL I want to delete slide_duration if it doesn't contain anything previously.
EDIT:
I have this code to set the background-video-length in the database:
$attachment_id = attachment_url_to_postid( $_POST[ 'background-video' ] );
$video_meta = get_post_meta( $attachment_id , '_wp_attachment_metadata', true );
if( isset( $_POST[ 'background-video' ] ) ) {
update_post_meta( $post_id, 'background-video-length', $video_meta['length'] );
}

Update all posts in custom post type with wp_cron()

I have made a function to apply a taxonomy term to post, if it has a post meta value set to true. This works as should.
The problem I am facing is that it only updates after I have manually saved/updated the post.
Is there any way to schedule this or do it dynamically for all posts inside the custom post type?
My code for the taxonomy term function:-
function save_cp_term_meta( $post_id, $post, $update ) {
$termshouldbe='new';
$meta_value = get_post_meta( $post->ID, 'new_used_cat', true );
if (!empty( $meta_value ))
{
$termshouldbe='used';
}
else
{
}
wp_set_object_terms($post_id,$termshouldbe,'vehicle_condition',false);
}
add_action( 'save_post', 'save_cp_term_meta', 10, 3 );
You can use WP_Cron() to schedule a task to run at a specific time each day and perform the update.
// check if the next cron is ours, if not schedule it.
if ( ! wp_next_scheduled( 'prefix_save_cp_term_meta_cron' ) ) {
wp_schedule_event( strtotime( '5:15PM' ), 'daily', 'prefix_save_cp_term_meta_cron' );
}
/**
* function to query for posts of a certain post type and update
* some term_meta based on a post_meta value.
*/
function prefix_save_cp_term_meta_runner() {
// make sure to set the correct post type you want here.
$args = array(
'post_type' => array( 'your post type' ),
'meta_key' => 'new_used_cat',
'posts_per_page' => -1,
);
// run the query.
$query = new WP_Query( $args );
// if the query has posts...
if ( $query->have_posts() ) {
// loop through them...
while ( $query->have_posts() ) {
$query->the_post();
// default value to use as term.
$termshouldbe = 'new';
// get the current post_meta if it exists.
$meta_value = get_post_meta( $post->ID, 'new_used_cat', true );
if ( ! empty( $meta_value ) ) {
// update the value for term based on having a value for new_used_cat.
$termshouldbe = 'used';
// NOTE: you may want to delete the post_meta here so that next
// iteration this query doesn't need to work with this post
// again as it's already processed.
}
// set the term with a value (either 'new' or 'used').
wp_set_object_terms( $post->ID, $termshouldbe, 'vehicle_condition', false );
}
// restore the main query.
wp_reset_postdata();
}
} // End if().
add_action( 'prefix_save_cp_term_meta_cron', 'save_cp_term_meta_runner' );
NOTE: You may want to look at adding this in intervals instead of at a fixed time - or run it via a system level cron job instead. This answer details some issues when working with WP_Cron() that might help you decide which method is best for you: https://wordpress.stackexchange.com/a/179774/37158

how to create unique reference number - wordpress

I have Suppliers which have their own products. WP backend is almost redesigned and there I have a page(with form) where 'admin' can add new supplier and I need to create unique a reference number for each supplier when form will be submitted.
Plus, I have a "Sort by" dropdown and one of the sorting options is by "Reference number".
At first, I thought to use the POST ID as reference number, but don't think that this can be best solution, as POST IDs will be different when some posts will be removed. Also I was thinking to use uniqid() function with some digit limit and only digits.
What is best to reach this? Any ideas?
You can specify a new custom meta field for (i.e. supplier_id) and create a function which ensure that this supplier_id is unique. This function will be executed every time when a supplier form submitted.
The action hook save_post is triggered whenever a post or page is created or updated. So we can use it for this purpose.
From the documentation:
save_post is an action triggered whenever a post or page is created or updated, which could be from an import, post/page edit form, xmlrpc, or post by email. The data for the post is stored in $_POST, $_GET or the global $post_data, depending on how the post was edited. For example, quick edits use $_POST.
Since this action is triggered right after the post has been saved, you can easily access this post object by using get_post($post_id)
Example:
function save_supplier_id( $post_id, $post, $update ) {
$post_type = get_post_type($post_id);
if ( "supplier" != $post_type ) return;
if ( isset( $_POST['supplier_id'] ) ) {
$my_supplier_id = $_POST['supplier_id'];
if ( ! is_int( $my_supplier_id ) ) $my_supplier_id = 1;
$all_other_suppliers = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'supplier',
'post__not_in' => array( $post_id )
));
$all_other_ids = array_map( function( $supplier ) { return $supplier->ID; }, all_other_suppliers );
if ( count( $all_other_ids ) && in_array( $my_supplier_id, $all_other_ids ) ) {
// ID is already in use by another supplier, let's create an new one
$my_supplier_id = max( $all_other_ids ) + 1;
}
update_post_meta( $post_id, 'supplier_id', $my_supplier_id ) );
}
}
add_action( 'save_post', 'save_supplier_id', 10, 3 );
Explantion:
The format for supplier_idis simple a consecutive number. If the provided id is not an integer, we set it to 1. Now we get all other supplier id's and check if the give id no occur twice. If so, the we get the max id and increase it by 1.

WooCommerce get category slug - Undefined property notice with a function

I use this function to convert the woocommerce category id into a category slug
function woocommerceCategorySlug($id){
$term = get_term( $id, 'product_cat' );
return $term->slug;
}
This is working, but the problem is that i'm getting a notice
Notice: Undefined property: WP_Error::$slug
Is there a way to avoid this notice?
The working solution for this is to use WordPress native function get_term_by() and to transpose it in your code this way:
function woocommerceCategorySlug( $id ){
$term = get_term_by('id', $id, 'product_cat', 'ARRAY_A');
return $term['slug'];
}
Reference:
Code Reference > Function get_term_by()
Can't get category object in some templates of WooCommerce
The get_term() function could return a WP_Error object if the term wasn't found, which is exactly the problem reported by the error you cited.
While the answer submitted by #LoicTheAztec works, the most direct approach might be to bake in some defensive programming. Here are a couple of ways:
Option 1
function woocommerceCategorySlug( $id )
{
$term = get_term( $id, 'product_cat' );
if( is_wp_error( $term ) || !is_object( $term ) || !property_exists( $term, 'slug' ) )
return null;
return $term->slug;
}
Now, if get_term() returns a WP_Error object, or not an object at all, or the expected object doesn't have a 'slug' property, then return null. Otherwise, return the slug.
Option 2
Alternatively, you could have the get_term() function return the result as an associative array and simplify the checks a bit:
function woocommerceCategorySlug( $id )
{
$term = get_term( $id, 'product_cat', ARRAY_A );
return isset( $term['slug'] ) ? $term['slug'] : null;
}
In this version, isset() serves a dual purpose: to see if the slug exists in the expected array, or fail silently if $term isn't an array in the first place.

WordPress echo post meta array value inside input

I'm sending array meta box data using update_post_meta like below. However I cannot seem to output the post meta array value into an empty input. The meta is being stored correctly.
if( get_post_meta( $post->ID, 'date-meta', true ) ) {
$date_info = get_post_meta( $post->ID, 'date-meta', true );
}
My input field looks like this:
<input type="date" class="widefat" name="vp-date" id="vp-date" value="<?php echo $date_info['vp-date']; ?>" />
I also get a notice which traces back to the if get_post_meta function above. It says:
Trying to get property of non-object in
Any help would be great.
Thanks
That error message means that the $post is $post->ID is not an object. I don't know what script you are in but try putting
global $post;
above the if.
Making it
global $post;
if( get_post_meta( $post->ID, 'date-meta', true ) ) {
$date_info = get_post_meta( $post->ID, 'date-meta', true );
}

Categories