I created the following Array ($stuArr) in PHP.
I want to print the Array in an HTML-Table so that I can create a Table like this (Calendar-System):
The numbers in the table are the dates of the month.
And each user has a own row. I generate the table with this:
$days = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$days = $days + 2;
echo "<table border='1'>";
echo "<tr>";
for ($j = 0; $j < $days; $j++) {
echo "<th>$j</th>";
}
echo "</tr>";
//Person
$file = file_get_contents('MOCK_DATA-100.json');
$data = json_decode($file);
//Events
$file2 = file_get_contents('calendar.json');
$data2 = json_decode($file2);
$stuArr = [];
foreach($data as $student) {
$id = $student->id;
$name = $student->name;
$mark = false;
foreach($data2 as $cal) {
if($cal->resource == $id) {
$start = new DateTime(substr($cal->start, 0, 10));
$end = new DateTime(substr($cal->end, 0, 10));
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
$dd = [];
if($month == $start->format('n')) {
foreach ($period as $dt) {
if($month != $dt->format('n'))
break;
$dd[] = $dt->format("j");
}
$stuArr[] = [$id, $dd];
}
}
}
}
var_export($stuArr);
foreach($stuArr as $student) {
$id = $student[0];
$dates = $student[1];
}
echo "</table>";
Output of var_export($stuArr);:
array ( 0 => array ( 0 => '2', 1 => array ( 0 => '22', 1 => '23', 2 => '24', 3 => '25', ), ), 1 => array ( 0 => '3', 1 => array ( 0 => '23', 1 => '24', 2 => '25', ), ), )
Thanks for your help! Regards, Fynn
If you have any question for me or need an explanation of some part of the code, just say it!!!
Error:
Try the below code. I can see you printed o-29 as days, try starting from 1 instead of 0 in the loop.
// update inside the Student loop, previous code remains as it is
foreach($stuArr as $student) {
$dates = $student[1];
echo "<tr>";
for ($j = 1; $j <= $days; $j++) {
if(in_array($j, $dates))
echo "<td>X</t>";
else
echo "<td> </td>";
}
echo "</tr>";
}
Related
I have a question about how to make an iteration. I want to place a total row after each item in the array if the next element in the array matches a specific condition. Spesific conditions have logic like this
the data like this
if i request a qty for example = 60 the result i hope like this
you can see
data[2] = 01/03/2020 just took 10 out of 40
$iter = new \ArrayIterator($values);
$sum = 0;
foreach($values as $key => $value) {
$nextValue = $iter->current();
$iter->next();
$nextKey = $iter->key();
if(condition) {
$sum += $value;
}
}
dd($iter);
how to make this logic work on php language/ laravel?
Following logic might help you on your way:
<?php
$stock = [
'01/01/2020' => 20,
'01/02/2020' => 30,
'01/03/2020' => 40
];
showStatus($stock, 'in stock - before transaction');
$demand = 60;
foreach ($stock as $key => $value) {
if ($value <= $demand) {
$stock[$key] = 0;
$supplied[$key] = $value;
$demand -= $value;
} else {
$stock[$key] -= $demand;
$supplied[$key] = $value - ($value - $demand);
$demand = 0;
}
}
showStatus($supplied, 'supplied');
showStatus($stock, 'in stock - after transaction');
function showStatus($arr = [], $msg = '')
{
echo $msg;
echo '<pre>';
print_r($arr);
echo '</pre>';
}
?>
**Output:**
in stock - before transaction
Array
(
[01/01/2020] => 20
[01/02/2020] => 30
[01/03/2020] => 40
)
supplied
Array
(
[01/01/2020] => 20
[01/02/2020] => 30
[01/03/2020] => 10
)
in stock - after transaction
Array
(
[01/01/2020] => 0
[01/02/2020] => 0
[01/03/2020] => 30
)
Working demo
I'm not sure I've understood you correctly but this might help:
$values = [
'01/01/2020' => 20,
'01/02/2020' => 30,
'01/03/2020' => 40
];
$demand = 60;
$total = array_sum($values);
$decrease = $total - $demand; //(20+30+40) - 60 = 30
$last_key = array_keys($values,end($values))[0]; //Is 01/03/2020 in this case
$values[$last_key] -= $decrease; //Decrease value with 30 calulated above
Would output:
Array
(
[01/01/2020] => 20
[01/02/2020] => 30
[01/03/2020] => 10
)
I have to create a html table for a room booking system, but i have hit a wall trying to think of ways to insert data into cells. At the moment i am getting data from a database (start time and end time for the booking). I then loop through the times from an array and use an if statement to compare the start time to the time in the time array.
This is what i have at the moment :
Room booking image
The main problem that i am having is that in my database if there are two bookings on the same day it will only show that last one in the array.
$tableStart = "<table class='table_main'><thead><tr id='table_first' class='first_last'><th class='first_last'>Time:</th>";
$tableMid = "</tr></thead><tbody>";
$tableEnd = "</tbody></table>";
foreach ($newBookings as $booking) {
$tableStart .= "<th class='first_last'>$booking[0]</th>";
}
foreach ($times as $time) {
$tableMid .= "<tr class='even_row'><td class='time'>{$time['times']}</td>";
$i = 0;
foreach ($newBookings as $booking) {
unset($booking[0]);
$x = count($booking);
if ($x > 0) {
if ($booking[$i]['start_Time'] == $time['times']) {
$tableMid .= "<td class='new'>{$booking[$i]['start_Time']}</td>";
} else if($booking[$i]['end_Time'] == $time['times']) {
$tableMid .= "<td class='new'>{$booking[$i]['end_Time']}</td>";
} else {
$tableMid .= "<td class='new'></td>";
}
} else {
$tableMid .= "<td class='new'></td>";
}
++$i;
}
}
$tableStart .= $tableMid;
$tableStart .= $tableEnd;
return $tableStart;`
The way i have my data set up at the moment in the arrays currently look like this:
$times = [
0 => ['06:00'],
1 => ['06:30'],
2 => ['07:00'],
3 => ['07:30'],
4 => ['08:00'],
5 => ['08:30'],
6 => ['09:00'],
7 => ['09:30'],
8 => ['10:00'],
9 => ['10:30'],
10 => ['11:00'],
11=> ['11:30'],
12 => ['12:00'],
13 => ['12:30'],
14 => ['13:00'],
15 => ['13:30'],
16 => ['14:00'],
17 => ['14:30'],
18 => ['15:00'],
19 => ['15:30'],
20 => ['16:00'],
21 => ['16:30'],
22 => ['17:00'],
23 => ['17:30'],
24 => ['18:00'],];
$newBookings = [
0 => [
0 => 'Room 33'
],
1 => [
0 => 'New room 8',
1 => [
'room_Name' => 'New room 8',
'start_Time' => '11:30',
'end_Time' => '12:30'
]
],
2 => [
0 => 'sds',
1 => [
'room_Name' => 'sds',
'start_Time' => '09:30',
'end_Time' => '11:30'
],
2 => [
'room_Name' => 'sds',
'start_Time' => '14:30',
'end_Time' => '16:30'
]
],
3 => [
0 => 'New Room 3'
],
4 => [
0 => 'NewRoom5'
],
5 => [
0 => 'New room 55'
]
];
I apologise if i have left anything out or am too vague with my description. Thank you
For anyone who sees this i found a fix, i used ADyson's recommendation for the array and reworked my code so that it now works correctly. For anyone interested here is the code i used :
public function render(): string
{
$data = $this->tableData; //from abstract class contains table data
$times = $this->tableTimes; //gets times
$rooms = $this->roomNames; //gets room names
$startTime = $times[0]['start_time']; //sets the start time
$endTime = $times[0]['end_time']; // sets the end time
$times = $this->setTimeArray($startTime, $endTime); //goes to function
$newBookings = $this->setDataArray($data, $rooms); // goes to function
$tableStart = "<table class='table_main'><thead><tr id='table_first' class='first_last'><th class='first_last'>Room:</th>";
$tableMid = "</tr></thead><tbody>";
$tableEnd = "</tbody></table>";
foreach ($times as $key => $time) {
$tableStart .= "<th class='first_last'>{$time}</th>";
}
foreach ($newBookings as $booking) {
$tableMid .= "<tr class='even_row'><td class='room_Name'>{$booking['Room']}</td>";
$x = 0;
$e = 0;
foreach ($times as $time) {
if ($x == count($booking['Bookings'])) {
$x = 0;
}
if ($e == count($booking['Bookings'])) {
$e = 0;
}
if (count($booking['Bookings']) < 1) {
$tableMid .= "<td class='new'></td>";
} else if ($booking['Bookings'][$x]['start_Time'] == $time) {
$tableMid .= "<td class='room_Booked'>{$booking['Bookings'][$x]['start_Time']}</td>";
$x++;
} else if ($booking['Bookings'][$e]['end_Time'] == $time) {
$tableMid .= "<td class='room_Booked'>{$booking['Bookings'][$e]['end_Time']}</td>";
$e++;
} else {
$tableMid .= "<td class='new'></td>";
}
}
}
$tableStart .= $tableMid;
$tableStart .= $tableEnd;
return $tableStart;
}
Setting the times to an array
public function setTimeArray($startTime, $endTime)
{
$i = 0;
$endTimes = strtotime($endTime);
$endTime = date("H:i", strtotime('+30 minutes', $endTimes));
do {
$times[$i] = $startTime;
$time = strtotime($startTime);
$startTime = date("H:i", strtotime('+30 minutes', $time));
$i++;
} while ($startTime != $endTime);
return ($times);
}
Putting room booking data into one array
public function setDataArray($data, $rooms)
{
$newBookings = [];
$x = 0;
foreach ($rooms as $key) {
$newBookings[$x] = array(
'Room' => $key['room_name'], 'Bookings' => []
);
$y = 0;
foreach ($data as $value) {
if ($value['room_name'] == $newBookings[$x]['Room']) {
$newBookings[$x]['Bookings'][$y] = [
'room_Name' => $value['room_name'],
'start_Time' => $value['requested_time'],
'end_Time' => $value['requested_time_end']
];
$y++;
}
}
$x++;
}
return ($newBookings);
}
I have a two-dimensional array containing events and dates:
$events = array(
array('event' => 'event1', 'date' => '2016-05-05'),
array('event' => 'event2', 'date' => '2016-05-08'),
array('event' => 'event3', 'date' => '2016-05-08'),
array('event' => 'event4', 'date' => '2016-05-10'),
array('event' => 'event5', 'date' => '2016-05-10'),
array('event' => 'event6', 'date' => '2016-05-11'),
array('event' => 'event7', 'date' => '2016-05-11'),
array('event' => 'event8', 'date' => '2016-05-13')
};
Let's say today is 2016-05-10 and I want to create 3 new arrays:
$recent - all events happened on the previous available day
$today - all events today
$upcoming - all events happening on the next available day
$today is easy:
$today = array();
for($i = 0; $i < count($events); ++$i) {
if($events[$i]['date'] == date("Y-m-d") {
array_push($today, $events[$i]['event']);
}
}
So, I will need $recent to contain event2 and event3, and $upcoming to contain event6 and event7.
The question is how to find the recent and the upcoming ones.
*Clarification:
I don't want all the events in $recent happened before today, but the events happened on the previous available day. So in this case only events happened on 2016-05-08
// Take all dates from source array
$dates = array_unique(array_map(function ($i) { return strtotime($i); } , array_column($events, 'date')));
sort($dates);
$today = strtotime('midnight');
// find previouse date. It will be 1970-1-1 if not present in array
$prev = #max(array_filter($dates, function($i) use($today) { return $i < $today; }));
// find ัััะต date. It will be 1970-1-1 if not present in array
$next = #min(array_filter($dates, function($i) use($today) { return $i > $today; }));
$prev = date('Y-m-d', $prev);
$next = date('Y-m-d', $next);
// fill arrays
$recent = array();
$upcoming = array();
$today = array();
for($i = 0; $i < count($events); ++$i) {
if($events[$i]['date'] == date('Y-m-d')) {
array_push($today, $events[$i]['event']);
}
if($events[$i]['date'] == $prev) {
array_push($recent, $events[$i]['event']);
}
if($events[$i]['date'] == $next) {
array_push($upcoming , $events[$i]['event']);
}
}
Try with creating three (3) blank array, check the date is greater or less than today or not and push into array according to conditions.
$today = array();
$upcoming = array();
$recent = array();
$thisDay = date("Y-m-d");
$count = count($events);
$max = max(array_column($events, 'date'));
$min = min(array_column($events, 'date'));
for($i = 0; $i < $count; $i++){
if($events[$i]['date'] > $thisDay){
$max = ($max > $events[$i]['date']) ? $events[$i]['date'] : $max;
array_push($upcoming, $events[$i]['event']);
array_push($upcoming_dates, $events[$i]['date']);
}
elseif($events[$i]['date'] < $thisDay){
$min = ($min < $events[$i]['date']) ? $events[$i]['date'] : $min;
array_push($recent, $events[$i]['event']);
array_push($recent_dates, $events[$i]['date']);
}
else
array_push($today, $events[$i]['event']);
}
foreach($recent_dates as $key => $value){
if($value != $min)
unset($recent[$key]);
}
foreach($upcoming_dates as $key => $value){
if($value != $max)
unset($upcoming[$key]);
}
echo '<pre>';
print_r($today);
print_r($upcoming);
print_r($recent);
Result
Today:
Array
(
[0] => event4
[1] => event5
)
Upcoming:
Array
(
[0] => event6
[1] => event7
)
Recent:
Array
(
[1] => event2
[2] => event3
)
Note: You use push_array which is not any library function in PHP. For Re-index of recent and upcoming you can use array_values.
Another solution should be
$recent = array();
$upcoming = array();
$today = array();
$all_dates = array();
foreach ($events as $event):
array_push($all_dates, $event['date']);
endforeach;
if ($key = array_search('2016-05-10', $all_dates)) {
$prev_date = $all_dates[$key - 1];
}
for ($i = 0; $i < count($all_dates); $i++) {
if ($all_dates[$i] > $all_dates[$key]) {
$next_date = $all_dates[$i + 1];
break;
}
}
for ($i = 0; $i < count($events); ++$i) {
if ($events[$i]['date'] == date('Y-m-d')) {
array_push($today, $events[$i]['event']);
}
if ($events[$i]['date'] == $prev_date) {
array_push($recent, $events[$i]['event']);
}
if ($events[$i]['date'] == $next_date) {
array_push($upcoming, $events[$i]['event']);
}
}
echo '<pre>';
print_r($upcoming);
print_r($today);
print_r($recent);
Output will be
Array
(
[0] => event6
[1] => event7
)
Array
(
[0] => event4
[1] => event5
)
Array
(
[0] => event2
[1] => event3
)
I am trying to create a schedule of who uses a specific item on which day.
I have 2 arrays.
one with dates &
another with names and how many days they can use the item.
i have managed to create dates array using this.
function dateArray($from, $to, $value = NULL) {
$begin = new DateTime($from);
$end = new DateTime($to);
$interval = DateInterval::createFromDateString('1 day');
$days = new DatePeriod($begin, $interval, $end);
$baseArray = array();
foreach ($days as $day) {
$dateKey = $day->format("d-m-Y");
$baseArray[$dateKey] = $value;
}
return $baseArray;
}
$dates_array = dateArray('01-01-2014', '30-09-2014',true);
print_r($dates_array );
which gives me dates as
Array
(
[01-01-2014] => 1
[02-01-2014] => 1
[03-01-2014] => 1
[04-01-2014] => 1
[05-01-2014] => 1
[06-01-2014] => 1
[07-01-2014] => 1
[08-01-2014] => 1
[09-01-2014] => 1
and so on.
)
i have another array of names having name as key and days as value , they can use the item like this.
$names_array = array("name1" => "4", "name2" => "3", "name3" => "1");
Now i would like to assign names to dates depending on how many days the person can use the item.
like this.
I need my final output array to be like this
Array
(
[01-01-2014] => name1
[02-01-2014] => name1
[03-01-2014] => name1
[04-01-2014] => name1
[05-01-2014] => name2
[06-01-2014] => name2
[07-01-2014] => name2
[08-01-2014] => name3
[09-01-2014] => name1
and so on. notice name1 comes again
)
so i am trying to get output like above but i am failing at the while loop inside the foreach.
so far i have tried this.
function dateArray($from, $to, $value = NULL) {
$begin = new DateTime($from);
$end = new DateTime($to);
$interval = DateInterval::createFromDateString('1 day');
$days = new DatePeriod($begin, $interval, $end);
$baseArray = array();
foreach ($days as $day) {
$dateKey = $day->format("d-m-Y");
$baseArray[$dateKey] = $value;
}
return $baseArray;
}
$dates_array = dateArray('01-01-2014', '30-09-2014',true);
$names_array = array("name1" => "4", "name2" => "3", "name3" => "1");
print_r($dates_array );
$new_dates = array();
foreach($dates_array as $dates => $key){
//echo $dates;
foreach ($names_array as $name => $days){
while($days <= 1){
$new_dates[$dates] = $name ;
$days = $days - 1;
}
}
}
print_r($new_dates);
But my final array is empty.
so how can i solve this ?
You can use a MultipleIterator whereby the second array (names) loops around when needed:
$names_array = array();
// unwind the array values
foreach (array("name1" => "4", "name2" => "3", "name3" => "1") as $value => $freq) {
for ($i = 0; $i < $freq; ++$i) {
$names_array[] = $value;
}
}
// attach both arrays
$m = new MultipleIterator;
$m->attachIterator(new ArrayIterator(array_keys($dates_array)));
$m->attachIterator(new InfiniteIterator(new ArrayIterator($names_array)));
// build final array
$result = array();
foreach ($m as $value) {
$result[$value[0]] = $value[1];
}
It should probably go like this...
while($days <= 1){
$new_dates[$dates] = $name ;
$names_array[$name] = $days - 1;
}
Hi You can try this one
$dates_array = array_keys(dateArray('01-01-2014', '30-09-2014',true));
$names_array = array("name1" => "4", "name2" => "3", "name3" => "1");
$new_dates = array();
$daysindex = 0;
while($daysindex < count($dates_array)){
foreach ($names_array as $name => $day){
for($x = 0; $x<$day; $x++){
if(isset($dates_array[$daysindex])){
$new_dates[$dates_array[$daysindex]] = $name ;
$daysindex++;
}
}
}
}
print_r($new_dates);
$dates = dateArray('01-01-2014', '30-09-2014',true);
$names = array('name1' => 4,'name2' => 3,'name3' => 1);
$count = current($names);
$name = key($names);
foreach($dates as &$value) {
$value = $name;
//if we've displayed a name $count times, move to the next name
if(--$count == 0) {
//if we're at the end of $names, wrap around
if(false === next($names)) {
reset($names);
}
$count = current($names);
$name = key($names);
}
}
print_r($dates);
For a rent application, I have an array $dates like this:
Array
(
[2013-07-19] => 1
[2013-07-21] => 3
[2013-07-23] => 2
[2013-07-24] => 4
[2013-07-25] => 4
[2013-07-26] => 2
[2013-07-27] => 2
[2013-07-30] => 3
[2013-07-31] => 1
)
The date is the key, and the values are the number of items rent in that day for a specific product
How can I split this array in many sub arrays containing each a list of consecutive days?
Like this:
Array
(
[0] => Array
(
[2013-07-19] => 1
)
[1] => Array
(
[2013-07-21] => 3
)
[2] => Array
(
[2013-07-23] => 2
[2013-07-24] => 4
[2013-07-25] => 4
[2013-07-26] => 2
[2013-07-27] => 2
)
[3] => Array
(
[2013-07-30] => 3
[2013-07-31] => 1
)
)
$newArray = array();
foreach ($array as $date => $value)
{
// Make sure the newArray starts off with at least one element
if (empty($newArray))
$newArray[] = array();
// Calculate the difference in dates.
// (I like using DateTime, but use whichever method you like)
$dateTime = new DateTime($date);
$lastDateTime = new DateTime($lastDate);
$dateDiff = $dateTime->diff($lastDateTime);
// Add a new array to the end if the difference between this element and the last was more than a day
if ($dateDiff->days > 1)
$newArray[] = array();
// We can now be guaranteed that the last element of $newArray is the one we want to append to
$newArray[count($newArray) - 1][$date] = $value;
// Keep track of the last date you saw
$lastDate = $date;
}
Here it is in action: https://eval.in/38039
$newArray = array();
$i = 0;
foreach ($array as $date => $key) {
$thisDay = end(explode('-', $date));
$nextDay = end(explode('-', next($array[$date])));
if ($thisDay + 1 != $nextDay + 0)
$i++;
if (!isset($newArray[$i])) {
$newArray[$i] = array($date => $key);
} else {
if (!isset($newArray[$i][$date])) {
$newArray[$i][$date] = $key;
} else {
$newArray[$i][$date] = $key;
}//END IF
}//END IF
}//END FOREACH LOOP
This is the code i would use to do what you are asking.
UPDATE:
I was wrong above. i have altered the code to work this time:
$newArray = array();
$i = 0;
foreach ($array as $date => $key) {
$thisDay = end(explode('-', $date));
$nextDay = array_key_exists(date('Y-m-d', strtotime($date . ' +1 day')), $array);
if (!isset($newArray[$i])) {
$newArray[$i] = array($date => $key);
} else {
if (!isset($newArray[$i][$date])) {
$newArray[$i][$date] = $key;
} else {
$newArray[$i][$date] = $key;
}//END IF
}//END IF
if (!$nextDay)
$i++;
}//END FOREACH LOOP
Here is my test case:
<?php
$array = array(
'2013-07-19' => 1,
'2013-07-21' => 3,
'2013-07-23' => 2,
'2013-07-24' => 4,
'2013-07-25' => 4,
'2013-07-26' => 2,
'2013-07-27' => 2,
'2013-07-30' => 3,
'2013-07-31' => 1
);
echo '<pre>' . print_r($array, true) . '</pre>';
$newArray = array();
$i = 0;
foreach ($array as $date => $key) {
$thisDay = end(explode('-', $date));
$nextDay = array_key_exists(date('Y-m-d', strtotime($date . ' +1 day')), $array);
if (!isset($newArray[$i])) {
$newArray[$i] = array($date => $key);
} else {
if (!isset($newArray[$i][$date])) {
$newArray[$i][$date] = $key;
} else {
$newArray[$i][$date] = $key;
}//END IF
}//END IF
if (!$nextDay)
$i++;
}//END FOREACH LOOP
echo '<pre>' . print_r($newArray, true) . '</pre>';
?>
you can do it like this:
$data = array(
'2013-07-19' => 1,
'2013-07-21' => 3,
'2013-07-23' => 2,
'2013-07-24' => 4,
'2013-07-25' => 4,
'2013-07-26' => 2,
'2013-07-27' => 2,
'2013-07-30' => 3,
'2013-07-31' => 1
);
$result = array();
$ref = new DateTime('1821-11-11');
foreach ($data as $datum => $nb) {
if ($ref->add(new DateInterval('P1D'))->format('Y-m-d')!=$datum) {
$result[] = array();
$ref = new DateTime($datum);
}
$result[array_pop(array_keys($result))][$datum] = $nb;
}
print_r($result);