Revert "Add "Filter Products by Stock" block (https://github.com/woocommerce/woocommerce-blocks/pull/4145)"
This reverts commit 44db8317a7
.
This commit is contained in:
parent
44db8317a7
commit
8f2bc114a4
|
@ -1,9 +0,0 @@
|
|||
.wc-filter-element-label-list-count {
|
||||
&::before {
|
||||
content: " (";
|
||||
}
|
||||
&::after {
|
||||
content: ")";
|
||||
}
|
||||
opacity: 0.6;
|
||||
}
|
|
@ -9,7 +9,10 @@ import PropTypes from 'prop-types';
|
|||
*/
|
||||
import ProductList from './product-list';
|
||||
|
||||
const ProductListContainer = ( { attributes } ) => {
|
||||
const ProductListContainer = ( {
|
||||
attributes,
|
||||
hideOutOfStockItems = false,
|
||||
} ) => {
|
||||
const [ currentPage, setPage ] = useState( 1 );
|
||||
const [ currentSort, setSort ] = useState( attributes.orderby );
|
||||
useEffect( () => {
|
||||
|
@ -28,6 +31,7 @@ const ProductListContainer = ( { attributes } ) => {
|
|||
return (
|
||||
<ProductList
|
||||
attributes={ attributes }
|
||||
hideOutOfStockItems={ hideOutOfStockItems }
|
||||
currentPage={ currentPage }
|
||||
onPageChange={ onPageChange }
|
||||
onSortChange={ onSortChange }
|
||||
|
|
|
@ -27,7 +27,12 @@ import ProductSortSelect from './product-sort-select';
|
|||
import ProductListItem from './product-list-item';
|
||||
import './style.scss';
|
||||
|
||||
const generateQuery = ( { sortValue, currentPage, attributes } ) => {
|
||||
const generateQuery = ( {
|
||||
sortValue,
|
||||
currentPage,
|
||||
attributes,
|
||||
hideOutOfStockItems,
|
||||
} ) => {
|
||||
const { columns, rows } = attributes;
|
||||
const getSortArgs = ( orderName ) => {
|
||||
switch ( orderName ) {
|
||||
|
@ -57,6 +62,9 @@ const generateQuery = ( { sortValue, currentPage, attributes } ) => {
|
|||
catalog_visibility: 'catalog',
|
||||
per_page: columns * rows,
|
||||
page: currentPage,
|
||||
...( hideOutOfStockItems && {
|
||||
stock_status: [ 'instock', 'onbackorder' ],
|
||||
} ),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -110,24 +118,14 @@ const ProductList = ( {
|
|||
onSortChange,
|
||||
sortValue,
|
||||
scrollToTop,
|
||||
hideOutOfStockItems = false,
|
||||
} ) => {
|
||||
// These are possible filters.
|
||||
const [ productAttributes, setProductAttributes ] = useQueryStateByKey(
|
||||
'attributes',
|
||||
[]
|
||||
);
|
||||
const [ productStockStatus, setProductStockStatus ] = useQueryStateByKey(
|
||||
'stock_status',
|
||||
[]
|
||||
);
|
||||
const [ minPrice, setMinPrice ] = useQueryStateByKey( 'min_price' );
|
||||
const [ maxPrice, setMaxPrice ] = useQueryStateByKey( 'max_price' );
|
||||
|
||||
const [ queryState ] = useSynchronizedQueryState(
|
||||
generateQuery( {
|
||||
attributes,
|
||||
sortValue,
|
||||
currentPage,
|
||||
hideOutOfStockItems,
|
||||
} )
|
||||
);
|
||||
const { products, totalProducts, productsLoading } = useStoreProducts(
|
||||
|
@ -137,6 +135,14 @@ const ProductList = ( {
|
|||
const totalQuery = extractPaginationAndSortAttributes( queryState );
|
||||
const { dispatchStoreEvent } = useStoreEvents();
|
||||
|
||||
// These are possible filters.
|
||||
const [ productAttributes, setProductAttributes ] = useQueryStateByKey(
|
||||
'attributes',
|
||||
[]
|
||||
);
|
||||
const [ minPrice, setMinPrice ] = useQueryStateByKey( 'min_price' );
|
||||
const [ maxPrice, setMaxPrice ] = useQueryStateByKey( 'max_price' );
|
||||
|
||||
// Only update previous query totals if the query is different and the total number of products is a finite number.
|
||||
const previousQueryTotals = usePrevious(
|
||||
{ totalQuery, totalProducts },
|
||||
|
@ -203,7 +209,6 @@ const ProductList = ( {
|
|||
const hasProducts = products.length !== 0 || productsLoading;
|
||||
const hasFilters =
|
||||
productAttributes.length > 0 ||
|
||||
productStockStatus.length > 0 ||
|
||||
Number.isFinite( minPrice ) ||
|
||||
Number.isFinite( maxPrice );
|
||||
|
||||
|
@ -219,7 +224,6 @@ const ProductList = ( {
|
|||
<NoMatchingProducts
|
||||
resetCallback={ () => {
|
||||
setProductAttributes( [] );
|
||||
setProductStockStatus( [] );
|
||||
setMinPrice( null );
|
||||
setMaxPrice( null );
|
||||
} }
|
||||
|
@ -250,6 +254,7 @@ const ProductList = ( {
|
|||
|
||||
ProductList.propTypes = {
|
||||
attributes: PropTypes.object.isRequired,
|
||||
hideOutOfStockItems: PropTypes.bool,
|
||||
// From withScrollToTop.
|
||||
scrollToTop: PropTypes.func,
|
||||
};
|
||||
|
|
|
@ -36,7 +36,6 @@ const buildCollectionDataQuery = ( collectionDataQueryState ) => {
|
|||
export const useCollectionData = ( {
|
||||
queryAttribute,
|
||||
queryPrices,
|
||||
queryStock,
|
||||
queryState,
|
||||
} ) => {
|
||||
let context = useQueryStateContext();
|
||||
|
@ -51,14 +50,9 @@ export const useCollectionData = ( {
|
|||
calculatePriceRangeQueryState,
|
||||
setCalculatePriceRangeQueryState,
|
||||
] = useQueryStateByKey( 'calculate_price_range', null, context );
|
||||
const [
|
||||
calculateStockStatusQueryState,
|
||||
setCalculateStockStatusQueryState,
|
||||
] = useQueryStateByKey( 'calculate_stock_status_counts', null, context );
|
||||
|
||||
const currentQueryAttribute = useShallowEqual( queryAttribute || {} );
|
||||
const currentQueryPrices = useShallowEqual( queryPrices );
|
||||
const currentQueryStock = useShallowEqual( queryStock );
|
||||
|
||||
useEffect( () => {
|
||||
if (
|
||||
|
@ -99,19 +93,6 @@ export const useCollectionData = ( {
|
|||
calculatePriceRangeQueryState,
|
||||
] );
|
||||
|
||||
useEffect( () => {
|
||||
if (
|
||||
calculateStockStatusQueryState !== currentQueryStock &&
|
||||
currentQueryStock !== undefined
|
||||
) {
|
||||
setCalculateStockStatusQueryState( currentQueryStock );
|
||||
}
|
||||
}, [
|
||||
currentQueryStock,
|
||||
setCalculateStockStatusQueryState,
|
||||
calculateStockStatusQueryState,
|
||||
] );
|
||||
|
||||
// Defer the select query so all collection-data query vars can be gathered.
|
||||
const [ shouldSelect, setShouldSelect ] = useState( false );
|
||||
const [ debouncedShouldSelect ] = useDebounce( shouldSelect, 200 );
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useQueryStateByKey } from '@woocommerce/base-context/hooks';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -32,39 +31,9 @@ const ActiveFiltersBlock = ( {
|
|||
'attributes',
|
||||
[]
|
||||
);
|
||||
const [ productStockStatus, setProductStockStatus ] = useQueryStateByKey(
|
||||
'stock_status',
|
||||
[]
|
||||
);
|
||||
const [ minPrice, setMinPrice ] = useQueryStateByKey( 'min_price' );
|
||||
const [ maxPrice, setMaxPrice ] = useQueryStateByKey( 'max_price' );
|
||||
|
||||
const STOCK_STATUS_OPTIONS = getSetting( 'stockStatusOptions', [] );
|
||||
const activeStockStatusFilters = useMemo( () => {
|
||||
if ( productStockStatus.length > 0 ) {
|
||||
return productStockStatus.map( ( slug ) => {
|
||||
return renderRemovableListItem( {
|
||||
type: __( 'Stock Status', 'woo-gutenberg-products-block' ),
|
||||
name: STOCK_STATUS_OPTIONS[ slug ],
|
||||
removeCallback: () => {
|
||||
const newStatuses = productStockStatus.filter(
|
||||
( status ) => {
|
||||
return status !== slug;
|
||||
}
|
||||
);
|
||||
setProductStockStatus( newStatuses );
|
||||
},
|
||||
displayStyle: blockAttributes.displayStyle,
|
||||
} );
|
||||
} );
|
||||
}
|
||||
}, [
|
||||
STOCK_STATUS_OPTIONS,
|
||||
productStockStatus,
|
||||
setProductStockStatus,
|
||||
blockAttributes.displayStyle,
|
||||
] );
|
||||
|
||||
const activePriceFilters = useMemo( () => {
|
||||
if ( ! Number.isFinite( minPrice ) && ! Number.isFinite( maxPrice ) ) {
|
||||
return null;
|
||||
|
@ -106,7 +75,6 @@ const ActiveFiltersBlock = ( {
|
|||
const hasFilters = () => {
|
||||
return (
|
||||
productAttributes.length > 0 ||
|
||||
productStockStatus.length > 0 ||
|
||||
Number.isFinite( minPrice ) ||
|
||||
Number.isFinite( maxPrice )
|
||||
);
|
||||
|
@ -157,7 +125,6 @@ const ActiveFiltersBlock = ( {
|
|||
) : (
|
||||
<>
|
||||
{ activePriceFilters }
|
||||
{ activeStockStatusFilters }
|
||||
{ activeAttributeFilters }
|
||||
</>
|
||||
) }
|
||||
|
@ -168,7 +135,6 @@ const ActiveFiltersBlock = ( {
|
|||
setMinPrice( undefined );
|
||||
setMaxPrice( undefined );
|
||||
setProductAttributes( [] );
|
||||
setProductStockStatus( [] );
|
||||
} }
|
||||
>
|
||||
<Label
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
import { useCallback, useEffect, useState, useMemo } from '@wordpress/element';
|
||||
import CheckboxList from '@woocommerce/base-components/checkbox-list';
|
||||
import DropdownSelector from '@woocommerce/base-components/dropdown-selector';
|
||||
import Label from '@woocommerce/base-components/filter-element-label';
|
||||
import FilterSubmitButton from '@woocommerce/base-components/filter-submit-button';
|
||||
import isShallowEqual from '@wordpress/is-shallow-equal';
|
||||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
|
@ -23,6 +22,7 @@ import { decodeEntities } from '@wordpress/html-entities';
|
|||
*/
|
||||
import { getAttributeFromID } from '../../utils/attributes';
|
||||
import { updateAttributeFilter } from '../../utils/attributes-query';
|
||||
import Label from './label';
|
||||
import { previewAttributeObject, previewOptions } from './preview';
|
||||
import './style.scss';
|
||||
|
||||
|
|
|
@ -5,18 +5,13 @@ import { _n, sprintf } from '@wordpress/i18n';
|
|||
import Label from '@woocommerce/base-components/label';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
* The label for an filter elements.
|
||||
* The label for an attribute term filter.
|
||||
*
|
||||
* @param {Object} props Incoming props for the component.
|
||||
* @param {string} props.name The name for the label.
|
||||
* @param {number} props.count The count of products this status is attached to.
|
||||
* @param {number} props.count The count of products this attribute is attached to.
|
||||
*/
|
||||
const FilterElementLabel = ( { name, count } ) => {
|
||||
const AttributeFilterLabel = ( { name, count } ) => {
|
||||
return (
|
||||
<>
|
||||
{ name }
|
||||
|
@ -35,7 +30,7 @@ const FilterElementLabel = ( { name, count } ) => {
|
|||
) }
|
||||
wrapperElement="span"
|
||||
wrapperProps={ {
|
||||
className: 'wc-filter-element-label-list-count',
|
||||
className: 'wc-block-attribute-filter-list-count',
|
||||
} }
|
||||
/>
|
||||
) }
|
||||
|
@ -43,4 +38,4 @@ const FilterElementLabel = ( { name, count } ) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default FilterElementLabel;
|
||||
export default AttributeFilterLabel;
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Label from '@woocommerce/base-components/filter-element-label';
|
||||
import Label from './label';
|
||||
|
||||
export const previewOptions = [
|
||||
{
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
.wc-block-attribute-filter {
|
||||
margin-bottom: $gap-large;
|
||||
|
||||
.wc-block-attribute-filter-list-count {
|
||||
&::before {
|
||||
content: " (";
|
||||
}
|
||||
&::after {
|
||||
content: ")";
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-attribute-filter-list {
|
||||
margin: 0;
|
||||
|
||||
|
@ -16,6 +25,10 @@
|
|||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-attribute-filter-list-count {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.is-single .wc-block-attribute-filter-list-count,
|
||||
|
|
|
@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
|
|||
import { ProductListContainer } from '@woocommerce/base-components/product-list';
|
||||
import { InnerBlockLayoutContextProvider } from '@woocommerce/shared-context';
|
||||
import { gridBlockPreview } from '@woocommerce/resource-previews';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
* The All Products Block.
|
||||
|
@ -25,6 +26,8 @@ class Block extends Component {
|
|||
return gridBlockPreview;
|
||||
}
|
||||
|
||||
const hideOutOfStockItems = getSetting( 'hideOutOfStockItems', false );
|
||||
|
||||
/**
|
||||
* Todo classes
|
||||
*
|
||||
|
@ -39,6 +42,7 @@ class Block extends Component {
|
|||
<ProductListContainer
|
||||
attributes={ attributes }
|
||||
urlParameterSuffix={ urlParameterSuffix }
|
||||
hideOutOfStockItems={ hideOutOfStockItems }
|
||||
/>
|
||||
</InnerBlockLayoutContextProvider>
|
||||
);
|
||||
|
|
|
@ -1,278 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { speak } from '@wordpress/a11y';
|
||||
import { usePrevious, useShallowEqual } from '@woocommerce/base-hooks';
|
||||
import {
|
||||
useQueryStateByKey,
|
||||
useQueryStateByContext,
|
||||
useCollectionData,
|
||||
} from '@woocommerce/base-context/hooks';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import { useCallback, useEffect, useState, useMemo } from '@wordpress/element';
|
||||
import CheckboxList from '@woocommerce/base-components/checkbox-list';
|
||||
import FilterSubmitButton from '@woocommerce/base-components/filter-submit-button';
|
||||
import Label from '@woocommerce/base-components/filter-element-label';
|
||||
import isShallowEqual from '@wordpress/is-shallow-equal';
|
||||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { previewOptions } from './preview';
|
||||
import './style.scss';
|
||||
|
||||
const hideOutOfStockItems = getSetting( 'hideOutOfStockItems', false );
|
||||
const { outofstock, ...otherStockStatusOptions } = getSetting(
|
||||
'stockStatusOptions',
|
||||
{}
|
||||
);
|
||||
const STOCK_STATUS_OPTIONS = hideOutOfStockItems
|
||||
? otherStockStatusOptions
|
||||
: { outofstock, ...otherStockStatusOptions };
|
||||
// Filter added to handle if there are slugs without a corresponding name defined.
|
||||
const initialOptions = Object.entries( STOCK_STATUS_OPTIONS )
|
||||
.map( ( [ slug, name ] ) => ( { slug, name } ) )
|
||||
.filter( ( status ) => !! status.name )
|
||||
.sort( ( a, b ) => a.slug.localeCompare( b.slug ) );
|
||||
|
||||
/**
|
||||
* Component displaying an stock status filter.
|
||||
*
|
||||
* @param {Object} props Incoming props for the component.
|
||||
* @param {Object} props.attributes Incoming block attributes.
|
||||
* @param {boolean} props.isEditor
|
||||
*/
|
||||
const StockStatusFilterBlock = ( {
|
||||
attributes: blockAttributes,
|
||||
isEditor = false,
|
||||
} ) => {
|
||||
const [ checked, setChecked ] = useState( [] );
|
||||
const [ displayedOptions, setDisplayedOptions ] = useState(
|
||||
blockAttributes.isPreview ? previewOptions : []
|
||||
);
|
||||
|
||||
const [ queryState ] = useQueryStateByContext();
|
||||
const [
|
||||
productStockStatusQuery,
|
||||
setProductStockStatusQuery,
|
||||
] = useQueryStateByKey( 'stock_status', [] );
|
||||
|
||||
const {
|
||||
results: filteredCounts,
|
||||
isLoading: filteredCountsLoading,
|
||||
} = useCollectionData( {
|
||||
queryStock: true,
|
||||
queryState,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Get count data about a given status by slug.
|
||||
*/
|
||||
const getFilteredStock = useCallback(
|
||||
( slug ) => {
|
||||
if ( ! filteredCounts.stock_status_counts ) {
|
||||
return null;
|
||||
}
|
||||
return filteredCounts.stock_status_counts.find(
|
||||
( { status, count } ) =>
|
||||
status === slug && Number( count ) !== 0
|
||||
);
|
||||
},
|
||||
[ filteredCounts ]
|
||||
);
|
||||
|
||||
/**
|
||||
* Compare intersection of all stock statuses and filtered counts to get a list of options to display.
|
||||
*/
|
||||
useEffect( () => {
|
||||
/**
|
||||
* Checks if a status slug is in the query state.
|
||||
*
|
||||
* @param {string} queryStatus The status slug to check.
|
||||
*/
|
||||
const isStockStatusInQueryState = ( queryStatus ) => {
|
||||
if ( ! queryState?.stock_status ) {
|
||||
return false;
|
||||
}
|
||||
return queryState.stock_status.some( ( { status = [] } ) =>
|
||||
status.includes( queryStatus )
|
||||
);
|
||||
};
|
||||
|
||||
if ( filteredCountsLoading || blockAttributes.isPreview ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newOptions = initialOptions
|
||||
.map( ( status ) => {
|
||||
const filteredStock = getFilteredStock( status.slug );
|
||||
|
||||
if (
|
||||
! filteredStock &&
|
||||
! checked.includes( status.slug ) &&
|
||||
! isStockStatusInQueryState( status.slug )
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const count = filteredStock ? Number( filteredStock.count ) : 0;
|
||||
|
||||
return {
|
||||
value: status.slug,
|
||||
name: decodeEntities( status.name ),
|
||||
label: (
|
||||
<Label
|
||||
name={ decodeEntities( status.name ) }
|
||||
count={ blockAttributes.showCounts ? count : null }
|
||||
/>
|
||||
),
|
||||
};
|
||||
} )
|
||||
.filter( Boolean );
|
||||
|
||||
setDisplayedOptions( newOptions );
|
||||
}, [
|
||||
blockAttributes.showCounts,
|
||||
blockAttributes.isPreview,
|
||||
filteredCountsLoading,
|
||||
getFilteredStock,
|
||||
checked,
|
||||
queryState.stock_status,
|
||||
] );
|
||||
|
||||
const onSubmit = useCallback(
|
||||
( isChecked ) => {
|
||||
if ( isEditor ) {
|
||||
return;
|
||||
}
|
||||
if ( isChecked ) {
|
||||
setProductStockStatusQuery( checked );
|
||||
}
|
||||
},
|
||||
[ isEditor, setProductStockStatusQuery, checked ]
|
||||
);
|
||||
|
||||
// Track checked STATE changes - if state changes, update the query.
|
||||
useEffect( () => {
|
||||
if ( ! blockAttributes.showFilterButton ) {
|
||||
onSubmit( checked );
|
||||
}
|
||||
}, [ blockAttributes.showFilterButton, checked, onSubmit ] );
|
||||
|
||||
const checkedQuery = useMemo( () => {
|
||||
return productStockStatusQuery;
|
||||
}, [ productStockStatusQuery ] );
|
||||
|
||||
const currentCheckedQuery = useShallowEqual( checkedQuery );
|
||||
const previousCheckedQuery = usePrevious( currentCheckedQuery );
|
||||
// Track Stock query changes so the block reflects current filters.
|
||||
useEffect( () => {
|
||||
if (
|
||||
! isShallowEqual( previousCheckedQuery, currentCheckedQuery ) && // Checked query changed.
|
||||
! isShallowEqual( checked, currentCheckedQuery ) // Checked query doesn't match the UI.
|
||||
) {
|
||||
setChecked( currentCheckedQuery );
|
||||
}
|
||||
}, [ checked, currentCheckedQuery, previousCheckedQuery ] );
|
||||
|
||||
/**
|
||||
* When a checkbox in the list changes, update state.
|
||||
*/
|
||||
const onChange = useCallback(
|
||||
( checkedValue ) => {
|
||||
const getFilterNameFromValue = ( filterValue ) => {
|
||||
const { name } = displayedOptions.find(
|
||||
( option ) => option.value === filterValue
|
||||
);
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
const announceFilterChange = ( { filterAdded, filterRemoved } ) => {
|
||||
const filterAddedName = filterAdded
|
||||
? getFilterNameFromValue( filterAdded )
|
||||
: null;
|
||||
const filterRemovedName = filterRemoved
|
||||
? getFilterNameFromValue( filterRemoved )
|
||||
: null;
|
||||
if ( filterAddedName ) {
|
||||
speak(
|
||||
sprintf(
|
||||
/* translators: %s stock statuses (for example: 'instock'...) */
|
||||
__(
|
||||
'%s filter added.',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
filterAddedName
|
||||
)
|
||||
);
|
||||
} else if ( filterRemovedName ) {
|
||||
speak(
|
||||
sprintf(
|
||||
/* translators: %s stock statuses (for example:'instock'...) */
|
||||
__(
|
||||
'%s filter removed.',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
filterRemovedName
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const previouslyChecked = checked.includes( checkedValue );
|
||||
|
||||
const newChecked = checked.filter(
|
||||
( value ) => value !== checkedValue
|
||||
);
|
||||
|
||||
if ( ! previouslyChecked ) {
|
||||
newChecked.push( checkedValue );
|
||||
newChecked.sort();
|
||||
announceFilterChange( { filterAdded: checkedValue } );
|
||||
} else {
|
||||
announceFilterChange( { filterRemoved: checkedValue } );
|
||||
}
|
||||
|
||||
setChecked( newChecked );
|
||||
},
|
||||
[ checked, displayedOptions ]
|
||||
);
|
||||
|
||||
if ( displayedOptions.length === 0 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const TagName = `h${ blockAttributes.headingLevel }`;
|
||||
const isLoading = ! blockAttributes.isPreview && ! STOCK_STATUS_OPTIONS;
|
||||
const isDisabled = ! blockAttributes.isPreview && filteredCountsLoading;
|
||||
|
||||
return (
|
||||
<>
|
||||
{ ! isEditor && blockAttributes.heading && (
|
||||
<TagName>{ blockAttributes.heading }</TagName>
|
||||
) }
|
||||
<div className="wc-block-stock-filter">
|
||||
<CheckboxList
|
||||
className={ 'wc-block-stock-filter-list' }
|
||||
options={ displayedOptions }
|
||||
checked={ checked }
|
||||
onChange={ onChange }
|
||||
isLoading={ isLoading }
|
||||
isDisabled={ isDisabled }
|
||||
/>
|
||||
{ blockAttributes.showFilterButton && (
|
||||
<FilterSubmitButton
|
||||
className="wc-block-stock-filter__button"
|
||||
disabled={ isLoading || isDisabled }
|
||||
onClick={ () => onSubmit( checked ) }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default StockStatusFilterBlock;
|
|
@ -1,130 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { InspectorControls } from '@wordpress/block-editor';
|
||||
import {
|
||||
Disabled,
|
||||
PanelBody,
|
||||
ToggleControl,
|
||||
withSpokenMessages,
|
||||
} from '@wordpress/components';
|
||||
import HeadingToolbar from '@woocommerce/editor-components/heading-toolbar';
|
||||
import BlockTitle from '@woocommerce/editor-components/block-title';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Block from './block.js';
|
||||
import './editor.scss';
|
||||
|
||||
const Edit = ( { attributes, setAttributes } ) => {
|
||||
const {
|
||||
className,
|
||||
heading,
|
||||
headingLevel,
|
||||
showCounts,
|
||||
showFilterButton,
|
||||
} = attributes;
|
||||
|
||||
const getInspectorControls = () => {
|
||||
return (
|
||||
<InspectorControls key="inspector">
|
||||
<PanelBody
|
||||
title={ __( 'Content', 'woo-gutenberg-products-block' ) }
|
||||
>
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Product count',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
help={
|
||||
showCounts
|
||||
? __(
|
||||
'Product count is visible.',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
: __(
|
||||
'Product count is hidden.',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
}
|
||||
checked={ showCounts }
|
||||
onChange={ () =>
|
||||
setAttributes( {
|
||||
showCounts: ! showCounts,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
<p>
|
||||
{ __(
|
||||
'Heading Level',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<HeadingToolbar
|
||||
isCollapsed={ false }
|
||||
minLevel={ 2 }
|
||||
maxLevel={ 7 }
|
||||
selectedLevel={ headingLevel }
|
||||
onChange={ ( newLevel ) =>
|
||||
setAttributes( { headingLevel: newLevel } )
|
||||
}
|
||||
/>
|
||||
</PanelBody>
|
||||
<PanelBody
|
||||
title={ __(
|
||||
'Block Settings',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Filter button',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
help={
|
||||
showFilterButton
|
||||
? __(
|
||||
'Products will only update when the button is pressed.',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
: __(
|
||||
'Products will update as options are selected.',
|
||||
'woo-gutenberg-products-block'
|
||||
)
|
||||
}
|
||||
checked={ showFilterButton }
|
||||
onChange={ ( value ) =>
|
||||
setAttributes( {
|
||||
showFilterButton: value,
|
||||
} )
|
||||
}
|
||||
/>
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{ getInspectorControls() }
|
||||
{
|
||||
<div className={ className }>
|
||||
<BlockTitle
|
||||
headingLevel={ headingLevel }
|
||||
heading={ heading }
|
||||
onChange={ ( value ) =>
|
||||
setAttributes( { heading: value } )
|
||||
}
|
||||
/>
|
||||
<Disabled>
|
||||
<Block attributes={ attributes } isEditor={ true } />
|
||||
</Disabled>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default withSpokenMessages( Edit );
|
|
@ -1,36 +0,0 @@
|
|||
.wc-block-stock-filter {
|
||||
.components-placeholder__instructions {
|
||||
border-bottom: 1px solid #e0e2e6;
|
||||
width: 100%;
|
||||
padding-bottom: 1em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
.components-placeholder__label svg {
|
||||
fill: currentColor;
|
||||
margin-right: 1ch;
|
||||
}
|
||||
.components-placeholder__fieldset {
|
||||
display: block; /* Disable flex box */
|
||||
}
|
||||
.woocommerce-search-list__search {
|
||||
border-top: 0;
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
.wc-block-stock-filter__add-stock-button {
|
||||
margin: 0 0 1em;
|
||||
vertical-align: middle;
|
||||
height: auto;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
margin-left: 0.5ch;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
.wc-block-stock-filter__read_more_button {
|
||||
display: block;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { withRestApiHydration } from '@woocommerce/block-hocs';
|
||||
import { renderFrontend } from '@woocommerce/base-utils';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Block from './block.js';
|
||||
|
||||
const getProps = ( el ) => {
|
||||
return {
|
||||
attributes: {
|
||||
showCounts: el.dataset.showCounts === 'true',
|
||||
heading: el.dataset.heading,
|
||||
headingLevel: el.dataset.headingLevel || 3,
|
||||
showFilterButton: el.dataset.showFilterButton === 'true',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
renderFrontend( {
|
||||
selector: '.wp-block-woocommerce-stock-filter',
|
||||
Block: withRestApiHydration( Block ),
|
||||
getProps,
|
||||
} );
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { Icon, server } from '@woocommerce/icons';
|
||||
import classNames from 'classnames';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import edit from './edit.js';
|
||||
|
||||
registerBlockType( 'woocommerce/stock-filter', {
|
||||
title: __( 'Filter Products by Stock', 'woo-gutenberg-products-block' ),
|
||||
icon: {
|
||||
src: <Icon srcElement={ server } />,
|
||||
foreground: '#96588a',
|
||||
},
|
||||
category: 'woocommerce',
|
||||
keywords: [ __( 'WooCommerce', 'woo-gutenberg-products-block' ) ],
|
||||
description: __(
|
||||
'Allow customers to filter the grid by products stock status. Works in combination with the All Products block.',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
supports: {
|
||||
html: false,
|
||||
multiple: false,
|
||||
},
|
||||
example: {
|
||||
attributes: {
|
||||
isPreview: true,
|
||||
},
|
||||
},
|
||||
attributes: {
|
||||
heading: {
|
||||
type: 'string',
|
||||
default: __(
|
||||
'Filter by stock status',
|
||||
'woo-gutenberg-products-block'
|
||||
),
|
||||
},
|
||||
headingLevel: {
|
||||
type: 'number',
|
||||
default: 3,
|
||||
},
|
||||
showCounts: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
showFilterButton: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* Are we previewing?
|
||||
*/
|
||||
isPreview: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
edit,
|
||||
// Save the props to post content.
|
||||
save( { attributes } ) {
|
||||
const {
|
||||
className,
|
||||
showCounts,
|
||||
heading,
|
||||
headingLevel,
|
||||
showFilterButton,
|
||||
} = attributes;
|
||||
const data = {
|
||||
'data-show-counts': showCounts,
|
||||
'data-heading': heading,
|
||||
'data-heading-level': headingLevel,
|
||||
};
|
||||
if ( showFilterButton ) {
|
||||
data[ 'data-show-filter-button' ] = showFilterButton;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={ classNames( 'is-loading', className ) }
|
||||
{ ...data }
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
className="wc-block-product-stock-filter__placeholder"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
} );
|
|
@ -1,22 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import Label from '@woocommerce/base-components/filter-element-label';
|
||||
|
||||
export const previewOptions = [
|
||||
{
|
||||
value: 'preview-1',
|
||||
name: 'In Stock',
|
||||
label: <Label name="In Stock" count={ 3 } />,
|
||||
},
|
||||
{
|
||||
value: 'preview-2',
|
||||
name: 'Out of sotck',
|
||||
label: <Label name="Out of stock" count={ 3 } />,
|
||||
},
|
||||
{
|
||||
value: 'preview-3',
|
||||
name: 'On backorder',
|
||||
label: <Label name="On backorder" count={ 2 } />,
|
||||
},
|
||||
];
|
|
@ -1,29 +0,0 @@
|
|||
.wc-block-stock-filter {
|
||||
margin-bottom: $gap-large;
|
||||
|
||||
.wc-block-stock-filter-list {
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
text-decoration: underline;
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-single,
|
||||
.wc-block-dropdown-selector .wc-block-dropdown-selector__list {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.wc-block-stock-filter__button {
|
||||
margin-top: $gap-smaller;
|
||||
}
|
||||
}
|
|
@ -38,7 +38,6 @@ const blocks = {
|
|||
},
|
||||
'price-filter': {},
|
||||
'attribute-filter': {},
|
||||
'stock-filter': {},
|
||||
'active-filters': {},
|
||||
cart: {
|
||||
customDir: 'cart-checkout/cart',
|
||||
|
|
|
@ -27,5 +27,6 @@ class AllProducts extends AbstractBlock {
|
|||
$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( 'hideOutOfStockItems', 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ), true );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||
|
||||
/**
|
||||
* AttributeFilter class.
|
||||
*/
|
||||
class StockFilter extends AbstractBlock {
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'stock-filter';
|
||||
|
||||
/**
|
||||
* Extra data passed through from server to client for block.
|
||||
*
|
||||
* @param array $stock_statuses Any stock statuses that currently are available from the block.
|
||||
* Note, this will be empty in the editor context when the block is
|
||||
* not in the post content on editor load.
|
||||
*/
|
||||
protected function enqueue_data( array $stock_statuses = [] ) {
|
||||
parent::enqueue_data( $stock_statuses );
|
||||
$this->asset_data_registry->add( 'stockStatusOptions', wc_get_product_stock_status_options(), true );
|
||||
$this->asset_data_registry->add( 'hideOutOfStockItems', 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ), true );
|
||||
|
||||
}
|
||||
}
|
|
@ -116,7 +116,6 @@ final class BlockTypesController {
|
|||
'AllProducts',
|
||||
'PriceFilter',
|
||||
'AttributeFilter',
|
||||
'StockFilter',
|
||||
'ActiveFilters',
|
||||
];
|
||||
|
||||
|
@ -140,7 +139,6 @@ final class BlockTypesController {
|
|||
'AllProducts',
|
||||
'PriceFilter',
|
||||
'AttributeFilter',
|
||||
'StockFilter',
|
||||
'ActiveFilters',
|
||||
'Cart',
|
||||
'Checkout',
|
||||
|
|
|
@ -47,11 +47,10 @@ class ProductCollectionData extends AbstractRoute {
|
|||
*/
|
||||
protected function get_route_response( \WP_REST_Request $request ) {
|
||||
$data = [
|
||||
'min_price' => null,
|
||||
'max_price' => null,
|
||||
'attribute_counts' => null,
|
||||
'stock_status_counts' => null,
|
||||
'rating_counts' => null,
|
||||
'min_price' => null,
|
||||
'max_price' => null,
|
||||
'attribute_counts' => null,
|
||||
'rating_counts' => null,
|
||||
];
|
||||
$filters = new ProductQueryFilters();
|
||||
|
||||
|
@ -65,20 +64,6 @@ class ProductCollectionData extends AbstractRoute {
|
|||
$data['max_price'] = $price_results->max_price;
|
||||
}
|
||||
|
||||
if ( ! empty( $request['calculate_stock_status_counts'] ) ) {
|
||||
$filter_request = clone $request;
|
||||
$counts = $filters->get_stock_status_counts( $filter_request );
|
||||
|
||||
$data['stock_status_counts'] = [];
|
||||
|
||||
foreach ( $counts as $key => $value ) {
|
||||
$data['stock_status_counts'][] = (object) [
|
||||
'status' => $key,
|
||||
'count' => $value,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $request['calculate_attribute_counts'] ) ) {
|
||||
$taxonomy__or_queries = [];
|
||||
$taxonomy__and_queries = [];
|
||||
|
@ -163,12 +148,6 @@ class ProductCollectionData extends AbstractRoute {
|
|||
'default' => false,
|
||||
];
|
||||
|
||||
$params['calculate_stock_status_counts'] = [
|
||||
'description' => __( 'If true, calculates stock counts for products in the collection.', 'woo-gutenberg-products-block' ),
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
];
|
||||
|
||||
$params['calculate_attribute_counts'] = [
|
||||
'description' => __( 'If requested, calculates attribute term counts for products in the collection.', 'woo-gutenberg-products-block' ),
|
||||
'type' => 'array',
|
||||
|
|
|
@ -29,7 +29,7 @@ class ProductCollectionDataSchema extends AbstractSchema {
|
|||
*/
|
||||
public function get_properties() {
|
||||
return [
|
||||
'price_range' => [
|
||||
'price_range' => [
|
||||
'description' => __( 'Min and max prices found in collection of products, provided using the smallest unit of the currency.', 'woo-gutenberg-products-block' ),
|
||||
'type' => [ 'object', 'null' ],
|
||||
'context' => [ 'view', 'edit' ],
|
||||
|
@ -52,7 +52,7 @@ class ProductCollectionDataSchema extends AbstractSchema {
|
|||
]
|
||||
),
|
||||
],
|
||||
'attribute_counts' => [
|
||||
'attribute_counts' => [
|
||||
'description' => __( 'Returns number of products within attribute terms.', 'woo-gutenberg-products-block' ),
|
||||
'type' => [ 'array', 'null' ],
|
||||
'context' => [ 'view', 'edit' ],
|
||||
|
@ -75,7 +75,7 @@ class ProductCollectionDataSchema extends AbstractSchema {
|
|||
],
|
||||
],
|
||||
],
|
||||
'rating_counts' => [
|
||||
'rating_counts' => [
|
||||
'description' => __( 'Returns number of products with each average rating.', 'woo-gutenberg-products-block' ),
|
||||
'type' => [ 'array', 'null' ],
|
||||
'context' => [ 'view', 'edit' ],
|
||||
|
@ -98,29 +98,6 @@ class ProductCollectionDataSchema extends AbstractSchema {
|
|||
],
|
||||
],
|
||||
],
|
||||
'stock_status_counts' => [
|
||||
'description' => __( 'Returns number of products with each stock status.', 'woo-gutenberg-products-block' ),
|
||||
'type' => [ 'array', 'null' ],
|
||||
'context' => [ 'view', 'edit' ],
|
||||
'readonly' => true,
|
||||
'items' => [
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'status' => [
|
||||
'description' => __( 'Status', 'woo-gutenberg-products-block' ),
|
||||
'type' => 'string',
|
||||
'context' => [ 'view', 'edit' ],
|
||||
'readonly' => true,
|
||||
],
|
||||
'count' => [
|
||||
'description' => __( 'Number of products.', 'woo-gutenberg-products-block' ),
|
||||
'type' => 'integer',
|
||||
'context' => [ 'view', 'edit' ],
|
||||
'readonly' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -132,15 +109,14 @@ class ProductCollectionDataSchema extends AbstractSchema {
|
|||
*/
|
||||
public function get_item_response( $data ) {
|
||||
return [
|
||||
'price_range' => ! is_null( $data['min_price'] ) && ! is_null( $data['max_price'] ) ? (object) $this->prepare_currency_response(
|
||||
'price_range' => ! is_null( $data['min_price'] ) && ! is_null( $data['max_price'] ) ? (object) $this->prepare_currency_response(
|
||||
[
|
||||
'min_price' => $this->prepare_money_response( $data['min_price'], wc_get_price_decimals() ),
|
||||
'max_price' => $this->prepare_money_response( $data['max_price'], wc_get_price_decimals() ),
|
||||
]
|
||||
) : null,
|
||||
'attribute_counts' => $data['attribute_counts'],
|
||||
'rating_counts' => $data['rating_counts'],
|
||||
'stock_status_counts' => $data['stock_status_counts'],
|
||||
'attribute_counts' => $data['attribute_counts'],
|
||||
'rating_counts' => $data['rating_counts'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -319,9 +319,6 @@ class ProductQuery {
|
|||
if ( $wp_query->get( 'stock_status' ) ) {
|
||||
$args['join'] = $this->append_product_sorting_table_join( $args['join'] );
|
||||
$args['where'] .= ' AND wc_product_meta_lookup.stock_status IN ("' . implode( '","', array_map( 'esc_sql', $wp_query->get( 'stock_status' ) ) ) . '")';
|
||||
} elseif ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
|
||||
$args['join'] = $this->append_product_sorting_table_join( $args['join'] );
|
||||
$args['where'] .= ' AND wc_product_meta_lookup.stock_status NOT IN ("outofstock")';
|
||||
}
|
||||
|
||||
if ( $wp_query->get( 'min_price' ) || $wp_query->get( 'max_price' ) ) {
|
||||
|
|
|
@ -47,72 +47,6 @@ class ProductQueryFilters {
|
|||
return $wpdb->get_row( $price_filter_sql ); // phpcs:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stock status counts for the current products.
|
||||
*
|
||||
* @param \WP_REST_Request $request The request object.
|
||||
* @return array status=>count pairs.
|
||||
*/
|
||||
public function get_stock_status_counts( $request ) {
|
||||
global $wpdb;
|
||||
$product_query = new ProductQuery();
|
||||
$stock_status_options = array_map( 'esc_sql', array_keys( wc_get_product_stock_status_options() ) );
|
||||
$hide_outofstock_items = get_option( 'woocommerce_hide_out_of_stock_items' );
|
||||
if ( 'yes' === $hide_outofstock_items ) {
|
||||
unset( $stock_status_options['outofstock'] );
|
||||
}
|
||||
|
||||
add_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10, 2 );
|
||||
add_filter( 'posts_pre_query', '__return_empty_array' );
|
||||
|
||||
$query_args = $product_query->prepare_objects_query( $request );
|
||||
unset( $query_args['stock_status'] );
|
||||
$query_args['no_found_rows'] = true;
|
||||
$query_args['posts_per_page'] = -1;
|
||||
$query = new \WP_Query();
|
||||
$result = $query->query( $query_args );
|
||||
$product_query_sql = $query->request;
|
||||
|
||||
remove_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10 );
|
||||
remove_filter( 'posts_pre_query', '__return_empty_array' );
|
||||
|
||||
$stock_status_counts = array();
|
||||
|
||||
foreach ( $stock_status_options as $status ) {
|
||||
$stock_status_count_sql = $this->generate_stock_status_count_query( $status, $product_query_sql, $stock_status_options );
|
||||
|
||||
$result = $wpdb->get_row( $stock_status_count_sql ); // phpcs:ignore
|
||||
$stock_status_counts[ $status ] = $result->status_count;
|
||||
}
|
||||
|
||||
return $stock_status_counts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate calculate query by stock status.
|
||||
*
|
||||
* @param string $status status to calculate.
|
||||
* @param string $product_query_sql product query for current filter state.
|
||||
* @param array $stock_status_options available stock status options.
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
private function generate_stock_status_count_query( $status, $product_query_sql, $stock_status_options ) {
|
||||
if ( ! in_array( $status, $stock_status_options, true ) ) {
|
||||
return false;
|
||||
}
|
||||
global $wpdb;
|
||||
$status = esc_sql( $status );
|
||||
return "
|
||||
SELECT COUNT( DISTINCT posts.ID ) as status_count
|
||||
FROM {$wpdb->posts} as posts
|
||||
INNER JOIN {$wpdb->postmeta} as postmeta ON posts.ID = postmeta.post_id
|
||||
AND postmeta.meta_key = '_stock_status'
|
||||
AND postmeta.meta_value = '{$status}'
|
||||
WHERE posts.ID IN ( {$product_query_sql} )
|
||||
";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attribute counts for the current products.
|
||||
*
|
||||
|
|
|
@ -100,7 +100,6 @@ const LegacyMainConfig = {
|
|||
'all-products',
|
||||
'price-filter',
|
||||
'attribute-filter',
|
||||
'stock-filter',
|
||||
'active-filters',
|
||||
'checkout',
|
||||
'cart',
|
||||
|
@ -124,7 +123,6 @@ const LegacyFrontendConfig = {
|
|||
'all-products',
|
||||
'price-filter',
|
||||
'attribute-filter',
|
||||
'stock-filter',
|
||||
'active-filters',
|
||||
'checkout',
|
||||
'cart',
|
||||
|
@ -141,7 +139,6 @@ const LegacyStylingConfig = {
|
|||
'all-products',
|
||||
'price-filter',
|
||||
'attribute-filter',
|
||||
'stock-filter',
|
||||
'active-filters',
|
||||
'checkout',
|
||||
'cart',
|
||||
|
|
Loading…
Reference in New Issue