Offset PHP array results - php

I am looking to offset a group of PHP array results to create multiple rows of data.
For example, the first row will contain the first four array results, with the second row displaying results 5-8 and the third row containing results 9-12.
Currently, I am printing out all 12 in one list, however I'd like a bit more display control (i.e. ordering the results into columns which I can style independent of each), hence why I'd like to offset the results.
My current PHP is below:
<?php
if (empty($tmdb_cast['cast'])) {
} else {?>
<section class="cast">
<p class="title">Cast</p>
<ul class="section_body"><?php
foreach($tmdb_cast['cast'] as $key => $castMember){
if ($key < 12) {?>
<li class="actor_instance clearfix"><?php
if ($castMember['profile_path'] != '') {?>
<img src="http://cf2.imgobject.com/t/p/w45<?php echo $castMember['profile_path']; ?>" class="actor_image pull-left" alt="<?php echo $castMember['name']; ?>" title="<?php echo $castMember['name']; ?>" /><?php
} else {?>
<img src="assets/images/castpic_unavailable.png" class="actor_image pull-left" alt="No image available" title="No image available" /><?php
}?>
<p class="actor"><?php echo $castMember['character']; ?> - <?php echo $castMember['name']; ?></p>
</li><?php
}
}?>
<div class="morecast pull-right">[...view all cast]</div>
</ul>
</section><?php
}?>
P.S. Apologies for how I've formatted the code in the above block - I'm still not 100% sure how to make it look "nice" on StackOverflow.

Use array_chunk to break a single dimension array into a 2D array. Then you can loop through each chunk, and then each result, to get that "offset" effect between them.
$chunks = array_chunk($tmdb_cast['cast'], 4); // 4 here, is the number you want each group to have
foreach($chunks as $key => $chunk)
{
foreach($chunk as $castMember)
{
//display castMember here
}
// add code between groups of 4 cast members here
}

