setAttributes( { stockStatus } ) }
+ />
+ );
+};
+
+ProductStockControl.propTypes = {
+ /**
+ * Callback to update the stock status setting.
+ */
+ setAttributes: PropTypes.func.isRequired,
+ /**
+ * The selected stock status setting.
+ */
+ value: PropTypes.string.isRequired,
+};
+
+export default ProductStockControl;
diff --git a/assets/js/utils/shared-attributes.js b/assets/js/utils/shared-attributes.js
index 5533b7022ea..3597f015679 100644
--- a/assets/js/utils/shared-attributes.js
+++ b/assets/js/utils/shared-attributes.js
@@ -72,4 +72,12 @@ export default {
type: 'boolean',
default: false,
},
+
+ /**
+ * Whether to display in stock, out of stock or backorder products.
+ */
+ stockStatus: {
+ type: 'string',
+ default: 'any',
+ },
};
diff --git a/src/BlockTypes/AbstractProductGrid.php b/src/BlockTypes/AbstractProductGrid.php
index aa441c94f5b..f9263aa195e 100644
--- a/src/BlockTypes/AbstractProductGrid.php
+++ b/src/BlockTypes/AbstractProductGrid.php
@@ -31,6 +31,13 @@ abstract class AbstractProductGrid extends AbstractDynamicBlock {
*/
protected $query_args = array();
+ /**
+ * Meta query args.
+ *
+ * @var array
+ */
+ protected $meta_query = array();
+
/**
* Get a set of attributes shared across most of the grid blocks.
*
@@ -50,6 +57,7 @@ protected function get_block_type_attributes() {
'align' => $this->get_schema_align(),
'alignButtons' => $this->get_schema_boolean( false ),
'isPreview' => $this->get_schema_boolean( false ),
+ 'stockStatus' => $this->get_schema_string( 'any' ),
);
}
@@ -161,6 +169,7 @@ protected function parse_attributes( $attributes ) {
'rating' => true,
'button' => true,
),
+ 'stockStatus' => 'any',
);
return wp_parse_args( $attributes, $defaults );
@@ -172,6 +181,9 @@ protected function parse_attributes( $attributes ) {
* @return array
*/
protected function parse_query_args() {
+ // Store the original meta query.
+ $this->meta_query = WC()->query->get_meta_query(); // phpcs:ignore WordPress.DB.SlowDBQuery
+
$query_args = array(
'post_type' => 'product',
'post_status' => 'publish',
@@ -180,7 +192,7 @@ protected function parse_query_args() {
'no_found_rows' => false,
'orderby' => '',
'order' => '',
- 'meta_query' => WC()->query->get_meta_query(), // phpcs:ignore WordPress.DB.SlowDBQuery
+ 'meta_query' => $this->meta_query, // phpcs:ignore WordPress.DB.SlowDBQuery
'tax_query' => array(), // phpcs:ignore WordPress.DB.SlowDBQuery
'posts_per_page' => $this->get_products_limit(),
);
@@ -189,6 +201,7 @@ protected function parse_query_args() {
$this->set_ordering_query_args( $query_args );
$this->set_categories_query_args( $query_args );
$this->set_visibility_query_args( $query_args );
+ $this->set_stock_status_query_args( $query_args );
return $query_args;
}
@@ -272,6 +285,30 @@ protected function set_visibility_query_args( &$query_args ) {
);
}
+ /**
+ * Set which stock status to use when displaying products.
+ *
+ * @param array $query_args Query args.
+ * @return void
+ */
+ protected function set_stock_status_query_args( &$query_args ) {
+ // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ if ( 'yes' !== get_option( 'woocommerce_hide_out_of_stock_items' ) &&
+ isset( $this->attributes['stockStatus'] ) &&
+ ( 'any' !== $this->attributes['stockStatus'] && '' !== $this->attributes['stockStatus'] )
+ ) {
+ // Reset meta_query then update with our stock status.
+ $query_args['meta_query'] = $this->meta_query;
+ $query_args['meta_query'][] = array(
+ 'key' => '_stock_status',
+ 'value' => $this->attributes['stockStatus'],
+ );
+ } else {
+ $query_args['meta_query'] = $this->meta_query;
+ }
+ // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ }
+
/**
* Works out the item limit based on rows and columns, or returns default.
*
@@ -498,6 +535,7 @@ protected function get_title_html( $product ) {
if ( empty( $this->attributes['contentVisibility']['title'] ) ) {
return '';
}
+
return '' . wp_kses_post( $product->get_title() ) . '
';
}
@@ -621,5 +659,6 @@ protected function enqueue_data( array $attributes = [] ) {
$this->asset_data_registry->add( 'min_rows', wc_get_theme_support( 'product_blocks::min_rows', 1 ), true );
$this->asset_data_registry->add( 'max_rows', wc_get_theme_support( 'product_blocks::max_rows', 6 ), true );
$this->asset_data_registry->add( 'default_rows', wc_get_theme_support( 'product_blocks::default_rows', 3 ), true );
+ $this->asset_data_registry->add( 'hide_out_of_stock', get_option( 'woocommerce_hide_out_of_stock_items' ), true );
}
}
diff --git a/src/BlockTypes/ProductTag.php b/src/BlockTypes/ProductTag.php
index f4be1af9545..164b7cc8898 100644
--- a/src/BlockTypes/ProductTag.php
+++ b/src/BlockTypes/ProductTag.php
@@ -48,6 +48,7 @@ protected function get_block_type_attributes() {
'default' => 'any',
),
'isPreview' => $this->get_schema_boolean( false ),
+ 'stockStatus' => $this->get_schema_string( 'any' ),
);
}
diff --git a/src/BlockTypes/ProductsByAttribute.php b/src/BlockTypes/ProductsByAttribute.php
index 9d559b89cc2..9a18103e5f1 100644
--- a/src/BlockTypes/ProductsByAttribute.php
+++ b/src/BlockTypes/ProductsByAttribute.php
@@ -67,6 +67,7 @@ protected function get_block_type_attributes() {
'orderby' => $this->get_schema_orderby(),
'rows' => $this->get_schema_number( wc_get_theme_support( 'product_blocks::default_rows', 3 ) ),
'isPreview' => $this->get_schema_boolean( false ),
+ 'stockStatus' => $this->get_schema_string( 'any' ),
);
}
}