在我的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
。每当我编辑已保存段的排放值时,它仍会返回旧的排放值(数据库中的排放值)。
答案 0 :(得分:0)
我已经能够使用Ajax和PHP会话实现结果。这就是我的所作所为:
// 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();
}
});
}
// 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;
}
不确定这是否是最简单的方法,但它对我有用。但是,如果有人有更好的解决方案,请随时告诉我!