I am trying to insert the $addresscustom to the Woocommerce REST API, but it displays the Error:
> I/flutter (19003): FormatException: Unexpected character (at character 1)
> I/flutter (19003): <style type="text/css"> .wp-die-message {display: none; }
> I/flutter (19003): ^
Why it is saying the response is not json decoded (Flutter FormatException: Unexpected character (at character 1)), when it is indeed decoded? For instance, when I use the code 2, it works and displays the URL in the REST API:
The code:
function get_address_store( $response, $order_obj, $request, $object) {
if( empty( $response->data ) )
return $response;
$order = WC_Order( $order_obj->get_order_number() );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
$itemdata = $item->get_data();
$item_id = $itemdata['id'];
}
$gift_wrap = wc_get_order_item_meta( $item_id, 'anbieter',true);
$vendor_data_new = get_page_by_title($gift_wrap, '', 'wpsl_stores');
$addresscustom = get_post_meta( $vendor_data_new->ID, 'wpsl_address', true );
$response->data['line_items'][0]['store_address'] = $addresscustom;
return $response;
}
add_filter( "woocommerce_rest_prepare_shop_order_object","get_address_store", 10, 3 );
Code 2 (working):
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($order_pid);
$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","get_product_order_image", 10, 3 );
Thanks for taking a time to read it :)
Related
I'd like to add a custom message below the available shipping methods in the cart, but only if ALL products in the cart have a tag named 'express'.
Therefore I use this snippet:
add_action( 'woocommerce_after_shipping_rate', 'action_after_shipping_rate', 20, 2 );
function action_after_shipping_rate ( $method, $index ) {
if( 'flat_rate:1' === $method->id ) {
echo __("<p>Arriving on your chosen date between 9am - 1pm Perfect for business addresses & special occasions</p>");
}
if( 'flat_rate:2' === $method->id ) {
echo __("<p>Arriving on your chosen date between 9am - 7pm Perfect for residential addresses</p>");
}
}
add_filter( 'woocommerce_shipping_details', 'hide_shipping_details', 10, 2 );
function hide_shipping_details( $rates, $package ) {
$terms = array( 'express' );
$taxonomy = 'product_tag';
$found = false;
foreach( $package['contents'] as $cart_item ) {
if ( !has_term( $terms, $taxonomy, $cart_item['product_id'] ) ){
$found = true;
break;
}
}
if ( $found === false ) {
remove_action( 'woocommerce_after_shipping_rate', 'action_after_shipping_rate', 20, 2 );
}
}
But right now, the custom message remains if 1 or 2 products have the tag 'express' but not ALL products. Can someone help me solve this problem?
No need to call from one hook to another, while you can just loop through all the products in cart in the woocommerce_after_shipping_rate hook
So you get:
function action_woocommerce_after_shipping_rate( $method, $index ) {
// Settings
$terms = array( 'express', 'tag-1' );
$taxonomy = 'product_tag';
// Initialize
$flag = false;
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
// Checks if the current product has NOT any of given terms
if ( ! has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) {
$flag = true;
break;
}
}
// When false
if ( ! $flag ) {
// Compare
if ( $method->get_id() === 'flat_rate:1' ) {
$text = 'My text 1';
} elseif ( $method->get_id() === 'flat_rate:3' ) {
$text = 'My text 2';
} elseif ( $method->get_id() === 'local_pickup:1' ) {
$text = 'My text 3';
}
// When isset
if ( isset( $text ) ) {
// Output
echo '<p>' . sprintf( __( '%s', 'woocommerce' ), $text ) . '</p>';
}
}
}
add_action( 'woocommerce_after_shipping_rate', 'action_woocommerce_after_shipping_rate', 10, 2 );
The customer requested me to disable email notification for free products in WoocCmmerce, but only in case the order contains this free product id = 5274
If the order includes this free product and any other product, the order email notification should be trigger.
This is the code I use now:
add_filter('woocommerce_email_recipient_new_order', 'disable_notification_free_product', 10, 2);
function disable_notification_free_product($recipient, $order)
{
$page = $_GET['page'] = isset($_GET['page']) ? $_GET['page'] : '';
if ('wc-settings' === $page) {
return $recipient;
}
if (!$order instanceof WC_Order) {
return $recipient;
}
//the product id is 5274
$items = $order->get_items();
$items_cart = WC()->cart->get_cart_contents_count();
foreach ($items as $item) {
$product_id = $item['product_id'];
if ($product_id == 5274 and $items_cart == 1) {
$recipient = '';
}
return $recipient;
}
}
The code works before adding "and $items_cart == 1" to disable the email notification when the free product is in the order, but after adding the "and $items_cart == 1" nothing changed. Any advice?
That's because WC()->cart->get_cart_contents_count() should only be used with the $cart object, with the $order object you can use count( $order->get_items() )
So you get:
function filter_woocommerce_email_recipient_new_order( $recipient, $order, $email ) {
// Avoiding backend displayed error in WooCommerce email settings
if ( ! is_a( $order, 'WC_Order' ) ) return $recipient;
// Loop through order items
foreach ( $order->get_items() as $key => $item ) {
// Product ID
$product_id = $item->get_variation_id() > 0 ? $item->get_variation_id() : $item->get_product_id();
// Product ID occurs and count is equal to 1
if ( in_array( $product_id, array( 5274 ) ) && count( $order->get_items() ) == 1 ) {
$recipient = '';
break;
}
}
return $recipient;
}
add_filter( 'woocommerce_email_recipient_new_order', 'filter_woocommerce_email_recipient_new_order', 10, 3 );
I want to check if, at least, one of item has specific attribute term in WooCommerce order to display something in the mail order.
Attribute tax is 'pa_labels' and the term is 'tree' but something is missing... Any Idea ?
add_action( 'woocommerce_thankyou', 'webroom_check_product_attr_in_order', 5 );
function webroom_check_product_attr_in_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$attr_in_order = false;
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( has_term( 'tree', 'pa_labels', $product_id ) ) {
$attr_in_order = true;
break;
}
}
// Echo content only if $attr_in_order == true
if ( $attr_in_order ) {
add_action( 'woocommerce_email_customer_details', 'custom_woocommerce_email_customer_details', 25);
}
}
You can try something like this:
// check if in the order there is at least one product with the attribute "pa_labels" => "tree"
add_action( 'woocommerce_thankyou', 'webroom_check_product_attr_in_order', 5 );
function webroom_check_product_attr_in_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$attr_in_order = false;
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( has_term( 'tree', 'pa_labels', $product->get_id() ) ) {
$attr_in_order = true;
break;
}
}
// Echo content only if $attr_in_order == true
if ( $attr_in_order ) {
custom_woocommerce_email_customer_details();
}
}
// add content to the customer details in the email
add_action( 'woocommerce_email_customer_details', 'custom_woocommerce_email_customer_details', 25);
function custom_woocommerce_email_customer_details() {
// do stuff
}
The code must be added to the functions.php of the active theme.
I am trying to change the product edit url which is created from this plugins function:
function dokan_edit_product_url( $product ) {
if ( ! $product instanceof WC_Product ) {
$product = wc_get_product( $product );
}
if ( ! $product ) {
return false;
}
if ( 'publish' === $product->get_status() ) {
$url = trailingslashit( get_permalink( $product->get_id() ) ) . 'edit/';
} else {
$url = add_query_arg(
[
'product_id' => $product->get_id(),
'action' => 'edit',
],
dokan_get_navigation_url( 'products' )
);
}
return apply_filters( 'dokan_get_edit_product_url', $url, $product );
}
You can see it has a apply_filters available. So I am trying to create a filter to modify the URL to be: example.com/edit-product/product-id
add_filter( 'dokan_get_edit_product_url', function() {
// I need to get the PRODUCT ID here somehow.
$url = 'example.com/dashboard/edit-product' . $product_id;
return $url;
} );
How can I get the product ID in my filter? I need to grab the product ID and attach it to: example.com/dashboard/edit-product/ + product_id
Here is one attempt:
add_filter( 'dokan_get_edit_product_url', function( $product ) {
$product = wc_get_product( $product );
var_dump($product);
return $url;
} );
Result:
/app/filters.php:175:boolean false
Following a suggestion in the comments from #howard-e, I was simply missing global $product;
Here is my full filter:
add_filter( 'dokan_get_edit_product_url', function( $product ) {
global $product;
$url = dokan_get_navigation_url() . 'edit-product?product_id=' . $product->get_id();
return $url;
} );
Obviously the format of the $url is unique to my set up, but worth posting the full code anyway.
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