I have this code in a WordPress Plugin that will register a custom post type to manage some products that I will display using the rest API.
public function setup_post_type()
{
$post_type_supports = [
'title',
'editor',
'revisions',
'thumbnail'
//'custom-fields'
];
register_post_type(
'products',
[
'label' => 'Products',
'description' => 'Temporary products managment',
'show_in_rest' => true,
'rest_namespace' => $this->namespace,
'public' => true,
'supports' => $post_type_supports,
'show_ui' => true,
'show_in_menu' => true,
'menu_icon' => 'dashicons-store',
'register_meta_box_cb' => [$this, 'register_product_metabox']
]
);
}
//
public function register_product_metabox()
{
add_meta_box(
'temporary_product_metabox',
'Products informations',
[$this, 'product_metabox_content'],
'products',
);
}
public function product_metabox_content()
{
wp_nonce_field('product_metabox', 'product_metabox_nonce');
?>
<p>
<label for="cod-prod">Product code</label>
</p>
<p>
<input type="text" id="cod-prod" name="product_code">
</p>
<p>
<label for="category">Category</label>
</p>
<p>
<input type="text" id="category" name="category">
</p>
<p>
<label fro="unit">Unit</label>
</p>
<p>
<select name="unit" id="unit">
<option disabled selected>Select an option</option>
<option value="kg">kg</option>
<option value="pcs">pcs</option>
</select>
</p>
<p>
<label for="info">Info</label>
</p>
<p>
<input type="text" name="info" id="info">
</p>
<p>
<label for="start">Start date</label>
</p>
<p>
<input type="date" id="start" name="start_date">
</p>
<p>
<label for="end">End date</label>
</p>
<p>
<input type="date" id="end" name="end_date">
</p>
<?php
}
public function save_product_metabox_data($post_id)
{
if( !wp_verify_nonce('product_metabox', 'product_metabox_nonce') ){
return false;
} else {
//
//$post_mets = array_map($this->check_post_array(), $_POST);
$serached_keys = [
'product_code',
'category',
'unit',
'info',
'start_date',
'end_date'
];
$post_meta = array_intersect_key($_POST, $serached_keys);
foreach( $post_meta as $key => $val ){
update_post_meta(
$post_id,
$key,
$val,
);
}
}
}
I've noticed that when I try to save the data that are coming from the metabox, inside the postmeta table nothing is added, but only the post is saved correctly.
What I'm doing wrong and how I can fix this?
CodePudding user response:
You should be able to fix this by adding the fourth argument to the update_post_meta function:
update_post_meta(
$post_id,
$key,
$val,
get_post_meta( $post_id, $key, true )
);
In the foreach loop, you are passing the correct arguments to the update_post_meta function ($post_id, $key, and $val), but you are not passing the fourth argument, which is the previous value of the meta key. This is causing the function to return false and not update the post meta.
CodePudding user response:
Your error is coming from array_intersect_key
array_intersect_key only compares keys and returns items with the same keys.
Going by the below array in your code:
$serached_keys = [
'product_code',
'category',
'unit',
'info',
'start_date',
'end_date'
];
The keys to the above array are integer like so:
$serached_keys = [
0 =>'product_code',
1 =>'category',
2 =>'unit',
3 =>'info',
4 =>'start_date',
5 =>'end_date'
];
Using array_intersect_key
to compare the $serached_keys array
and a $_POST array
which has string keys like the array below will return empty array
$POST = [ 'product_code' => 'product code value',
'category' => 'category value',
'unit' => 'unit value',
'info' => 'info value',
'start_date' => 'start_date value',
'end_date' => 'end date value' ];
Now to the solution since we have detected the problem:
reverse your check array like so:
$new_serached_keys = [
'product_code' => 0,
'category' =>1,
'unit' => 2,
'info' => 3,
'start_date'=>4,
'end_date' =>5
];
Using this in $post_meta = array_intersect_key($_POST, $new_serached_keys);
will return an array of item that have similar keys on both array
NOTE this will not compare values