wordpress API: how to update custom meta box - php

I've created a custom meta box, but i can't update that through api rest. This is my code. The var $_POST in a function save_custom_meta_box is always empty when I send a request.
Create meta box
add_action( 'add_meta_boxes', 'adding_custom_meta_boxes', 10, 2 );
if (!function_exists('adding_custom_meta_boxes')) {
function adding_custom_meta_boxes( $post_type, $post ) {
add_meta_box(
"demo-meta-box",
"Custom Meta Box",
"custom_meta_box_markup",
"post",
"side",
"high",
null
);
}
}
Storing Meta Data
add_action("save_post", "save_custom_meta_box", 10, 3);
function save_custom_meta_box($post_id, $post, $update)
{
if(!current_user_can("edit_post", $post_id)){
return $post_id;
}
if($post->post_type != "post"){
return $post_id;
}
$meta_box_checkbox_value = "";
if(isset($_POST["meta-box-checkbox"]))
{
$meta_box_checkbox_value = $_POST["meta-box-checkbox"];
}
update_post_meta($post_id, "meta-box-checkbox", $meta_box_checkbox_value);
}
SOLUTION:
Use action rest_after_insert_post.
add_action('rest_after_insert_post', 'wp_kama_rest_after_insert_post_type_action', 10, 3);
function wp_kama_rest_after_insert_post_type_action( $post, $request, $creating ) {
if ($creating) {
return;
}
$body = json_decode($request->get_body());
if($body->metaBoxCheckbox)
{
update_post_meta($post->ID, "meta-box-checkbox", $body->metaBoxCheckbox);
}
return;
}

Related

How do I add cookie value in order metadata in WooCommerce?

I want the value of cookie my_cookie in order metadata.
add_action('init','thankyou_grab_cookie_as_meta_data', 10, 1 );
function thankyou_grab_cookie_as_meta_data( $order_id ){
if( ! $order_id ){
return;
}
if(isset($_COOKIE["my_cookie"]) && ! get_post_meta( $order_id, 'some default value', true ) ){
update_post_meta( $order_id, 'some default value', esc_attr($_COOKIE["my_cookie"]) );
}
}
The metadata shown now in postman
I guess the problem is with the check on ! get_post_meta and then you update_post_meta while it doesn't exists yet. Have update the code below.
add_action('init', 'thankyou_grab_cookie_as_meta_data', 10, 1);
function thankyou_grab_cookie_as_meta_data($order_id) {
if (!$order_id) {
return;
}
if (isset($_COOKIE["my_cookie"])) {
$my_cookie = esc_attr($_COOKIE["my_cookie"]);
if (!get_post_meta($order_id, 'some_meta_key', true)) {
add_post_meta($order_id, 'some_meta_key', $my_cookie);
} else {
update_post_meta($order_id, 'some_meta_key', $my_cookie);
}
}
}
Seems like you are using the WP REST API, maybe you haven't registered the custom field yet. You can use register_rest_field
add_action('rest_api_init', 'custom_register_rest_field');
function custom_register_rest_field() {
register_rest_field(
'post', // post type
'some_meta_key', // meta key
);
}

Checking user role on a hooked function breaking website in WooCommerce

