WooCommerce Code Reference

Dropdown.php

Source code

<?php
declare( strict_types = 1 );

namespace Automattic\WooCommerce\Blocks\BlockTypes;

/**
 * Dropdown block (native select).
 */
final class Dropdown extends AbstractBlock {

	use EnableBlockJsonAssetsTrait;

	/**
	 * Block name.
	 *
	 * @var string
	 */
	protected $block_name = 'dropdown';

	/**
	 * Plain-text label for a select option (no HTML in `<option>`).
	 *
	 * @param array $item Selectable item from context.
	 * @return string
	 */
	private function get_option_text( array $item ): string {
		if ( isset( $item['label'] ) && is_string( $item['label'] ) ) {
			return wp_strip_all_tags( $item['label'] );
		}
		if ( ! empty( $item['ariaLabel'] ) && is_string( $item['ariaLabel'] ) ) {
			return $item['ariaLabel'];
		}
		return '';
	}

	/**
	 * Render the block.
	 *
	 * @param array     $attributes Block attributes.
	 * @param string    $content    Block content.
	 * @param \WP_Block $block      Block instance.
	 * @return string Rendered block type output.
	 */
	protected function render( $attributes, $content, $block ) {
		if ( empty( $block->context['woocommerce/selectableItems'] ) ) {
			return '';
		}

		$selectable_items = $block->context['woocommerce/selectableItems'];
		$items            = is_array( $selectable_items['items'] ?? null ) ? $selectable_items['items'] : array();
		$store_namespace  = is_string( $selectable_items['storeNamespace'] ?? null ) ? $selectable_items['storeNamespace'] : 'woocommerce/add-to-cart-with-options';

		if ( empty( $items ) ) {
			return '';
		}

		$attribute_id       = $block->context['woocommerce/attributeId'] ?? '';
		$has_external_label = is_string( $attribute_id ) && '' !== $attribute_id;
		$select_id          = $has_external_label
			? $attribute_id
			: wp_unique_id( 'wc-block-dropdown-' );

		$wrapper_attributes = array(
			'class'               => 'wc-block-dropdown',
			'data-wp-interactive' => 'woocommerce/dropdown',
			'data-wp-context'     => (string) wp_json_encode(
				array(
					'storeNamespace' => $store_namespace,
				),
				JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
			),
		);

		$aria_label = isset( $selectable_items['groupLabel'] ) && is_string( $selectable_items['groupLabel'] ) ? $selectable_items['groupLabel'] : __( 'Choose an option', 'woocommerce' );

		ob_start();
		?>
		<div <?php echo get_block_wrapper_attributes( $wrapper_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
			<fieldset class="wc-block-dropdown__fieldset">
				<?php if ( ! $has_external_label ) : ?>
					<legend class="screen-reader-text"><?php echo esc_html( __( 'Choose an option', 'woocommerce' ) ); ?></legend>
				<?php endif; ?>
				<select
					class="wc-block-dropdown__select"
					id="<?php echo esc_attr( $select_id ); ?>"
					<?php if ( $has_external_label ) : ?>
						aria-labelledby="<?php echo esc_attr( $attribute_id . '_label' ); ?>"
					<?php else : ?>
						aria-label="<?php echo esc_attr( $aria_label ); ?>"
					<?php endif; ?>
					data-wp-bind--value="state.selectValue"
					data-wp-on--change="actions.onDropdownChange"
				>
					<option value="">
						<?php echo esc_html( __( 'Choose an option', 'woocommerce' ) ); ?>
					</option>
					<?php foreach ( $items as $item ) : ?>
						<?php
						if ( ! is_array( $item ) ) {
							continue;
						}
						$option_label = $this->get_option_text( $item );
						if ( empty( $option_label ) ) {
							continue;
						}
						$item_id    = isset( $item['id'] ) && is_string( $item['id'] ) ? $item['id'] : '';
						$item_value = isset( $item['value'] ) && is_string( $item['value'] ) ? $item['value'] : '';
						?>
						<option
							id="<?php echo esc_attr( $item_id ); ?>"
							value="<?php echo esc_attr( $item_value ); ?>"
							<?php disabled( ! empty( $item['disabled'] ) ); ?>
							<?php
							if ( ! empty( $item['hidden'] ) ) :
								?>
							hidden
								<?php
							endif;
							if ( ! empty( $item['selected'] ) ) :
								?>
								selected
								<?php
							endif;
							?>
							data-wp-each-child
						>
							<?php echo esc_html( $option_label ); ?>
						</option>
					<?php endforeach; ?>
					<template
						data-wp-interactive="<?php echo esc_attr( $store_namespace ); ?>"
						data-wp-each--item="state.selectableItems"
						data-wp-each-key="context.item.id"
					>
						<option
							data-wp-bind--value="context.item.value"
							data-wp-bind--disabled="context.item.disabled"
							data-wp-bind--hidden="context.item.hidden"
							data-wp-text="context.item.label"
						></option>
					</template>
				</select>
			</fieldset>
		</div>
		<?php
		$output = ob_get_clean();
		return is_string( $output ) ? $output : '';
	}
}