when I use For loop, key pass the next step. while the foreach data did not changed data.PHP - php

This is my function, which to calculate the intersection time range of two people. when I use three loops, the first loop could pass the key to the next step, but the data they used belong to other people's data. I am very confused.
public function test()
{
//choose records of viva arrangement
$records = DB::table('application_student')
->where('allocationStatus', '=', 1)
->select('user_id', 'supervisor_id', 'assessor_id')
->get()->toArray();
//single records
foreach ($records as $key => $record) {
$viva[] = [
$sup_id = $record->supervisor_id, // key 0=>supervisor
$stu_id = $record->user_id, // key 1=>student
];
}
// $x is the key number of viva[]
for ($x = 0; $x <count($records); $x++){
$sup_id = $viva[$x][0]; //supervisor_id of record $x
$stu_id = $viva[$x][1]; //student_id of record $x
//find availability of supervisor
$sup_time = DB::table('time_allocates')
->where('user_id','=',$sup_id)
->select('start','end')->get()->toArray();
//find availability of student
$stu_time = DB::table('time_allocates')
->where('user_id','=',$stu_id)
->select('start','end')->get()->toArray();
//every single availability of supervisor
foreach ($sup_time as $key => $supT) {
$sup[] = [
$s1 = strtotime($supT->start), //key 0=>start time
$e1 = strtotime($supT->end), //key 1=>end time
];
}
//every single availability of student
foreach ($stu_time as $key => $stuT) {
$stu[] = [
$s2 = strtotime($stuT->start), //key 0=>start time
$e2 = strtotime($stuT->end), //key 1=>end time
];
}
//$i is the key number of single supervisor availability record
for ($i = 0; $i < count($sup_time); $i++) {
//$j is the key number of single student availability record
for ($j = 0; $j < count($stu_time); $j++) {
echo "$x+'$i'+'$j <br>";
$sup_s1 = $sup[$i][0]; // start time of supervisor
$sup_e1 = $sup[$i][1]; // end time of supervisor
$stu_s2 = $stu[$j][0]; // start time of student
$stu_e2 = $stu[$j][1]; // end time of student
//make sure the time range of student between supervisor has intersection
if($stu_s2>=$sup_s1 && $sup_e1>$stu_s2){
$start = $stu_s2;
if ($sup_e1<=$stu_e2){
$end = $sup_e1;
}else{
$end =$stu_e2;
}
if ($end-$start>=3600){
$start_date = date('Y-m-d H:i:s', $start);
$end_date = date('Y-m-d H:i:s', $end);
echo "$start_date '-' $end_date -$stu_id -$sup_id<br>";
}
}elseif ($sup_s1>=$stu_s2 && $sup_e1>$stu_s2){
$start =$sup_s1;
if ($sup_e1<=$stu_e2){
$end=$sup_e1;
}else{
$end=$stu_e2;
}
if ($end-$start>=3600){
$start_date = date('Y-m-d H:i:s', $start);
$end_date = date('Y-m-d H:i:s', $end);
echo "$start_date '-' $end_date -$stu_id-$sup_id <br>";
}
}
}
}
}
}
this is the result of the window. the student id changed from 2 to 3, but the data use the 2 always. please help me, guys.
enter image description here

You're not reinitializing $sup for each loop.
$sup[] = [
$s1 = strtotime($supT->start), //key 0=>start time
$e1 = strtotime($supT->end), //key 1=>end time
];
Same for $stu[]
for the second student, it will add the data on top of those of the first one.
You need to do it like this
//every single availability of supervisor
$sup = [];
foreach ($sup_time as $key => $supT) {
$sup[] = [
$s1 = strtotime($supT->start), //key 0=>start time
$e1 = strtotime($supT->end), //key 1=>end time
];
}
//every single availability of student
$stu = [];
foreach ($stu_time as $key => $stuT) {
$stu[] = [
$s2 = strtotime($stuT->start), //key 0=>start time
$e2 = strtotime($stuT->end), //key 1=>end time
];
}
PS: you have a lot of redundant code and many extra loops to remove.

Related

To Manage Schedule in PHP foreach loop

