Foreach pagination - php

I am looking for help in how to paginate my foreach output. I've looked at other questions and answers and cannot find a solution that works for me or that I can figure out on my own. Right now my code, which is below, outputs everything into table rows. My problem, of course, is that it dumps all data on a single page -- hence the reason I want pagination. I want to paginate for every 11 items on the page. The page is a magazine archive, and there are 11 issues pear year -- so every page is equal to 1 year of our magazine. The first page should host issues 1-11 and page two should host issues 12 through 22, etc. We have 10 years worth of magazine issues. Any help would be greatly appreciated. Thank you!
<table>
<tr>
<?php $col = 0; ?>
<?php foreach (get_terms('term') as $cat) : ?>
<?php if ($col > 0 && $col % 3 == 0): ?>
</tr>
<tr>
<?php endif; ?>
<?php $col++; ?>
<td>
<strong><?php echo $cat->name; ?></strong><br>
<em><?php echo $cat->description; ?></em><br>
<img src="<?php echo z_taxonomy_image_url($cat->term_id); ?>" />
</td>
<?php endforeach; ?>
</tr>
</table>

What framework/ application is this? While I don't understand 100% where the data is coming from, you could try modifying your code to add a break when you hit 11 entries (or 10 when you are starting from 0).
<?php $col = 0; ?>
<?php foreach (get_terms('term') as $cat) : ?>
<?php if ($col > 0 && $col % 3 == 0): ?>
</tr>
<tr>
...
<?php if(10 == $col) { break;}
endforeach; ?>
That will limit this to the first 11 results of your foreach loop. From there, you would have to modify how you select the data so that the second page starts at record 12.
Of course, it may just be easier to use limit syntax on your sql query, eg:
limit 12, 22

I think this is what you want:
get_terms('term', array('offset' => $page * 11, 'number' => 11));
Where $page starts at 0 for the first page. If you want page to start at 1, use ($page-1) * 11.
How you determine what page to show is up to you.
See the get_terms documentation for more information: http://codex.wordpress.org/Function_Reference/get_terms

this may not be what you were looking for or expecting but hope you or someone else finds useful.
the following script does everything small configuration required ps_pagination.php
You need to include the ps_pagination.php into the pages where you want to use it and then use the following code to populate the information on the paginated pages.
Hope its helpful.
db_connection = mysql_connect('localhost', 'user', 'password')or die("cannot connect");
mysql_select_db('database',$conn);
// mysql query
$sql_query="SELECT * FROM example ORDER BY id DESC";
// Create the ps_pagination object here
$pager = new ps_pagination($db_connection,$sql_query,10,5);
//The paginate() function returns a mysql result set
$rs = $pager->paginate();
while($rows = mysql_fetch_assoc($rs)) {
// table to display results here // modify here
echo $rows["title"].'</p>';
echo '<p> '.$rows["post"].'</p>';
echo '<p><span class="style1">By</span>: '.$rows["name"].' ';
echo '<p>Date/Time</span>:'.$rows["datetime"].'</p>';
echo "<BR>";
}
// close mysql connection here
mysql_close();
//Display the full navigation in one go
echo $pager->renderFullNav();

Here is the code I used to solve my problem:
<?php
$url = $_SERVER["REQUEST_URI"];
$segments = explode('/', $url);
$page = is_numeric($segments[count($segments)-2]) ? $segments[count($segments)-2] : 1;
$next = $page + 1;
$prev = $page - 1;
$issues_per_page = 11;
$lastpage = ceil(wp_count_terms( 'mag') / $issues_per_page) ;
?>
<?php wp_count_terms( 'mag' ); ?>
<table>
<tr>
<?php $col = 0; ?>
<?php foreach (get_terms('mag', array('offset' => ($page - 1) * $issues_per_page, 'number' => $issues_per_page)) as $cat) : ?>
<?php if ($col > 0 && $col % 3 == 0): ?>
</tr>
<tr>
<?php endif; ?>
<?php $col++; ?>
<td>
<strong><?php echo $cat->name; ?></strong><br>
<em><?php echo $cat->description; ?></em><br>
<img src="<?php echo z_taxonomy_image_url($cat->term_id); ?>" />
</td>
<?php endforeach; ?>
</tr>
</table>
<?php if ($prev > 0) : ?>
Previous
<?php endif ?>
<?php if ($page < $lastpage) : ?>
Next
<?php endif ?>

