Woocommerce REST API extending order response - wordpress

I'm looking for a way to extend the wc-api/vX/orders/ reponse. I've added multiple custom fields to the checkout (for eg: relation number, delivery date etc). These meta are saved within the order (wp_postmeta table). But why are they not returned with the api?
Normally you can extend the api response with some code like:
add_action( 'rest_api_init', 'custom_register_api_fields' );
function custom_register_api_fields() {
register_rest_field( 'shop_order','relation_number',
array(
'get_callback' => 'custom_api_meta_callback',
'update_callback' => null,
'schema' => null,
)
);
}
/**
*
* #param array $object Details of current post.
* #param string $field_name Name of field.
* #param WP_REST_Request $request Current request
*
* #return mixed
*/
function custom_api_meta_callback( $object, $field_name, $request ) {
return get_post_meta( $object[ 'id' ], $field_name, true );
}
But when I test the response (with Postman and the php lib), my-website.co/wc-api/v2/orders the custom meta are not visible.
Is there a way to register api fields for the wc-api?
Tnx!

i have the same requirement, add new value to "line_items" in order response
am using wc api v2
https://website.com/wp-json/wc/v2/orders
function get_product_order_image( $response, $object, $request ) {
if( empty( $response->data ) )
return $response;
$order_pid= $response->data['line_items'][0]['product_id'];
$l_w_product_meta = get_post_meta($response->data['line_items'][0]['product_id']);
$order_imgUrl= wp_get_attachment_url( $l_w_product_meta['_thumbnail_id'][0], 'full' );
$response->data['line_items'][0]['cover_image'] = $order_imgUrl;
return $response;
}
add_filter( "woocommerce_rest_prepare_shop_order_object", array( $this, "get_product_order_image"), 10, 3 );
Result
cover image added to line item result
i hope this will help someone in future.

REST API hook for add new value (product image) to "line_items" in order response for simple product and variable product both
Also Use for multiple products
function get_product_order_image( $response, $object, $request ) {
if( empty( $response->data ) )
return $response;
$images = array();
foreach($response->data['line_items'] as $key => $productItems){
$productID = $productItems['product_id'];
$variationID = $productItems['variation_id'];
if($variationID == 0){
$thumbnailID = get_post_meta( $productID, '_thumbnail_id', true);
$attachment = wp_get_attachment_image_src($thumbnailID, 'woocommerce_thumbnail' );
$image = $attachment[0];
}else{
$variation = new WC_Product_Variation( $variationID );
$image_id = $variation->get_image_id();
$attachment = wp_get_attachment_image_src($image_id, 'woocommerce_thumbnail' );
$image = $attachment[0];
}
$response->data['line_items'][$key]['image'] = $image;
}
return $response;
}
add_filter( "woocommerce_rest_prepare_shop_order_object", "get_product_order_image", 10, 3 );
Request:
wp-json/wc/v3/orders
wp-json/wc/v3/orders/XXX
wp-json/wc/v3/orders/?customers=XXX

Related

Wordpress - Add submit button to admin toolar

