Skip to content

Commit

Permalink
Merge pull request #3499 from 10up/feature/facet-abstract-classes
Browse files Browse the repository at this point in the history
Implement abstract Block facet feature class
  • Loading branch information
felipeelia committed Aug 7, 2023
2 parents c4450d3 + 83cb6cb commit 93d8ead
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 166 deletions.
58 changes: 58 additions & 0 deletions includes/classes/Feature/Facets/Block.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Abstract Facet Block class.
*
* @since 4.7.0
* @package elasticpress
*/

namespace ElasticPress\Feature\Facets;

/**
* Abstract Facet Block class.
*/
abstract class Block {

/**
* Setup hooks and filters for facet block.
*/
abstract public function setup();

/**
* Register facet block.
*/
abstract public function register_block();

/**
* Setup REST endpoints for facet feature.
*/
abstract public function setup_endpoints();

/**
* Render the block.
*
* @param array $attributes Block attributes.
* @return string
*/
abstract public function render_block( $attributes );

/**
* Outputs the block preview
*
* @param \WP_REST_Request $request REST request
* @return string
*/
abstract public function render_block_preview( $request );

/**
* Check if the current user has permission to view the facets REST endpoint.
*
* @return true|\WP_Error
*/
public function check_facets_rest_permission() {
if ( ! current_user_can( 'edit_theme_options' ) ) {
return new \WP_Error( 'ep_rest_forbidden', esc_html__( 'Sorry, you cannot view this resource.', 'elasticpress' ), array( 'status' => 401 ) );
}
return true;
}
}
78 changes: 78 additions & 0 deletions includes/classes/Feature/Facets/Renderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* Abstract Facet Renderer class.
*
* @since 4.7.0
* @package elasticpress
*/

namespace ElasticPress\Feature\Facets;

