如何根据其他选择的值过滤选择结果

时间:2016-06-02 15:11:45

标签: php ajax wordpress advanced-custom-fields

在我的WordPress主题中,我有一个名为Segments的自定义帖子类型,其中包含两个使用ACF制作的自定义字段。我想要实现的是根据第一个字段的值进行第二个字段的搜索。

第一个被称为emission,该字段的类型是一个分类,它将Segment帖子与排放分类法联系起来。

第二个被称为剧集,该字段的类型是一个post_object,它将Segment帖子链接到剧集帖子类型。

现在,我想要的是第二个字段,用于过滤与第一个字段的选定值具有相同发射的剧集。

我遇到的问题是,在没有保存细分的情况下,我无法获得第一个字段的值。以下是我尝试过的内容:

add_filter('acf/fields/post_object/query/key=field_57503ed5193d6', array($this, 'show_episodes'), 10, 3);

/*
* Function to show episodes that are from the same program as the current segment.
*/
public function show_episodes($args, $field, $post_id){
    error_log('Post Id: ' . $post_id);
    error_log(json_encode(get_field_object('emission')));
    error_log(json_encode(get_field('emission', $post_id)));

    return $args;
}

当我为已经保存的段调用它时,它会返回保存的排放值,这是合乎逻辑的,因为它是保存在数据库中的值。当我为新段调用它时,它没有工作,因为它没有保存在数据库中的值,因此,它返回null。每当我编辑已保存段的排放值时,它仍会返回旧的排放值(数据库中的排放值)。

1 个答案:

答案 0 :(得分:0)

我已经能够使用Ajax和PHP会话实现结果。这就是我的所作所为:

的Javascript

// The id of the emission field generated by ACF
this.emissionField = $('#acf-field_57473a3f32f6d-input');

if(this.emissionField.length){
    let programId = this.emissionField.val();

    // Update the program id on page load if it's not empty, otherwise hide the emission box
    if(programId != ""){
        this.updateEpisodeFilter(this.emissionField.val());
    }else if(this.episodeBox.length) this.episodeBox.hide();

    // Update the program id when the emission change
    this.emissionField.on('change', function(){
        // Clear the select on value change
        $('#s2id_acf-field_57503ed5193d6-input').select2('val', '');

        this.updateEpisodeFilter(this.emissionField.val());
    }.bind(this));
}

/*
* Function to update the program id in the session.
*/
updateEpisodeFilter(programId){
    let episodeBox = this.episodeBox;

    $.ajax({
        url: '/wp-admin/admin-ajax.php',
        type: 'POST', 
        data:{
            action: 'update_filter_episodes',
            postId: $('#post_ID').val(),
            programId: programId,
        },
        success: function(response){
            if(response && episodeBox.length) episodeBox.show();
        }
    });
}

PHP

// Add the action hook for the Ajax
add_action('wp_ajax_update_filter_episodes', 'update_filter_episodes');
add_action('wp_ajax_admin_update_filter_episodes', 'update_filter_episodes');

因此,当我们通过Ajax收到动作filter_episodes时,它会调用PHP函数update_filter_episodes

/*
* Function to update the program id for the episodes filter.
*/
public function update_filter_episodes(){
    $this->startSession();
    if(isset($_POST['postId']) && isset($_POST['programId'])){
        $_SESSION['post-' . $_POST['postId'] . '-emission-id'] = $_POST['programId'];
        wp_send_json(true);
    }
    wp_send_json(false);
}

startSession函数检查会话是否已经启动:

/*
* Function to start the session if it's not already started.
*/
protected function startSession(){
    if(session_status() != PHP_SESSION_ACTIVE)
        @session_start();
}

要更新ACF调用的查询,我们需要另一个调用函数show_episodes的钩子:

add_filter('acf/fields/post_object/query/key=field_57503ed5193d6', 'show_episodes', 10, 3);

/*
* Function to show episodes that are from the same show as the current segment.
*/
public function show_episodes($args, $field, $post_id){
    $this->startSession();

    $index = 'post-' . $post_id . '-emission-id';
    if(isset($_SESSION[$index]) && !empty($_SESSION[$index]))
        $args['tax_query'] = array(array('taxonomy' => 'category', 'terms' => $_SESSION[$index]));

    return $args;
}

不确定这是否是最简单的方法,但它对我有用。但是,如果有人有更好的解决方案,请随时告诉我!