I am trying to add a tab to the My Account page if a specific user exists.
I created a check_user_role function that checks if a specific role exists.
If the premium_member role exists an extra tab should be added to the My Account page.
Right now when I add the check_user_role function it breaks my website.
Everything is in the functions.php file
function check_user_role($roles, $user_id = null) {
if ($user_id) $user = get_userdata($user_id);
else $user = wp_get_current_user();
if (empty($user)) return false;
foreach ($user->roles as $role) {
if (in_array($role, $roles)) {
return true;
}
}
return false;
}
// ------------------
// 1. Register new endpoint (URL) for My Account page
// Note: Re-save Permalinks or it will give 404 error
function vehicle_intake_form_endpoint() {
add_rewrite_endpoint( 'vehicle-intake-form', EP_ROOT | EP_PAGES );
}
add_action( 'init', 'vehicle_intake_form_endpoint' );
// ------------------
// 2. Add new query var
function vehicle_intake_form_query_vars( $vars ) {
$vars[] = 'vehicle-intake-form';
return $vars;
}
add_filter( 'query_vars', 'vehicle_intake_form_query_vars', 0 );
// ------------------
// 3. Insert the new endpoint into the My Account menu
if(check_user_role(array('premium_member'))) {
function vehicle_intake_form_link_my_account( $items ) {
$items['vehicle-intake-form'] = 'Vehicle Intake Form';
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'vehicle_intake_form_link_my_account' );
}
// ------------------
// 4. Add content to the new tab
function vehicle_intake_form_content() {
echo '<h3>Premium WooCommerce Support</h3><p>Welcome to the WooCommerce support area. As a premium customer, you can submit a ticket should you have any WooCommerce issues with your website, snippets or customization. <i>Please contact your theme/plugin developer for theme/plugin-related support.</i></p>';
//echo do_shortcode( ' /* your shortcode here */ ' );
}
add_action( 'woocommerce_account_vehicle-intake-form_endpoint', 'vehicle_intake_form_content' );
Your If statement needs to be inside the function, never outside it.
You can use current_user_can() function, but inside your hooked function like:
add_filter( 'woocommerce_account_menu_items', 'vehicle_intake_form_link_my_account' );
function vehicle_intake_form_link_my_account( $items ) {
if( current_user_can('premium_member') ) {
$items['vehicle-intake-form'] = __('Vehicle Intake Form');
}
return $items;
}
Or use check_user_role() revisited function to be used inside your hooked function like:
function check_user_role( $roles, $user_id = null ) {
$user = $user_id ? new WP_User( $user_id ) : wp_get_current_user();
if ( is_a($user, 'WP_User') && count( array_intersect($roles, $user->roles) ) > 0 ) {
return true;
}
return false;
}
add_filter( 'woocommerce_account_menu_items', 'vehicle_intake_form_link_my_account' );
function vehicle_intake_form_link_my_account( $items ) {
if( check_user_role( array('premium_member') ) ) {
$items['vehicle-intake-form'] = __('Vehicle Intake Form');
}
return $items;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Show/hide shipping methods based on a WooCommerce checkout field value

In WooCommerce, I have set different shipping methods, but one in particular must be exclusive for companies.
For this I am using the following code:
add_filter( 'woocommerce_package_rates', array( $this, 'package_rates' ), 10, 2 );
public function package_rates( $rates, $package ) {
$company_rate_id = 'flat_rate:7';
if(!empty(WC()->customer->get_billing_company())){
$company_rates = $rates[ $company_rate_id ];
$rates = array( $company_rate_id => $company_rates );
}else{
unset( $rates[ $company_rate_id ] );
}
return $rates;
}
The solution works, but only if the billing company already exist and is saved in the database. So if a customer updates this information on the checkout page, it doesn't work.
A possible solution would be to save this field live (billing_company).
I tried the following function:
add_filter( 'woocommerce_checkout_fields' , 'trigger_update_checkout_on_change' );
function trigger_update_checkout_on_change( $fields ) {
$fields['billing']['billing_company']['class'][] = 'update_totals_on_change';
return $fields;
}
This updates the shipping method, the problem is that again, the field is not saved in the database and the package_rates() function can not find it live.
This is a bit more complicated than that… jQuery and Ajax code are required to allow showing/hiding shipping methods based on a checkout field user input.
The following code will enable show/hide pre defined shipping methods based on checkout billing company field:
// Conditionally show/hide shipping methods
add_filter( 'woocommerce_package_rates', 'shipping_package_rates_filter_callback', 100, 2 );
function shipping_package_rates_filter_callback( $rates, $package ) {
// The defined rate id
$company_rate_id = 'flat_rate:7';
if( WC()->session->get('company' ) === '1' ) {
$rates = array( $company_rate_id => $rates[ $company_rate_id ] );
} else {
unset( $rates[ $company_rate_id ] );
}
return $rates;
}
// function that gets the Ajax data
add_action( 'wp_ajax_get_customer_company', 'wc_get_customer_company' );
add_action( 'wp_ajax_nopriv_get_customer_company', 'wc_get_customer_company' );
function wc_get_customer_company() {
if ( isset($_POST['company']) && ! empty($_POST['company']) ){
WC()->session->set('company', '1' );
} else {
WC()->session->set('company', '0' );
}
die(); // (required)
}
// The Jquery Ajax script
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() {
if( WC()->session->__isset('company') )
WC()->session->__unset('company');
// Only on checkout when billing company is not defined
if( is_checkout() && ! is_wc_endpoint_url() ):
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
var fieldId = 'input#billing_company';
function companyTriggerAjax( company ){
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'get_customer_company',
'company': company,
},
success: function (result) {
// Trigger refresh checkout
$('body').trigger('update_checkout');
}
});
}
// On start
if( $(fieldId).val() != '' ) {
companyTriggerAjax( $(fieldId).val() );
}
// On change
$(fieldId).change( function () {
companyTriggerAjax( $(this).val() );
});
});
</script>
<?php
endif;
}
// Enabling, disabling and refreshing session shipping methods data
add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods( $post_data ){
$bool = true;
if ( WC()->session->get('company' ) === '1' )
$bool = false;
// Mandatory to make it work with shipping methods
foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
WC()->session->set( 'shipping_for_package_' . $package_key, $bool );
}
WC()->cart->calculate_shipping();
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Related: Remove shipping cost if custom checkbox is checked in WooCommerce Checkout

