how to use php to exclude the last row in an array - php

I've been trying to read up on this in the manual, but basically I've got an array where I'm trying to reverse it and exclude the last item. So I got 14 items currently in my array and I'm getting it to reverse and it shows 14-2. My code got it to exclude the last item. So I guess it technically works, but I actually want it to output as 13-1. I tried using array_pop and array_shift but I didn't know how to integrate it with array_reverse.
function smile_gallery( $atts ) {
if( have_rows('smile_gallery', 3045) ):
$i = 1;
$html_out = '';
$html_out .= '<div class="smile-container">';
$html_out .= '<div class="fg-row row">';
// vars
$rows = get_field('smile_gallery', 3045);
$count = count( get_field('smile_gallery', 3045) );
$html_out .= '<div class="col-md-8">'; // col-md-offset-1
$html_out .= '<div class="smile-thumbs">';
foreach( array_reverse($rows) as $row) :
// vars
$week = "smile_week";
$img = "smile_img";
$caption = "smile_caption";
// Do stuff with each post here
if( $i < $count) :
$html_out .= '<div class="smile-thumb-container">';
$html_out .= '><h6>Week ' . $row["smile_week"] . '</h6></a>'; // smile thumb week
$html_out .= '</div>'; // smile thumb container
endif;
$i++;
endforeach;
$html_out .= '</div>';
$html_out .= '</div>';
$html_out .= '</div>';
$html_out .= '</div>'; // smile container
endif;
return $html_out;
}
add_shortcode( 'show_smiles', 'smile_gallery' );

I'm reading your question as the following, correct me if I'm wrong.
I've got an array where I'm trying to reverse it and exclude the first and last items.
To do that as you know you're want to use array_pop() and array_shift().
<?php
//
$rows = get_field('smile_gallery', 3045);
$count = count($rows);
array_pop($rows);
array_shift($rows);
foreach (array_reverse($rows) as $row):
...
If you want to reverse first and then do your operations, which is not required if your removing items from both ends. Take out array_reverse from the foreach and then do your manipulations.
<?php
// vars
$rows = get_field('smile_gallery', 3045);
$count = count($rows);
$rows = array_reverse($rows);
array_pop($rows);
array_shift($rows);
foreach ($rows as $row):
...
Let me know if that helps.

Related

How to remove the last comma of a Wordpress php foreach output?

I already tried some things with trim and so on but nothing works.
Maybe I made a mistake and you can help me? The code looks currently like that:
$post = get_post();
$terms = wp_get_post_terms($post->ID, 'genre');
if ($terms)
{
$output = '';
foreach ($terms as $term) {
$output .= '' . $term->name . ', ';
}
};
echo $output;
Try putting in substr_replace($term->name,"",-1), check documentation for more info, this should delete comma from last string.
just add a counter to check the last item of the array
$post = get_post();
$terms = wp_get_post_terms($post->ID, 'genre');
if ($terms)
{
$output = '';
$i = 0;
foreach ($terms as $term) {
$output .= '' . $term->name . ' ';
$output .= ($i == count($terms) - 1) ? '' : ',';
$i++;
}
};
echo $output;

Counting items in a PHP array_chunk