I am having table like below
So there are priority and sqft, i want to start manufacturing schedule (from current date) that every day 1700 SQFT will be processed, like below image
but as you can see its not working
I have tried below code
foreach($priorityArraySum as $key=>$val)
{
$totalDays=ceil($val/1700);
$cutSQFT=$val;
for($j=1;$j<=$totalDays;$j++)
{
if($cutSQFT>1700)
{
echo '1700';
$cutDate=date('Y-m-d', strtotime($cutDate. ' + 1 days'));
$cutSQFT=$cutSQFT-1700;
}
else
{
echo $cutSQFT;
$cutSQFT=$cutSQFT-$cutSQFT;
}
}
}
#Nigel, to Make this dynamic, I have changed code to below, but its not working.
$pln_qry=mysql_query("select * from tbl_mfg_schedule where ms_date='".$today."'") or die(mysql_error());
$pln_data=mysql_fetch_array($pln_qry);
$max = $pln_data['ms_po_sqft'];
$dailyLeft = $max;
$current = reset($priorityArraySum);
$output = [];
//$day = date('Y-m-d');
$day = date('Y-m-d');
while (true) {
$pln_qry=mysql_query("select * from tbl_mfg_schedule where ms_date='".$today."'") or die(mysql_error());
$pln_data=mysql_fetch_array($pln_qry);
$max = $pln_data['ms_po_sqft'];
if ( $current >= $dailyLeft ) {
//$day=date('Y-m-d', strtotime($day. ' + 1 days'));
$output[] = ["priority" => key($priorityArraySum),
"amount" => $dailyLeft,
"day" => $day
];
$day=date('Y-m-d', strtotime($day. ' + 1 days'));
$current -= $dailyLeft;
$dailyLeft = $max;
}
else {
$output[] = ["priority" => key($priorityArraySum),
"amount" => $current,
"day" => $day
];
$dailyLeft -= $current;
if ( ($current = next($priorityArraySum)) === false ) {
break;
}
}
}
This code uses a while() loop to create an output array of the days work. It uses $current to keep track of each item and how much is left to allocate. It also uses $dailyLeft to keep track of how much capacity is left on a particular day. It checks the two and if the current is less than the daily capacity left, it allocates a full day to that item and resets the daily capacity. If there is extra capacity for that day it allocates this item to the day and gets the next item.
The day is only incremented (using $day++) when the capacity for that day is filled...
$max = 1700;
$dailyLeft = $max;
$current = reset($priorityArraySum);
$output = [];
$day = 1;
while (true) {
// echo $current."/".$dailyLeft."=".$day.PHP_EOL;
if ( $current >= $dailyLeft ) {
$output[] = ["priority" => key($priorityArraySum),
"amount" => $dailyLeft,
"day" => $day++
];
$current -= $dailyLeft;
$dailyLeft = $max;
}
else {
$output[] = ["priority" => key($priorityArraySum),
"amount" => $current,
"day" => $day
];
$dailyLeft -= $current;
if ( ($current = next($priorityArraySum)) === false ) {
break;
}
}
}
print_r($output);

Find records between two time slots in php

i have time slots like
$timeslot = ['09:00-10:00', .... '23:00-00:00', '00:00-01:00'];
I have records with updated time as 23:15:00, 23:30:00, 00:15:00, 09:15:00 etc.
What i'm trying to find is the sum of records between each of the $timeslot. I'm not considering what day got updated, only time i'm looking for.
i tried with:-
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
foreach($data as $val) {
$cnt = 0;
foreach($timeslot as $slots) {
$slot = explode("-", $slots);
if( (strtotime($val) > strtotime($slot[0])) && (strtotime($val) <= strtotime($slot[1])) ) {
$up_time[$slot[0] . '-' . $slot[1]] = $cnt++;
}
}
}
echo '<pre>';print_r($up_time);echo '</pre>';
The expected output is:-
09:00-10:00 = 1
23:00-00:00 = 2
00:00-01:00 = 1
Strtotime is not required since your time can be compared as strings.
This code works as you expected.
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
$timeslot = ['09:00-10:00', '23:00-00:00', '00:00-01:00'];
$up_time = array();
foreach ($data as $val) {
$myTime = substr($val, 0, 5);
foreach ($timeslot as $slot) {
$times = explode("-", $slot);
if (substr($times[1], 0, 3) == "00:") {
$times[1] = "24:" . substr($times[1], 3);
}
if ($myTime >= $times[0] && $myTime <= $times[1]) {
if (!isset($up_time[$slot])) {
$up_time[$slot] = 1;
} else {
$up_time[$slot]++;
}
}
}
}
echo '<pre>';
print_r($up_time);
echo '</pre>';
The if with 'substr' is needed because for midnight you have '00' and not '24' so the computer thinks is an empty set (such as hours bigger then 23 and smaller then 0).
Comparison is made between string because bigger time is also a bigger string since you use 2 digits for hours.
You need to count equal slots so you need an array with an element for each slot and increment if duplicate or create an element if not found (the condition '!isset').
Update for modification request
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
// added unused slot 8:00-9:00
$timeslot = ['08:00-09:00','09:00-10:00', '23:00-00:00', '00:00-01:00'];
$up_time = array();
// new initialization
foreach ($timeslot as $slot) {
$up_time[$slot] = 0;
}
foreach ($data as $val) {
$myTime = substr($val, 0, 5);
foreach ($timeslot as $slot) {
$times = explode("-", $slot);
if (substr($times[1], 0, 3) == "00:") {
$times[1] = "24:" . substr($times[1], 3);
}
if ($myTime >= $times[0] && $myTime <= $times[1]) {
$up_time[$slot]++; // simplified
}
}
}

