So I know this is simple but I've been banging my head against the wall for a while trying to figure it out. I want to show a ruler at the bottom of my loop on each one except the last one. I can get it to work if I have the exact number of records but not if I have less. For example if the max number to show is 10 but there are only 5 records I want the divider after the 4th record. Likewise, if there are 20 results but max is 10 I want it after the 9th.
<?php $subscriberIDs = ba_getUsersByRole( 'subscriber' );
// Loop through each user
$i=0;
$max = 10; //max number of results
$total_users =count($subscriberIDs); //total number of records
foreach($subscriberIDs as $user) :
if($i<=$max) : ?>
<li>
<?echo $user['data'];?>
</li>
<?php
if(($i < $total_user-1 && $max >= $total_users) || ($i < max-1 && $total_users <= $max)){echo "<hr>";}
$i++;
endif;
endforeach; ?
// <hr> goes in every spot, but not on the last item, up to 10
$position = min($max-1, count($subscriberIDs)-1);
$i = 0;
foreach($subscriberIDs as $user){
echo '<li>' . $user['data'] . '</li>';
if($i != $position){
echo '<hr>';
}
$i++;
}
This takes the lesser of either $max-1 or count($subscriberIDs)-1, which by definition is will be the last item you'll iterate over. If you have more than $max items, then this will be $max-1, if you have less than $max items, then this will be count(.)-1.
Then, during the iteration, the if statement prints an <hr> so long as the current item is not the last item.
Related
I'm trying to make a select list of prices in my system. The prices are stored as integers. I'm able to get the lowest price and highest price but I want to display them in a select list. I don't want the select list to increment slowly but by 100 or 10,000 or, 100,000 depending on what my starting number is what where i'm at in my incrementation.
For example, say I have these 2 prices:
500000
12345689
I'm trying to increment them by 100,000 Then when I get to 1,000,000 I want to increment by that. It will look something like this:
500000
600000
700000
800000
900000
1000000
2000000
I'm using a custom function and a bit of formatting to get all my prices and get my start price and end price:
$prices = my_custom_function(); // Pulls All Prices in a random order
if(!empty($prices)){
sort($prices); // Sort Prices Lowest to Highest
$price_low = $prices[0];
$price_high = $prices[count($prices)-1];
$price_start = intval( $price_low[0].str_repeat( '0', strlen( $price_low ) - 1 ) );
$price_end = intval( ( $price_high[0] + 1 ).str_repeat( '0', strlen( $price_high ) -1 ) );
}
Using the same example above, my start price and end price will be:
$price_start = 500000
$price_end = 20000000
Now it's at the loop where I run into trouble incrementing it by the values I want. I'm trying to use a while loop and determine where I am in my incrementer:
<?php $i = $price_start; $x = 0; while($x < 10) : ?>
<option value="<?php echo $i; ?>"><?php echo format_price($i); ?></option>
<?php
if(1000 % $i == 0)
$i+=1000;
else if(10000 % $i == 0)
$i+=10000;
else if(100000 % $i == 0)
$i+=100000;
else if(1000000 % $i == 0)
$i+=1000000;
else
$i+=10000000;
$x++;
endwhile;
?>
I ended up adding in the x variable because I kept running into infinite loop problems but theoretically it should be while($i <= $price_end). Can somebody point me in the right direction on how to get the expected output please? I feel like I'm close but not quite there yet and there's probably a better / faster way to go about it. Any help would be great.
I guess a simplified way of looking at it is:
1 -> +1
10 -> +10
100 -> +100
1000 -> +1000
10000 -> +10000
and so forth.
Get power of 10: log10(1234); // 3.09131
Round down: floor(log10(1234)); // 3
Re-raise as power of 10: pow(10,floor(log10(1234))); // 1000
???
Profit.
If someone needs the full solution here it is:
$price = 100; // Starting Price
$priceEnd = 10000; // Ending Price
while($price <= $priceEnd) {
echo $price . "<br/>";
$increase = pow(10,floor(log10($price)));
$price = $price + $increase;
}
I am trying to achieve a fairly complex layout. I've managed to do it but cant help think that the IF statement is a little lacking in refinement.
I have a for loop which loops through grid items, the first item and every 5th one are larger and every second large item is floated to the right rather than the left. There are four small items to every large one in a row (so the large is the same size as the four small).
I just think my IF isnt particularly elegant and also restricts the size of the grid.
$i = 0;
foreach ($items as $item) {
if ($i % 5 == 0) { ?>
<article <?php if ($i == 5 || $i == 15 || $i == 25 || $i == 35 || $i == 45 || $i == 55) { ?>style="float:right;" <?php } ?>>
//do big item
</article>
} else {
<article>
//do small item
</article>
}
$i++;
}
Im also trying to work out how I can wrap every row of 5 items in another div to help with sizing? I was thinking another block of if ($i % 5 == 0) { may help with this but Im conscious of loading times and best practice too.
As always any help greatly appreciated!
Just introduce a second mod operator. eg.
if ($i % 5 == 0){
if ( ($i-5) % 10 == 0 ){
// so this will work for values of %i = 5, 15, 25, 35 ...
// big article
}else{
// small article
}
$i++ ; // as previous comment #javad pointed out. You are not incrementing i
How do you calculate (sum) + a value in foreach loop?
I am working on a cricket application where i have to count the loop for each 6 times and then count specific value and then echo the total.
I have a code not exact but something like this.
And there are two values:
Balls $balls['1']; array like 1,2,3,4,5 and up to 300-1000 balls
Runs $balls['6']; array like 2,3,1,5 random numbers could be any;
Values comes from mysql table columns balls and runs
foreach( $balls as $ball ){
$countball++;
// here is what i need to know how do i calculate the values of $ball + $ball?
// so i can echo it inside the below if condition?
$runs = $ball['runs'] + $ball['runs']; // not working
if($countball == 6){
echo $runs;
}
$runs+= $ball; // reset the ball counting to continue addition from loop?
// and reset the
}// end foreach
however something like this works fine for the first $countball == 6. but after that it does not show the exact value
You forget to reset the $countball.
You may change the if part as :
if($countball == 6)
{
echo $runs;
$countball = 0;
}
Maybe this is what you need:
$runs = 0;
foreach( $balls as $ball ){
$runs += $ball['runs'];
}
echo $runs;
With help of #Barmar from above i got the desired output as followings
$runs = 0;
$countball=0;
foreach( $balls as $ball ){
$countball++;
$runs += $ball['runs'];
if($countball == 6){
// reset runs from current loop runs for next, if i reset $runs = 0
// for some reason it does not (SUM) + this loops $ball['runs'] with last 5;
$runs = $ball['runs'];
$countball=0;
}// end if $countball == 6
}// end foreach
echo $runs;
I am facing an problem. I have built a foreach loop in PHP:
<?php $show = false; ?>
<?php foreach ($this->items as $item) : ?>
But I want to echo the first 20 items and continue with the following 16 items.
I have managed to make it to do a break after 20 items but I am not getting the following 16 items ( starting from nr 21 ).
This is what I have so far:
<?php $show = false; ?>
<?php $i = $item->id = 1; ?>
<?php foreach ($this->items as $item) : ?>
<?php if(++$i > 20) break; ?>
If I set $i to '21' it still echos item 1 and so on.
Solution ## Thanks to #dhavald
<?php $show = false; ?>
<?php foreach (array_slice ($this->items, 0, 20) as $item) : ?>
By placing an array_slice in the foreach you can control the items you want show.
So on the next div i want to show item 21 to 36, the only thing i had to change was the 0 and 20 into , 20, 36
To clarify what I am looking for, I have three divs where I want to echo some items onto it. If an user collapse a div on the first there will appear the first 20 items and if a user clicks div2 the next 16 items will appear.
How can I correct this code to make that happen?
As i forgotten to mention, the solutions you bring on helped me really to understand the process but as i used a component generator for Joomla 3.1 there is one row of code that make it a little bit more complex to call the first 20 and second 16 items.
Directly after the foreach loop there is this line of code
if($item->state == 1 || ($item->state == 0 && JFactory::getUser()>authorise('core.edit.own',' com_ncitycatemus.vraagantwoordtoevoegen.'.$item->id))):
$show = true;
How can i manage it than with the loop ? Or do you suggest another way?
Thanks in advance! Really helped me to understand the loop!!
break breaks out of and stops a loop. continue skips the rest of the code in the loop, and jumps to the next iteration.
Using break and continue is in my opinion the wrong approach here. I'd simply use two for loops:
$keys = array_keys($this->items);
$keysLength = count($keys);
echo '<div id="div1">';
for ($i = 0; $i < min($keysLength, 20); $i++) {
echo $this->items[$keys[$i]];
}
echo '</div>';
if ($keysLength >= 20) {
echo '<div id="div2">';
for ($i = 20; $i < min($keysLength, 36); $i++) { //36 being 20 + 16
echo $this->items[$keys[$i]];
}
echo '</div>';
}
Note: This will work with any amount of items in $this->items. If it's under 20, it'll simply skip the next 16, and if it's above 36, it'll simply ignore the rest.
you can use array_slice to get a part of $this->items array and assign it into 3 different variables and loop over them separately.
$itemsDiv1 = array_slice($this->items, 0, 20); // gives first 20 items
$itemsDiv2 = array_slice($this->items, 20, 16); // gives next 16 items
and so on..
Don't use break; use continue;
<?php $i = 0; ?>
<!-- first group -->
<div>
<?php foreach ($this->items as $item) : ?>
<?php
/**
* Check if count divided by 20 has no remainder
*/
if ( (++$i % 20) == 0 ): ?>
</div>
<!-- start new group -->
<div>
<?php endif ?>
<?php endforeach ?>
<!-- end last group -->
</div>
$stockNotNull = StockDetail::where('sku', 10101001)
->where('stock_quantity', '>', 0)->get('stock_id', 'stock_quantity');
$toSell = 14;
// decrements just once for each $stockNotNull
foreach ($stockNotNull as $product) {
if ($toSell < 1) {
return;
}
$product->decrement('stock_quantity');
// $product->stock_quantity--; returns with a null
// dump($product->stock_quantity);
$product->save();
$toSell--;
// dump($toSell);
if($product->stock_quantity === 0) {
continue;
}
}
This is what I got so far, decrementing in the usual manner i.e $variable-- gives me a null value, $product->decrement('stock_quantity') subtracts 1 on each run, even if the stock_quantity field is far greater than the $toSell variable. The logic is there in my head, I'm just having trouble taking the quantity from the current item and moving on to the next only when the stock_quantity is 0.
This code will divide the score until it reaches the number 5.
The $rows[score] is equal to 6600 in the database.
<?php
$i = $rows[score]; //score is 6600 in the database
while ($i >= 5) {
echo $i = $i /2;
echo "<br>";
}
?>
This is what my browser outputs:
3300
1650
825
412.5
206.25
103.125
51.5625
25.78125
12.890625
6.4453125
3.22265625
I don't understand why the browser output the last 3.22 - how do I stop the loop from echo out the last one that is less than 5??
Nothing wrong here the last value you get is from 6.4453125 / 2 = 3.22265625 since 6.4453125 still greater than 5
because 6 is higher than 5? so it does one more loop making $i 3.2 where the loop stops
If ($i<5) it wont go into the loop but there is no way to know until you check. $i = 6.4453125 the last time it checks, so it goes into the loop and it divides it by 2, which makes it less than 5 so it doesn't go into the loop again and stops.
I found the way to answer my own question so 3,22 will not be viewed on the page.
<?php
$i = $rows[score]; //score is 6600 in the database
while ($i >= 5) {
$i = $i /2;
if($i >= 5) {
echo $i;
echo "<br>";
}
}
?>
Since you're dividing by two immediately before displaying the result, you want to stop your loop when $i >= (5*2) i.e. $i >= 10, not 5.
<?php
$i = $rows[score]; //score is 6600 in the database
while ($i >= 10) {
echo $i = $i /2;
echo "<br>";
}
?>
This gives:
3300
1650
825
412.5
206.25
103.125
51.5625
25.78125
12.890625
6.4453125