I have the below function which gets wordpress posts and outputs them in a bootstrap grid (3 posts per row). Each array chunk has 3 posts in it. Basically what I want to do is if the chunk is not complete and only has say 2 posts in it then the first post in that chunk gets "col-sm-offset-2" class added. I believe I need some way off counting the posts in the chunk but I'm not sure how to implement.
function post_events($atts) {
global $post;
$args = array(
'post_type' => 'event',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'ASC',
);
$posts = get_posts($args);
$posts_chunks = array_chunk($posts, 3);
$output = '';
foreach ($posts_chunks as $row) {
$output .= '<div class="row">';
foreach ($row as $post) {
setup_postdata($post);
$output .= '<div class="col-md-6 col-sm-6 event-item">';
$output .= '' .get_the_post_thumbnail(). '';
$output .= '<div class="event-item-text">';
$output .= '<h3>' .get_the_title(). '</h3>';
$output .= '<span class="event-date">' .get_the_date("d-m-Y"). '</span>';
$output .= '<p>' .wp_trim_words( get_the_content(), 40, '...' ). '</p>';
$output .= '</div>';
$output .= '</div>';
}
$output .= '</div>';
}
return $output;
}
add_shortcode('post_events','post_events');
You can just use count() on $row, and then set the class based on whether it's the first iteration or not:
$class = 'col-md-6 col-sm-6 event-item';
$count = count($row);
foreach( $row as $k => $post )
{
$cls = ($k == 0 && $count < 2) ? $class.' col-sm-offset-2' : $class;
setup_postdata($post);
$output.= '<div class="'.$cls.'">';
//...
}
Since you have chunked, the subarrays will be 0 based and the first post will be 0. So just check that and if the count is less than 3:
foreach ($posts_chunks as $row) {
$output .= '<div class="row">';
foreach ($row as $key => $post) {
$extra = ''; //set extra class to empty
if($key == 0 && count($row) < 3) { //check first post and count less than 3
$extra = 'col-sm-offset-2 '; //set extra class
}
setup_postdata($post);
//use $extra somewhere
$output .= '<div class="'.$extra.'col-md-6 col-sm-6 event-item">';
$output .= '' .get_the_post_thumbnail(). '';
$output .= '<div class="event-item-text">';
$output .= '<h3>' .get_the_title(). '</h3>';
$output .= '<span class="event-date">' .get_the_date("d-m-Y"). '</span>';
$output .= '<p>' .wp_trim_words( get_the_content(), 40, '...' ). '</p>';
$output .= '</div>';
$output .= '</div>';
}
$output .= '</div>';
}

ACF - how do you reverse the order of repeater rows?

I’m trying to sort the rows in the while so that they are 3,2,1 instead of 1,2,3. Would be dope if it could be sorted by $week as it returns a numerical value. I read the ACF page on sorting rows but given I already have some custom code in here to exclude the last row in the while I am not sure how to merge it all.
function smile_gallery( $atts ) {
if( have_rows('smile_gallery', 3045) ):
$i = 1;
$html_out = '';
$html_out .= '<div class="smile-container">';
// vars
$rows = get_field('smile_gallery', 3045);
$end_row = end($rows);
$recent = $end_row['smile_week'];
$count = count( get_field('smile_gallery', 3045) );
$html_out .= '<div class="col-md-6">';
$html_out .= '<div class="smile-recent">';
$html_out .= $recent;
$html_out .= '</div>';
$html_out .= '</div>';
$html_out .= '<div class="col-md-6">';
$html_out .= '<div class="smile-thumbs">';
while( have_rows('smile_gallery', 3045) ): the_row();
// vars
$week = get_sub_field('smile_week', 3045);
$img = get_sub_field('smile_img', 3045);
$caption = get_sub_field('smile_caption', 3045);
// Do stuff with each post here
if( $i < $count) :
// vars
$order = array();
$html_out .= '<div class="smile-thumb-container">';
$html_out .= '<div class="smile-thumb-img" style="background: url('. $img .') no-repeat center top; background-size: cover;">';
$html_out .= '</div>'; // smile thumb img
$html_out .= '<a class="smile-thumb-week" href="' . $img . '" data-lightbox="smile-set" ';
if ($caption) :
$html_out .= 'data-title="' . 'Week ' . $week . ' - ' . $caption . '"';
endif;
$html_out .= '><h6>Week ' . $week . '</h6></a>'; // smile thumb week
$html_out .= '</div>'; // smile thumb container
endif;
$i++;
endwhile;
$html_out .= '</div>';
$html_out .= '</div>';
$html_out .= '</div>'; // smile container
endif;
return $html_out;
}
add_shortcode( 'show_smiles', 'smile_gallery' );

php - foreach loop, custom slide

