1

I am having a hard time getting a foreach loop to skip over values if it doesnt contain any values. Here is my code. Right now its looping through values from 2016-01-04 in 14 day intervals and returning the days the employee worked along with pay and hours in that pay period. However, if the employee didnt work that pay period I would like it the user to not be able to see the date range of the period. I've tried using continue; and break; but it just stops at the first results.

Here's what I'm looking at. Notice on-

Jan 18th - Jan 31st, 2016

it displays nothing of use. How can I go about getting rid of that in PHP? Thanks.

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container-fluid bone">
  <h4>Pay Periods <i class="fa fa-chevron-down"></i></h4>
</pre><div class="panel panel-info"><div class="panel-heading ">Feb 1st
 - Feb 14th, 2016
</div>  <div class="panel-body" style="padding:0px;"><ul class="list-group" style="margin-bottom:0px;"><li class="list-group-item"><dt class="pull-right">$200.00</dt><a href="editfishbone.php?view=test5&amp;edit=26 &amp;hours=8.00 &amp;number=5555" id="edit1" data-intro="edit leave button"><dt>Mon, Feb 1, 10:34 AM</dt>  </a><small class="text-muted">8 Hours </small><small class="text-muted pull-right">$166.00 net </small></li><ul class="list-group" style="margin-bottom:0px;"><li class="list-group-item"><dt class="pull-right">$200.00</dt><a href="editfishbone.php?view=test5&amp;edit=25 &amp;hours=8.00 &amp;number=222" id="edit1" data-intro="edit leave button"><dt>Sun, Feb 7, 10:29 AM</dt>  </a><small class="text-muted">8 Hours </small><small class="text-muted pull-right">$166.00 net </small></li><ul class="list-group" style="margin-bottom:0px;"><li class="list-group-item"><dt class="pull-right">$250.00</dt><a href="editfishbone.php?view=test5&amp;edit=24 &amp;hours=10.00 &amp;number=0655" id="edit1" data-intro="edit leave button"><dt>Mon, Feb 8, 8:15 AM</dt>  </a><small class="text-muted">10 Hours </small><small class="text-muted pull-right">$207.50 net </small></li></ul></ul></ul></div>  <div class="panel-footer" style="padding-top:0px; padding-bottom:0px; border-bottom: #DDDDDD; border-bottom-width: 10px; border-bottom-style: solid;"><strong class="pull-right"> Total Pay: $539.50 </strong><strong style="margin-bottom:0px;"> Total Hours: 26 </strong></div><div class="panel-heading ">Jan 18th
 - Jan 31st, 2016
</div>  <div class="panel-body" style="padding:0px;"></div>  <div class="panel-footer" style="padding-top:0px; padding-bottom:0px; border-bottom: #DDDDDD; border-bottom-width: 10px; border-bottom-style: solid;"><strong class="pull-right"> Total Pay: $0.00 </strong><strong style="margin-bottom:0px;"> Total Hours: 0 </strong></div><div class="panel-heading ">Jan 4th
 - Jan 17th, 2016
</div>  <div class="panel-body" style="padding:0px;"><ul class="list-group" style="margin-bottom:0px;"><li class="list-group-item"><dt class="pull-right">$200.00</dt><a href="editfishbone.php?view=test5&amp;edit=32 &amp;hours=8.00 &amp;number=555" id="edit1" data-intro="edit leave button"><dt>Mon, Jan 11, 9:49 AM</dt>  </a><small class="text-muted">8 Hours </small><small class="text-muted pull-right">$166.00 net </small></li></ul></div>  <div class="panel-footer" style="padding-top:0px; padding-bottom:0px; border-bottom: #DDDDDD; border-bottom-width: 10px; border-bottom-style: solid;"><strong class="pull-right"> Total Pay: $166.00 </strong><strong style="margin-bottom:0px;"> Total Hours: 8 </strong></div>      </div>

    //php
    $begin = new DateTime('2016-01-04');
    $end = new DateTime();

    $interval = DateInterval::createFromDateString('14 days');
    $period = new DatePeriod($begin, $interval, $end);
    $period = array_reverse(iterator_to_array($period));

    $query = "SELECT hours, number, payRate, start, id FROM fishbone WHERE user='$user' ORDER by start ASC ";
    $result = $con->query($query);
    $num    = $result->num_rows;

while ($row  = $result->fetch_array(MYSQLI_ASSOC)) {
        $rows[] = $row;
        // echo '<pre>',print_r($row),'</pre>';
    }

foreach loops--

