Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Merge branch 'trunk' into update/singleproducttemplatecompatibility-8…
Browse files Browse the repository at this point in the history
….1-compatibility
  • Loading branch information
tjcafferkey authored Nov 8, 2023
2 parents 6428e31 + 0cd5468 commit 25908ac
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 6 deletions.
2 changes: 2 additions & 0 deletions assets/js/blocks/product-collection/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const DEFAULT_QUERY: ProductCollectionQuery = {
woocommerceStockStatus: getDefaultStockStatuses(),
woocommerceAttributes: [],
woocommerceHandPickedProducts: [],
timeFrame: undefined,
};

export const DEFAULT_ATTRIBUTES: Partial< ProductCollectionAttributes > = {
Expand Down Expand Up @@ -86,4 +87,5 @@ export const DEFAULT_FILTERS: Partial< ProductCollectionQuery > = {
woocommerceAttributes: [],
taxQuery: DEFAULT_QUERY.taxQuery,
woocommerceHandPickedProducts: [],
timeFrame: undefined,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* External dependencies
*/
import { __, _x } from '@wordpress/i18n';
import {
Flex,
FlexItem,
RadioControl,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - Ignoring because `__experimentalToggleGroupControl` is not yet in the type definitions.
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalToggleGroupControl as ToggleGroupControl,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - Ignoring because `__experimentalToggleGroupControlOption` is not yet in the type definitions.
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
// @ts-expect-error Using experimental features
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';

/**
* Internal dependencies
*/
import { ETimeFrameOperator, QueryControlProps } from '../types';

const CreatedControl = ( props: QueryControlProps ) => {
const { query, setQueryAttribute } = props;
const { timeFrame } = query;

return (
<ToolsPanelItem
label={ __( 'Created', 'woo-gutenberg-products-block' ) }
hasValue={ () => timeFrame?.operator && timeFrame?.value }
onDeselect={ () => {
setQueryAttribute( {
timeFrame: undefined,
} );
} }
>
<Flex direction="column" gap={ 3 }>
<FlexItem>
<ToggleGroupControl
label={ __(
'Created',
'woo-gutenberg-products-block'
) }
isBlock
onChange={ ( value: ETimeFrameOperator ) => {
setQueryAttribute( {
timeFrame: {
...timeFrame,
operator: value,
},
} );
} }
value={ timeFrame?.operator || ETimeFrameOperator.IN }
>
<ToggleGroupControlOption
value={ ETimeFrameOperator.IN }
label={ _x(
'Within',
'Product Collection query operator',
'woo-gutenberg-products-block'
) }
/>
<ToggleGroupControlOption
value={ ETimeFrameOperator.NOT_IN }
label={ _x(
'Before',
'Product Collection query operator',
'woo-gutenberg-products-block'
) }
/>
</ToggleGroupControl>
</FlexItem>
<FlexItem>
<RadioControl
onChange={ ( value: string ) => {
setQueryAttribute( {
timeFrame: {
operator: ETimeFrameOperator.IN,
...timeFrame,
value,
},
} );
} }
options={ [
{
label: 'last 24 hours',
value: '-1 day',
},
{
label: 'last 7 days',
value: '-7 days',
},
{
label: 'last 30 days',
value: '-30 days',
},
{
label: 'last 3 months',
value: '-3 months',
},
] }
selected={ timeFrame?.value }
/>
</FlexItem>
</Flex>
</ToolsPanelItem>
);
};

export default CreatedControl;
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import AttributesControl from './attributes-control';
import TaxonomyControls from './taxonomy-controls';
import HandPickedProductsControl from './hand-picked-products-control';
import LayoutOptionsControl from './layout-options-control';
import CreatedControl from './created-control';

const ProductCollectionInspectorControls = (
props: BlockEditProps< ProductCollectionAttributes >
Expand Down Expand Up @@ -98,6 +99,7 @@ const ProductCollectionInspectorControls = (
<KeywordControl { ...queryControlProps } />
<AttributesControl { ...queryControlProps } />
<TaxonomyControls { ...queryControlProps } />
<CreatedControl { ...queryControlProps } />
</ToolsPanel>
) : null }
<ProductCollectionFeedbackPrompt />
Expand Down
11 changes: 11 additions & 0 deletions assets/js/blocks/product-collection/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ export interface ProductCollectionDisplayLayout {
shrinkColumns?: boolean;
}

export enum ETimeFrameOperator {
IN = 'in',
NOT_IN = 'not-in',
}

export interface TimeFrame {
operator?: ETimeFrameOperator;
value?: string;
}

export interface ProductCollectionQuery {
exclude: string[];
inherit: boolean | null;
Expand All @@ -39,6 +49,7 @@ export interface ProductCollectionQuery {
postType: string;
search: string;
taxQuery: Record< string, number[] >;
timeFrame: TimeFrame | undefined;
woocommerceOnSale: boolean;
/**
* Filter products by their stock status.
Expand Down
16 changes: 16 additions & 0 deletions docs/internal-developers/testing/releases/1145.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Testing notes and ZIP for release 11.4.5

Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/13294232/woocommerce-gutenberg-products-block.zip)

## WooCommerce Core

### Bug Fixes

#### Fix Single Product Classic Template block not showing on the front-end. [11455](https://github.com/woocommerce/woocommerce-blocks/pull/11455)

1. Enable WordPress 6.4.
2. Enable a block theme.
3. Go to Site Editor → Single Product template.
4. Remove the blockified template and add the “Classic Template” block.
5. Save and check the front-end.
6. Check that the template is correctly rendered on the front-end.
1 change: 1 addition & 0 deletions docs/internal-developers/testing/releases/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,5 @@ Every release includes specific testing instructions for new features and bug fi
- [11.4.2](./1142.md)
- [11.4.3](./1143.md)
- [11.4.4](./1144.md)
- [11.4.5](./1145.md)
- [11.5.0](./1150.md)
6 changes: 6 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ Release and roadmap notes available on the [WooCommerce Developers Blog](https:/

- Remove bullet points and unnecessary padding from `SearchListControl`. ([11444](https://github.com/woocommerce/woocommerce-blocks/pull/11444))

= 11.4.5 - 2023-11-07 =

#### Bug Fixes

- WordPress 6.4: fixed a bug which would break sites using the Classic Template block for the Single Product template. https://github.com/woocommerce/woocommerce-blocks/pull/11455

= 11.4.4 - 2023-11-06 =

#### Enhancements
Expand Down
11 changes: 9 additions & 2 deletions src/BlockTypes/ClassicTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,16 @@ protected function render_single_product() {
*/
do_action( 'woocommerce_before_main_content' );

while ( have_posts() ) :
$product_query = new \WP_Query(
array(
'post_type' => 'product',
'p' => get_the_ID(),
)
);

while ( $product_query->have_posts() ) :

the_post();
$product_query->the_post();
wc_get_template_part( 'content', 'single-product' );

endwhile;
Expand Down
6 changes: 3 additions & 3 deletions src/BlockTypes/MiniCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ protected function enqueue_data( array $attributes = [] ) {
public function print_lazy_load_scripts() {
$script_data = $this->asset_api->get_script_data( 'build/mini-cart-component-frontend.js' );

$num_dependencies = count( $script_data['dependencies'] );
$num_dependencies = is_countable( $script_data['dependencies'] ) ? count( $script_data['dependencies'] ) : 0;
$wp_scripts = wp_scripts();

for ( $i = 0; $i < $num_dependencies; $i++ ) {
Expand Down Expand Up @@ -307,7 +307,7 @@ protected function append_script_and_deps_src( $script ) {
return;
}

if ( count( $script->deps ) ) {
if ( is_countable( $script->deps ) && count( $script->deps ) ) {
foreach ( $script->deps as $dep ) {
if ( ! array_key_exists( $dep, $this->scripts_to_lazy_load ) ) {
$dep_script = $this->get_script_from_handle( $dep );
Expand Down Expand Up @@ -453,7 +453,7 @@ protected function get_markup( $attributes ) {

// Determine if we need to load the template part from the DB, the theme or WooCommerce in that order.
$templates_from_db = BlockTemplateUtils::get_block_templates_from_db( array( 'mini-cart' ), 'wp_template_part' );
if ( count( $templates_from_db ) > 0 ) {
if ( is_countable( $templates_from_db ) && count( $templates_from_db ) > 0 ) {
$template_slug_to_load = $templates_from_db[0]->theme;
} else {
$theme_has_mini_cart = BlockTemplateUtils::theme_has_template_part( 'mini-cart' );
Expand Down
41 changes: 40 additions & 1 deletion src/BlockTypes/ProductCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ public function update_rest_query_in_editor( $args, $request ): array {
$stock_status = $request->get_param( 'woocommerceStockStatus' );
$product_attributes = $request->get_param( 'woocommerceAttributes' );
$handpicked_products = $request->get_param( 'woocommerceHandPickedProducts' );
$time_frame = $request->get_param( 'timeFrame' );
// This argument is required for the tests to PHP Unit Tests to run correctly.
// Most likely this argument is being accessed in the test environment image.
$args['author'] = '';
Expand All @@ -219,6 +220,7 @@ public function update_rest_query_in_editor( $args, $request ): array {
'stock_status' => $stock_status,
'product_attributes' => $product_attributes,
'handpicked_products' => $handpicked_products,
'timeFrame' => $time_frame,
)
);
}
Expand Down Expand Up @@ -305,6 +307,7 @@ private function get_final_frontend_query( $query, $page = 1, $is_exclude_applie
$product_attributes = $query['woocommerceAttributes'] ?? [];
$taxonomies_query = $this->get_filter_by_taxonomies_query( $query['tax_query'] ?? [] );
$handpicked_products = $query['woocommerceHandPickedProducts'] ?? [];
$time_frame = $query['timeFrame'] ?? null;

$final_query = $this->get_final_query_args(
$common_query_values,
Expand All @@ -315,6 +318,7 @@ private function get_final_frontend_query( $query, $page = 1, $is_exclude_applie
'product_attributes' => $product_attributes,
'taxonomies_query' => $taxonomies_query,
'handpicked_products' => $handpicked_products,
'timeFrame' => $time_frame,
),
$is_exclude_applied_filters
);
Expand All @@ -338,11 +342,12 @@ private function get_final_query_args( $common_query_values, $query, $is_exclude
$attributes_query = $this->get_product_attributes_query( $query['product_attributes'] );
$taxonomies_query = $query['taxonomies_query'] ?? [];
$tax_query = $this->merge_tax_queries( $visibility_query, $attributes_query, $taxonomies_query );
$date_query = $this->get_date_query( $query['timeFrame'] ?? [] );

// We exclude applied filters to generate product ids for the filter blocks.
$applied_filters_query = $is_exclude_applied_filters ? [] : $this->get_queries_by_applied_filters();

$merged_query = $this->merge_queries( $common_query_values, $orderby_query, $on_sale_query, $stock_query, $tax_query, $applied_filters_query );
$merged_query = $this->merge_queries( $common_query_values, $orderby_query, $on_sale_query, $stock_query, $tax_query, $applied_filters_query, $date_query );

return $this->filter_query_to_only_include_ids( $merged_query, $handpicked_products );
}
Expand Down Expand Up @@ -959,4 +964,38 @@ function( $rating ) use ( $product_visibility_terms ) {
),
);
}

/**
* Constructs a date query for product filtering based on a specified time frame.
*
* @param array $time_frame {
* Associative array with 'operator' (in or not-in) and 'value' (date string).
*
* @type string $operator Determines the inclusion or exclusion of the date range.
* @type string $value The date around which the range is applied.
* }
* @return array Date query array; empty if parameters are invalid.
*/
private function get_date_query( array $time_frame ) : array {
// Validate time_frame elements.
if ( empty( $time_frame['operator'] ) || empty( $time_frame['value'] ) ) {
return array();
}

// Determine the query operator based on the 'operator' value.
$query_operator = 'in' === $time_frame['operator'] ? 'after' : 'before';

// Construct and return the date query.
return array(
'date_query' => array(
array(
'column' => 'post_date_gmt',
$query_operator => $time_frame['value'],
'inclusive' => true,
),
),
);
}


}

0 comments on commit 25908ac

Please sign in to comment.