It should be a slider, which shows all posts, but only 15 posts on each slide. I get all Posts.
(I use Wordpress functions.)
In the -div class = "slide"- there are 15 posts, after that a new -div class = "slide"- with 15 posts should be created.
Here is the code for all posts:
$myposts = get_posts($args);
$result = '<div id="fullpage">';
$result .= '<div class="section" id="section1">';
$result .= '<div class="slide">';
foreach ($myposts as $post) {
$result .= '' . $post->post_title . '';
// the_post_thumbnail('full');
}
$result .= '</div>';
$result .= ' </div>';
$result .= '</div>';
return $result;
After 15 posts, I would like a new slide. I do not know how to adjust the foreach loop. Should I do this with an if statement, or can I do this with a foreach loop?
Use a counter, and reset it after 15. (Not tested, I have no PHP at the moment)
$counter = 1;
foreach ($myposts as $post) {
if ($counter == 1) {
$result .= '<div class="slide">';
}
$result .= '' . $post->post_title . '';
$counter++;
if ($counter == 16) {
$counter = 1;
$result .= '</div>';
}
}

HTML every nth iteration with a twist--the nth changes every xth time using array values

Everyone knows how to output a bit of html every nth iteration in a foreach loop.
$i=0;
foreach($info as $key){
if($i%3 == 0) {
echo $i > 0 ? "</div>" : ""; // close div if it's not the first
echo "<div>";
}
//do stuff
$i++;
}
I'm trying to do this same thing, but instead of a known value for $i, I'm pulling values in from an array like
Array(0=>2, 1=>1, 2=>5)
so that instead of
<div>
item
item
item
</div>
<div>
item
item
item
</div>
<div>
item
item
item
</div>
I can get something like this:
<div>
item
item
</div>
<div>
item
</div>
<div>
item
item
item
item
item
</div>
But I just can't get it to work. I think I'm close, but something's just escaping me. Any ideas?
Here's the code I'm running right now:
//$footnote = array of values
$i=0;
$m=0;
$bridge .= '<div class="grid block menu">';
foreach($value['sections'] as $section) {
if ($i++%$footnote[$m] === 0) {
$bridge .= '</div><div class="grid block menu">';
$m++;
}
$secname = $section['name'];
$dishcount = count($section['items']);
$bridge .= '<h3>'. $secname .' '.$footnote[0].'</h3>';
$i++;
} //end section foreach
$bridge .= '</div>';
I think the issue you're having is in the if($i++%...) section of your code.
Instead of incrementing $i and checking the result of the modular expression, just check if $i == $footnote[$m] and then reset $i back to 0 when it is a success.
I modified your script a little locally, try this out:
$i = $m = 0;
$bridge .= '<div class="grid block menu">';
foreach($value['sections'] as $section)
{
if ($i == $footnote[$m])
{
$bridge .= '</div><div class="grid block menu">';
$m++;
$i = 0;
}
$secname = $section['name'];
$dishcount = count($section['items']);
$bridge .= '<h3>'. $secname .' '.$footnote[$m].'</h3>';
$i++;
}
$bridge .= '</div>';
This way, you are actually iterating through each footnote instead of just checking to see if it is divisible by the number specified.
Untested code, let me know if any changes are necessary so I can update the answer appropriately.
// Calculate section breaks
$sections = [ 2, 1, 5];
$sectionBreaks = [];
$sum = 0;
foreach ($sections as $section) {
$sum += $section;
$sectionBreaks[] = $sum;
}
// Add the items to each section
$results = [];
$result = '';
$i = 0;
foreach ($items as $item) {
if (array_search($i, $sectionBreaks) !== false) {
$results[] = $result;
$result = '';
}
$result .= '<h3>' . $item . '</h3>';
}
// Collapse it all together
$finalResult = '<div>' . implode('</div><div>', $results) . '</div>';
This is the way to loop thru data in order to achieve the example you exposed at first. foreach and for. This works, but unless you give us some data to work with I wont be able to adjust it to it.
$bridge='';
foreach($value['sections'] as $section) {
$bridge .= '<div class="grid block menu" number="'.$section.'"><h3>MY TITLE!! '. $section['name'] .'</h3>';
for ($x = 0; $x <= $section; $x++) {
$bridge .= "Here goes the content; Item $x<br>";
}
$bridge .= '</div>';
}
echo $bridge;
I hope it helps :)

Categories