PHP foreach loop mark up - php

I have a PHP foreach loop which outputs a series of items.
What I want to achieve is some code (a div) wrapped around items 1 & 2 and also wrapped around 3 & the very last item.
Here is the PHP:
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<div class="<?php echo ($key%2) ? "odd" : "even"; ?> type<?php echo ucfirst($extraField->type); ?> group<?php echo $extraField->group; ?>">
<span class="itemExtraFieldsValue"><?php echo JHTML::_('content.prepare', $extraField->value); ?></span>
<div class="clearfix"></div>
</div>
<?php $counter++; endforeach; ?>
Any ideas on how I could achieve this?
Many thanks in advance.

Maybe something like this, forgive me my PHP is a bit rusty.
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<?php
$len = count($this->item->extra_fields);
if ($key == 1 || $key == 2 || $key == 3 || $key == len) {
echo "<div>";
}
?>
<div class="<?php echo ($key%2) ? "odd" : "even"; ?> type<?php echo ucfirst($extraField->type); ?> group<?php echo $extraField->group; ?>">
<span class="itemExtraFieldsValue"><?php echo JHTML::_('content.prepare', $extraField->value); ?></span>
<div class="clearfix"></div>
</div>
<?php
if ($key == 1 || $key == 2 || $key == 3 || $key == len) {
echo "</div>" ;
}
?>
<?php $counter++; endforeach; ?>
Might have to account for the length of the list, so your last check might be len + 1, and your first 3 checks might be (0, 1, and 2), it depends on what the $key value is.
It's a bit confusing what the $counter++ part of your code does in a foreach, perhaps you should be using that for your modulus and in place of the key.
Regardless it's difficult to code up a solution as I believe your code snippet is incomplete, and it would also be helpful to know what the data is that we are looping through and the intended output of just having the first 3 and the last item wrapped in a div.

Related

Conditions with PHP

