Home » Php » php – Advanced Custom Fields display last three sub-repeater rows

php – Advanced Custom Fields display last three sub-repeater rows

Posted by: admin July 12, 2020 Leave a comment

Questions:

I am using Advanced Custom Fields (ACF) to pull repeater information from an events page and displaying a shortened list of the events on the home page.

I have set up a repeater to allow the user to input which month the event will take place in(Allowing them to put in multiple months of events), then a sub-repeater to allow them to add multiple events for the given month. Example below:

March

  • March 9th event
  • March 12th event
  • March 28th event

April

  • April 1st event
  • April 28th event

This is the current output on the events page, and it works as intended.

On the home page of the website, I need to pull the 3 newest(the event that is at the bottom of the list is the newest event) events and display them on the home page.

I am not having an issue with pulling and displaying the events on the home page. What I am having a problem with is displaying the events when the last three events(the child repeater) cross between months(the parent repeater).

Simply limiting the event output using a php loop across the if, while, statements only limits the number of events output in that month. My code I’m currently using on the home page, is below.

<?php if( have_rows('event_month', 1263)): ?>
<ul>
    <?php while ( have_rows('event_month', 1263) ) : the_row(); ?>
        <?php if( have_rows('event', 1263)):;   ?>
            <?php while ( have_rows('event', 1263) ) : the_row(); ?>
                <li>
                    <h3>
                        <a href="<?php echo esc_url( home_url( '/' ) ); ?>events/"><?php $summary = get_sub_field('event_title');
                            echo substr($summary, 0, 34),'...'; ?></a>
                            <span><?php the_sub_field('event_day_of_week');?>, <?php the_sub_field('event_sub_month');?> <?php the_sub_field('event_day');?></span>
                    </h3>
                </li>
            <?php endwhile; ?>
        <?php else: ?>
            <p>Show dates to be announced soon.</p><?php the_sub_field('event_title'); ?>
        <?php endif; ?>
    <?php endwhile; ?>
</ul>

What my desired output on the home page would look like if we capture the three latest events:

  • March 28th event
  • April 1st event
  • April 28th event
How to&Answers:

Probably you should be using for instead of while. And consider the following algorithm:

1) Get the last row from event_month

2) Count the number of events in that month

3) If the number of events are more than or equal to 3.

  3.1) Get last 3 events and display them

4) Else count the number of remaing events (3-<<events in last month>>)

  4.1) Now get the second last row and repeat steps 2,3,4

So using the above logic your code should look something like:

<?php 

function getEvents($rows, $noOfEvents){
    $resultArray = array();
    if($rows && count($rows > 0)) {
        $events = $rows[count($rows)-1]['event'];
        $events = is_array($events) ? $events : array();
        $eventCount = count($events);
        if($eventCount < $noOfEvents){
            $noOfOtherEvents = $noOfEvents-$eventCount;
            array_pop($rows);
            $iterate = getEvents($rows,$noOfOtherEvents);
            $resultArray = array_merge($events,$iterate);     
        }
        else{
            $resultArray =  array_slice($rows, 0-$eventCount, $eventCount);
        }
        return $resultArray;
}

$rows = get_field('event_month', 1263);
if($rows) {
    $requiredEvents = getEvents($rows,3);        //3 or how many ever last you want
    foreach($requiredEvents as $event){
        var_dump($event); //this should have all you need like $event['event_title'],$event['event_day'],ect... 
    }
}

Answer:

This may not be the answer that everyone was looking for on this one, but here’s what I did as a work-around, which worked well enough for me.

I ended up resolving the issue outside of php, using css to select the last three list items. Here is what I used, worked great.

.connect-list-wrapper ul li
{
    display: none;
}
.connect-list-wrapper ul li:nth-last-child(-n+3) 
{
    display: block;
}