Skip to content

Commit

Permalink
Merge pull request #3289 from 10up/feature/issue-3118
Browse files Browse the repository at this point in the history
Facet by Meta Range block foundations
  • Loading branch information
felipeelia authored Feb 1, 2023
2 parents 741c267 + db873e9 commit 664cb13
Show file tree
Hide file tree
Showing 12 changed files with 1,054 additions and 33 deletions.
20 changes: 20 additions & 0 deletions assets/js/blocks/facets/meta-range/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"title": "Facet by Meta Range (ElasticPress)",
"textdomain": "elasticpress",
"name": "elasticpress/facet-meta-range",
"icon": "feedback",
"category": "widgets",
"attributes": {
"facet": {
"type": "string",
"default": ""
}
},
"supports": {
"html": false
},
"editorScript": "ep-facets-meta-range-block-script",
"style": "file:/../../../../../dist/css/facets-styles.css"
}
81 changes: 81 additions & 0 deletions assets/js/blocks/facets/meta-range/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* global facetMetaBlock */

import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, Spinner, Placeholder, SelectControl } from '@wordpress/components';
import {
Fragment,
useEffect,
useState,
useCallback,
createInterpolateElement,
} from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';
import { __ } from '@wordpress/i18n';

const FacetBlockEdit = (props) => {
const { attributes, setAttributes } = props;
const [metaKeys, setMetaKeys] = useState([]);
const [preview, setPreview] = useState('');
const [loading, setLoading] = useState(false);
const { facet, min, max } = attributes;

const blockProps = useBlockProps();

const load = useCallback(async () => {
const metaKeys = await apiFetch({
path: '/elasticpress/v1/facets/meta-range/keys',
});
setMetaKeys(metaKeys);
}, [setMetaKeys]);

useEffect(load, [load]);

useEffect(() => {
setLoading(true);
const params = new URLSearchParams({ facet });
apiFetch({
path: `/elasticpress/v1/facets/meta-range/block-preview?${params}`,
})
.then((preview) => setPreview(preview))
.finally(() => setLoading(false));
}, [facet, min, max]);

return (
<Fragment>
<InspectorControls>
<PanelBody title={__('Facet Settings', 'elasticpress')}>
<SelectControl
label={__('Meta Field Key', 'elasticpress')}
help={createInterpolateElement(
__(
'This is the list of meta fields indexed in Elasticsearch. If your desired field does not appear in this list please try to <a>sync your content</a>',
'elasticpress',
),
// eslint-disable-next-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
{ a: <a href={facetMetaBlock.syncUrl} /> },
)}
value={facet}
options={[
...metaKeys.map((metaKey) => ({
label: metaKey,
value: metaKey,
})),
]}
onChange={(value) => setAttributes({ facet: value })}
/>
</PanelBody>
</InspectorControls>

<div {...blockProps}>
{loading && (
<Placeholder>
<Spinner />
</Placeholder>
)}
{/* eslint-disable-next-line react/no-danger */}
{!loading && <div dangerouslySetInnerHTML={{ __html: preview }} />}
</div>
</Fragment>
);
};
export default FacetBlockEdit;
15 changes: 15 additions & 0 deletions assets/js/blocks/facets/meta-range/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* WordPress dependencies.
*/
import { registerBlockType } from '@wordpress/blocks';

/**
* Internal dependencies.
*/
import edit from './edit';
import block from './block.json';

registerBlockType(block, {
edit,
save: () => {},
});
36 changes: 36 additions & 0 deletions includes/classes/Feature/Facets/FacetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,40 @@ public function get_sanitize_callback() : string {
return apply_filters( 'ep_facet_default_sanitize_callback', 'sanitize_text_field' );
}

/**
* Format selected values.
*
* @since 4.5.0
* @param string $facet Facet name
* @param mixed $value Facet value
* @param array $filters Selected filters
* @return array
*/
public function format_selected( string $facet, $value, array $filters ) {
$terms = explode( ',', trim( $value, ',' ) );
$filters[ $this->get_filter_type() ][ $facet ] = [
'terms' => array_fill_keys( array_map( $this->get_sanitize_callback(), $terms ), true ),
];
return $filters;
}

/**
* Add selected filters to the query string.
*
* @since 4.5.0
* @param array $query_params Existent query parameters
* @param array $filters Selected filters
* @return array
*/
public function add_query_params( array $query_params, array $filters ) : array {
$selected = $filters[ $this->get_filter_type() ];

foreach ( $selected as $facet => $filter ) {
if ( ! empty( $filter['terms'] ) ) {
$query_params[ $this->get_filter_name() . $facet ] = implode( ',', array_keys( $filter['terms'] ) );
}
}

return $query_params;
}
}
51 changes: 20 additions & 31 deletions includes/classes/Feature/Facets/Facets.php
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,17 @@ public function get_aggs( $response, $query, $query_args, $query_object ) {
continue;
}