Related

Return a Key from the Next and Last Element in Array / Foreach Loop

I am hoping to modify the manner in which discounts are displayed for an eCommerce platform (OpenCart - PHP MVC based).
The default behaviour is that the discounts will be displayed as:
5 or more: $20.00
10 or more: $18.00
20 or more: $16.00
I would prefer:
5 - 9: $20.00
10 - 19: $18.00
20+: $16.00
Stripping out the "or more" text is simple enough through the template file (code provided below).
For all but the last element, this would require taking the quantity key ($discount['quantity']) from the next element and applying a basic maths function (- 1), then returning this new value besides the original.
For the last element, I would need to simply return the last quantity value and add "+" text.
Original code (controller):
$discounts = $this->model_catalog_product->getProductDiscounts($this->request->get['product_id']);
$this->data['discounts'] = array();
foreach ($discounts as $discount) {
$this->data['discounts'][] = array(
'quantity' => $discount['quantity'],
'price' => $this->currency->format($this->tax->calculate($discount['price'], $product_info['tax_class_id'], $this->config->get('config_tax')))
);
}
Original code (template):
<?php if ($discounts) { ?>
<div class="discount">
<?php foreach ($discounts as $discount) { ?>
<span><?php echo sprintf($text_discount, $discount['quantity'], $discount['price']); ?></span>
<?php } ?>
</div>
<?php } ?>
Modified code to strip "or more" text from template (Note: Separate echo's used to allow table formatting - To maintain simplicity, these tags are not included):
<?php if ($discounts) { ?>
<div class="discount">
<?php foreach ($discounts as $discount) { ?>
<?php echo $discount['quantity']; ?><?php echo $discount['price']; ?>
<?php } ?>
</div>
<?php } ?>
How can I further modify this code to return the quantities in the preferred format?
Note: The arrays are quite small but I would still consider performance as a priority.
Edit:
Thank you tttony for providing the solution below. This is the code I have used in the template file for the custom table formatting (without the sprintf/formatted string function).
<?php for ($i=0; $i < count($discounts) -1; $i++) { ?>
<tr>
<td><?php echo $discounts[$i]['quantity']; ?> - <?php echo (int)$discounts[$i+1]['quantity'] - 1; ?></td>
<td><?php echo $discounts[$i]['price']; ?></td>
</tr>
<?php } ?>
<?php if (count($discounts)) { ?>
<tr>
<td><?php echo $discounts[$i]['quantity']; ?>+</td>
<td><?php echo $discounts[$i]['price']; ?></td>
</tr>
<?php } ?>
You can try this, very simple, in the product.php controller file
$discounts = $this->model_catalog_product->getProductDiscounts($this->request->get['product_id']);
$discounts_formated = array();
for ($i=0; $i < count($discounts) -1; $i++) {
$discounts_formated[] = sprintf("%s - %s", $discounts[$i]['quantity'], (int)$discounts[$i+1]['quantity'] - 1);
}
// Last discount: 30+
$discounts_formated[] = sprintf("%s+", $discounts[$i]['quantity']);
var_dump($discounts_formated);
Output:
array (size=3)
0 => string '10 - 19' (length=7)
1 => string '20 - 29' (length=7)
2 => string '30+' (length=3)
EDIT:
Edit the file product.tpl, I tested with OC 1.5.6.4 and it's working
<?php if ($discounts) { ?>
<br />
<div class="discount">
<?php for ($i=0; $i < count($discounts) -1; $i++) { ?>
<?php echo sprintf("%s - %s: %s", $discounts[$i]['quantity'], (int)$discounts[$i+1]['quantity'] - 1, $discounts[$i]['price']); ?><br />
<?php } ?>
<?php if (count($discounts)) { // last discount ?>
<?php echo sprintf("%s+: %s", $discounts[$i]['quantity'], $discounts[$i]['price']); ?><br />
<?php } ?>
</div>
<?php } ?>
Will print something like this:
10 - 19: $88.00
20 - 29: $77.00
30+: $66.00

PHP Show 2nd foreach in td next to the first loop's values

I have a SQLite- file with values.
I get those values and display them in a table of 2 columns:
<?php
$db = new PDO("sqlite:$dbPath");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$stmt = $db->prepare('SELECT * FROM Object;');
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<table id="table1">
<caption><em>caption</em></caption>
<?php foreach($res as $objekt):
$imageFile = basename($objekt['image']); ?>
<tr>
<td><?php if(isset($objekt['image'])): ?>
<figure class="objectPicture center">
<img src="img/bmo/250/<?php echo $imageFile;?>" alt="<?php echo $objekt['title'];?>">
<?php else: ?>no picture.<?php endif ?><br>
<figcaption><?php echo $objekt['title']; ?>
</figcaption>
</figure>
</td>
<td><?php echo $objekt['text']; ?><br>
<?php echo $objekt['owner']; ?></td>
</tr>
<?php endforeach; ?>
</table>
What I'd like to do is to show the next foreach-loop (values of row2 in the SQLite- file) in another 2 columns next to the first result. And the 3rd loop under the first one and so on.
How do I do that? (total newbie to PHP and SQL here, in case you didn't notice)
The results now:
What I want:
3 Changes to make
Add $idx to foreach loop
<?php foreach($res as $idx => $objekt):
Wrap if around <tr>
<?php if($idx % 2 == 0) { ?>
<tr>
<?php } ?>
Wrap if around </tr>
<?php if($idx % 2 == 1) { ?>
</tr>
<?php } ?>
The above code doesn't consider the case when row number is odd

Change foreach to show only first/last added image

I have following code construction. It gives out an image of the product, which was even added to the shopping card. Images appear in the adding order: the image on top is the image, which was added last.
How can i change this code so, that i get showing only one image, from recently added product (but not all images from all added products)? I guess, i need change something in foreach ($items as $item) so, that the image is showing not for each $item, but only for one $item, but don't know how to modify this code exactly...
Thanks for your help and advises!
Here is the code:
<table>
<?php $i=0; $k=0; $subtotal = 0;?>
<?php foreach ($items as $item) : ?>
<?php
$link = K2StoreItem::getK2Link($item->product_id);
$link = JRoute::_($link);
$image_path = K2StoreItem::getK2Image($item->product_id, $this->params);
?>
<tr class="row<?php echo $k; ?>">
<?php if($this->params->get('show_thumb_cart')) : ?>
<td class="warkorb2">
<?php if(!empty($image_path)) : ?>
<img src="<?php echo $image_path; ?>" class="itemImg<?php echo $this->params->get('cartimage_size','small') ?>" />
<?php endif;?>
</td>
<?php endif; ?>
</tr>
<?php ++$i; $k = (1 - $k); ?>
<?php endforeach; ?>
<table>
You can use a Query with a limit or do something like this
<?php $lastItem = end($items) ?> <!-- return the last item in the $items array -->
<?php
$link = K2StoreItem::getK2Link($lastItem->product_id);
$link = JRoute::_($link);
$image_path = K2StoreItem::getK2Image($lastItem->product_id, $this->params);
?>
in the query that you did not post you can do a LIMIT 0,1 and also add in a SORT BY .. be it id, time etc..

Order data in three columns instead of one

At the moment, with the code from below, I have the data shown like this:
http://img27.imageshack.us/img27/8083/29769986.jpg
but I want it to be shown like this:
http://img259.imageshack.us/img259/3233/24033830.jpg
The code for the data shown, as it is on the first image, is:
<div id="content">
<?php foreach ($categories as $category) { ?>
<div class="manufacturer-list">
<div class="manufacturer-heading"><?php echo $category['name']; ?><a id="<?php echo $category['name']; ?>"></a></div>
<div class="manufacturer-content">
<?php if ($category['manufacturer']) { ?>
<?php for ($i = 0; $i < count($category['manufacturer']);) { ?>
<ul>
<?php $j = $i + ceil(count($category['manufacturer']) / 4); ?>
<?php for (; $i < $j; $i++) { ?>
<?php if (isset($category['manufacturer'][$i])) { ?>
<li><?php echo $category['manufacturer'][$i]['name']; ?></li>
<?php } ?>
<?php } ?>
</ul>
<?php } ?>
<?php } ?>
</div>
</div>
<?php } ?>
</div>
I order to get the "Hewlett-Packard" text under the "HTC" text, I've changed the "/ 4" into "/ 1", but I have no idea how to make the data to be shown into three columns (like on the second picture), instead of one, as it is now (as shown on the first picture).
Thanks in advance.
EDIT: What I actually need, is to count and to do the calculation on this code:
<?php foreach ($categories as $category) { ?>
.
.
.
<?php } ?>
So it needs to count the number of categoris, do the calculations, and present the code between into three columns.
Try this one.
<div id="content">
<div class="content-column">
<?php
$cols = 3; // Change to columns needed.
$catcount = count($categories);
$catpercol = ceil($catcount / $cols);
$c = 0;
foreach ($categories as $category) {
if ( $c == $catpercol ) {
$c = 0;
print "</div><div class='content-column'>";
}
?>
<div class="manufacturer-list">
<div class="manufacturer-heading"><?php echo $category['name']; ?><a id="<?php echo $category['name']; ?>"></a></div>
<div class="manufacturer-content">
<?php if ($category['manufacturer']) { ?>
<?php for ($i = 0; $i < count($category['manufacturer']);) { ?>
<ul>
<?php $j = $i + ceil(count($category['manufacturer']) / 4); ?>
<?php for (; $i < $j; $i++) { ?>
<?php if (isset($category['manufacturer'][$i])) { ?>
<li><?php echo $category['manufacturer'][$i]['name']; ?></li>
<?php } ?>
<?php } ?>
</ul>
<?php } ?>
<?php } ?>
</div>
</div>
<?php $c++; } ?>
</div>
</div>
Add .content-column { float: left; width: 33.33333%; } to your CSS.
Details:
$cols = 3; enables you to set the desired number of columns (note: you might need to change CSS accordingly).
$catcount = count($categories); gives you the total number of categories about to be rendered.
$catpercol = ceil($catcount / $cols); divides that total number evenly into the required number of columns with the last column having eventually less items than the others.
$c = 0; is your counter. It increases at the end of the outer foreach loop.
Within the loop, $cis checked if it matches the $catpercol number and if so, the current parent div is closed and a new one created. You end up with as many parent divs as you need columns. Just add appropiate CSS to make them appear besides each other.
understand the following code that according to your requirement, the code just give the hint to achieve that you want according to your given screen shoot http://img259.imageshack.us/img259/3233/24033830.jpg
echo "<table>";
echo "<tr>";
$i = 1;
do{
// column range
$range = 3;
echo "<td>" . $i;
if( $i % $range == 0 ){
echo "</tr>";
echo "<tr>";
}
echo "</td>";
$i++;
}while( $i <= 10 );
echo "</tr>";
echo "</table>";
Hope this will help you
I think it is possible to create three column layout via html/css and without any change of your PHP code. Just use float:left; width: 33%. You can also use absolute value for width property because of margins and borders.

PHP end div after X amount of divs and start new one

I am trying to achieve to show 4 divs on 1 line and after those 4 divs it should automatically end the line and continue with the new line of 4 divs. What I have right now is;
<?php
// Make sure to just show items if there are any.
if ($is_empty)
{
echo 'There are no products found.';
}
else
{
// Start counting the products.
$i = 1;
// List up all products.
foreach ($results as $item):
// Count up the productcount.
$i++;
?>
<a href="<?php echo base_url(); ?>product/<?php echo $item['product_id']."-".$item['name_clean']; ?>.html">
<?php echo $item['name']; ?>
</a>
<?php
endforeach;
}
?>
So like, if $i = 4, 8, 12 etc etc, cut off the line (maybe add a div that's holding those 4?) and start a new one.
Is that possible? I know it is with tables, as I found here PHP: End and start a new <tr> after 6 rows
Thanks.
Use modulus (%) to calculate every 4th element.
<?php
// Start counting the products.
$i = 0;
// List up all products.
foreach ($results as $item):
// Count up the productcount.
$i++;
?>
<a href="<?php echo base_url(); ?>product/<?php echo $item['product_id']."-".$item['name_clean']; ?>.html">
<?php echo $item['name']; ?>
</a>
<?php
if($i%4 == 0):
?>
<br />
<?php
endif;
?>
endforeach;
?>

Categories