I'm still pretty new to PHP and trying to figure out an issue I've found on our website at work. In the screenshot, the last div.image-group should be inside the div.image-row that only has two items in it — basically, I always want the div.image-group to be inside a div.image-row, which should hold at most three div.image-group's (but the first div.image-row might contain fewer).
Can anyone point me in the right direction to correct this?
Here's the code:
<?php $counter = 0; ?>
<?php foreach ($rows as $id => $row): ?>
<?php $counter++; ?>
<?php if ($counter % 3 == 1 || $counter === 1) { ?>
<div class="image-row small clearfix">
<?php } ?>
<div class="image-group"><?php print $row; ?></div>
<?php if (($counter != 1 && $counter % 2 == 1) || ($id == count($rows) -1 && $counter % 2 != 1)) { ?>
</div>
<?php } ?>
<?php endforeach; ?>
The code will be simpler if you divide the original array into groups of three at the beginning.
<?php foreach (array_chunk($rows, 3) as $image_row): ?>
<div class="image-row small clearfix">
<?php foreach ($image_row as $image_group): ?>
<div class="image-group"><?= $image_group ?></div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
The second condition should be:
<?php if ($counter % 3 == 0 || $counter == count($rows)) { ?>
$counter % 3 == 0 is true after every third row, and $counter == count($rows) is true after the last row.

Manipulating a foreach loop

I have the following foreach loop:
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<span class="itemExtraFieldsValue"><?php echo $extraField->value; ?></span>
<?php endforeach; ?>
The first 2 items are fine but the items 3-14 I need to wrap in a div so I can control the layout. I am wondering how I would do this? The problem is not all of the 3-14 items will be populated.
Any advice would be welcome ... thanks
You need a control variable to determine which iteration you are at, from there you can add divs or whatever you want to do from the third iteration onward. You could try something like this:
<?php $i = 0;
foreach ($this->item->extra_fields as $key=>$extraField): ?>
<?php $i++;
if ($i < 3) { ?>
<span class="itemExtraFieldsValue"><?php echo $extraField->value; ?></span>
<?php } else { ?>
Add divs, or whatever you want to do here.
<?php }
endforeach; ?>
So with your additions, since the original formula should work, don't mess with that part. Instead make an addition via a $style variable like so:
$i = 1;
foreach ($this->item->extra_fields as $key=>$extraField):
if($i == 1)
$style = 'id="largeImageWrap" class="pull-left"';
elseif($i == 2)
$style = 'id="sidePanelWrap"';
else
$style = 'class="row"';
// If less than or equal to 3, add <div>
if(($i <= 3))
$front = true;
// If greater than 14 <div>
elseif(($i > 14))
$front = true;
// Else no <div>
else
$front = false;
if($front == true) echo "<div $style>"; ?>
<span class="itemExtraFieldsValue"><?php echo $extraField->value; ?></span>
<?php
// If greater than 2 and less than 14 echo blank or </div>
echo (($i > 2) && ($i < 14))? "":"
</div>";
$i++;
endforeach;

Foreach loop, offset or skip first post in the loop

I'm trying to figure this out for hours but I can't. I just want to show the second post and skip the first one, just like the Wordpress offset function. I'm using AW blog extension for Magento and I want to skip the first post in the recent blog posts. Below is my modified code showing one post recent post in a homepage block. I just want to create another block that will show the second recent post. :(
<?php $posts = $this->getPosts(); ?>
<div id="messages_product_view">
<?php Mage::app()->getLayout()->getMessagesBlock()-> setMessages(Mage::getSingleton('customer/session')->getMessages(true)); ?>
<?php echo Mage::app()->getLayout()->getMessagesBlock()->getGroupedHtml(); ?>
</div>
<?php
foreach ($posts as $post):
if ($i++ >= 1) break;
?>
<div class="postWrapper">
<div class="postTitle">
<h3><a href="<?php echo $post->getAddress(); ?>" ><?php echo $post->getTitle(); ?></a></h3>
</div>
<div class="postContent"><?php echo $post->getPostContent(); ?></div>
</div>
<?php endforeach; ?>
I will recommend you to check the count and after printing it stop the loop, otherwise it will loop the entire array to the end and print just the second iteration.
$i=0;
foreach ($posts as $post){
if ($i==1) {
//print your div here
$i++; //added here after edit.
continue;
}else if ( $i>1 ){
break;
}
$i++;
}
This way it will only iterate twice.
Try changing:
foreach ($posts as $post):
if ($i++ >= 1) break;
to:
//set $i outside of loop
$i=0;
foreach ($posts as $post):
if ($i==0) {
$i++;
//skip the first record
continue;
}
Try this -
<?php $i=1;
foreach ($posts as $post):
if ($i > 1) {
?>
<div class="postWrapper">
<div class="postTitle">
<h3><a href="<?php echo $post->getAddress(); ?>" ><?php echo $post->getTitle(); ?></a></h3>
</div>
<div class="postContent"><?php echo $post->getPostContent(); ?></div>
</div>
<?php }
$i++;
endforeach; ?>

Generating increasing number

I Have a ordered list and i want to generate a incemental number for the data-slide-to starting from 0
That is the php code
get("display_indicators", 1)): ?>
$item){
$activeclass = "";
if($key == 0){
$activeclass = "active";
}
?>
id;?>" data-slide-to="" class="">
You could use a variable to contain a counter...
<?php $counter = 0; ?>
<li data-target="#carousel<?php echo $module->id;?>" data-slide-to="<?php
echo $counter;
$counter++;
?>" class="<?php echo $activeclass; ?>"></li>
You could even use the following instead of echo-ing and incrementing on two lines...
echo $counter++;
This echoes the current count and increments afterwards, but some people prefer to avoid this.
Try this, hope it'll help you
<?php $uniqueNo=0; ?>
<li data-target="#carousel<?php echo $module->id;?>" data-slide-to="
<?php echo $uniqueNo+=1; ?>" class="<?php echo $activeclass; ?>"></li>
Use an incremential counter
<?php $counter = 0; ?>
<ul>
enter code here
<li data-target="#carousel<?php echo $module->id;?>" data-slide-to="<?=$counter++?>"
class="<?php echo $activeclass; ?>"></li>
this however could not be "unique" application wide

Offset PHP array results

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; ?>

Categories