Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
wp-content
/
plugins
/
woocommerce
/
src
/
Blocks
/
BlockTypes
/
AddToCartWithOptions
:
VariationSelectorAttributeOptions.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php declare(strict_types=1); namespace Automattic\WooCommerce\Blocks\BlockTypes\AddToCartWithOptions; use Automattic\WooCommerce\Blocks\BlockTypes\AbstractBlock; use Automattic\WooCommerce\Blocks\BlockTypes\EnableBlockJsonAssetsTrait; use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils; /** * Block type for variation selector attribute options in add to cart with options. * It's responsible to render the attribute options. */ class VariationSelectorAttributeOptions extends AbstractBlock { use EnableBlockJsonAssetsTrait; /** * Block name. * * @var string */ protected $block_name = 'add-to-cart-with-options-variation-selector-attribute-options'; /** * Render the block. * * @param array $attributes Block attributes. * @param string $content Block content. * @param WP_Block $block Block instance. * @return string Rendered block output. */ protected function render( $attributes, $content, $block ): string { if ( ! isset( $block->context['woocommerce/attributeName'], $block->context['woocommerce/attributeId'], $block->context['woocommerce/attributeTerms'] ) ) { return ''; } $attribute_slug = wc_variation_attribute_name( $block->context['woocommerce/attributeName'] ); $classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array(), array( 'extra_classes' ) ); $option_style = array_key_exists( 'optionStyle', $attributes ) ? $attributes['optionStyle'] : null; // During the beta period, `optionStyle` was called `style`, so we check // `style` for backwards compatibility. if ( ! $option_style && array_key_exists( 'style', $attributes ) && 'dropdown' === $attributes['style'] ) { $option_style = 'dropdown'; } $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classes_and_styles['classes'], 'style' => $classes_and_styles['styles'], ) ); if ( 'dropdown' === $option_style ) { $content = $this->render_dropdown( $attributes, $content, $block ); } else { $content = $this->render_pills( $attributes, $content, $block ); } return sprintf( '<div %s>%s</div>', $wrapper_attributes, $content ); } /** * Get the normalized version of the attributes. * * @param array $attributes The element's attributes. * @param array $default_attributes The element's default attributes. * @return string The HTML element's attributes. */ public static function get_normalized_attributes( $attributes, $default_attributes = array() ) { $normalized_attributes = array(); $merged_attributes = array_merge( $default_attributes, $attributes ); foreach ( $merged_attributes as $key => $value ) { if ( is_null( $value ) ) { continue; } if ( is_array( $value ) || is_object( $value ) ) { $value = wp_json_encode( $value, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ); } $normalized_attributes[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) ); } return implode( ' ', $normalized_attributes ); } /** * Get the default selected attribute. * * @param string $attribute_slug The attribute's slug. * @param array $attribute_terms The attribute's terms. * @return string|null The default selected attribute. */ protected function get_default_selected_attribute( $attribute_slug, $attribute_terms ) { if ( isset( $_GET[ $attribute_slug ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $raw = wp_unslash( $_GET[ $attribute_slug ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if ( is_string( $raw ) ) { $attribute_slug_from_request = sanitize_title( $raw ); foreach ( $attribute_terms as $attribute_term ) { if ( sanitize_title( $attribute_term['value'] ) === $attribute_slug_from_request ) { return $attribute_term['value']; } } } } else { foreach ( $attribute_terms as $attribute_term ) { if ( $attribute_term['isSelected'] ) { return $attribute_term['value']; } } } return null; } /** * Render the attribute options as pills. * * @param array $attributes Block attributes. * @param string $content Block content. * @param WP_Block $block Block instance. * @return string The pills. */ protected function render_pills( $attributes, $content, $block ) { $attribute_id = $block->context['woocommerce/attributeId']; $attribute_slug = wc_variation_attribute_name( $block->context['woocommerce/attributeName'] ); $attribute_terms = $block->context['woocommerce/attributeTerms']; wp_interactivity_state( 'woocommerce/add-to-cart-with-options', array( 'isOptionSelected' => function () { $context = wp_interactivity_get_context(); return $context['option']['value'] === $context['selectedValue']; }, ) ); $pills = ''; foreach ( $attribute_terms as $attribute_term ) { $input = sprintf( '<input type="radio" %s/>', $this->get_normalized_attributes( array( 'class' => 'wc-block-add-to-cart-with-options-variation-selector-attribute-options__pill-input', 'name' => $attribute_slug, 'value' => $attribute_term['value'], 'data-wp-bind--checked' => 'state.isOptionSelected', 'data-wp-bind--disabled' => 'state.isOptionDisabled', 'data-wp-watch' => 'callbacks.watchSelected', 'data-wp-on--click' => 'actions.handlePillClick', 'data-wp-on--keydown' => 'actions.handleKeyDown', 'data-wp-context' => array( 'option' => $attribute_term, ), ), ) ); $pills .= '<label class="wc-block-add-to-cart-with-options-variation-selector-attribute-options__pill">' . $input . esc_html( $attribute_term['label'] ) . '</label>'; } return sprintf( '<div %s>%s</div>', $this->get_normalized_attributes( array( 'class' => 'wc-block-add-to-cart-with-options-variation-selector-attribute-options__pills', 'role' => 'radiogroup', 'id' => $attribute_id, 'aria-labelledby' => $attribute_id . '_label', 'data-wp-context' => array( 'name' => $attribute_slug, 'options' => $attribute_terms, 'selectedValue' => $this->get_default_selected_attribute( $attribute_slug, $attribute_terms ), 'focused' => '', ), 'data-wp-init' => 'callbacks.setDefaultSelectedAttribute', ), ), $pills, ); } /** * Render the attribute options as a dropdown. * * @param array $attributes Block attributes. * @param string $content Block content. * @param WP_Block $block Block instance. * @return string The dropdown. */ protected function render_dropdown( $attributes, $content, $block ) { $attribute_id = $block->context['woocommerce/attributeId']; $attribute_slug = wc_variation_attribute_name( $block->context['woocommerce/attributeName'] ); $attribute_terms = $block->context['woocommerce/attributeTerms']; $default_option = array( 'label' => esc_html__( 'Choose an option', 'woocommerce' ), 'value' => '', 'isSelected' => false, ); $attribute_terms = array_merge( array( $default_option ), $attribute_terms ); $selected_attribute = $this->get_default_selected_attribute( $attribute_slug, $attribute_terms ); $options = ''; foreach ( $attribute_terms as $attribute_term ) { $option_attributes = array( 'value' => $attribute_term['value'], 'data-wp-bind--disabled' => 'state.isOptionDisabled', 'data-wp-context' => array( 'option' => $attribute_term, 'name' => $attribute_slug, 'options' => $attribute_terms, ), ); if ( $attribute_term['value'] === $selected_attribute ) { $option_attributes['selected'] = 'selected'; } $options .= sprintf( '<option %s>%s</option>', $this->get_normalized_attributes( $option_attributes ), esc_html( $attribute_term['label'] ) ); } return sprintf( '<select %s>%s</select>', $this->get_normalized_attributes( array( 'class' => 'wc-block-add-to-cart-with-options-variation-selector-attribute-options__dropdown', 'id' => $attribute_id, 'data-wp-context' => array( 'name' => $attribute_slug, 'options' => $attribute_terms, 'selectedValue' => $selected_attribute, ), 'data-wp-init' => 'callbacks.setDefaultSelectedAttribute', 'data-wp-on--change' => 'actions.handleDropdownChange', 'name' => $attribute_slug, ), ), $options, ); } }