Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Example usage:
- *
- * new CustomReviewFilters([
- * // Add a custom filter for some child categories
- * 'filter_by_food' => [ // filter name (must start with "filter_by_")
- * 'parent_term' => 'foods', // parent category ID or slug (must be a Site Reviews category!)
- * 'placeholder' => 'All Foods', // dropdown placeholder
- * 'type' => 'term', // type of filter (term or custom)
- * ],
- * // Add a custom filter for a custom field named "surcharge"
- * 'filter_by_surcharge' => [ // filter name (must start with "filter_by_")
- * 'cast' => 'string', // What to cast the value as (string or int)
- * 'type' => 'custom', // type of filter (term or custom)
- * 'placeholder' => 'Any Surcharge', // dropdown placeholder
- * 'options' => [ // dropdown options
- * 'Yes' => 'Surcharge: Yes',
- * 'No' => 'Surcharge: No',
- * ],
- * ],
- * ]);
- *
- */
- class CustomReviewFilters
- {
- public $filters = [];
- public function __construct(array $filters = [])
- {
- add_action('init', function () use ($filters) {
- if (!function_exists('glsr')
- || !function_exists('glsr_get')
- || !glsr()->addon('site-reviews-filters')
- || !class_exists('\GeminiLabs\SiteReviews\Addon\Filters\Defaults\FilteredDefaults')) {
- return;
- }
- $this->filters = $this->normalize($filters);
- foreach ($this->filters as $filter => $values) {
- if ('custom' === $values['type']) {
- add_action('site-reviews-filters/sql-and/build/'.$filter, [$this, 'filterSqlAndForCustom'], 10, 3);
- add_action('site-reviews-filters/sql-join/build/'.$filter, [$this, 'filterSqlJoinForCustom'], 10, 3);
- }
- }
- add_filter('site-reviews-filters/defaults/filtered/defaults', [$this, 'filterDefaults']);
- add_filter('site-reviews-filters/defaults/filtered/casts', [$this, 'filterCasts']);
- add_filter('site-reviews-filters/config/forms/filters-form', [$this, 'filterConfig']);
- add_filter('site-reviews-filters/status/filtered-by', [$this, 'filterFilteredBy'], 10, 2);
- add_filter('site-reviews/shortcode/atts', [$this, 'filterShortcodeAttributes'], 10, 3);
- });
- }
- public function filterDefaults(array $defaults)
- {
- foreach ($this->filters as $filter => $values) {
- $defaults[$filter] = '';
- }
- return $defaults;
- }
- public function filterCasts(array $casts)
- {
- foreach ($this->filters as $filter => $values) {
- $casts[$filter] = glsr_get($values, 'cast', 'string');
- }
- return $casts;
- }
- public function filterConfig(array $config)
- {
- foreach ($this->filters as $filter => $values) {
- $config[$filter] = [
- 'options' => ['' => $values['placeholder']] + $values['options'],
- 'type' => 'select',
- 'value' => filter_input(INPUT_GET, $filter, FILTER_SANITIZE_FULL_SPECIAL_CHARS),
- ];
- }
- return $config;
- }
- public function filterFilteredBy(array $filteredBy, array $filters)
- {
- foreach ($filters as $filter => $value) {
- if (array_key_exists($filter, $this->filters)) {
- $filteredBy[] = $this->filters[$filter]['name'] ?? $this->filters[$filter]['options'][$value] ?? $value;
- }
- }
- return $filteredBy;
- }
- public function filterShortcodeAttributes(array $attributes, $type, $shortcode)
- {
- if ('site_reviews' !== $shortcode) {
- return $attributes;
- }
- $parameters = glsr('Addon\Filters\Defaults\FilteredDefaults')->merge();
- $terms = [$attributes['assigned_terms'] ?? ''];
- foreach ($this->filters as $filter => $values) {
- if ('term' === $values['type'] && !empty($parameters[$filter])) {
- $terms[] = $parameters[$filter];
- }
- }
- $attributes['assigned_terms'] = implode(',', $terms);
- return $attributes;
- }
- public function filterSqlAndForCustom($value, $key, $modifier)
- {
- $tablekey = str_replace('filters/', '', $key);
- $metakey = str_replace('filters/filter_by_', '_custom_', $key);
- $modifier->values[$key] = sprintf("AND (%s.meta_key = '%s' AND %s.meta_value = '%s')", $tablekey, $metakey, $tablekey, $value);
- }
- public function filterSqlJoinForCustom($value, $key, $modifier)
- {
- global $wpdb;
- $tablekey = str_replace('filters/', '', $key);
- $modifier->values[$key] = "INNER JOIN {$wpdb->posts} AS p ON r.review_id = p.ID";
- $modifier->values[$key] = sprintf("INNER JOIN {$wpdb->postmeta} AS %s ON r.review_id = %s.post_id", $tablekey, $tablekey);
- }
- public function normalize(array $filters)
- {
- $normalized = [];
- foreach ($filters as $filter => $values) {
- $filter = sanitize_key($filter);
- if (!str_starts_with($filter, 'filter_by_')) {
- continue;
- }
- $values = wp_parse_args($values, [
- 'cast' => '',
- 'name' => null,
- 'options' => [],
- 'parent_term' => '',
- 'placeholder' => '',
- 'type' => '',
- ]);
- if ('custom' === $values['type']) {
- $normalized[$filter] = $this->normalizeCustomFilter($values);
- } elseif ('term' === $values['type']) {
- $term = term_exists($values['parent_term'], glsr()->taxonomy);
- if (!empty($term)) {
- $normalized[$filter] = $this->normalizeTermFilter($values, $term['term_id']);
- }
- }
- }
- return $normalized;
- }
- protected function normalizeCustomFilter(array $values)
- {
- $values['options'] = is_array($values['options']) ? $values['options'] : [];
- return $values;
- }
- protected function normalizeTermFilter(array $values, int $termId)
- {
- $values['cast'] = 'int';
- $values['options'] = get_terms([
- 'count' => false,
- 'fields' => 'id=>name',
- 'hide_empty' => true,
- 'parent' => $termId,
- 'taxonomy' => glsr()->taxonomy,
- ]);
- $values['parent_term'] = $termId;
- return $values;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement