diff --git a/src/BlockTypes/AddToCartForm.php b/src/BlockTypes/AddToCartForm.php
index ed161525904..9677db846d2 100644
--- a/src/BlockTypes/AddToCartForm.php
+++ b/src/BlockTypes/AddToCartForm.php
@@ -36,17 +36,9 @@ protected function render( $attributes, $content, $block ) {
return '';
}
- ob_start();
- /**
- * Trigger the single product add to cart action for each product type.
- *
- * @since 9.7.0
- */
- do_action( 'woocommerce_' . $product->get_type() . '_add_to_cart' );
+ $add_to_cart_form = $this->add_to_cart_form( $product );
- $product = ob_get_clean();
-
- if ( ! $product ) {
+ if ( ! $add_to_cart_form ) {
return '';
}
@@ -54,12 +46,486 @@ protected function render( $attributes, $content, $block ) {
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
return sprintf(
- '
%4$s
',
+ '%4$s
',
esc_attr( $classes_and_styles['classes'] ),
esc_attr( $classname ),
esc_attr( $classes_and_styles['styles'] ),
- $product
+ $add_to_cart_form
+ );
+ }
+
+ /**
+ * Return the Add to Cart Form for a given product.
+ *
+ * @param \WC_Product $product Product object.
+ *
+ * @return string
+ */
+ protected function add_to_cart_form( $product ) {
+ $product_type = $product->get_type();
+
+ switch ( $product_type ) {
+ case 'simple':
+ $add_to_cart_form = $this->add_simple_product_to_cart( $product );
+ break;
+ case 'variable':
+ $add_to_cart_form = $this->add_variable_product_to_cart( $product );
+ break;
+ case 'grouped':
+ $add_to_cart_form = $this->add_grouped_product_to_cart( $product );
+ break;
+ case 'external':
+ $add_to_cart_form = $this->add_external_product_to_cart( $product );
+ break;
+ default:
+ $add_to_cart_form = '';
+ break;
+ }
+
+ return $add_to_cart_form;
+ }
+
+ /**
+ * The add to cart form for a simple product.
+ *
+ * @param \WC_Product $product Product object.
+ */
+ protected function add_simple_product_to_cart( $product ) {
+ if ( ! $product->is_purchasable() || ! $product->is_in_stock() ) {
+ return '';
+ }
+
+ ob_start();
+ /**
+ * Hook: woocommerce_before_add_to_cart_form.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_before_add_to_cart_form' );
+
+ echo wp_kses_post( wc_get_stock_html( $product ) );
+ ?>
+
+ get_variation_attributes();
+ $attribute_keys = array_keys( $attributes );
+ $available_variations = $product->get_available_variations();
+ $variations_attr = wp_json_encode( $available_variations );
+
+ return $this->variable_product_form( $product, $attributes, $attribute_keys, $available_variations, $variations_attr );
+ }
+
+ /**
+ * The add to cart form for a grouped product.
+ *
+ * @param \WC_Product $product Product object.
+ *
+ * @return string
+ */
+ protected function add_grouped_product_to_cart( $product ) {
+ $post = get_post( $product->get_id() );
+ $grouped_products = array_filter( array_map( 'wc_get_product', $product->get_children() ), 'wc_products_array_filter_visible_grouped' );
+
+ return $this->grouped_product_form( $product, $post, $grouped_products );
+ }
+
+ /**
+ * The add to cart form for an external product.
+ *
+ * @param \WC_Product $product Product object.
+ *
+ * @return string
+ */
+ protected function add_external_product_to_cart( $product ) {
+ $add_to_cart_url = $product->add_to_cart_url();
+ $button_text = $product->single_add_to_cart_text();
+
+ if ( ! $button_text || ! $add_to_cart_url ) {
+ return '';
+ }
+
+ ob_start();
+ /**
+ * Hook: woocommerce_before_add_to_cart_form.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_before_add_to_cart_form' );
+ ?>
+
+ get_min_purchase_quantity();
+
+ $args = [
+ 'min_value' => $product->get_min_purchase_quantity(),
+ 'max_value' => $product->get_max_purchase_quantity(),
+ 'input_value' => $input_value,
+ ];
+ } elseif ( 'grouped' === $product_type ) {
+ if ( ! $grouped_product_child ) {
+ return;
+ }
+
+ // phpcs:ignore WordPress.Security.NonceVerification.Missing
+ $input_value = isset( $_POST['quantity'][ $grouped_product_child->get_id() ] ) ? wc_stock_amount( wc_clean( wp_unslash( $_POST['quantity'][ $grouped_product_child->get_id() ] ) ) ) : '';
+
+ $args = [
+ 'input_name' => 'quantity[' . $grouped_product_child->get_id() . ']',
+ 'input_value' => $input_value,
+ 'min_value' => 0,
+ 'max_value' => $grouped_product_child->get_max_purchase_quantity(),
+ 'placeholder' => '0',
+ ];
+ }
+
+ /**
+ * Hook: woocommerce_before_add_to_cart_quantity.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_before_add_to_cart_quantity' );
+
+ echo wp_kses_post( woocommerce_quantity_input( $args, $product ) );
+
+ /**
+ * Hook: woocommerce_after_add_to_cart_quantity.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_after_add_to_cart_quantity' );
+ }
+
+ /**
+ * Output the add to cart button.
+ *
+ * @param \WC_Product $product Product object.
+ * @param string $name Name of the button.
+ *
+ * @return void
+ */
+ protected function add_to_cart_button( $product, $name = '' ) {
+ /**
+ * Hook: woocommerce_before_add_to_cart_button.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_before_add_to_cart_button' );
+
+ echo sprintf(
+ '',
+ esc_attr( $name ),
+ esc_attr( $product->get_id() ),
+ esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ),
+ esc_html( $product->single_add_to_cart_text() )
);
+
+ /**
+ * Hook: woocommerce_after_add_to_cart_button.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_after_add_to_cart_button' );
+ }
+
+ /**
+ * The inputs for an individual variable product.
+ *
+ * @param int $product_id Product ID.
+ *
+ * @return void
+ */
+ protected function variable_inputs( $product_id ) {
+ echo sprintf(
+ '
+
+ ',
+ absint( $product_id )
+ );
+ }
+
+ /**
+ * The add to cart form for an individual variable product.
+ *
+ * @param \WC_Product $product Product object.
+ * @param array $attributes Array of attributes.
+ * @param array $attribute_keys Array of attribute keys.
+ * @param array $available_variations Array of available variations.
+ * @param string $variations_attr HTML encoded string of variations.
+ *
+ * @return string
+ */
+ protected function variable_product_form( $product, $attributes, $attribute_keys, $available_variations, $variations_attr ) {
+ ob_start();
+ /**
+ * Hook: woocommerce_before_add_to_cart_form.
+ *
+ * @since TBD
+ */
+ do_action( 'woocommerce_before_add_to_cart_form' );
+
+ $product_id = $product->get_id();
+ ?>
+
+
+
+