First: mixing php and html this way is a very bad habbit... one day you will have to maintain your code and that day you will vomit all over your desk because you mixed different languages in one file...
That being said..
and without creating a new array:
foreach($tmdb_cast['cast'] as $key => $castMember)
{
if ($key < 12)
{
// your code goes here
// if key is 3, or 7 the code below will close the listcontainer and open a new one...
if( ($key+1)%4 == 0 AND $key <11)
echo '</ul> <ul class="section_body">';
}
}
Also replace this:
if (empty($tmdb_cast['cast']))
{
}
else {
with this:
if (!empty($tmdb_cast['cast']))
{

I'm not entirely sure what you're looking for but here's how I would format your code. Alternative syntax for 'if' is a little more readable, and the use of for loops instead of a foreach will give you the control over row numbers you say you're looking for.
<?php if( ! empty($tmdb_cast['cast'])): ?>
<section class="cast">
<p class="title">Cast</p>
<ul class="section_body">
<?php
for($i = 0; $i < 12; $i++):
$castMember = $tmdb_cast['cast'][$i];
?>
<li class="actor_instance clearfix">
<?php if($castMember['profile_path'] != ''): ?>
<img src="http://cf2.imgobject.com/t/p/w45<?php echo $castMember['profile_path']; ?>" class="actor_image pull-left" alt="<?php echo $castMember['name']; ?>" title="<?php echo $castMember['name']; ?>" />
<?php else: ?>
<img src="assets/images/castpic_unavailable.png" class="actor_image pull-left" alt="No image available" title="No image available" />
<?php endif; ?>
<p class="actor"><?php echo $castMember['character']; ?> - <?php echo $castMember['name']; ?></p>
</li>
<?php endfor; ?>
<div class="morecast pull-right">[...view all cast]</div>
</ul>
</section>
<?php endif; ?>

Related

Combining php loop and count - Wordpress ACF

I wondered if anyone could help me combine two blocks of code I have. I have one block looping though items and the start of another block showing a count and hopefully enabling me to display the items looping through in rows by adding a div around them every two items... Heres the first bit of code, the loop:
<?php if(get_field('areas')): ?>
<?php while(has_sub_field('areas')): ?>
<div class="single-area-item six columns">
<p> <img src="<?php the_sub_field('area_icon'); ?>" style="width:100%;"> <p>
<h4> <?php the_sub_field('area_title'); ?> </h4>
<p> <?php the_sub_field('area_info'); ?> <p>
</div>
<?php endwhile; ?>
<?php endif; ?>
I'm using Advance Custom Fields for Wordpress and this is pulling through repeater fields... this displays them just one after the other.
Here's the code I have found to hopefully display them in rows.
<?php
$num = 1;
foreach ( $terms as $term ) {
if($num%2) {
echo '<div class="area-row">';
}
// Other Code
if($num %2) {
echo '</div>';
}
$num++
}
?>
I would like to display them in rows of two...
ONE TWO
THREE FOUR
FIVE SIX
Etc...
So, Im guessing I need to combine the code somehow... I currently have this: but it doesn't seem to work:
<?php
$num = 1;
foreach ( $terms as $term ) {
if($num%2) {
echo '<div class="area-row">';
}
if(get_field('areas')): ?>
<?php while(has_sub_field('areas')): ?>
<div class="single-area-item six columns">
<p> <img src="<?php the_sub_field('area_icon'); ?>" style="width:100%;"> <p>
<h4> <?php the_sub_field('area_title'); ?> </h4>
<p> <?php the_sub_field('area_info'); ?> <p>
</div>
<?php endwhile; ?>
<?php endif; ?>
if($num %2) {
echo '</div>';
}
$num++
}
?>
Okay so it looks like there was a couple of simple issues with this, you had closed the php tag after your if statment and then continued to write php without reopening the php tags. Also there is a slight logic error with the if($num%2) statements as one of these needs to be if, the other needs to be if not, so that the alternate.
Give this code a try and let me know how you get on:
<?php
if(get_field('areas')):
$num = 1;
?>
<?php while(has_sub_field('areas')):
if($num%2) {
echo '<div class="area-row">';
} ?>
<div class="single-area-item six columns">
<p> <img src="<?php the_sub_field('area_icon'); ?>" style="width:100%;"> <p>
<h4> <?php the_sub_field('area_title'); ?> </h4>
<p> <?php the_sub_field('area_info'); ?> <p>
</div>
<?php
if(!$num%2) {
echo '</div>';
}
$num++
endwhile; ?>
<?php endif; ?>
The main reason behind this question was for me to be able to target the third item of the looped through items, as it had padding on it that was breaking the rows that I needed to remove.
I have since found another solution that seems to be working.
By using the nth-child element, I have been able to target and remove the padding on every third item that's looped through - fixing the issue.
.single-area-item:nth-child(3n+3) {
margin-left: 0;
}
This is for rows or 2 items, if it were rows of 3 or 4 then it would need to target every 4th or 5th item respectively.

Pagination in php using div and bootstrap

I'm trying to implement a simple pagination using PHP and Twitter Bootstrap but got stuck.
Everything seems to work fine the only problem is my div's are floating all around leaving some empty spaces in the page like in this picture:
Below is my code:
<?php foreach($tester as $data): ?>
<div class="col-sm-2">
<img src="" width="150" height="150"/>
<br>
<span><?php echo $data['Description'];?></span><br>
<span><?php echo $data['Unit_Price'];?></span><br>
<span>In Stock:<?php echo $data['Qty'];?></span><br>
<span>Arriving Soon:<?php echo $data['In_Transit'];?></span><br>
<span>Show All Products In:<?php echo $data['P_Class_Name'];?></span>
</div>
<?php endforeach;?>
Put class="clearfix" div after each 6 elements to create non float sensitive line break
<?php $i=0; foreach($tester as $data): $i++; ?>
<div class="col-sm-2">
<img src="" width="150" height="150"/>
<br>
<span><?php echo $data['Description'];?></span><br>
<span><?php echo $data['Unit_Price'];?></span><br>
<span>In Stock:<?php echo $data['Qty'];?></span><br>
<span>Arriving Soon:<?php echo $data['In_Transit'];?></span><br>
<span>Show All Products In:<?php echo $data['P_Class_Name'];?></span>
</div>
<?php if ($i % 6 == 0) { ?><div class="clearfix"><?php } ?>
<?php endforeach;?>
However, this solution shouldn't be used if you need a different number of elements to displayed per row for a different viewpoint size.

Two items per foreach loop

Apologies if this has already been asked (I cannot find an answer) but I am using PHP and I am building a slider, but would like two images per slide, not one. So, in theory the foreach() needs to include two per each.
An example of the setup is as follows:
<?php foreach ($page->images as $image) : ?>
<img src="<?php echo $image->url; ?>"/>
<?php endforeach; ?>
I was thinking I could do something like a count...
<?php $index = 0; foreach ($page->images as $image) : ?>
<img src="<?php echo $image->url; ?>"/>
<?php $index++; ?>
<?php if ( $index % 2 == 0 && $index !=count($page->images) ) : ?>
<li></li>
<?php endif; ?>
<?php endforeach; ?>
But I got a little confused as this would insert something every 2... not include two of whatever the foreach loop is fetching at once.
Hope this makes sense and thanks in advance
Why so complicated? Use a simple for loop instead:
<?php for ($i=0; $i<count($page->images)-1; $i+=2) { ?>
<img src="<?php echo $page->images[$i]->url; ?>"/>
<img src="<?php echo $page->images[$i+1]->url; ?>"/>
<?php } ?>
Or even more elegant, a do/while loop:
<?php $i=0; do { ?>
<img src="<?php echo $page->images[$i++]->url; ?>"/>
<img src="<?php echo $page->images[$i++]->url; ?>"/>
<?php } while ($i<count($page->images)) ?>
Compared to using a foreach loop these approaches have another advantage: you do not create copies of all objects. This can make a huge difference if those objects are non-trivial.
Okay, I managed to work this out... hopefully it will help.
<div class="each-slide">
<?php $index = 0; foreach ($page->images as $image) : ?>
<img src="<?php echo $image->url; ?>"/>
<?php $index++; ?>
<?php if ( $index % 2 == 0 && $index !=count($page->images) ) : ?>
</div><div class="each-slide">
<?php endif; ?>
<?php endforeach; ?>
</div>

For each wrap every 4 elements in a div using existing ¿counter?

i have to modify this code, to echo every 4 thumbs (extraimage) inside a div...
I searched on Stackoverflow but all answers talk about setting a counter, i want to avoid this (if possible) using a counter that is already counting the extraimages.. i think it most be as easy as a conditional
if counter extraimages==3 echo div.. but how do i go back to 0 ,, or maybe i am missunderstanding the way to do this..
This is the part of the code where the array is set and the for each is set.
<?php if($extraimagecount >0){?>
<?php foreach ($extraimage as $key=>$value){?>
<?php }?>
<?php }?>
<a href="<?php echo DATA_DIR."/".$id."/".$this->get_variable('firstimage');?>" >
<img src="<?php echo DATA_DIR."/".$id."/".$this->get_variable('firstimage');?>" class="minis"/>
</a>
<?php if($extraimagecount >0){
$rotate=1;
$tumppr=0;
?>
<?php foreach ($extraimage as $key=>$value){
$rotate=$rotate+1;
?>
<a href="<?php echo DATA_DIR."/".$id."/".$value['image'];?>" >
<img src="<?php echo DATA_DIR."/".$id."/t_".$value['image'];?>" class="minis"/>
</a>
<?php
if($rotate==8)
{
$rotate=0;
$tumppr=$tumppr+1;
?>
<?php
}
?>
<?php }?>
<?php }?>
</div>
<?php
$lftstr="";
$rgtstr="";
if($extraimagecount >0)
{
$extcnt=count($extraimage);
$extcntnew=$extcnt+1;
$extdivide=intval(($extcntnew/8));
$extmode=($extcntnew % 8);
for($i=0;$i<$extdivide;$i++) //************ For Right Arrow ***************/
{
?>
<div id="rgt_<?php echo $i;?>" class="rgt" <?php if($i >0 || $extmode ==0){?>style="display: none;"<?php }?> ><img class="rgtimg" src="images/rnext.png"></div>
<?php
$rgtstr=$rgtstr.$i.'_';
}
for($ii=1;$ii<$extdivide;$ii++) //************ For left Arrow ***************/
{
?>
<div id="lft_<?php echo $ii;?>" class="lft" style="display: none;" ><img class="lftimg" src="images/lnext.png"></div>
<?php
$lftstr=$lftstr.$ii.'_';
}
if($extmode >0)
{
?>
<div id="lft_<?php echo $extdivide;?>" class="lft" style="display: none;" ><img class="lftimg" src="images/lnext.png"></div>
<?php
$lftstr=$lftstr.$extdivide.'_';
}
}
?>
Its actually quite easy, use the % operator. a%b will return the remainder of a/b. heres how you use it
for($i=0;$i<9;$i++)
{
echo $i%3." ";
}
this will print out
0 1 2 0 1 2 0 1 2
You can then use this to create groups of 4 in your case.

Filtering out items using SimpleXML

Been looking around and am stumped. Basically I'm trying to filter out a result from an xml feed and hide it from displaying in the html output. I'm trying to find out the venue "Hornblower Cruises and Events" and if it exists, hide the whole , which is the parent of all the nodes.
Here's the URL: http://www.sandiegomagazine.com/goldstartest/rss3-exclude.php
Here's my code:
<?php
$myfeed = simplexml_load_file('https://www.goldstar.com/api/listings.xml?api_key=6d0d598c69dfecfcf028b0d2b3c9b693b606ad8c&postal_code=92101');
$i = 0;
foreach ($myfeed as $goldstar):
$title=$goldstar->headline_as_html;
$summary=$goldstar->summary_as_html;
$dates=$goldstar->upcoming_dates->event_date->date;
$ourprice=$goldstar->our_price_range;
$fullprice=$goldstar->full_price_range;
$img=$goldstar->image;
$link=$goldstar->link;
$venue_name=$goldstar->venue->name;
$venue_street=$goldstar->venue->address->street_address;
$venue_locality=$goldstar->venue->address->locality;
$venue_region=$goldstar->venue->address->region;
$venue_zip=$goldstar->venue->address->postal_code;
$venue_phone=$goldstar->venue->phone;
$category=$goldstar->category_list->category->name;
// if ($venue_name == 'Hornblower Cruises and Events'){
// unset($myfeed->event);
//echo $myfeed->asxml();
//}
if (++$i > 20) {
// stop after 10 loops
break;
}
?>
<html>
<head></head>
<body>
<div class="gs-item">
<div class="gs-itemcontent">
<h3 class="gs-cat"><?php echo $category; ?></h3>
<h2><?php echo $title; ?></h2>
<h4 class="gs-date">Date: <?php echo $dates; ?> <br/>For more show dates, click here</h4>
<img src="<?php echo $img; ?>" />
<p><?php echo $summary; ?></p>
<div id="gs-callout">
<span class="fullprice">Full Price: <?php echo $fullprice; ?></span>
<br/>
<span class="ourprice">Our Price: <span class="gs-hilite"><?php echo $ourprice; ?></span></span>
<p><a class="gs-button" href="<?php echo $link; ?>" target="_blank">Buy Tickets »</a></p>
</div>
<ul class="gs-venue">
<li><strong><?php echo $venue_name; ?></strong> | </li>
<li><?php echo $venue_street; ?></li>
<li><?php echo $venue_locality; ?>, <?php echo $venue_region; ?> <?php echo $venue_zip; ?></li>
<li><?php echo $venue_phone; ?></li>
</ul>
</div>
<div class="gs-clear"></div>
</div>
<? endforeach; ?>
</body>
Help?
Use a keyed foreach
foreach ($myfeed as $key => $goldstar):
And then unset the entire current xml using the key
unset($myfeed->$key);
Or unset just the venue with unset($myfeed->$key->venue);
Alternately, you could just build a new obj instead of trying to edit the existing one. Instantiate a new object before your loop and then only add the pieces to it that you want to keep.
Or, you can just continue the foreach if you find the unwanted venue. The only downside is that you won't have a copy of your ok'd list in $myfeed. So...
if ($venue_name == 'Hornblower Cruises and Events') { continue; }
Firstly you should cast every object that you are getting from your SimpleXML object to the relevant type. For example you should cast string attributes or nodes with putting (string) before reading the field:
$venue_name = (string)$goldstar->venue->name
For your question about filtering, I'd suggest your own way to keep looking for the match string and then decide to add or not.
EDIT
You're trying to see if the venue name is 'Hornblower Cruises and Events' then unset the current event field and echo it as XML? Firstly you should write unset($myfeed) because it's the event field itself. Next asxml would return nothing if you unset $myfeed. And you have HTML mistake in your code. In every loop of your for, you're writing:
<html>
<head></head>
<body>
You should place them before the for. And there is no closing tag for them. Put the closing tags after for. If you want to just get the fields with not venue name 'Hornblower Cruises and Events', put the <?php if($venue_name != 'Hornblower Cruises and Events') : ?> before <div class="gs-item"> and put <?php endif; ?> after </ul>.

Categories