Search code examples
phpwordpresswoocommerceproducthook-woocommerce

How does woocommerce_loop_add_to_cart_link filter hook work in depth?


I have some basic Woocommerce questions and cannot find anywhere online.

  • from the code below, where are $args come from?
  • how $product and $args assign to %s ?

thanks!

global $product;

echo apply_filters( 'woocommerce_loop_add_to_cart_link', // WPCS: XSS ok.
    sprintf( '<a href="%s" data-quantity="%s" class="%s" %s>%s</a>',
        esc_url( $product->add_to_cart_url() ),
        esc_attr( isset( $args['quantity'] ) ? $args['quantity'] : 1 ),
        esc_attr( isset( $args['class'] ) ? $args['class'] : 'button' ),
        isset( $args['attributes'] ) ? wc_implode_html_attributes( $args['attributes'] ) : '',
        esc_html( $product->add_to_cart_text() )
    ),
$product, $args );

Solution

  • 1) Explanations for $args variable in template file loop/add_to_cart.php:

    The code in your question come from the template file loop/add_to_cart.php.
    It is called by content-product.php template file on woocommerce_after_shop_loop_item hook:

    /**
     * Hook: woocommerce_after_shop_loop_item.
     *
     * @hooked woocommerce_template_loop_product_link_close - 5
     * @hooked woocommerce_template_loop_add_to_cart - 10
     */
    do_action( 'woocommerce_after_shop_loop_item' );
    

    As you can see the template function woocommerce_template_loop_add_to_cart() does this job and it is located in WooCommerce plugin under includes/wc-template-functions.php.

    So the default arguments are:

    $defaults = array(
        'quantity'   => 1,
        'class'      => implode(
            ' ',
            array_filter(
                array(
                    'button',
                    wc_wp_theme_get_element_class_name( 'button' ), // escaped in the template.
                    'product_type_' . $product->get_type(),
                    $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
                    $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock() ? 'ajax_add_to_cart' : '',
                )
            )
        ),
        'attributes' => array(
            'data-product_id'  => $product->get_id(),
            'data-product_sku' => $product->get_sku(),
            'aria-label'       => $product->add_to_cart_description(),
            'aria-describedby' => $product->add_to_cart_aria_describedby(),
            'rel'              => 'nofollow',
        ),
    );
    

    They are parsed through the filter hook woocommerce_loop_add_to_cart_args:

    $args = apply_filters( 'woocommerce_loop_add_to_cart_args', wp_parse_args( $args, $defaults ), $product );
    

    … allowing to make changes on this arguments.

    The $args variable in woocommerce_loop_add_to_cart_link is made of that.


    1. How $product and $args are assigned to %s:

    This is specific to PHP printf() and sprintf() function where each %s are a placeholder.

    In '<a href="%s" data-quantity="%s" class="%s" %s>%s</a>':

    • the 1st placeholder %s will be replaced by esc_url( $product->add_to_cart_url() )
    • the 2nd placeholder %s by esc_attr( isset( $args['quantity'] ) ? $args['quantity'] : 1 )
    • and so on…

    Documentation for printf() and sprintf() php functions.