I have my own function fsww_i_add_funds_request_daily that I wrote to perform the addition of a profit by a user based on the role of the user. This function was created / added for one plugin that I use. I am not sending any parameters to the function. I need to call this function using the submit button which will be on the admin toolbar. The function should be implemented in the plugin as it is necessary to use its "library" (maybe I spoke badly, I'm still a beginner in WP). How and where I need these functions implement?
Function
function fsww_i_add_funds_request_daily() {
require_once(dirname(__FILE__) . '/Wallet.php');
global $wpdb;
$query = $wpdb->get_results("SELECT user_id FROM {$wpdb->prefix}fswcwallet ORDER BY user_id ASC");
if($query) {
foreach($query as $user)
{
$user_id = $user->user_id;
$dailyProvision = 0;
if($user_id != 0)
{
$balance = fsww_price(Wallet::get_balance($user_id));
$last_deposit = fswcw_format_date(Wallet::get_last_deposit($user_id));
$status = Wallet::get_status($user_id);
$username = get_user_by('id', $user_id);
}
}
}
}
function fb_add_admin_bar_profit() {
global $wp_admin_bar;
$current_object = get_queried_object();
$wp_admin_bar->add_menu(
array( 'id' => 'addprofit',
'title' => __('Add profit'),
'href' => ?????)
);
}
add_action( 'admin_bar_menu', 'fb_add_admin_bar_profit');
Could you please help me with this?
Create plugin Custom Plugin and add the below code to that plugin. and in you admin bar custom button add URL like this home_url( '/?funds_request_daily=true' ) and check this query string funds_request_daily params on init hook.
<?php
/**
* Plugin Name: Custom Plugin
* Plugin URI: https://example.com/plugins/the-basics/
* Description: Handle the basics with this plugin.
* Version: 1.0.0
* Author: Cleemas
* Author URI: https://author.example.com/
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: my-custom-plugin
* Domain Path: /languages
*/
function fsww_i_add_funds_request_daily() {
if( isset( $_GET['funds_request_daily'] ) && $_GET['funds_request_daily'] == 'true' ){
require_once(dirname(__FILE__) . '/Wallet.php');
global $wpdb;
$query = $wpdb->get_results("SELECT user_id FROM {$wpdb->prefix}fswcwallet ORDER BY user_id ASC");
if( $query ) {
foreach( $query as $user ) {
$user_id = $user->user_id;
$dailyProvision = 0;
if($user_id != 0) {
$balance = fsww_price(Wallet::get_balance($user_id));
$last_deposit = fswcw_format_date(Wallet::get_last_deposit($user_id));
$status = Wallet::get_status($user_id);
$username = get_user_by('id', $user_id);
}
}
}
}
}
add_action( 'init', 'fsww_i_add_funds_request_daily', 10, 1 );
function fb_add_admin_bar_profit() {
global $wp_admin_bar;
$current_object = get_queried_object();
$wp_admin_bar->add_menu(
array(
'id' => 'addprofit',
'title' => __('Add profit'),
'href' => home_url( '/?funds_request_daily=true' )
)
);
}
add_action( 'admin_bar_menu', 'fb_add_admin_bar_profit');
?>

Automatically assign new user_email and restrict update after first login

How can I automatically assign a new email to a user in WordPress AND restrict any further update after the first login ?
For example setting the email to the following structure:
{user_id}#example.com
I've tried a few things but couldn't figure it out, any help is appreciated.
I wrote this code, but only users whose email has been registered, their email has been edited, other people who have not registered email, no email has been registered for them. How do I solve this?
my code:
add_action ('admin_head','set_auto_mail');
function set_auto_mail() {
$users = get_users(array('fields'=>'all'));
foreach($users as $user){
$user = get_userdata($user->ID);
if ( in_array( 'subscriber', (array) $user->roles ) ) {
$mail = ($user->ID)."#example.com";
if($mail!=' ') wp_update_user( array ('ID' => $user->ID, 'user_email' => $mail) );
else wp_update_user( array ('ID' => $user->ID, 'user_email' => $user->user_email) );
if($user->user_email == '')
wp_update_user( array ('ID' => $user->ID, 'user_email' => $user->user_email) );
}
}
}
This should do exactly what you wanted.
We set a new user meta data called is_new_user which we will use later on to detect if this is the first ever login for a specific user.
We set a hook to update the user_email on first time login and we update is_new_user to specify that this isn't a new user anymore. Like that we prevent permanent update on login.
Then we fire up the necessary functions to disable email updates. Visually and from the backend for all non-new users.
I'm using first_name, las_name and ID for the email structure. Output:
$first_name.$last_name$ID#bogus.com
<?php
/**
* Adds meta data is_new_user to a user, which let us detect new users on first login.
*
* Fires immediately after a new user is registered.
*
* #link https://developer.wordpress.org/reference/hooks/wp_login/
*/
add_action( 'user_register', 'wpso66983605_add_user_meta_is_new_user' );
function wpso66983605_add_user_meta_is_new_user( $user_id ) {
add_user_meta( $user_id, 'is_new_user', 1, true );
};
/**
* Update user email on first login.
*
* Fires after the user has successfully logged in.
*
* #link https://developer.wordpress.org/reference/hooks/wp_login/
*/
add_action( 'wp_login', 'wpso66983605_set_user_email_on_first_login', 10, 2 );
function wpso66983605_set_user_email_on_first_login( $user_login, $user ) {
if ( ! get_user_meta( $user->ID, 'is_new_user', true ) ) {
return;
};
if ( get_user_meta( $user->ID, 'is_new_user', true ) ) {
update_user_meta( $user->ID, 'is_new_user', 0, 1 );
$userdata = array (
'ID' => $user->ID,
'user_email' => sanitize_email( sanitize_title_with_dashes( $user->first_name . '.' . $user->last_name . $user->ID) . '#bogus.com' ),
);
wp_update_user( $userdata );
};
};
/**
* Prevent users from changing their email address
*
* Modified to ONLY fire when a user is considered as non-new user (user has already made at least 1 login).
*
* #link https://wordpress.stackexchange.com/a/363376/190376
*/
if ( ! class_exists( 'DisableMailChange' ) ) {
class DisableMailChange {
public function __construct() {
add_action( 'personal_options_update', array( $this, 'disable_mail_change_BACKEND' ), 5 );
add_action( 'show_user_profile', array( $this, 'disable_mail_change_HTML' ) );
}
public function disable_mail_change_BACKEND( $user_id ) {
if ( ! get_user_meta( get_current_user_id(), 'is_new_user', true ) ) {
if ( ! current_user_can( 'manage_options' ) ) {
$user = get_user_by( 'id', $user_id );
$_POST['email'] = $user->user_email;
};
};
}
public function disable_mail_change_HTML( $user ) {
if ( ! get_user_meta( get_current_user_id(), 'is_new_user', true ) ) {
if ( ! current_user_can( 'manage_options' ) ) {
echo '<script>document.getElementById("email").setAttribute("disabled","disabled");</script>';
};
};
}
};
new DisableMailChange();
};

Woocommerce custom order status not triggering custom email

I have a custom order status called Shipping Details which will be selected after the Order complete trigger is fired.
Code for the Order Status
function register_shipping_details_status() {
register_post_status( 'wc-shipping-details', array(
'label' => 'Send Shipping Details',
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true
//'label_count' => _n_noop( 'Shipping Details <span class="count">(%s)</span>', 'Shipping Details <span class="count">(%s)</span>' )
) );
}
add_action( 'init', 'register_shipping_details_status' );
// Add to list of WC Order statuses
function add_shipping_details_to_order_statuses( $order_statuses ) {
$new_order_statuses = array();
// add new order status after completed
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-completed' === $key ) {
$new_order_statuses['wc-shipping-details'] = 'Send Shipping Details';
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'add_shipping_details_to_order_statuses' );
and my email trigger code is here.
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Shipping_Details_Email' ) ) :
/**
* Customer Shipping Details Email
*/
class WC_Shipping_Details_Email extends WC_Email {
/**
* Constructor.
*/
public function __construct() {
$this->id = 'wc_shipping_details';
$this->customer_email = true;
$this->title = __( 'Shipping Details', 'woocommerce' );
$this->description = __( 'Shipping details emails are sent after the order has been marked completed .', 'woocommerce' );
$this->heading = __( 'Shipping Details for your order', 'woocommerce' );
$this->subject = __( 'Shipping details for your order from INAI', 'woocommerce' );
$this->template_html = 'emails/customer-shipping-details.php';
$this->template_plain = 'emails/plain/customer-shipping-details.php';
// Triggers for this email
add_action( 'woocommerce_order_status_shipping_details_notification', array( $this, 'trigger' ) );
// Call parent constuctor
parent::__construct();
}
/**
* Trigger.
*
* #param int $order_id
*/
public function trigger( $order_id ) {
if ( $order_id ) {
$this->object = wc_get_order( $order_id );
$this->recipient = $this->object->billing_email;
$this->find['order-date'] = '{order_date}';
$this->find['order-number'] = '{order_number}';
$this->replace['order-date'] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) );
$this->replace['order-number'] = $this->object->get_order_number();
}
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
return;
}
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
The action for registering the email
//custom hooks for custom woocommerce order email
function register_custom_order_status_action( $actions ){
$actions[] = 'woocommerce_order_status_shipping_details';
return $actions;
}
add_filter( 'woocommerce_email_actions', 'register_custom_order_status_action' );
For some reason the mail is not getting triggered. I have looked around a lot and even found a few others for whom the problem has been solved. WooCommerce - send custom email on custom order status change.
My code is almost exactly the same, still don't know what i'm missing. Please help.

