Override External Product URL to "Add to Cart" product button - php

I work on site that use External products from Amazon, but want instead pointing users to that external URL, first to add to cart that product. I have this function, that change Default Button text for each product, to Add to cart.
function sv_wc_external_product_button( $button_text, $product ) {
if ( 'external' === $product->get_type() ) {
// enter the default text for external products
return $product->button_text ? $product->button_text : 'Add To Cart';
}
return $button_text;
}
add_filter( 'woocommerce_product_single_add_to_cart_text',
'sv_wc_external_product_button', 10, 2 );
But this function not add product to cart.
How to make this function to Add selected product to cart?
Thanks.

Updated 2020
This is a complete different way with simple products and a custom field external link.
In this answer we will use simple products instead of external products.
We add an "External URL" custom field in product option settings and we save the data.
Add a custom field on general product option settings for simple products only :
add_action( 'woocommerce_product_options_general_product_data', 'simple_product_with_external_url' );
function simple_product_with_external_url() {
global $product_object;
echo '<div class="options_group show_if_simple hidden">';
// External Url
woocommerce_wp_text_input( array(
'id' => '_ext_url_cust',
'label' => 'External Url',
'description' => 'Custom external URL',
'desc_tip' => 'true',
'placeholder' => 'Enter here your custom external URL'
) );
echo '</div>';
}
Save the custom field data if it's a simple product and not empty:
add_action( 'woocommerce_admin_process_product_object', 'save_simple_product_with_external_url' );
function save_simple_product_with_external_url( $product ) {
if( $product->is_type('simple') && isset($_POST['_ext_url_cust']) ) {
$product->update_meta_data( '_ext_url_cust', sanitize_url($_POST['_ext_url_cust']) );
}
}
2) This will not work on shop pages and archives pages, if we don't set in WooCommerce the cart redirection when adding a product to cart.
So we will replace add-to-cart button (just for our simple products with a custom link redirection) on shop pages and archives pages by a linked custom button to single product pages.
Replacing add-to-cart button in shop pages and archives pages (for simple products with custom external url):
add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_woocommerce_loop_add_to_cart_link', 10, 2 );
function quantity_inputs_for_woocommerce_loop_add_to_cart_link( $html, $product ) {
$external_url = $product->get_meta('_ext_url_cust');
if ( ! empty($external_url) ) {
$html = sprintf( '%s', $product->get_permalink(), __("Read More", "woocommerce") );
}
return $html;
}
3) If the custom field value is not empty, the product is added to cart first and then redirected to the external URL (our custom field value in single product pages)
External URL redirection after adding to cart (when custom field is not empty in simple products):
add_filter( 'woocommerce_add_to_cart_redirect', 'redirect_simple_product_with_external_url' );
function redirect_simple_product_with_external_url( $url ) {
if( isset($_REQUEST['add-to-cart']) && absint( $_REQUEST['add-to-cart'] ) > 0 )
return get_post_meta( absint( $_REQUEST['add-to-cart'] ), '_ext_url_cust', true );
return $url;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works on WooCommerce version 3+

Use https://stackoverflow.com/a/44036965/3730754 instead.
You should try to use woocommerce_product_add_to_cart_url filter hook to change the add-to-cart link (here for grouped products), this way:
add_filter( 'woocommerce_product_add_to_cart_url', 'override_external_product_url', 10, 2 );
function override_external_product_url( $url, $product ){
if ( 'external' === $product->get_type() ) {
//Get product ID -- WooCommerce compatibility
if ( method_exists( $product, 'get_id' ) ) {
$product_id = $product->get_id();
} else {
$product_id = $product->id;
}
// custom add to cart url example
$url = home_url( "/product/?add-to-cart=$product_id");
}
return $url;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Update: But this will not add to cart this external product before redirecting to an external url even if it works displaying the add-to-cart url (as add-to-cart is ajax driven).

I fixed myself. For External products, to replace default "Buy This Product" with other generic text, add this functions into functions.php file into theme:
add_filter( 'woocommerce_product_add_to_cart_text' ,
'wpf_custom_add_cart_text_archive',11);
function wpf_custom_add_cart_text_archive() {
global $product;
$product_type = $product->product_type;
switch ( $product_type ) {
case 'external':
return __( 'Add to Cart', 'woocommerce' );
break;
case 'grouped':
return __( 'View products', 'woocommerce' );
break;
case 'simple':
return __( 'Add to cart', 'woocommerce' );
break;
case 'variable':
return __( 'Select options', 'woocommerce' );
break;
default:
return __( 'Read more', 'woocommerce' );
}
}
add_filter( 'woocommerce_product_single_add_to_cart_text',
'wpf_custom_add_cart_text',11);
and this one:
function wpf_custom_add_cart_text() {
return __( 'Add to Cart', 'woocommerce' );
}
to replace text everywhere.

Related

Disabling Add to Cart Button for Specific WooCommerce Products

I'm trying to disable adding to cart certain products which have the "Call to Order" checkbox ticked (see code below) on the product editor.
add_action( 'woocommerce_product_options_general_product_data', 'custom_general_product_data_custom_fields' );
/**
* Add `Call to Order` field in the Product data's General tab.
*/
function custom_general_product_data_custom_fields() {
// Checkbox.
woocommerce_wp_checkbox(
array(
'id' => '_not_ready_to_sell',
'wrapper_class' => 'show_if_simple',
'label' => __( 'Call to Order', 'woocommerce' ),
'description' => __( '', 'woocommerce' )
)
);
}
add_action( 'woocommerce_process_product_meta', 'custom_save_general_proddata_custom_fields' );
/**
* Save the data values from the custom fields.
* #param int $post_id ID of the current product.
*/
function custom_save_general_proddata_custom_fields( $post_id ) {
// Checkbox.
$woocommerce_checkbox = isset( $_POST['_not_ready_to_sell'] ) ? 'yes' : 'no';
update_post_meta( $post_id, '_not_ready_to_sell', $woocommerce_checkbox );
}
add_filter( 'woocommerce_is_purchasable', 'custom_woocommerce_set_purchasable', 10, 2);
/**
* Mark "Not ready to sell" products as not purchasable.
*/
function custom_woocommerce_set_purchasable() {
$not_ready_to_sell = get_post_meta( get_the_ID(), '_not_ready_to_sell' , true);
return ( 'yes' == $not_ready_to_sell ? false : true );
}
add_filter( 'woocommerce_product_add_to_cart_text', 'custom_product_add_to_cart_text' );
/**
* Change "Read More" button text for non-purchasable products.
*/
function custom_product_add_to_cart_text() {
$not_ready_to_sell = get_post_meta( get_the_ID(), '_not_ready_to_sell', true );
if ( 'yes' === $not_ready_to_sell ) {
return __( 'Call to Order', 'woocommerce' );
} else {
return __( 'Add to Cart', 'woocommerce' );
}
}
The products that have the checkbox ticked, are in fact not purchasable, which is the desired outcome.
The problem I'm having is when I click "Add to Cart" for purchasable products (those without the checkbox ticked) on the product catalog page, I am redirected to the product page and a default WooCommerce message "Sorry, this product cannot be purchased." appears. What should be happening is that when the "Add to Cart" button is clicked, the product is automatically added to the cart.
Also from the single product page, I can add the purchasable cart without a problem.
I am not sure why this is happening this way. Any ideas?
I have tested your code and it work without problems… I don't have the problematic behavior you describe… So something else is making trouble:
You will need first to make a database backup… Then you should try to:
Check if in your other customizations, there is something that is disabling Ajax add to cart and making that message appear. Try to comment your other customizations to find the guilty one.
Try to disable all third party plugins related to Woocommerce (except Woocommerce). If the problem is gone, re-enable them one by one to find the guilty.
The problem could come from the theme too.
Now since Woocommerce 3 and introduced CRUD Objects, your code is a bit outdated.
Here is revisited and enhanced code version (for Woocommerce 3+):
// Add a custom field in the Product data's General tab (for simple products).
add_action( 'woocommerce_product_options_general_product_data', 'add_general_product_data_custom_field' );
function add_general_product_data_custom_field() {
woocommerce_wp_checkbox( array( // Checkbox.
'id' => '_not_ready_to_sell',
'label' => __( 'Call to Order', 'woocommerce' ),
'wrapper_class' => 'show_if_simple',
) );
}
// Save custom field value
add_action( 'woocommerce_admin_process_product_object', 'save_general_product_data_custom_field', 10, 1 );
function save_general_product_data_custom_field( $product ) {
$product->update_meta_data( '_not_ready_to_sell', isset( $_POST['_not_ready_to_sell'] ) ? 'yes' : 'no' );
}
// Make not purchasable, products with '_not_ready_to_sell' meta data set to "yes" (for simple products)
add_filter( 'woocommerce_is_purchasable', 'filter_woocommerce_set_purchasable', 10, 2);
function filter_woocommerce_set_purchasable( $purchasable, $product ) {
return 'yes' === $product->get_meta( '_not_ready_to_sell' ) && $product->is_type('simple') ? false : $purchasable;
}
// Change button text to "Call to Order" for simple products not purchasable.
add_filter( 'woocommerce_product_add_to_cart_text', 'filter_product_add_to_cart_text', 10, 2 );
function filter_product_add_to_cart_text( $button_text, $product ) {
if ( 'yes' === $product->get_meta( '_not_ready_to_sell' ) && $product->is_type('simple') ) {
$button_text = __( 'Call to Order', 'woocommerce' );
}
return $button_text;
}
Code goes on function.php file of your active child theme (or active theme). It could works.

Change Checkout "Billing Details" text for a specific product in Woocommerce

How can I change the text "Billing Details" in Woocommerce checkout page only for a specific product?
I have tried:
/* Change the Billing Details checkout label to Your Details: */
function wc_billing_field_strings( $translated_text, $text, $domain )
{
switch ( $translated_text ) {
case 'Billing Details' :
$translated_text = __( 'Your Details', 'woocommerce' );
break;
}
return $translated_text;
}
add_filter( 'gettext', 'wc_billing_field_strings', 20, 3 );
But it's changing the text for all products… How could I do this for one specific product?
To change a translatable text in checkout page when there is a specific item in cart, use the following:
add_filter( 'gettext', 'change_conditionally_checkout_heading_text', 10, 3 );
function change_conditionally_checkout_heading_text( $translated, $text, $domain ) {
if( $text === 'Billing details' && is_checkout() && ! is_wc_endpoint_url() ){
// HERE set the desired specific product ID
$targeted_product_id = 1980;
// Loop through cart items
foreach( WC()->cart->get_cart() as $cart_item ) {
if( $targeted_product_id == $cart_item['data']->get_id() ) {
return __( 'Your Details', $domain );
break; // Stop the loop
}
}
}
return $translated;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Note: In Woocommerce checkout the text to change is "Billing details" without a capital in "Details"
First, override the Woocommerce plugin template and change inside it
wp-content/plugins/woocommerce/templates/checkout/form-checkout.php
find your necessary template and change the text.

Add product description to cart items in Woocommerce

I'm struggling to find a simple solution to this problem I'm having with One-page-checkout plugin for Woocommerce.
My client would like to add the product description next to the product title in cart items.
Any thoughts on how I can manipulate the code to show the description?
This is what I have actually:
I would think that this plugin would just be hiding the description somewhere but I can't locate it anywhere in the code.
There is 2 ways to do it (making work for products and product variations):
1). With custom function hooked in woocommerce_get_item_data action hook (The best way):
add_filter( 'woocommerce_get_item_data', 'customizing_cart_item_data', 10, 2 );
function customizing_cart_item_data( $cart_data, $cart_item ) {
$description = $cart_item['data']->get_description(); // Get the product description
// For product variations when description is empty
if( $cart_item['variation_id'] > 0 && empty( $description ) ){
// Get the parent variable product object
$parent_product = wc_get_product( $cart_item['product_id'] );
// Get the variable product description
$description = $parent_product->get_description();
}
// If product or variation description exists we display it
if( ! empty( $description ) ){
$cart_data[] = array(
'key' => __( 'Description', 'woocommerce' ),
'value' => $description,
'display' => $description,
);
}
return $cart_data;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
… or …
2). With custom function hooked in woocommerce_cart_item_name filter hook:
WooCommerce: Display also product variation description on cart items
You could try this code in your functions.php located in your root of your theme folder. Not sure if it still works as I'm not active in Wordpress development anymore. [untested]
Updated: this should probably work for WooCommerce 3+
Using woocommerce_cart_item_name hook:
add_filter( 'woocommerce_cart_item_name', 'cart_description', 20, 3);
function cart_description( $name, $cart_item, $cart_item_key ) {
// Get the corresponding WC_Product
$product_item = $cart_item['data'];
if(!empty($product_item)) {
// WC 3+ compatibility
$description = $product_item->get_description();
$result = __( 'Description: ', 'woocommerce' ) . $description;
return $name . '<br>' . $result;
} else
return $name;
}
}

woocommerce add to cart button on single product page

On WooCommerce, I would like a custom add to cart button redirection for specific categories to contact us page (when customer click on the add to cart button in single product pages).
This is my code:
add_filter( 'woocommerce_add_to_cart_redirect', 'rv_redirect_to_url' );
function rv_redirect_to_url() {
global $woocommerce, $post;
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_REQUEST['add-to-cart'] ) );
$rv_woo_redirect_url = get_post_meta( $product_id, '_rv_woo_product_custom_redirect_url', true );
if ( ! empty( $rv_woo_redirect_url ) ) {
wp_redirect( esc_url( $rv_woo_redirect_url ) ); exit;
}
}
How can I change my code to get it working only for defined product categories?
Updated (the right custom url when it's a defined product category)
Using a custom function hooked in woocommerce_add_to_cart_redirect filter hook, that will redirect customer when a product is added to cart (for defined product category(ies)):
add_filter( 'woocommerce_add_to_cart_redirect', 'conditional_add_to_cart_redirection', 99, 1 );
function conditional_add_to_cart_redirection( $url ) {
// ==> HERE define your product category or categories in the array
$category = array( 'clothing', 'music' );
if ( ! isset( $_REQUEST['add-to-cart'] ) ) return $url; // Very important!
// When it's available (on add to cart click), get the product ID
$product_id = absint( $_REQUEST['add-to-cart'] );
// Get the custom url from product post meta data
$custom_url = get_post_meta( $product_id, '_rv_woo_product_custom_redirect_url', true );
// Exit to normal, If the custom URL redirection is not set in the product
if( empty( $custom_url ) ) return $url;
// Custom redirection only for your defined product category(ies)
if( has_term( $category, 'product_cat', $product_id ) ){
// Clear add to cart notice (with the cart link).
wc_clear_notices();
$url = $custom_url; // Updated here
}
return $url;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Code is tested on Woocommerce 3+ and works
Add to cart redirection will not work with ajax add to cart on shop and archives pages. So you will have to choose between that 2 options for shop and archives pages:
Disable ajax add-to-cart on shop and archives pages ( WC settings > Products > Display ).
Add the following code to replace the add to cart button, by a button linked to the product:
This 2nd option seems to be the best (as this is conditional on some products only):
// Conditionally changing add to cart button link and text on shop and archives
add_filter( 'woocommerce_loop_add_to_cart_link', 'replacing_add_to_cart_button', 10, 2 );
function replacing_add_to_cart_button( $button, $product ) {
if( $product->is_type( 'variable-subscription' ) || $product->is_type( 'variable' ) ) return $button;
// ==> HERE define your product category or categories in the array
$category = array( 'clothing', 'music' );
// Check that the custom url from product post meta data is not empty
$custom_url = get_post_meta( $post->ID, '_rv_woo_product_custom_redirect_url', true );
if( empty( $custom_url ) ) return $button;
// Check if the current product has a defined product category(ies)
if( ! has_term( $category, 'product_cat', $post->ID ) ) return $button;
$button_text = __( 'View product', 'woocommerce' );
$button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
return $button;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Code is tested on Woocommerce 3+ and works
If the product is not meant to be purchased outright, then I would filter woocommerce_is_purchasable and replace the add to cart button with a button-styled link to your contact form.
function so_46395830_not_purchasable( $is_purchasable, $product ) {
$rv_woo_redirect_url = $product->get_meta( '_rv_woo_product_custom_redirect_url', true );
if ( ! empty( $rv_woo_redirect_url ) ) {
add_action( 'woocommerce_single_product_summary', 'so_46395830_redirect_to_contact' );
}
return $is_purchasable;
}
add_filter( 'woocommerce_is_purchasable', 'so_46395830_not_purchasable', 10, 2 );
function so_46395830_redirect_to_contact( $url ) {
global $product;
$rv_woo_redirect_url = $product->get_meta( '_rv_woo_product_custom_redirect_url', true );
echo sprintf( '<a class="button" href="%s">%s</a>', esc_url( $rv_woo_redirect_url ), __( 'Contact Us for Info', 'your-plugin-textdomain' ) );
}

Change WooCommerce add to cart text for specific tag

I am looking for a function to change the Add to Cart text on a woocommerce button but only if the product in question has a specific tag. ie if the product has the tag "preorder" the button text changes to "Pre Order Now"
Changing the text globally can be achieved with this;
http://docs.woothemes.com/document/change-add-to-cart-button-text/
Thanks.
You can check for that particular term with has_term.
//For single product page
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' ); // 2.1 +
function woo_custom_cart_button_text() {
global $product;
if ( has_term( 'preorder', 'product_cat', $product->ID ) ) :
return __( 'Pre order Now!', 'woocommerce' );
endif;
}
//For Archive page
add_filter( 'woocommerce_product_add_to_cart_text', 'woo_archive_custom_cart_button_text' ); // 2.1 +
function woo_archive_custom_cart_button_text() {
if ( has_term( 'preorder', 'product_cat', $product->ID ) ) :
return __( 'Pre order Now!', 'woocommerce' );
else:
return __( 'Add to Cart', 'woocommerce' );
endif;
}
Let me know the output.
It's been a while, but try something along the following lines:
<?php
add_filter( 'woocommerce_product_add_to_cart_text' , 'custom_woocommerce_product_add_to_cart_text' );
/**
* custom_woocommerce_template_loop_add_to_cart
*/
function custom_woocommerce_product_add_to_cart_text() {
global $product;
$product_tag = $product->product_tag;
switch ( $product_tag ) {
case 'preorder':
return __( 'Pre order Now!', 'woocommerce' );
break;
default:
return __( 'Add to cart', 'woocommerce' );
}
}
Basically what you're trying to do is do a conditional where you check if the product tag is "preorder". I am not sure if this exact code would work if there are multiple tags.
Edit:
You might have to use this filter to change it on the product page
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' );
Add this into your child theme function.php file
add_filter( 'woocommerce_product_add_to_cart_text',
'woocommerce_add_to_cart_button_text_archives' );
function woocommerce_add_to_cart_button_text_archives() {
return __( 'Add to Cart Button Text', 'woocommerce' );
You can fix it by adding a few lines of codes in functions.php:
// Change the add to cart text on single product pages
add_filter( 'woocommerce_product_single_add_to_cart_text’, ‘woo_custom_cart_button_text' ); // 2.1 +
function woo_custom_cart_button_text() {
return __( 'ADD TO CART', 'woocommerce' );
}
//Change the add to cart text on product archives
add_filter( 'woocommerce_product_add_to_cart_text', 'woo_archive_custom_cart_button_text' ); // 2.1 +
function woo_archive_custom_cart_button_text() {
return __( 'ADD TO CART', 'woocommerce' );
}
http://visupporti.com/woocommerce-how-to-change-add-to-cart-text/

Categories