I'm coding some kind of schedule and get stuck itterating trough the the dates.
I have a timeline generated for 5 work-days starting at 6:00h till 18:30h this is no problem.
I have a table with users and a table with dates. The users can have multiple tasks during the week.
This is the array:
Array
(
[0] => Array
(
[dateStart] => 2011-09-14 13:00:00
[dateEnd] => 2011-09-15 11:00:00
[eventType] => 1
[data] => test
[taskDescription] => Vakantieverlof
[taskColor] => ff6600
)
[1] => Array
(
[dateStart] => 2011-09-14 15:00:00
[dateEnd] => 2011-09-14 18:00:00
[eventType] => 3
[data] =>
[taskDescription] => ADV
[taskColor] => 336600
)
[2] => Array
(
[dateStart] => 2011-09-15 16:00:00
[dateEnd] => 2011-09-16 10:00:00
[eventType] => 2
[data] =>
[taskDescription] => Ziek
[taskColor] => ff0000
)
)
And this is the loop trough the array:
$dat=0;
while($dat<count($row->dates))
{
$color = "cccccc";
if(!empty($row->dates[$dat]['taskColor'])) {
$color = $row->dates[$dat]['taskColor'];
$desc = $row->dates[$dat]['taskDescription'];
} else {
$color = "cccccc";
}
$datNext = $dat+1;
if($datNext >= count($row->dates)) $datNext = $dat;
if($row->dates[$datNext]['dateStart'] >= $hourCons AND $dat >= count($row->dates))
{
$dat++;
} else {
if( $row->dates[$dat]['dateStart'] < $hourConsEnd AND $row->dates[$dat]['dateEnd'] > $hourCons )
{
$wpcal .= "<div class=\"fullCell\" style=\"".$transparent." background-color: #".$color.";\"></div>";
} else {
$wpcal .= "<div class=\"emptyCell\" style=\"\"></div>";
}
}
$dat++;
}
Now I get 3 timelines representing each planned task. like this:
Screenshot
But I want 1 timeline containing each of these tasks... the green task in this case may overlap the orange.
Please help I'm strungling with it for a couple of days now...
Instead of looping through the array of appointments, loop through hours of the day for each day. Inside that loop, check if any of the appointments overlap that time, and draw filled if so.
$filled_flag = false;
foreach ($row->dates as $appt) {
if ($appt['dateStart'] < $hourConsEnd && $appt['dateEnd'] > $hourCons) {
$filled_flag = true;
break;
}
}
if ($filled_flag) {
$wpcal .= "<div class=\"fullCell\" style=\"".$transparent." background-color: #".$color.";\"></div>";
} else {
$wpcal .= "<div class=\"emptyCell\" style=\"\"></div>";
}
You need to merge the arrays into one array first, before you loop through them generating the <div>s. For example you can precreate an array with all the 'slots', and then fill them with the most applicable task. In the foreach where you do the merge, you can apply some business logic, like if the task is completely overlapped by another one, overwrite its slots etc.
Eventually my Array is part of an object per user:
stdClass Object
(
[id] => 2
[username] => Emminet
[user_level] => 100
[dates] => Array
(
[0] => Array
(
[dateStart] => 2011-09-07 07:00:00
[dateEnd] => 2011-09-14 15:29:59
[eventType] => 3
[data] => Dit is dan veld 2...
[taskDescription] => ADV
[taskColor] => 336600
)
[1] => Array
(
[dateStart] => 2011-09-14 09:00:00
[dateEnd] => 2011-09-14 16:29:59
[eventType] => 3
[data] => dit is veld 1
[taskDescription] => ADV
[taskColor] => 336600
)
[2] => Array
(
[dateStart] => 2011-09-15 12:30:00
[dateEnd] => 2011-09-15 16:29:59
[eventType] => 3
[data] =>
[taskDescription] => ADV
[taskColor] => 336600
)
)
)
So I loop through the users and for every user I loop trough the week like this:
for($day=1; $day<=7; $day++){
// Timeframing settings
$startDayAt = "06:00";
$frameAmount = 26;
$timeFrame = 30; // minutes
// Timeframing output
for($i=0,$eTime = strtotime($startDayAt); $i < $frameAmount; $i++, $eTime = strtotime("+$timeFrame minutes", $eTime)) {
$dat=0;
while($dat<count($row->dates))
{
$color = "cccccc";
if(!empty($row->dates[$dat]['taskColor'])) {
$color = $row->dates[$dat]['taskColor'];
$desc = $row->dates[$dat]['taskDescription'];
} else {
$color = "cccccc";
}
$datNext = $dat+1;
if($datNext >= count($row->dates)) $datNext = $dat;
if($row->dates[$datNext]['dateStart'] >= $hourCons AND $dat >= count($row->dates))
{
$dat++;
} else {
if( $row->dates[$dat]['dateStart'] < $hourConsEnd AND $row->dates[$dat]['dateEnd'] > $hourCons )
{
$wpcal .= "<div class=\"fullCell\" style=\"".$transparent." background-color: #".$color.";\"></div>";
} else {
$wpcal .= "<div class=\"emptyCell\" style=\"\"></div>";
}
}
$dat++;
}
}
}
So that's my actual loop, trough the days and then the hours and later the users...
Related
What i am attempting to do is something like this
[Col-3][Col-3][Col-3][Col-3]
[Col-4][Col-4][Col-4]
[Col-3][Col-3][Col-3][Col-3]
I am continuing this with a foreach statement, but without luck at the moment.
Currently i'm just doing something like this.
$post = new mm_post();
$rows = $post->getAllPosts();
$i = 1;
foreach ($rows as $key => $row) {
if ($i % 4 == 0) {
echo "[Col-3] <br>";
} else {
echo "[Col-4] <br>";
}
$i++;
}
I am looking for a solution and explanation for this :)
Obviously atm it just make every 3 post [col-3] but i want it to make 4 col-3 then 3 col-4 is what i am looking for.
So I hope you guys can help me! :)
Think about every 7 posts makes 2 lines...one with 4 cols and one with 3 cols:
so when the $i counter is divisible by 7 you print a < br>. Then when line element is less then 4 print col-3,when is 4 print col-3 and < br> otherwise print col-4
$post = new mm_post();
$rows = $post->getAllPosts();
$i = 1;
$line=0;
for($rows as $key => $row)
{
if($i-($line*7)<4)
{
echo "[col-3]";
}
else if($i-($line*7)==4)
{
echo "[col-3]<br>";
}
else
{
echo "[col-4]";
}
if($i%7==0)
{
echo "<br>";
$line++;
}
$i++;
}
function alternate_slices($arr) {
$slices = array();
$start = 0;
$length = 4;
while ($start < count($arr)) {
$slices[] = array_splice($arr, $start, $length);
$length = (4 - $length + 3);
}
return $slices;
}
$arr = range(1, 20);
$sliced_arr = alternate_slices($arr);
<!-- print_r($sliced_arr);
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
[1] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
[2] => Array
(
[0] => 8
[1] => 9
[2] => 10
[3] => 11
)
[3] => Array
(
[0] => 12
[1] => 13
[2] => 14
)
[4] => Array
(
[0] => 15
[1] => 16
[2] => 17
[3] => 18
)
[5] => Array
(
[0] => 19
[1] => 20
)
) -->
$sliced_arr = array_map(
function ($slice) {
return implode("||", $slice);
},
$sliced_arr
);
<!-- print_r($sliced_arr);
Array
(
[0] => 1||2||3||4
[1] => 5||6||7
[2] => 8||9||10||11
[3] => 12||13||14
[4] => 15||16||17||18
[5] => 19||20
) -->
$sliced_arr = implode("\n", $sliced_arr);
<!-- print($sliced_arr);
1||2||3||4
5||6||7
8||9||10||11
12||13||14
15||16||17||18
19||20 -->
Read about:
array_splice
array_map
implode
I am trying to create a calculation script from a JSON array (can be more or less entries) where the amount of weeks and seasons have points, and all together it should output a total, but not larger than 50.
Somewhere i make a mistake as my result is 0. As i am quite new to PHP this script already took me some time :-) Eager to learn.. can someone point me what i am doing wrong?
This is the array:
Array
(
[experiences] => Array
(
[0] => Array
(
[quantity] => 1
[unit] => seasons
[description] => skischool 1
)
[1] => Array
(
[quantity] => 5
[unit] => weeks
[description] => skischool 2
)
[2] => Array
(
[quantity] => 3
[unit] => seasons
[description] => skischool 3
)
[3] => Array
(
[quantity] => 2
[unit] => weeks
[description] => skischool 4
)
)
)
And here is my idea of the script:
$incoming = json_decode($text, true);
$experiences = Sanitize::getVar($incoming, 'experiences');
$total = 0;
$weeks_points = 0.5;
$seasons = 5;
if(!empty($experiences['experiences'])) {
foreach($experiences['experiences'] as $experience) {
if($experience['unit'] == 'seasons') {
$total = $total + ($experience['quantity'] * $sessons);
} else if($experience['unit'] == 'weeks') {
$total = $total + ($experience['quantity'] * $weeks_points);
}
}
}
$total = round($total);
echo $total = $total > 50 ? 50 : $total;
I may be wrong, but shouldn't the if and the loop look like this?
if(!empty($experiences)) {
foreach($experiences as $experience) {
Sorry if the title of the question is unclear, I couldn't sum it up more precisely.
This is the issue:
To begin with, I have an array in this format:
Array (
[0] => 09:00
[1] => 10:00
[2] => 11:00
[3] => 12:00
[4] => 13:00
[5] => 14:00
[6] => 15:00
[7] => 16:00
[8] => 17:00
[9] => 18:00
)
Then some of the members are unset, so after that we're left with something like:
Array (
[0] => 09:00
[1] => 10:00
[6] => 15:00
[7] => 16:00
[8] => 17:00
[9] => 18:00
)
As you see, the array represents time slots. Now, what I need to do is eliminate all time slots shorter than 3 hours. So I need to go through the array and, wherever there are less than 3 members of the original array present, take them out too. So in the example above, since 09:00 and 10:00 are not followed by 11:00, I need to take them out and be left with:
Array (
[6] => 15:00
[7] => 16:00
[8] => 17:00
[9] => 18:00
)
How do I accomplish this? Logically, I think it might be easiest to check for 3 consecutive indexes, rather then checking the actual times but I'm open to any suggestions.
I've solved the problem on my own, and I made it generic so it would work for any duration, not just 3 hours.
$dur=3; //could be anything
foreach($work_times as $member){
$key=array_search($member,$work_times);
$a_ok=0;
for($options=0;$options<$dur;$options++){
$thisone=1;
for($try=$key-$options;$try<$key-$options+$dur;$try++){
if(!array_key_exists($try,$work_times))
$thisone=0;
}
if($thisone==1)
$a_ok=1;
}
if($a_ok==0)
unset($work_times[$key]);
}
$arr = array(
0 => '09:00',
1 => '10:00',
6 => '15:00',
7 => '16:00',
8 => '17:00',
9 => '18:00'
);
// for some testing
$arr += array(12 => '19:00', 13 => '20:00', 14 => '21:00');
$arr += array(16 => '22:00', 17 => '23:00');
$dontRemove = array();
foreach($arr as $key => $val) {
// if the next 2 keys are set
if (isset($arr[$key+1]) && isset($arr[$key+2])) {
$dontRemove[] = $key;
$dontRemove[] = $key+1;
$dontRemove[] = $key+2;
}
}
// combine and diff the keys to get the keys which should be actually removed
$remove = array_diff(array_keys($arr), array_unique($dontRemove));
foreach($remove as $key) {
unset($arr[$key]);
}
print_r($arr);
Try this:
<?php
function check() {
global $array;
$tmpArr = array_keys( $array );
$val1 = $tmpArr[0];
$val2 = $tmpArr[1];
$val3 = $tmpArr[2];
if( ( ++$val1 == $val2 ) && ( ++$val2 == $val3 ) ) {
// continuous
} else {
// not continuous, remove it
unset( $array[$tmpArr[0]] );
}
}
$array = array(
'0' => '09:00',
'1'=> '10:00',
'6' => '15:00',
'7'=> '16:00',
'8' => '17:00',
'9' => '18:00'
);
$total = count( $array );
$ctotal = 0;
while( $ctotal < $total ) {
if( count( $array ) <= 2 ) {
// this array has 2 elements left, which obviously
// nullifies the 3 continuous element check
$array = array();
break;
} else {
//check the array backwards
check();
$total--;
}
}
?>
Hope this helps
$a = Array(
0 => "09:00",
1 => "10:00",
6 => "15:00",
7 => "16:00",
8 => "17:00",
9 => "18:00",
11 => "20:00",
);
foreach ($a as $k => $v) {
// previous or next two time slots exist
$consecutive = (isset($a[$k-1]) or
(isset($a[$k+1]) and isset($a[$k+2])));
if (!$consecutive)
unset($a[$k]);
}
I have a an array:
Array
(
[0] => Array
(
[id] => 53
[product] => something
[price] => £78
[quantity] => 23
[time] => 2011-07-15 20:29:21
)
[1] => Array
(
[id] => 52
[product] => product
[price] => £89
[quantity] => 1
[time] => 2011-07-14 00:51:57
)
[2] => Array
(
[id] => 51
[product] => product
[price] => £89
[quantity] => 1
[time] => 2011-07-14 00:51:37
))
I got this using the following sql statement:
select * from some_table GROUP BY time DESC
I want to display the results ordered by date, with the date as a heading:
e.g.
**2011-07-15**
all array elements for above date go here
**2011-07-15**
all array elements for above date go here
I thought about doing a seperate statement for each seperate day, but that sounds wrong. Is there a better way?
ORDER BY Time in your query, like this:
select * from some_table ORDER BY time DESC
Then loop in PHP:
$last_date = 0;
while($row = mysql_fetch_assoc($result)){
$date = date('Y-m-d', strtotime($row['time']));
if($date != $last_date)
echo '**'.$date.'**';
$last_date = $date;
echo '<br />';
echo 'Id: '.$row['Id'];
echo 'Product: '.$row['product'];
echo 'Price: '.$row['price'];
echo 'Quantity: '.$row['quantity'];
echo '<br /><br />';
}
If you're ouputting to a console instead of an HTML page then replace the '<br \>' with "\n"
<?
$arrDate = Array
(
[0] => Array
(
[id] => 53
[product] => something
[price] => £78
[quantity] => 23
[time] => 2011-07-15 20:29:21
);
$currentDate = null;
foreach ($arrDate as $item) {
if ($item["time"] == $currentDate) {
// print details
}
else {
$currentDate = $arrDate["time"];
// print date header.
// print details
}
}
?>
I'm trying to create a rather complex array for my calendar application. It's supposed to contain dates, with the name of the day, the 'type' and the events, if any. I got as far as creating this:
[dates] {
[22] {
[day] => [Friday]
[type] => [weekday]
}
[23] {
[day] => [Saturday]
[type] => [Weekend]
}
[24] {
[day] => [Sunday]
[type] => [Weekend]
}
}
Now I would like to add another key called 'events'. I want to add the events for each day to the array.. So I could get something like:
[24] {
[day] => [Sunday]
[type] => [Weekend]
[events] {
[1] {
[title] => [test event]
[description] => [my event]
[date] => [24-04-2011]
}
[2] {
[title] => [test event 2]
[description] => [my second event]
[date] => [24-04-2011]
}
}
Not sure if this makes sense.
I created the first example using this code:
for($i = 1; $i <= $data['days_in_curr_month']; $i++)
{
$day_info = $this->get_day_info($i, $data['current_month'], $data['current_year']);
$dates[$i]['name'] = $day_info['day_name'];
$dates[$i]['type'] = $day_info['day_type'];
}
return $dates;
I then wanted to grab the event info by doing:
$event_info = $this->get_event_info($i, $data['current_month'], $data['current_year']);
in the same for loop.
My get_event_info method looks like this:
public function get_event_info($day, $month, $year)
{
$date = $year . "-" . $month . "-" . $day;
$this->db->where('date', $date);
$this->db->where('user_id', '1');
$query = $this->db->get('tblEvents');
$event_info = array();
foreach($query->result() as $row)
{
$event_info['events'][$row->id]['title'] = $row->title;
$event_info['events'][$row->id]['description'] = $row->description;
}
return $event_info;
}
It outputs arrays like this:
Array ( [events] => Array ( [1] => Array ( [title] => Project 2 [description] => Test: Project 2 ) [2] => Array ( [title] => Illustrator [description] => Test: Illustrator 2 ) ) )
Now, I return the $event_info from get_events_info to the create_dates_list method, but I'm not sure how I would go about adding my event arrays to the $dates array.
The get_event_info gets the events for each date (1 - end of month-). I then want to add those to my $dates array in the format listed above in my second example.
I'm confused cause these are rather complex arrays. Thanks in advance.
I think all you need to do is (for example):
$append_events = get_event_info($day, $month, $year);
$array['dates']['1']['event'] = $append_events['events'];
Then you can access your elements:
$array['dates']['1']['event'][$id]['title']
$array['dates']['1']['event'][$id]['description']