update_post_meta for Wordpress Yoast SEO

I'm having trouble with Yoast Worpdress SEO to automatically Update the Title, Keywords and description,
I have tried several ways with no success,
First test I've done is something like this, adding directly in fucntions.php
update_post_meta('80', '_yoast_wpseo_title', 'Test SEO Title' );
It works fine, however when I try a method like this, it won't simply work
function save_seo_meta_data($post_id) {
global $post;
$data = new MovieData;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
if ('movie_post' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id))
return $post_id;
} elseif (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
#wpseo_set_value('title', $data->seotitle, $post_id);
#WPSEO_Meta::set_value('title', $data->seotitle,$post_id);
update_post_meta($post_id, '_yoast_wpseo_title', $data->title );
}
add_action( 'save_post', 'save_seo_meta_data',9999999);
all of these three works using the above code when I change the meta key to different value
wpseo_set_value('title', $data->seotitle, $post_id);
WPSEO_Meta::set_value('title', $data->seotitle,$post_id);
update_post_meta($post_id, '_yoast_wpseo_title', $data->title );
I check the wp_postmeta value and can see all the value if I set different keys, but not when I point to yoast seo meta keys,
I've been also looking into its class and functions from here,
:https://github.com/Yoast/wordpress-seo/blob/ba4b1ad63f64d9658a2cc8de22b4391459423516/inc/class-wpseo-meta.php
:https://github.com/Yoast/wordpress-seo/blob/ba4b1ad63f64d9658a2cc8de22b4391459423516/inc/wpseo-functions.php
But still no success
Any help would be appreciated,
Try the wpseo_saved_postdata hook:
add_action( 'save_post', 'wpse26642385_save_post', 1, 1 );
function wpse26642385_save_post( $post_id )
{
// check stuff
// $data = ...
add_action( 'wpseo_saved_postdata', function() use ( $post_id ) {
if( function_exists( 'wpseo_set_value' ) ) {
update_post_meta( $post_id, '_yoast_wpseo_title', $data->title );
}
}, 999 );
}

wordpress meta-box confusion

My question is on save($postID) function. Here there is a parameter $postID which is using in the function for saving as id. I see that this $postID has a null value. How does actual post id work for $postID?
This is the simple meta-box code
/* simple meta box */
/* creating field */
add_action('admin_menu', 'my_post_options_box');
function my_post_options_box() {
if ( function_exists('add_meta_box') ) {
add_meta_box('post_header', 'Asif, save me!', 'testfield', 'post', 'normal', 'low');
}
}
function testfield(){
global $post;
?>
<input type="text" name="Asif" id="Asif" value="<?php echo get_post_meta($post->ID, 'Sumon', true); ?>">
<?php
}
/* end of creating field */
/* storing field after pressing save button */
add_action('save_post', 'save');
function save($postID){
if (!defined('DOING_AUTOSAVE') && !DOING_AUTOSAVE) {
return $postID;
}
else
{
if($parent_id = wp_is_post_revision($postID))
{
$postID = $parent_id;
}
if ($_POST['Asif'])
{
update_custom_meta($postID, $_POST['Asif'], 'Sumon');
}
}
}
// saving in postmeta table
function update_custom_meta($postID, $newvalue, $field_name){
if(!get_post_meta($postID, $field_name)){
// create field
add_post_meta($postID, $field_name, $newvalue);
}
else{
//update field
update_post_meta($postID, $field_name, $newvalue);
}
}
You've used the wrong Action Hook.
Instead of using add_action('admin_menu', 'my_post_options_box');
Use add_action('add_meta_boxes', 'my_post_options_box');
add_action('add_meta_boxes', 'my_post_options_box');
function my_post_options_box() {
if ( function_exists('add_meta_box') ) {
add_meta_box('post_header', 'Asif, save me!', 'testfield', 'post', 'normal', 'low');
}
}
You can look in to http://codex.wordpress.org/Function_Reference/add_meta_box for detailed overview.
Some SO Question/Answers you can look into.
Add multiple dates to custom post type in Wordpress
how to add a meta box to wordpress pages
While Saving Post
Action save_post automatically passes Post ID to callback function. Which you can use inside your callback function.
Some already answered quesitons
https://wordpress.stackexchange.com/questions/41912/perform-an-action-when-post-is-updated-published
Reference
http://codex.wordpress.org/Plugin_API/Action_Reference/save_post

Categories