计算 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 '&lt;pre&gt;'.print_r($songs,1).'&lt;/pre&gt;';。这将告诉您是否有任何数据,以及采用什么格式。如果您没有任何数据,请在 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 字段

如何在页面模板中将ACF关系帖子显示为循环

根据 ACF 关系字段显示“相关帖子”

每页 ACF 关系字段帖子

按关系字段 (ACF) 的 Elementor 帖子的自定义查询过滤器

获取(并显示)与 ACF 关系字段匹配的其他帖子