Wordpress meta_query 过滤事件

问题描述 投票:0回答:1

我的事件发布类型有两个不同的元字段 age_fromage_to

现在我想根据选择框中的年龄跨度过滤事件。规则是,age_from - age_to 范围内的至少一个年龄必须与选择框中的范围相匹配。 Eventa 的年龄从最小 6 岁到最大 25 岁不等。

过滤器中的跨度: 6-8 9-12 13-18日 19-25

示例 age_from=8 且 age_to=17

的事件

选择框选择9-12岁

事件应该显示。

任何有关 meta_query 设计的建议都将受到高度赞赏。

protected function pre_get_posts( WP_Query $query ) {
    $existing_rules = (array) $query->get( 'meta_query' );
    $values         = (array) $this->currentValue;

    preg_match_all('!\d+!', $this->currentValue[0], $ages);
    
    $age_from = $ages[0][0];
    $age_to = $ages[0][1];

    write_log( $values );

        $new_rules[] = array(
            
            'relation' => 'OR',
            
            array (             
                'key'     => $this->age_from,
                'value'   => [$age_from, $age_to],
                'compare' => 'BETWEEN',
            ),
            array (             
                'key'     => $this->age_to,
                'value'   => [$age_from, $age_to],
                'compare' => 'BETWEEN',
            )
        );
    
    $relationship = apply_filters( 'tribe_events_filter_additional_fields_relationship', 'AND' );

    $nest = apply_filters( 'tribe_events_filter_additional_fields_nest_meta_queries',
        version_compare( $GLOBALS['wp_version'], '4.1', '>=' )
    );
    
    if ( $nest ) {
        $new_rules = array(
            __CLASS__ => $new_rules,
        );
    }

    $meta_query = array_merge_recursive( $existing_rules, $new_rules );
    
    if ( ! empty( $relationship ) && $nest ) {
        $meta_query[ __CLASS__ ][ 'relation' ] = $relationship;
    } elseif ( ! empty( $relationship ) ) {
        $meta_query[ 'relation' ] = $relationship;
    }

    write_log( $meta_query );

    $query->set( 'meta_query', $meta_query );
    
}
wordpress meta-query
1个回答
0
投票

我无法评论查询条件周围的代码,但让我们在接触代码之前先看看条件逻辑:

1 2 3 4 5 6 7 8 9
      +-----+     Event
    +-----+       Filter 1
        +---+     Filter 2
            +---+ Filter 3
+---------------+ Filter 4

上面描述了您的过滤范围应与事件匹配的 4 种情况:

  1. 当过滤器开始之前,但在事件范围内结束时。
  2. 当过滤器在事件范围内开始和结束时。
  3. 当过滤器在事件范围内、和之后启动时。
  4. 当过滤器在事件范围之前开始并在事件范围之后结束时。

这里有 2 条规则适用于上述所有情况:

  • 过滤器的开始位置低于(或等于)事件的结束位置。
  • 过滤器的结束位置高于(或等于)事件的结束位置。

让我们采用这两条规则,看看它们是否适用于我们期望不在事件范围内的过滤器:

1 2 3 4 5 6 7 8 9
      +-----+     Event
  +-+             Filter 5
              +-+ Filter 6

过滤器 5 不匹配,因为它的结束位置在事件的开始位置之前。 过滤器 6 不匹配,因为它的开始位置在事件的结束位置之后。

所以我们可以用它来进行查询:

WHERE [filter end] >= [event start]AND [filter start] <= [event end] 

或者,交换变量:

WHERE [event start] <= [filter end] AND [event end] >= [filter start]

转化为您的

WP_Query
标准:

        $new_rules[] = array(
            
            'relation' => 'AND',
            
            array (             
                'key'     => $this->age_from,
                'value'   => $age_to,
                'compare' => '<=',
            ),
            array (             
                'key'     => $this->age_to,
                'value'   => $age_from,
                'compare' => '>=',
            )
        );
© www.soinside.com 2019 - 2024. All rights reserved.