2个pre_get_posts函数可按自定义字段

时间:2017-05-02 11:08:57

标签: wordpress advanced-custom-fields

编辑:查看最后一个(第三个)代码段,它是工作代码片段。

我有一个"行动" page(名为Actions的自定义帖子类型的存档),相当于" events"。

我使用this tutorial使用自定义字段过滤它们:ville(city),action(操作类型)和日期,它完美无缺。

然后我创建了另一个函数来过滤"日期范围":过去,未来的行动。它也有效。但他们会积累"。当我选择"过去"行动和城市,它向我显示所有过去的行动+在城市中发生或将要发生的所有行为。

所以这两个功能都有效,但我不知道如何设置他们与AND的关系或者让他们一起工作的东西而不是"积累"。

有人可以帮我解决这个问题吗?

谢谢。

按类型/城市/日期自定义字段过滤的功能:     

// array of filters (field key => field name)
$GLOBALS['my_query_filters'] = array( 
    'action'  => 'action', 
    'ville'   => 'ville', 
    'date'    => 'date',

);

// action
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);

function my_pre_get_posts( $query ) {

    // bail early if is in admin
    if( is_admin() ) return;

    // bail early if not main query
    // - allows custom code / plugins to continue working
    if( !$query->is_main_query() ) return;

    // get meta query
    $meta_query = $query->get('meta_query');

    // loop over filters
    foreach( $GLOBALS['my_query_filters'] as $key => $name ) {

        // continue if not found in url
        if( empty($_GET[ $name ]) ) {

            continue;

        }

        // get the value for this filter
        // eg: http://www.website.com/events?city=melbourne,sydney
        $value = explode(',', $_GET[ $name ]);


        // append meta query
        $meta_query[] = array(
            'key'       => $name,
            'value'     => $value,
            'compare'   => 'IN',
        );

    } 

    $query->set( 'orderby', array( 'date' => 'DESC' ) );

    // update meta query
    $query->set('meta_query', $meta_query);

    return;

}

?>

未来/过去行动的功能:

<?php

add_action('pre_get_posts', 'future_past_actions', 10, 1);

function future_past_actions( $query ) {

// bail early if is in admin
    if( is_admin() ) return;

    // bail early if not main query
    // - allows custom code / plugins to continue working
    if( !$query->is_main_query() ) return;

    // get meta query
    $meta_query = $query->get('meta_query');


    if( isset($_GET['range']) ) {

    $range = explode(',', $_GET['range']);

    $meta_query[] = array(
        'key'     => 'range',
        'value'   => $range,
        'compare' => 'IN',
        );


        if( $query->get( 'range' ) == 'future' ) {
             $meta_query[] = array(
             'key' => 'date',
             'value' => date("Ymd"),
             'compare' => '>',
            );
            $meta_query['relation'] = 'OR';
        }

        elseif( $query->get( 'range' ) == 'past' ) {
             $meta_query[] = array(
             'key' => 'date',
             'value' => date("Ymd"),
             'compare' => '<',
            );
            $meta_query['relation'] = 'OR';
        }

        elseif( $query->get( 'range' ) == 'toutes' ) {
           return;
        }

    }

    $query->set( 'meta_key', 'date' );
    $query->set( 'orderby', array( 'date' => 'DESC' ) );
    $query->set('meta_query', $meta_query);

    return;

    }

    ?>

最终合并和工作的代码:

 <?php
// array of filters (field key => field name)
        $GLOBALS['my_query_filters'] = array( 
            'action'    => 'action', 
            'ville'     => 'ville', 
            'date'      => 'date'
        );

add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);

function my_pre_get_posts( $query ) {

    // bail early if is in admin
    if( is_admin() ) return;

    // bail early if not main query
    // - allows custom code / plugins to continue working
    if( !$query->is_main_query() ) return;

    if( ! is_post_type_archive( 'actions' ) ) return;

     // CITY/TYPE/DATE filters
    // loop over filters
    foreach( $GLOBALS['my_query_filters'] as $key => $name ) {

        // continue if not found in url
        if( empty($_GET[ $name ]) ) { continue; }

        // get the value for this filter
        // eg: http://www.website.com/events?city=melbourne,sydney
        $value = explode(',', $_GET[ $name ]);

        // append meta query
        $meta_query[] = array(
            'key'       => $name,
            'value'     => $value,
            'compare'   => 'IN',  
        );
    }

        // FUTURE/PAST/ALL filters
    if( isset($_GET['range']) ) {

    $range = $_GET['range'];

      if($range != "toutes") {

          // Select what kind of compare you need
          if($range == "past") {
            $comparer = '<';
          } else if($range == "future") {
            $comparer = '>=';
          }

        // If you need to filter by date add this to meta_query array
        $meta_query[] = array(
            'key'     => 'date',
            'value'   => date("Ymd"),
            'compare' => $comparer,
            );
          }
       }

    // update meta query
    $query->set('meta_query', $meta_query);

    $query->set( 'meta_key', 'date' );
    $query->set( 'orderby', array( 'date' => 'DESC' ) );
    $query->set('posts_per_page', '20');

}

?>

1 个答案:

答案 0 :(得分:0)

在这种情况下,我认为最佳解决方案是在其中包含一个操作并检查查询参数,然后确定您要执行的逻辑类型。

$ query变量包含您指定的所有参数,因此您的代码可能如下所示:

根据对情况的评论进行编辑,您必须使用两个元字段之间的AND关系。代码内部操作应如下所示:

add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);

function my_pre_get_posts( $query ) {
  $meta_query = array(
    'relation' => 'AND',
    array(
        'key'     => 'ville',
        'value'   => '$value',
        'compare' => '=',
    )
  );

  // Select what kind of compare you need
  if($range == "past") {
    $compare = ">";
  } else if($range == "future") {
    $compare = "<";
  }
  if($range != "all") {
    // If you need to filter by date add this to meta_query array
    $date_query = array(
        'key'     => 'date',
        'value'   => 'date(\"Ymd\"),',
        'compare' => $compare,
    );
    $meta_query[] = $date_query;
  }
  $query->set( 'orderby', array( 'date' => 'DESC' ) );

  // update meta query
  $query->set('meta_query', $meta_query);
}

因为你现在所做的,所以你多次设置查询参数。 如果您需要更多参数来过滤掉,可以考虑使用哪种参数来有条件地将它们添加到$ meta_query变量。

我认为如果我理解正确,这种元查询应该返回所需的结果。