How to retrieve all media entries in Kaltura, beyond the 10k mark?

I am using the php5.3 SDK: https://github.com/kaltura/KalturaGeneratedAPIClientsPHP53
We have 90k media entries, but I can only got 20k entries. The following code is straight forward. Could anyone help me out?
// Main entry point
public function mywrite(Route $route, Console $console)
{
// Max records is 500, the range cannot be too big.
$range = 3600 * 24;
$this->__mywrite($route, $console, $range);
}
// Count how many objects we can get
// $veryStartDate == 1446173087, sep 2015
// $maxDate == 1526469375, may 2018
public function __mywrite($route, $console, $range) {
$configObj = $this->readMyWriteHistoryConfigFile();
$lastProcessObj = $this->readMyWriteLastProcessFile();
//
$veryStartDate = $configObj->veryStartDate;
$maxDate = $configObj->maxDate;
// Set start Date
$startDate = $veryStartDate;
$endDate = $startDate + $range;
//
$totalCount = 0;
while($startDate <= $maxDate) {
$objs = $this->listMediaByLastPlay($startDate, $endDate);
$totalCount += count($objs);
echo "\n$startDate - $endDate:\n";
echo "\n". count($objs). "\n";
$startDate = $endDate + 1;
$endDate = $endDate + $range;
} // end while loop
// we get like 25k records, but we have 90k records....
echo "\ncount: $totalCount\n";
}
// we call the client and get records by start last play date and end last play date
public function listMediaByLastPlay($startDate, $endDate) {
// Page size
$pageSize = 1000;
// Client with admin
$client = $this->getClient(\KalturaSessionType::ADMIN);
// media
$mediaObj = $client->media;
// Set a range to pull, order by last played at
$filter = new \KalturaMediaEntryFilter();
$filter->lastPlayedAtGreaterThanOrEqual = $startDate;
$filter->lastPlayedAtLessThanOrEqual = $endDate;
$filter->orderBy = '+lastPlayedAt';
// We still want more records
$pager = new \KalturaFilterPager();
$pager->pageSize = $pageSize;
// now list.....
$arr = $mediaObj->listAction($filter, $pager)->objects;
$buf = array();
foreach($arr as $k => $v) {
$t = array();
$t['dataUrl'] = $v->dataUrl;
$t['flavorParamsIds'] = $v->flavorParamsIds;
$t['plays'] = $v->plays;
$t['views'] = $v->views;
$t['lastPlayedAt'] = $v->lastPlayedAt;
$buf[] = $t;
}
return $buf;
}
You're iterating on the first page of each response, there might be more that one page.
The kaltura ListResponse has a totalCount property.
so you code should something like:
$pager = new \KalturaFilterPager();
$pageIndex = 1;
$entriesGot = 0;
$buf = array();
do
{
$pager->pageSize = $pageSize;
$pager->pageIndex = $pageIndex++;
// now list.....
$response = $mediaObj->listAction($filter, $pager);
$arr = $response->objects;
$entriesGot += count($arr);
foreach($arr as $k => $v) {
$t = array();
$t['dataUrl'] = $v->dataUrl;
$t['flavorParamsIds'] = $v->flavorParamsIds;
$t['plays'] = $v->plays;
$t['views'] = $v->views;
$t['lastPlayedAt'] = $v->lastPlayedAt;
$buf[] = $t;
}
}while($entriesGot < $response->totalCount);

