%s', $label_id, esc_html( $label_text ) ); return $html; } /** * Render variation selector dropdown. * * @param WC_Product $product The product object. * @param string $attribute_name Name of the attribute. * @param array $options Available options for this attribute. * @return string Rendered dropdown HTML. */ protected function render_variation_selector( $product, $attribute_name, $options ): string { $selected = $this->get_selected_attribute_value( $product, $attribute_name ); $select_id = esc_attr( 'attribute_' . sanitize_title( $attribute_name ) ); $html = sprintf( ''; return $html; } /** * Get selected attribute value. * * @param WC_Product $product The product object. * @param string $attribute_name Name of the attribute. * @return string Selected value */ private function get_selected_attribute_value( $product, $attribute_name ): string { return $product->get_variation_default_attribute( $attribute_name ); } /** * Get HTML for variation options. * * @param WC_Product $product The product object. * @param string $attribute_name Name of the attribute. * @param array $options Available options. * @param string $selected Selected value. * @param bool $is_taxonomy Whether this is a taxonomy-based attribute. * @return string Options HTML */ private function get_variation_options_html( $product, $attribute_name, $options, $selected, $is_taxonomy ): string { if ( empty( $options ) ) { return ''; } $html = ''; $items = $is_taxonomy ? wc_get_product_terms( $product->get_id(), $attribute_name, array( 'fields' => 'all' ) ) : $options; foreach ( $items as $item ) { $option_value = $is_taxonomy ? $item->slug : $item; $option_label = $is_taxonomy ? $item->name : $item; if ( ! $is_taxonomy || in_array( $option_value, $options, true ) ) { $selected_attr = $is_taxonomy ? selected( sanitize_title( $selected ), $option_value, false ) : selected( $selected, $option_value, false ); /** * Filter the variation option name. * * @since 9.7.0 * * @param string $option_label The option label. * @param WP_Term|string|null $item Term object for taxonomies, option string for custom attributes. * @param string $attribute_name Name of the attribute. * @param WC_Product $product Product object. */ $filtered_label = apply_filters( 'woocommerce_variation_option_name', $option_label, $is_taxonomy ? $item : null, $attribute_name, $product ); $html .= sprintf( '', esc_attr( $option_value ), $selected_attr, esc_html( $filtered_label ) ); } } return $html; } /** * Render variation form. * * @param WC_Product $product Product instance. * @param array $attributes Block attributes. * @return string Rendered form HTML */ private function render_variation_form( $product, $attributes ): string { $variation_attributes = $product->get_variation_attributes(); if ( empty( $variation_attributes ) ) { return ''; } $variations = $this->get_variations_data( $product ); if ( empty( $variations ) ) { return ''; } wp_enqueue_script( 'wc-add-to-cart-variation' ); return $this->get_form_html( $product, $variations, $variation_attributes ); } /** * Get variations data. * * @param WC_Product $product Product instance. * @return array|false */ private function get_variations_data( $product ) { /** * Filter the number of variations threshold. * * @since 9.7.0 * * @param int $threshold Maximum number of variations to load upfront. * @param WC_Product $product Product object. */ $get_variations = count( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product ); return $get_variations ? $product->get_available_variations() : false; } /** * Get form HTML. * * @param WC_Product $product Product instance. * @param array $variations Variations data. * @param array $variation_attributes Variation attributes. * @return string Form HTML */ private function get_form_html( $product, $variations, $variation_attributes ): string { $variations_json = wp_json_encode( $variations ); $variations_attr = function_exists( 'wc_esc_json' ) ? wc_esc_json( $variations_json ) : _wp_specialchars( $variations_json, ENT_QUOTES, 'UTF-8', true ); $form = $this->get_form_opening( $product, $variations_attr ); $form .= $this->get_variations_table( $product, $variation_attributes ); $form .= ''; return $form; } /** * Get form opening HTML. * * @param WC_Product $product Product instance. * @param string $variations_attr Variations JSON. * @return string Form opening HTML */ private function get_form_opening( $product, $variations_attr ): string { return sprintf( '