Create Post with Meta Field – WP REST API

I have just started with REST API and using it for creating posts from frontend. I managed to publish post with Title, Excerpt, Content.
I want to add a Custom Meta Field value aswell, any example or help is much appreciated.
This is my Ajax Code, all other fields working fine except meta value is not being added in post
jQuery( document ).ready( function ( $ ) {
$( '#post-submission-form' ).on( 'submit', function(e) {
e.preventDefault();
var title = $( '#post-submission-title' ).val();
var excerpt = $( '#post-submission-excerpt' ).val();
var content = $( '#post-submission-content' ).val();
var status = 'draft';
var data = {
title: title,
excerpt: excerpt,
content: content,
status: status,
meta: {
'video_url_url' : 'abc',
}
};
$.ajax({
method: "POST",
url: POST_SUBMITTER.root + 'wp/v2/posts',
data: data,
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', POST_SUBMITTER.nonce );
},
success : function( response ) {
console.log( response );
alert( POST_SUBMITTER.success );
},
fail : function( response ) {
console.log( response );
alert( POST_SUBMITTER.failure );
}
});
});
} );
Add this to your functions.php :
/**
* Add the meta fields to REST API responses for posts read and write
* Read and write a post meta fields in post responses
*/
function mg_register_meta_api() {
//Meta Fields that should be added to the API
$meta_fields = array(
'video_url_url',
'another_meta_key'
);
//Iterate through all fields and add register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'ring',
$field,
array(
'get_callback' => array( $this, 'mg_fw_get_meta'),
'update_callback' => array( $this, 'mg_fw_update_meta'),
'schema' => null,
)
);
}
}
add_action( 'rest_api_init', 'mg_register_meta_api' );
/**
* Handler for getting custom field data.
*
* #since 0.1.0
*
* #param array $object The object from the response
* #param string $field_name Name of field
*
* #return mixed
*/
function mg_get_meta( $object, $field_name ) {
return get_post_meta( $object[ 'id' ], $field_name );
}
/**
* Handler for updating custom field data.
*
* #since 0.1.0
* #link http://manual.unyson.io/en/latest/helpers/php.html#database
* #param mixed $value The value of the field
* #param object $object The object from the response
* #param string $field_name Name of field
*
* #return bool|int
*/
function mg_update_meta( $value, $object, $field_name ) {
if ( ! $value || ! is_string( $value ) ) {
return;
}
return update_post_meta( $object->ID, $field_name, maybe_serialize( strip_tags( $value ) ) );
}
Now you should be able to read and write for meta 'video_url_url' using the api.
I was playing around with this today and came up with the following solution that works well and adds multiple fields.
Hope this helps anyone who may be stuck on this.
add_action( 'rest_api_init', 'foo_register_meta_api' );
function foo_register_meta_api() {
// Meta Fields to add to the API
$meta_fields = array(
'field_1',
'foo_bar',
'foobar',
'another_field'
);
// Loop all fields and register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'my-post-type',
$field,
array(
'get_callback' => function ($params) use ($field) {
return \get_post_meta($params['id'], $field);
},
'update_callback' => function ($value, $object, $fieldName){
return \update_post_meta($object->ID, $fieldName, $value);
},
'schema' => null
)
);
}
}
I am trying to save phy_marks in post type candidates. What I've got is creating the post but not saving phy_marks.
My JSON data:
{ "title": "Why not working finally","content": "Test", "status": "publish" ,"post_type": "candidates", "meta": {
"phy_marks": 66 } }
My Code:
add_action( 'rest_api_init', 'foo_register_meta_api' );
function foo_register_meta_api() {
// Meta Fields to add to the API
$meta_fields = array(
'phy_marks'
);
// Loop all fields and register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'candidates',
$field,
array(
'get_callback' => function ($params) use ($field) {
return \get_post_meta($params['id'], $field);
},
'update_callback' => function ($value, $object, $fieldName){
return \update_post_meta($object->ID, $fieldName, $value);
},
'schema' => null
)
);
}
}

