计算 ACF 中的关系帖子数
Posted
技术标签:
【中文标题】计算 ACF 中的关系帖子数【英文标题】:Count the number of relation posts in ACF 【发布时间】:2020-03-07 02:23:30 【问题描述】:我正在为一个乐队制作一个网站,您可以在其中添加演出并添加在该特定演出中播放的歌曲。
所以我创建了两种自定义帖子类型: - 演出 - 歌曲
我有一个“关系”类型的自定义字段“歌曲”。此字段显示在自定义帖子类型上。这样我就可以将歌曲添加到特定的演出中。这完美无缺。
但我想在该网站的主页上显示一些统计数据:我想计算一首特定歌曲的播放次数并显示前 10 名。所以我想我必须遍历 gig 自定义帖子类型和计算与“歌曲”的关系。
我认为这样可以解决问题:
<?php
$args = array(
'post_type' => 'gig'
);
?>
<?php $loop = new WP_Query($args); ?>
<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php
print_r(get_field('songs'))
//$song_count = count(get_field('songs'));
//echo $song_count . " ";
the_title();
?><br />
<?php endwhile; ?>
<?php else: ?>
<!-- No gigs available -->
<?php endif; ?>
<?php wp_reset_postdata(); ?>
你可以在这里找到 print_r 的结果:http://snippi.com/s/njzg3uu
例如:歌曲“A memory”在 2 场演出中。这就是为什么你可以在数组中找到它两次的原因。 “Wasted”这首歌只能找到一次,因为它在 1 场演出中。
【问题讨论】:
尝试var_dump(get_field('songs'))
看看你的领域到底有什么。
@Stender 我得到 NULL 结果。
好的,我越来越近了。我已经更改了循环中的帖子类型。我不必看歌曲,但要看演出。因为我必须检查一首歌在演出中出现了多少次。你可以在这里查看我的 var_dump 输出:snippi.com/s/njzg3uu 歌曲“A Memory”在 2 个演出中。所以你看到这首歌在数组中出现了两次。
@Stender 我最终想要实现的是播放次数最多的 10 首歌曲的列表。
【参考方案1】:
希望帮助:
<?php
$args = array(
'post_type' => 'song'
);
?>
<?php $loop = new WP_Query($args); ?>
<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php
$song_count = count(get_field('songs', get_the_ID())); <-- add
echo $song_count . " ";
the_title();
?><br />
<?php endwhile; ?>
<?php else: ?>
<!-- No gigs available -->
<?php endif; ?>
<?php wp_reset_postdata(); ?>
【讨论】:
嗨,Dmitry,结果仍然是 0。我也尝试过回显 "count:" 。 get_field('歌曲', get_the_ID());但这什么也没打印。 不,您必须循环播放 cpt 'gig' 而不是歌曲。因为您必须检查歌曲在演出中播放了多少次。【参考方案2】:我对您的问题的理解是,您正在寻求生成与演出相关的前 10 名歌曲列表。解决此问题的最佳方法是生成一个集合,该集合将映射一个唯一标识符和该歌曲被观看次数的计数值。
这是一个例子:
<?php
// Get all the posts
$gigs = get_posts([
'post_type' => 'gigs',
'numberposts' => -1
]);
// We will use this array to key a running tally of
$set = [];
// If the key doesn't exist yet on the array, then we will initialize it, otherwise, increment the count
function add_set_element(&$set, $key)
if (!isset($set[$key]))
$set[$key] = 1;
else
$set[$key]++;
function iterate_songs($songs, &$set)
/** @var WP_Post $song */
foreach($songs as $song)
$key = $song->post_title;// This can be what ever unique identifier you want to get from $song object, such as ID or title
add_set_element($set, $key);
foreach($gigs as $gig)
setup_postdata($gig);
$songs = get_the_field('songs');
iterate_songs($songs, $set);
之后,您可以对$set
变量进行排序和操作,但您认为可以从中获取所需的数据。
如果我误解了您的问题,请告诉我,我可以提供另一个答案。
【讨论】:
没错:我想显示在演出中播放次数最多的歌曲的前 x 列表(例如前 10 名列表)。我已经复制了你的代码并做了一个 var_dump($set) 这就是结果 array(0) 我已将 get_posts 查询 post_type 更改为 "gig",因为 "gigs" 不是 post_type :-) 但是我在这一行收到错误:$songs = get_the_field('songs ');致命错误:未捕获错误:调用未定义函数 get_the_field() 不是get_the_field()
。应该是get_field()
。这就是为什么您会遇到未定义函数的致命错误。
@Jarom 我已将其更改为 get_field,但在 iterate_songs() 函数中的 foreach 上出现错误。警告:为 foreach() 提供的参数无效
那很好。你现在又近了一步。您现在遇到的错误意味着底部 foreach 循环中的 $songs = get_field('songs')
行不是数组。它需要是一系列你的歌曲(你的关系)。在该行下方尝试echo '<pre>'.print_r($songs,1).'</pre>';
。这将告诉您是否有任何数据,以及采用什么格式。如果您没有任何数据,请在 CMS 中检查您的关系名称。如果你有数据,那么它是什么样的?在传递给 iterate_songs() 之前可能需要对其进行格式化。【参考方案3】:
你可以用简单而简短的方式做到这一点:
$args = array(
'post_type' => 'gig'
);
$gigs = get_posts($args);
$songsarr = array();
foreach($gigs as $gig)
$posts = get_field('songs', $gig->ID);
array_push($songsarr,$posts[0]);
//echo "<pre>;
//print_r($songsarr);
$countsongs = array_count_values($songsarr);
echo 'No. of Duplicate Items: '.count($countsongs).'<br><br>';
// print_r($countsongs);
foreach($countsongs as $songID => $songname)
echo get_the_title( $songID );
echo $songname;
我尝试过制作两个自定义帖子类型(演出、歌曲),我通过这种方式获得了歌曲的计数,您可以在主页中显示,也可以在最后一个 foreach 循环中给出条件如果歌曲不止一首等等。
希望对您有所帮助!
【讨论】:
【参考方案4】:您可以使用此代码创建所有歌曲的数组:
<?php
$args = array(
'post_type' => 'gig'
);
$countArray = []; //create an array where you can put all the song id's and the number of times played
?>
<?php $loop = new WP_Query($args); ?>
<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php
$posts = get_field('songs');
if( $posts ):
foreach( $posts as $post):
setup_postdata($post);
//if the song id already exists -> count + 1
if (array_key_exists($post->ID, $countArray))
$countArray[$post->ID]++;
else // otherwise the song is played 1 time
$countArray[$post->ID] = 1;
endforeach;
wp_reset_postdata();
endif;
?>
<?php endwhile; ?>
上面的代码将创建一个包含歌曲 ID 的数组以及它在 post_type "gig" 中的使用次数。
现在您可以使用数组$countArray
并使用它做任何您想做的事情。
在您的示例中,您要对其进行排序,因此您必须这样做 arsort($countArray);
这样数组按其值(播放次数)从高到低排序。
然后你必须循环遍历数组: foreach ($countArray as $key => $value) ?>
<?php echo get_post_permalink($key); //=the permalink of the song ?>
<?php echo get_the_title($key); //= the title of the song ?>
<?php echo $value; //number of times play in a gig ?>
<?php
所以完整的代码是:
<?php
$args = array(
'post_type' => 'gig'
);
$countArray = [];
?>
<?php $loop = new WP_Query($args); ?>
<?php if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
<?php
$posts = get_field('songs');
if( $posts ):
foreach( $posts as $post):
setup_postdata($post);
if (array_key_exists($post->ID, $countArray))
$countArray[$post->ID]++;
else
$countArray[$post->ID] = 1;
endforeach;
wp_reset_postdata();
endif;
?>
<?php endwhile; ?>
<?php
arsort($countArray);
foreach ($countArray as $key => $value)
?>
<?php echo get_post_permalink($key); //=the permalink of the song ?>
<?php echo get_the_title($key); //= the title of the song ?>
<?php echo $value; //number of times play in a gig ?>
<?php
?>
<?php else: ?>
<!-- No gigs available -->
<?php endif; ?>
<?php wp_reset_postdata(); ?>
【讨论】:
以上是关于计算 ACF 中的关系帖子数的主要内容,如果未能解决你的问题,请参考以下文章
在帖子创建期间计算 PHP date_diff 并保存到 ACF 字段