Search code examples
phpwordpresswoocommerceadminorders

Change WooCommerce Order items admin product link to the product permalink (frontend)


In WooCommerce, the product links in order details currently lead to the product edit page instead of the product page in the webshop. I tried adding some code to fix this and using

$product_link = $product ? get_permalink( $product->get_id() ) : '';

but it doesn't work and it also duplicates the product title on the order details form.

Related question: Change product url in woocommerce order detail

add_action( 'woocommerce_before_order_itemmeta', 'custom_order_item_product_link', 10, 3 );
function custom_order_item_product_link( $item_id, $item, $product ) {
    if ( ! is_a( $product, 'WC_Product' ) ) {
        return;
    }
    $product_link = $product->is_visible() ? $product->get_permalink() : '';
    if ( $product_link ) {
        printf( '<a href="%s">%s</a>', esc_url( $product_link ), esc_html( $product->get_name() ) );
    } else {
        echo esc_html( $product->get_name() );
    }
}

Solution

  • As the product link in admin order edit pages is not editable/filterable via any hooks or templates, you need something a bit different using JavaScript, to be able to change this admin product link to the frontend product permalink.

    Try the following instead (works also with HPOS):

    add_action( 'woocommerce_before_order_itemmeta', 'add_admin_order_item_product_permalink', 10, 2 );
    function add_admin_order_item_product_permalink( $item_id, $item ) {
        if( $item->get_type() !== 'line_item' ) 
            return;
    
        $product = $item->get_product();
    
        // Add a hidden input field with the product permalink
        printf( '<input type="hidden" name="product-permalink" value="%s">', esc_url($product->get_permalink()));
    }
    
    // Change order items admin product link to the product frontend permalink
    add_filter( 'admin_footer', 'admin_order_items_with_product_permalink_js' );
    function admin_order_items_with_product_permalink_js() {
        global $pagenow, $typenow; 
    
        if ( ( $pagenow === 'post.php' && $typenow === 'shop_order' ) 
        || ( $pagenow === 'admin.php' && isset($_GET['page'])  && isset($_GET['action']) 
        && $_GET['page'] === 'wc-orders' && $_GET['action'] === 'edit' ) ) :
        ?>
        <script>
        jQuery('#order_line_items tr').each(function(){
            jQuery(this).find('td.name a').prop('href', jQuery(this).find('input[name=product-permalink]').val());
        });
        </script>
        <?php
        endif;
    }
    

    Code goes on functions.php file of your child theme (or in a plugin). Tested and works.