Automattic\WooCommerce\Blocks\BlockTypes
ProductFilterCheckboxList{} │ final │ WC 1.0└─ AbstractBlock
Product Filter: Checkbox List Block.
No Hooks.
Usage
$ProductFilterCheckboxList = new ProductFilterCheckboxList(); // use class methods
Methods
- protected get_block_type_style()
- private get_item_swatch_style( array $item )
- private static has_visual_swatches( array $items )
- protected render( $attributes, $content, $block )
ProductFilterCheckboxList{} ProductFilterCheckboxList{} code WC 10.9.1
<?php
final class ProductFilterCheckboxList extends AbstractBlock {
use EnableBlockJsonAssetsTrait;
/**
* Block name.
*
* @var string
*/
protected $block_name = 'product-filter-checkbox-list';
/**
* Default number of items to show before "Show more" button.
*
* @var int
*/
const DISPLAY_LIMIT = 15;
/**
* 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 '';
}
$block_context = $block->context['woocommerce/selectableItems'];
$items = is_array( $block_context['items'] ?? null ) ? $block_context['items'] : array();
$store_namespace = $block_context['storeNamespace'] ?? 'woocommerce/product-filters';
$filter_type = $block_context['filterType'] ?? '';
$display_limit = self::DISPLAY_LIMIT;
$is_rating = 'rating' === $filter_type;
$classes = '';
$style = '';
$tags = new \WP_HTML_Tag_Processor( $content );
if ( $tags->next_tag( array( 'class_name' => 'wc-block-product-filter-checkbox-list' ) ) ) {
$classes = $tags->get_attribute( 'class' );
$style = $tags->get_attribute( 'style' );
}
$wrapper_attributes = array(
'data-wp-interactive' => 'woocommerce/product-filter-checkbox-list',
'data-wp-context' => (string) wp_json_encode(
array(
'storeNamespace' => $store_namespace,
'displayLimit' => $display_limit,
'isExpanded' => false,
),
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
),
'class' => esc_attr( $classes ),
);
if ( ! empty( $style ) ) {
// Styles generated by Supports API doesn't include semicolon at the end.
$wrapper_attributes['style'] = esc_attr( $style ) . ';';
}
$checkbox_svg = '<svg class="wc-block-product-filter-checkbox-list__mark" viewBox="0 0 10 8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.25 1.19922L3.75 6.69922L1 3.94922" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
$star_path = '<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>';
$stars_svg = sprintf(
'<svg class="wc-block-product-filter-checkbox-list__stars-svg" width="120" height="24" viewBox="0 0 120 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">%1$s<g transform="translate(24, 0)">%1$s</g><g transform="translate(48, 0)">%1$s</g><g transform="translate(72, 0)">%1$s</g><g transform="translate(96, 0)">%1$s</g></svg>',
$star_path
);
$first_items = array_slice( $items, 0, $display_limit, true );
$overflow_items = array_slice( $items, $display_limit );
$overflow_selected_items = array_filter( $overflow_items, fn( $item ) => is_array( $item ) && ! empty( $item['selected'] ) );
$visible_items = array_merge( $first_items, $overflow_selected_items );
$hidden_count = count( $items ) - count( $visible_items );
$first_item = reset( $items );
$show_counts = is_array( $first_item ) && array_key_exists( 'count', $first_item );
$has_visual_swatches = self::has_visual_swatches( $items );
ob_start();
?>
<div <?php echo get_block_wrapper_attributes( $wrapper_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<fieldset>
<?php if ( ! empty( $block_context['groupLabel'] ) ) : ?>
<legend class="screen-reader-text"><?php echo esc_html( $block_context['groupLabel'] ); ?></legend>
<?php endif; ?>
<div class="wc-block-product-filter-checkbox-list__items">
<?php
foreach ( $visible_items as $item ) :
?>
<div
class="wc-block-product-filter-checkbox-list__item"
data-wp-each-child
<?php echo wp_interactivity_data_wp_context( array( 'item' => $item ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
data-wp-bind--hidden="context.item.hidden"
>
<label
class="wc-block-product-filter-checkbox-list__label"
for="<?php echo esc_attr( $item['id'] ); ?>"
>
<span class="wc-block-product-filter-checkbox-list__input-wrapper">
<input
id="<?php echo esc_attr( $item['id'] ); ?>"
class="wc-block-product-filter-checkbox-list__input"
type="checkbox"
<?php if ( ! empty( $item['ariaLabel'] ) ) : ?>
aria-label="<?php echo esc_attr( $item['ariaLabel'] ); ?>"
<?php endif; ?>
value="<?php echo esc_attr( $item['value'] ); ?>"
<?php checked( ! empty( $item['selected'] ) ); ?>
<?php disabled( ! empty( $item['disabled'] ) ); ?>
data-wp-bind--checked="context.item.selected"
data-wp-bind--disabled="context.item.disabled"
data-wp-on--change="actions.toggle"
>
<?php echo $checkbox_svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</span>
<span class="wc-block-product-filter-checkbox-list__text-wrapper">
<?php if ( $is_rating ) : ?>
<?php $rating_style = sprintf( 'width: %s%%', ( (int) $item['value'] ) * 20 ); ?>
<span
class="wc-block-product-filter-checkbox-list__stars"
aria-label="<?php echo esc_attr( $item['ariaLabel'] ?? '' ); ?>"
style="<?php echo esc_attr( $rating_style ); ?>"
data-wp-bind--style="woocommerce/product-filter-checkbox-list::state.ratingStyle"
>
<?php echo $stars_svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</span>
<?php else : ?>
<?php if ( $has_visual_swatches ) : ?>
<?php
$swatch_style = $this->get_item_swatch_style( $item );
$has_visual = '' !== $swatch_style;
?>
<span
class="wc-block-product-filter-checkbox-list__color-swatch<?php echo ! $has_visual ? ' is-empty' : ''; ?>"
<?php if ( $has_visual ) : ?>
style="<?php echo esc_attr( $swatch_style ); ?>"
<?php endif; ?>
aria-hidden="true"
></span>
<?php endif; ?>
<span class="wc-block-product-filter-checkbox-list__text">
<?php echo esc_html( $item['label'] ); ?>
</span>
<?php endif; ?>
<?php if ( isset( $item['count'] ) ) : ?>
<span class="wc-block-product-filter-checkbox-list__count">
(<span data-wp-text="context.item.count"><?php echo esc_html( $item['count'] ); ?></span>)
</span>
<?php endif; ?>
</span>
</label>
</div>
<?php endforeach; ?>
<template
data-wp-each--item="state.items"
data-wp-each-key="context.item.id"
>
<div
class="wc-block-product-filter-checkbox-list__item"
data-wp-bind--hidden="context.item.hidden"
>
<label
class="wc-block-product-filter-checkbox-list__label"
data-wp-bind--for="context.item.id"
>
<span class="wc-block-product-filter-checkbox-list__input-wrapper">
<input
class="wc-block-product-filter-checkbox-list__input"
type="checkbox"
data-wp-bind--id="context.item.id"
data-wp-bind--aria-label="context.item.ariaLabel"
data-wp-bind--value="context.item.value"
data-wp-bind--checked="context.item.selected"
data-wp-bind--disabled="context.item.disabled"
data-wp-on--change="actions.toggle"
>
<?php echo $checkbox_svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</span>
<span class="wc-block-product-filter-checkbox-list__text-wrapper">
<?php if ( $is_rating ) : ?>
<span
class="wc-block-product-filter-checkbox-list__stars"
data-wp-bind--aria-label="context.item.ariaLabel"
data-wp-bind--style="woocommerce/product-filter-checkbox-list::state.ratingStyle"
>
<?php echo $stars_svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</span>
<?php else : ?>
<?php if ( $has_visual_swatches ) : ?>
<span
class="wc-block-product-filter-checkbox-list__color-swatch"
data-wp-class--is-empty="woocommerce/product-filter-checkbox-list::state.isColorSwatchEmpty"
data-wp-bind--style="woocommerce/product-filter-checkbox-list::state.colorSwatchStyle"
aria-hidden="true"
></span>
<?php endif; ?>
<span
class="wc-block-product-filter-checkbox-list__text"
data-wp-text="context.item.label"
></span>
<?php endif; ?>
<?php if ( $show_counts ) : ?>
<span class="wc-block-product-filter-checkbox-list__count">
(<span data-wp-text="context.item.count"></span>)
</span>
<?php endif; ?>
</span>
</label>
</div>
</template>
</div>
<?php if ( $hidden_count > 0 ) : ?>
<div class="wc-block-product-filter-checkbox-list__show-more">
<button
type="button"
class="wc-block-product-filter-checkbox-list__show-more-button"
data-wp-on--click="actions.showAll"
data-wp-bind--hidden="context.isExpanded"
>
<?php
/* translators: %d: number of hidden items */
echo esc_html( sprintf( __( 'Show %d more', 'woocommerce' ), $hidden_count ) );
?>
</button>
</div>
<?php endif; ?>
</fieldset>
</div>
<?php
return ob_get_clean();
}
/**
* Check whether any item has visual swatch data.
*
* @param array $items Selectable items.
* @return bool
*/
private static function has_visual_swatches( array $items ): bool {
foreach ( $items as $item ) {
if ( is_array( $item ) && array_key_exists( 'visual', $item ) ) {
return true;
}
}
return false;
}
/**
* Build inline swatch style from item visual data.
*
* @param array $item Selectable item data.
* @return string
*/
private function get_item_swatch_style( array $item ): string {
$visual = isset( $item['visual'] ) && is_array( $item['visual'] ) ? $item['visual'] : array();
return VisualAttributeTermMeta::get_swatch_style( $visual );
}
/**
* Disable the style handle for this block type. We use block.json to load the style.
*
* @return null
*/
protected function get_block_type_style() {
return null;
}
}