/**
* Abstract Facet Renderer class.
*/
abstract class Renderer {
/**
* Whether the term count should be displayed or not.
*
* @var bool
*/
protected $display_count;

/**
* Method to render the facet.
*
* @param array $args Widget args
* @param array $instance Instance settings
*/
abstract public function render( $args, $instance );

/**
* Whether the facet should be rendered or not.
*
* @return bool
*/
protected function should_render() : bool {
return true;
}

/**
* Given an array of values, reorder them.
*
* @param array $values Multidimensional array of values. Each value should have (string) `name`, (int) `count`, and (bool) `is_selected`.
* @param string $orderby Key to be used to order.
* @param string $order ASC or DESC.
* @return array
*/
protected function order_values( array $values, string $orderby = 'count', $order = 'desc' ) : array {
$orderby = strtolower( $orderby );
$orderby = in_array( $orderby, [ 'name', 'count' ], true ) ? $orderby : 'count';

$order = strtoupper( $order );
$order = in_array( $order, [ 'ASC', 'DESC' ], true ) ? $order : 'DESC';

$values = wp_list_sort( $values, $orderby, $order, true );

$selected = [];
foreach ( $values as $key => $value ) {
if ( $value['is_selected'] ) {
$selected[ $key ] = $value;
unset( $values[ $key ] );
}
}
$values = $selected + $values;

return $values;
}

/**
* Get the markup for an individual facet item.
*
* @param array|object $item Facet item.
* @param string $url URL for the facet item.
* @return string|null
*/
public function get_facet_item_value_html( $item, string $url ) {
return null;
}
}
30 changes: 14 additions & 16 deletions includes/classes/Feature/Facets/Types/Meta/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
/**
* Facets block class
*/
class Block {
class Block extends \ElasticPress\Feature\Facets\Block {
/**
* Hook block funcionality.
*/
Expand All @@ -36,7 +36,7 @@ public function setup_endpoints() {
'facets/meta/keys',
[
'methods' => 'GET',
'permission_callback' => [ $this, 'check_facets_meta_rest_permission' ],
'permission_callback' => [ $this, 'check_facets_rest_permission' ],
'callback' => [ $this, 'get_rest_registered_metakeys' ],
]
);
Expand All @@ -45,7 +45,7 @@ public function setup_endpoints() {
'facets/meta/block-preview',
[
'methods' => 'GET',
'permission_callback' => [ $this, 'check_facets_meta_rest_permission' ],
'permission_callback' => [ $this, 'check_facets_rest_permission' ],
'callback' => [ $this, 'render_block_preview' ],
'args' => [
'searchPlaceholder' => [
Expand All @@ -69,19 +69,6 @@ public function setup_endpoints() {
);
}

/**
* Check permissions of the /facets/meta/* REST endpoints.
*
* @return WP_Error|true
*/
public function check_facets_meta_rest_permission() {
if ( ! current_user_can( 'edit_theme_options' ) ) {
return new \WP_Error( 'ep_rest_forbidden', esc_html__( 'Sorry, you cannot view this resource.', 'elasticpress' ), array( 'status' => 401 ) );
}

return true;
}

/**
* Return an array of registered meta keys.
*
Expand Down Expand Up @@ -243,4 +230,15 @@ protected function parse_attributes( $attributes ) {
}
return $attributes;
}

/**
* DEPRECATED. Check permissions of the /facets/meta/* REST endpoints.
*
* @return WP_Error|true
*/
public function check_facets_meta_rest_permission() {
_deprecated_function( __METHOD__, '4.7.0', '\ElasticPress\Feature\Facets\Types\Meta\Block::check_facets_rest_permission()' );

return $this->check_facets_rest_permission();
}
}
76 changes: 30 additions & 46 deletions includes/classes/Feature/Facets/Types/Meta/Renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/**
* Facets render class
*/
class Renderer {
class Renderer extends \ElasticPress\Feature\Facets\Renderer {
/**
* Holds the meta field selected.
*
Expand Down Expand Up @@ -149,21 +149,21 @@ public function render( $args, $instance ) {
$order = $instance['order'] ?? 'desc';

$values = $this->order_values( $values, $orderby, $order );
foreach ( $values as $raw_value => $value ) {
foreach ( $values as $raw_value => $item ) {

$field_filters = $selected_filters;
if ( $value['is_selected'] ) {
if ( $item['is_selected'] ) {
unset( $field_filters[ $facet_type->get_filter_type() ][ $this->meta_field ]['terms'][ $raw_value ] );
} else {
$field_filters[ $facet_type->get_filter_type() ][ $this->meta_field ]['terms'][ $raw_value ] = 1;
}

// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
echo $this->get_meta_value_html(
$value,
echo $this->get_facet_item_value_html(
$item,
$feature->build_query_url( $field_filters )
);
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
</div>
Expand All @@ -180,19 +180,19 @@ public function render( $args, $instance ) {
/**
* Get the markup for an individual facet item.
*
* @param array $value Value.
* @param array $item Facet item.
* @param string $url Filter URL.
* @return string HTML for an individual facet term.
*/
public function get_meta_value_html( array $value, string $url ) : string {
public function get_facet_item_value_html( $item, string $url ) : string {
$href = sprintf(
'href="%s"',
esc_url( $url )
);

$label = $value['name'];
$label = $item['name'];
if ( $this->display_count ) {
$label .= ' <span>(' . $value['count'] . ')</span>';
$label .= ' <span>(' . $item['count'] . ')</span>';
}

/**
Expand All @@ -201,10 +201,10 @@ public function get_meta_value_html( array $value, string $url ) : string {
* @since 4.3.0
* @hook ep_facet_meta_value_label
* @param {string} $label Facet meta value label.
* @param {array} $value Value array. It contains `value`, `name`, `count`, and `is_selected`.
* @param {array} $item Value array. It contains `value`, `name`, `count`, and `is_selected`.
* @return {string} Individual facet meta value label.
*/
$label = apply_filters( 'ep_facet_meta_value_label', $label, $value );
$label = apply_filters( 'ep_facet_meta_value_label', $label, $item );

/**
* Filter the accessible label for an individual facet meta value link.
Expand All @@ -217,34 +217,34 @@ public function get_meta_value_html( array $value, string $url ) : string {
* @since 4.3.0
* @hook ep_facet_meta_value_accessible_label
* @param {string} $label Facet meta value accessible label.
* @param {array} $value Value array. It contains `value`, `name`, `count`, and `is_selected`.
* @param {array} $item Value array. It contains `value`, `name`, `count`, and `is_selected`.
* @return {string} Individual facet term accessible label.
*/
$accessible_label = apply_filters(
'ep_facet_meta_value_accessible_label',
$value['is_selected']
$item['is_selected']
/* translators: %s: Filter term name. */
? sprintf( __( 'Remove filter: %s', 'elasticpress' ), $label )
/* translators: %s: Filter term name. */
: sprintf( __( 'Apply filter: %s', 'elasticpress' ), $label ),
$value
$item
);

$link = sprintf(
'<a aria-label="%1$s" %2$s rel="nofollow"><div class="ep-checkbox %3$s" role="presentation"></div>%4$s</a>',
esc_attr( $accessible_label ),
$value['count'] ? $href : 'aria-role="link" aria-disabled="true"',
$value['is_selected'] ? 'checked' : '',
$item['count'] ? $href : 'aria-role="link" aria-disabled="true"',
$item['is_selected'] ? 'checked' : '',
wp_kses_post( $label )
);

$html = sprintf(
'<div class="term level-%1$d %2$s %3$s" data-term-name="%4$s" data-term-slug="%5$s">%6$s</div>',
0,
$value['is_selected'] ? 'selected' : '',
! $value['count'] ? 'empty-term' : '',
esc_attr( strtolower( $value['value'] ) ),
esc_attr( strtolower( $value['value'] ) ),
$item['is_selected'] ? 'selected' : '',
! $item['count'] ? 'empty-term' : '',
esc_attr( strtolower( $item['value'] ) ),
esc_attr( strtolower( $item['value'] ) ),
$link
);

Expand All @@ -258,11 +258,11 @@ public function get_meta_value_html( array $value, string $url ) : string {
* @since 4.3.0
* @hook ep_facet_meta_value_html
* @param {string} $html Facet meta value HTML.
* @param {array} $value Value array. It contains `value`, `name`, `count`, and `is_selected`.
* @param {array} $item Value array. It contains `value`, `name`, `count`, and `is_selected`.
* @param {string} $url Filter URL.
* @return {string} Individual facet meta value HTML.
*/
return apply_filters( 'ep_facet_meta_value_html', $html, $value, $url );
return apply_filters( 'ep_facet_meta_value_html', $html, $item, $url );
}

/**
Expand Down Expand Up @@ -309,31 +309,15 @@ protected function get_selected_meta() : array {
}

/**
* Given an array of values, reorder them.
* DEPRECATED. Get the markup for an individual facet item.
*
* @param array $values Multidimensional array of values. Each value should have (string) `name`, (int) `count`, and (bool) `is_selected`.
* @param string $orderby Key to be used to order.
* @param string $order ASC or DESC.
* @return array
* @param array $value Value.
* @param string $url Filter URL.
* @return string HTML for an individual facet term.
*/
protected function order_values( array $values, string $orderby = 'count', $order = 'desc' ) : array {
$orderby = strtolower( $orderby );
$orderby = in_array( $orderby, [ 'name', 'count' ], true ) ? $orderby : 'count';

$order = strtoupper( $order );
$order = in_array( $order, [ 'ASC', 'DESC' ], true ) ? $order : 'DESC';

$values = wp_list_sort( $values, $orderby, $order, true );

$selected = [];
foreach ( $values as $key => $value ) {
if ( $value['is_selected'] ) {
$selected[ $key ] = $value;
unset( $values[ $key ] );
}
}
$values = $selected + $values;
public function get_meta_value_html( array $value, string $url ) : string {
_deprecated_function( __METHOD__, '4.7.0', '\ElasticPress\Feature\Facets\Types\Meta\Renderer::get_facet_item_value_html()' );

return $values;
return $this->get_facet_item_value_html( $value, $url );
}
}

0 comments on commit 93d8ead

Please sign in to comment.