//php
foreach ($period as $dt) {
        $i = new DateInterval('P13D');
        $d2 = clone $dt;
        $d2->add($i);
        echo "<div class='panel-heading '>";
        echo $dt->format("M jS\n");
        echo " - ";
        echo $d2->format("M jS, Y\n");
        echo "</div>";
        echo "  <div class='panel-body' style='padding:0px;'>";
        $sum = 0;
        $sum1 = 0;
        foreach ($rows as $row) {
            $startday = date('Y-m-d', strtotime($row['start']));
            $start = date('D, M j, g:i A', strtotime($row['start']));
            $hours = $row['hours'];
            $number = $row['number'];
            $payRate = $row['payRate'];
            $i = new DateInterval('P13D');
            $d2 = clone $dt;
            $d2->add($i);
            $pay = 0;
            $pay1 = 0;

            if ($startday >= $dt->format('Y-m-d') && $startday <= $d2->format('Y-m-d')) {
                $sum += $hours;
                $sum1 += ($hours*$payRate*-.17)+($hours*$payRate);
                $pay += ($hours*$payRate);
                $pay1 += ($hours*$payRate*-.17)+($hours*$payRate);
                echo "<ul class='list-group' style='margin-bottom:0px;'><li class='list-group-item'>";
                echo "<dt class = 'pull-right'>$" . (number_format($pay, 2, '.', '')) . "</dt>";
                echo "<a href='editfishbone.php?view=$view" . "&edit=" . $row['id'] . " " . "&hours=" . $row['hours'] . " " . "&number=" . $row['number'] . "' id= 'edit1' data-intro='edit leave button'><dt>" . $start  . "</dt>  </a>";
                echo "<small class = 'text-muted'>" . (number_format($hours, 2, '.', '')-0) . " Hours </small>";
                echo "<small class = 'text-muted pull-right'>$" . (number_format($pay1, 2, '.', '')) . " net </small>";
                echo "</li>";
            }
        }

        echo "</div>";
        echo "  <div class='panel-footer' style='padding-top:0px; padding-bottom:0px; border-bottom: #DDDDDD; border-bottom-width: 10px; border-bottom-style: solid;'>";
        echo "<strong class='pull-right'> Total Pay: $" . (number_format($sum1, 2, '.', '')) . " </strong>";
        echo "<strong style='margin-bottom:0px;'> Total Hours: " . (number_format($sum, 2, '.', '')-0) . " </strong>";
        echo "</div>";
    }

heres what my query is getting:

   Array
(
    [hours] => 8.00
    [number] => 555
    [payRate] => 25.00
    [start] => 2016-01-11 09:49:01
    [id] => 32
)
1
Array
(
    [hours] => 8.00
    [number] => 5555
    [payRate] => 25.00
    [start] => 2016-02-01 10:34:07
    [id] => 26
)
1
Array
(
    [hours] => 8.00
    [number] => 222
    [payRate] => 25.00
    [start] => 2016-02-07 10:29:01
    [id] => 25
)
1
Array
(
    [hours] => 10.00
    [number] => 0655
    [payRate] => 25.00
    [start] => 2016-02-08 08:15:02
    [id] => 24
)
1

2 Answers 2

5

If you can test for the condition you want to skip over, you can use the 'continue' keyword to go to the next iteration of the for(each) loop.

Example:

foreach($dates as $date) {
    if($date > $date_range) {
        continue; // 'skips', Goes back to the top of the foreach loop
    }

    // ... Do other things for values you didn't skip
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your help. I don't think I can 'continue;' until values during the $date_range have been checked in the second foreach loop.
Can you amend your SQL query to not return 0-hour periods? "SELECT hours, number, payRate, start, id FROM fishbone WHERE user='$user' AND hours > 0 ORDER by start ASC"
Yes. It's not getting results with 0 right now. There are none. I've edited my question so that you can see what I'm getting with my query. Thanks.
Hmm. How about doing "if(array_sum(array_column($rows, 'hours')) == 0) continue;" Under the first foreach? This should sum all the hours in that set of rows ahead of time, before you print anything out.
No dice. That's giving me 34 across each loop. Its adding up all rows hours.
|
1

Usually, I would craft some monstrous SQL query that would group and return the rows you want, with their period sums appended to the end.

As an easier fix though, you should be able to use the code below to skip periods with no hours in them. I tested it with a simple array, but it may (or may not) need some tweaking to work with yours.

$hoursForPeriod = array_reduce($rows, function($carry, $elem) use ($dt, $d2) {
    $startday = date('Y-m-d', strtotime($elem['start']));

    if ($startday >= $dt->format('Y-m-d') && $startday <= $d2->format('Y-m-d')) {
        $carry += $elem['hours'];
    }

    return $carry;
}, 0);

if($hoursForPeriod == 0)
    continue;

Try placing that code below these lines in your script:

$d2 = clone $dt;
$d2->add($i);

6 Comments

Notice: Undefined variable: dt2 in... Notice: Undefined variable: d2 in... Fatal error: Call to a member function format() on null in...
I think I may have to come back to this some other day. Thanks for you help.
Sorry, I meant to name the variable $d2, rather than $dt2 in "use()" portion of my answer. I've fixed it now. That should correct the problems you had.
this line: $carry += $elem * $dt; Notice: Object of class DateTime could not be converted to int... Notice: Object of class DateTime could not be converted to int... Got to convert DateTime objects to a integer somehow.
I think I'm going to have to pass two variables into the first for each statement. if this goes into the second for each I'll still get the date range.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.