Run plugin code from "functions.php" in WordPress

I have a plugin for allowing duplicate emails on registration and that is working fine if I have used the plugin. I want to use plugin code in functions.php (meaning to say run the plugin code functionality with themes).
Below is my plugin code:
/**
* Plugin Name: Allow duplicate emails on registration
* Plugin URI: http://wordpress.stackexchange.com/a/125129/26350
*/
add_action( 'plugins_loaded', array( 'Allow_Duplicate_Emails_Registration', 'get_instance' ) );
class Allow_Duplicate_Emails_Registratn
{
private $rand = '';
static private $instance = NULL;
static public function get_instance()
{
if ( NULL === self::$instance )
self::$instance = new self;
return self::$instance;
}
public function __construct()
{
// Generate some random string:
$this->rand = '_remove_' . rand( 0, 99999);
add_filter( 'user_registration_email', array( $this, 'user_registration_email' ) );
add_action( 'user_register', array( $this, 'user_register' ) );
}
public function user_registration_email( $user_email )
{
// inject random string into the email
$user_email = str_replace( '#', $this->rand . '#', $user_email );
return $user_email;
}
public function user_register( $user_id )
{
// retrieve the newly registered user object
$user = get_user_by( 'id', $user_id );
// remove the random string
$user_email = str_replace( $this->rand . '#', '#', $user->user_email );
// update the email of the newly registered user
$args = array(
'ID' => $user_id,
'user_email' => $user_email,
);
$result = wp_update_user( $args );
}
}
And I have changed the above code below and put in functions.php, but it is not working:
add_action( 'init', array( 'Allow_Duplicate_Emails_Registration', 'get_instance' ) );
I have solved the problem. Add the below code in the wp-content/themes/my-themes/functions.php file:
<?php
add_filter( 'user_registration_email', array( $this, 'user_registration_email' ) );
add_action( 'user_register', array( $this, 'user_register' ) );
function user_registration_email( $user_email )
{
// Inject a random string into the email
$user_email = str_replace( '#', $this->rand . '#', $user_email );
return $user_email;
}
function user_register( $user_id )
{
// Retrieve the newly registered user object
$user = get_user_by( 'id', $user_id );
// Remove the random string
$user_email = str_replace( $this->rand . '#', '#', $user->user_email );
// Update the email of the newly registered user
$args = array(
'ID' => $user_id,
'user_email' => $user_email,
);
$result = wp_update_user( $args );
}
?>

Resources