Override External Product URL to “Add to Cart” pro

2019-01-28 22:47发布

问题:

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.

回答1:

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.

1) We add an "External URL" custom field in product option settings and we save the data.

Add a custom field in simple product general option settings:

add_action( 'woocommerce_product_options_general_product_data', 'simple_product_with_external_url' );
function simple_product_with_external_url() {
    global $woocommerce, $post;

    // only WC products
    if( $post->post_type != 'product' )
        return;

    // Get an instance of WC_Product object
    $product = wc_get_product( $post->ID );

    // Only for simple products
    if ( 'simple' == $product->get_type() ):

        echo '<div class="options_group">';

        // 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>';

    endif;
}

Save the custom field data if it's a simple product and not empty:

add_action( 'woocommerce_process_product_meta', 'save_simple_product_with_external_url' , 10, 1);
function save_simple_product_with_external_url( $post_id ) {

    // Get an instance of WC_Product object
    $product = wc_get_product( $post_id );

    $external_url = $_POST['_ext_url_cust'];

    // Save data if it's not empty and only a simple product
    if( !empty( $external_url ) && 'simple' == $product->get_type() )
        update_post_meta( $post_id, '_ext_url_cust', $external_url );
}

2) This will not work on shop pages and archives pages, if the 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 ) {

    if ( method_exists( $product, 'get_id' ) ) {
        $product_id = $product->get_id();
    } else {
        $product_id = $product->id;
    }

    $external_url = get_post_meta( $product_id, '_ext_url_cust', true );

    if ( ! empty( $external_url ) ) {
        // Set HERE your button link
        $link = get_permalink($product_id);
        $html = '<a href="'.$link.'" class="button alt add_to_cart_button">'.__("Read More", "woocommerce").'</a>';
    }
    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', 10, 1 );
function redirect_simple_product_with_external_url( $url ) {

    $product_id = absint( $_REQUEST['add-to-cart'] );

    $external_url = get_post_meta( $product_id, '_ext_url_cust', true );
    $product = wc_get_product( $product_id );

    if ( 'simple' == $product->get_type() && ! empty( $external_url ) )
        $url = $external_url;

    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 2.6.x



回答2:

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).



回答3:

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.