if ( ! is_array( $agg ) || empty( $agg['buckets'] ) ) {
if ( ! is_array( $agg ) || ( empty( $agg['buckets'] ) && empty( $agg['value'] ) ) ) {
continue;
}

$GLOBALS['ep_facet_aggs'][ $key ] = [];

if ( ! empty( $agg['value'] ) ) {
$GLOBALS['ep_facet_aggs'][ $key ] = $agg['value'];
continue;
}

foreach ( $agg['buckets'] as $bucket ) {
$GLOBALS['ep_facet_aggs'][ $key ][ $bucket['key'] ] = $bucket['doc_count'];
}
Expand All @@ -374,29 +379,20 @@ public function get_aggs( $response, $query, $query_args, $query_object ) {
public function get_selected() {
$allowed_args = $this->get_allowed_query_args();

$filters = [];
$filter_names = [];
$sanitize_callbacks = [];
$filters = [];
$filter_names = [];
foreach ( $this->types as $type_obj ) {
$filter_type = $type_obj->get_filter_type();

$filters[ $filter_type ] = [];
$filter_names[ $filter_type ] = $type_obj->get_filter_name();
$sanitize_callbacks[ $filter_type ] = $type_obj->get_sanitize_callback();
$filter_names[ $type_obj->get_filter_name() ] = $type_obj;
}

foreach ( $_GET as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification
$key = sanitize_key( $key );

foreach ( $filter_names as $filter_type => $filter_name ) {
foreach ( $filter_names as $filter_name => $type_obj ) {
if ( 0 === strpos( $key, $filter_name ) ) {
$facet = str_replace( $filter_name, '', $key );
$sanitize_callback = $sanitize_callbacks[ $filter_type ];
$terms = explode( ',', trim( $value, ',' ) );
$facet = str_replace( $filter_name, '', $key );

$filters[ $filter_type ][ $facet ] = array(
'terms' => array_fill_keys( array_map( $sanitize_callback, $terms ), true ),
);
$filters = $type_obj->format_selected( $facet, $value, $filters );
}
}

Expand All @@ -416,20 +412,13 @@ public function get_selected() {
* @return string
*/
public function build_query_url( $filters ) {
$query_param = array();
$query_params = array();

foreach ( $this->types as $type_obj ) {
$filter_type = $type_obj->get_filter_type();

if ( ! empty( $filters[ $filter_type ] ) ) {
$type_filters = $filters[ $filter_type ];

foreach ( $type_filters as $facet => $filter ) {
if ( ! empty( $filter['terms'] ) ) {
$query_param[ $type_obj->get_filter_name() . $facet ] = implode( ',', array_keys( $filter['terms'] ) );
}
}
if ( empty( $filters[ $type_obj->get_filter_type() ] ) ) {
continue;
}
$query_params = $type_obj->add_query_params( $query_params, $filters );
}

$feature = Features::factory()->get_registered_feature( 'facets' );
Expand All @@ -438,22 +427,22 @@ public function build_query_url( $filters ) {
if ( ! empty( $filters ) ) {
foreach ( $filters as $filter => $value ) {
if ( in_array( $filter, $allowed_args, true ) ) {
$query_param[ $filter ] = $value;
$query_params[ $filter ] = $value;
}
}
}

$query_string = build_query( $query_param );
$query_string = build_query( $query_params );

/**
* Filter facet query string
*
* @hook ep_facet_query_string
* @param {string} $query_string Current query string
* @param {array} $query_param Query parameters
* @param {array} $query_params Query parameters
* @return {string} New query string
*/
$query_string = apply_filters( 'ep_facet_query_string', $query_string, $query_param );
$query_string = apply_filters( 'ep_facet_query_string', $query_string, $query_params );

$url = $_SERVER['REQUEST_URI'];
$pagination = strpos( $url, '/page' );
Expand Down
5 changes: 4 additions & 1 deletion includes/classes/Feature/Facets/Types/Meta/FacetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,10 @@ public function get_facets_meta_fields() {
continue;
}

if ( false === strpos( $instance['content'], 'elasticpress/facet-meta' ) ) {
if (
false !== strpos( $instance['content'], 'elasticpress/facet-meta-range' )
|| false === strpos( $instance['content'], 'elasticpress/facet-meta' )
) {
continue;
}

Expand Down
Loading

0 comments on commit 664cb13

Please sign in to comment.