PHP For Loop, Compare Incrementing Value to Incrementing Array

Short question: I am trying to see if a variable ($y) is between multiple array values from a database ($ending[0] && $starting[0], $ending[1] && $starting[1], etc...). "If" $y is between any of those, echo "statement".
I'm using a for loop to increment a drop down in 30 minute intervals from 9am - 7pm.
If any of those times = a time saved within my database, it echoes "not available" instead.
Now I need to see "if" the dropdown time is "between" the start and end times in the database and make those "not available" as well.
Everything works if I manually identify which array keys to compare...but my question is: can I check the drop down value against all of the values in the arrays?
Example:
Start Dropdown: 09:00am 09:30am 10:00am etc up until 07:30pm. End Dropdown: 09:30am 10:00am 10:30am etc. up until 08:00pm. If there is a start and end time of 09:00am(start) 10:00am(end) saved in the database for an appointment, the dropdown will show "Not available" for the corresponding starting and end times, so a user cannot double book an appointment. What I am asking about, is how to identify all of the "in between" values...09:30am for example, cannot be a start or an end time, if the 09:00am-10:00am slot is already booked.
$sql_slots = "SELECT * FROM XXXXX WHERE date = '$query_date' ORDER BY XXXXX ASC";
$result_slots = mysqli_query($connection, $sql_slots);
$open = strtotime("9:00am");
$close = strtotime("9:30am");
$starting = array();
$ending = array();
while($row_result_slots = mysqli_fetch_assoc($result_slots)){
$starting[] = $row_result_slots['start_time'];
$ending[] = $row_result_slots['end_time'];
}
echo'
<select name="start_time">';
for($b = 0; $b <= 20; $b++){
$y = strtotime(($b*30) . " Minutes", $open);
$the_time = date("h:ia", $y);
// Here, instead of only comparing the first values in the array, I need to match it up against $ending[1] & $starting[1], $ending[2] & $starting[2], etc...
if(in_array($the_time, $starting) || ($y <= strtotime($ending[0]) && $y >= strtotime($starting[0]))){
echo "<option>Not Available<br></option>";
} else {
echo "<option>" . $the_time . "<br></option>";
}
}
echo'</select>';
How about that?
$sql_slots = "SELECT * FROM XXXXX WHERE date = '$query_date' ORDER BY XXXXX ASC";
$result_slots = mysqli_query($connection, $sql_slots);
$open = strtotime("9:00am");
$close = strtotime("9:30am");
$reserved = array();
while($row_result_slots = mysqli_fetch_assoc($result_slots)){
$start = $row_result_slots['start_time'];
while ($start <= $row_result_slots['end_time']) {
$reserved[$start] = true;
$start = date("Y/m/d h:i:s", strtotime($start . "+30 minutes"));
}
}
echo '<select name="start_time">';
for($b = 0; $b <= 20; $b++){
$y = strtotime(($b*30) . " Minutes", $open);
$the_time = date("h:ia", $y);
if(isset($reserved[$the_time]){
echo "<option>Not Available<br></option>";
} else {
echo "<option>" . $the_time . "<br></option>";
}
}
echo'</select>';
Below is what I came up with. This uses a do while loop and creates a reserved array that will fill all time between what is given in the appointment.
I updated the data to use my own array but updated your mysqli work with what should be correct. If not I left in my testing code for you to view if needed. I also used the disabled attribute on an option over outputting some text.
<?php
$sql_slots = "SELECT * FROM XXXXX WHERE date = '$query_date' ORDER BY XXXXX ASC";
$result_slots = mysqli_query($connection, $sql_slots);
$open = strtotime("9:00am");
$close = strtotime("7:00pm");
$space = 900; //15min * 60 seconds space between?
//This seems more normal for people to see.
//Simulate these appoinments
/*
$query_results = array(
array(
"start_time" => "9:00am",
"end_time" => "9:30am"
),
array(
"start_time" => "10:30am",
"end_time" => "11:30am"
),
array(
"start_time" => "11:45am",
"end_time" => "12:30pm"
)
);
*/
$reserved = array();
while($row_result_slots = mysqli_fetch_assoc($result_slots)){
//**NOTE**: Make sure these are times or use strtotime()
$next_slot = $reserved[] = strtotime($row_result_slots['start_time']);
$end_time = strtotime($row_result_slots['end_time']);
while($next_slot < $end_time){
$next_slot += $space;
$reserved[] = $next_slot;
}
}
/*
foreach($query_results as $appoinment) {
$next_slot = $reserved[] = strtotime($appoinment['start_time']);
$end_time = strtotime($appoinment['end_time']);
while($next_slot < $end_time){
$next_slot += $space;
$reserved[] = $next_slot;
}
}
*/
echo'<select name="start_time">';
$current = $open;
do {
$disabled = in_array($current, $reserved) ? 'disabled' : '';
echo '<option ' . $disabled . '>' . date("h:ia", $current) . '</option>';
$current += $space;
} while($current <= $close);
echo'</select>';

WooCommerce Bookings - Available dates as drop down menu

I'm trying to customize the booking experience. My products are tours spread over the year and scrolling through the calendar to find an available day isn't efficient. What I want is a drop down list that has the next available day for that tour. Is there any plugin or solution for my situation?
Hi The file is located in wp-content/plugins/woocommerce-bookings/templates/booking-form
The code in the post described works for the most part but there are some errors
Warning: reset() expects parameter 1 to be array, string given in /home/betaacademyofflo/public_html/wp-content/plugins/woocommerce-bookings/templates/booking-form/date-picker.php on line 54
Warning: Variable passed to each() is not an array or object in /home/betaacademyofflo/public_html/wp-content/plugins/woocommerce-bookings/templates/booking-form/date-picker.php on line 55
This error appears for every date available.
A tweak that I am trying to make is that currently the select list shows duplicates of each date I need it to just show the date once.
By each date once I mean just the start date my bookings have the same start and end date.
You can see an example here example list I have suppresed the errors for now.
heres the code so far pretty much the same as the OP version on wordress support.
<?php
$year = array();
$month = array();
$days = array();
$s;
$day1;
$i=0;
$j=0;
foreach ($availability_rules as $value) {
foreach ( $value as $value2) {
foreach ( $value2 as $value3) {
reset($value3);
while (list($key, $val) = each($value3)) {
$year[$i] = $key; //add year to array - $i is the count of how many course
reset($val);
while (list($key2, $val2) = each($val)) {
if($key2 < 10){
$month[$i] = '0'.$key2; //add the month value to another array - with leading 0
}else{
$month[$i] = $key2; //add the month value to another array
}
$s = "";
$j = 0;
reset($val2);
while (list($key3, $val3) = each($val2)) {
if($j==0||$j==1){
$s = $s . $key3 .',';
}else{
$s = $s . $key3;
}
if($j==0){
$day1[$i] = $key3; //add the day value to another array
}
$j++;
}
$days[$i] = $s;
}
$i++; //increments each time we loop through a year
}
}
}
}
$arrlength = 0;
$arrlength = count($year); //this is our total amount of courses
?>
<fieldset class="wc-bookings-date-picker <?php echo implode( ' ', $class ); ?>">
<legend><?php echo $label; ?>: </small></legend>
<select id="availableDates">
<option value="">Select Date</option>
<?php
if($arrlength==0){
echo "<option value=''>There are no dates</option>";
}else{
$todays_date = date("d-m-Y");
$today = strtotime($todays_date);
for($total_dates = $arrlength -1; $total_dates >= 0; $total_dates--){ //loop through total amount
$expiration_date =strtotime($day1[$total_dates].'-'.$month[$total_dates].'-'.$year[$total_dates]);
$actualdates = $day1[$total_dates]-$month[$total_dates]-$year[$total_dates];
$displaydates = $day1[$total_dates]/$month[$total_dates]/$year[$total_dates];
//$input = array( $day1[$total_dates]-$month[$total_dates]-$year[$total_dates]);
//$result = array_keys($input);
if ($expiration_date > $today) {
echo "<option value='$day1[$total_dates]-$month[$total_dates]-$year[$total_dates]'>$day1[$total_dates]/$month[$total_dates]/$year[$total_dates]</option>"; //pull in the index for each date array
}
}
}
?>
What I've tried;
Running an extra foreach on the final result did not work
tried array_unique did not work
Anny guidance here would be most aprreciated.

Categories