Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facet by Meta Range block foundations #3289

Merged
merged 11 commits into from
Feb 1, 2023
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