2

For a calendar, I read start date and end date from database, and a dateRange function creates an array with one day for each key, like this:

$total_dates[]=dateRange('2012-04-01','2012-04-05');
$total_dates[]=dateRange('2012-04-06','2012-04-09');
$total_dates[]=dateRange('2012-04-10','2012-04-15');
$total_dates[]=dateRange('2012-04-17','2012-04-21');
$total_dates[]=dateRange('2012-04-24','2012-04-28');

will output:

Array (
[0] => Array ( [0] => 2012-04-01 [1] => 2012-04-02 [2] => 2012-04-03 [3] => 2012-04-04 [4] => 2012-04-05 )
[1] => Array ( [0] => 2012-04-06 [1] => 2012-04-07 [2] => 2012-04-08 [3] => 2012-04-09 )
[2] => Array ( [0] => 2012-04-10 [1] => 2012-04-11 [2] => 2012-04-12 [3] => 2012-04-13 [4] => 2012-04-14 [5] => 2012-04-15 )
[3] => Array ( [0] => 2012-04-17 [1] => 2012-04-18 [2] => 2012-04-19 [3] => 2012-04-20 [4] => 2012-04-21 )
[4] => Array ( [0] => 2012-04-24 [1] => 2012-04-25 [2] => 2012-04-26 [3] => 2012-04-27 [4] => 2012-04-28 )
)

Now it should output not-available on those dates that are included in the array and available on the free dates. There can be ONLY ONE reservation for each day (for now, later I also need to implement like morning and afternoon, so this will cross then).

The logic was to go from day1 to last day. If not, echo free, if yes, check if it was the last day of this dateRange, if yes, increase the key of the subarray...

Here is the code, but it does not increase the key if it is the last key...

reset($total_dates);
$array_i=0;


for ($i=1;$i<=$this_maxdays_month;$i++) {

if($i<10) {$i2="0".$i;} else {$i2=$i;} //if $i is 1-9, add a leading zero
if($i==1) {$month_begin=date('M',$this_date)." ";} else {$month_begin="";} //if 1st of month add e.g. Jan

if($total_dates[$array_i]) {
    if (in_array("$year-month-$i2",$total_dates[$array_i])) {
        echo "not available";

                // now check if the last key in date range, if yes, increase key -> does not work!
        if (key(array_slice($total_dates[$array_i], -1, 1, TRUE))+1==$i) {$array_i++;}

       }

    else {
        echo "available";

       }       
    }
}

PS: I have also tried:

$count_max_array_keys=count($total_dates[$array_i])+1;
if (!array_key_exists($count_max_array_keys,$total_dates[$array_i])) {$array_i++;}

and played with the +1 (as in the first example)...

...anyone any ideas what I am missing here??

Thank you in advance!


UPDATE: it should output (later build in a calendar-view), like:

1st April 2012: booked
2nd April 2012: booked
3rd April 2012: booked (this is the last date of this dateRange, so increase key)
4th April 2012: (not in array anymore) available
5th April 2012: available
6th April 2012: (is in the next dateRange) booked
...

hope this is clearer now, thx!


UPDATE 2: if I use if ( (count($total_dates[$array_i])-1)+1==$i) {$array_i++;} on the exact same place as the array_slice before, following happens:

row-number    $array_i    output of the count-statement
1: 0    4
2: 0    4
3: 0    4
4: 0    4
5: 1    3 (this is the last key, but here $array_i should still be 0, as the increase happens after the output, and why is suddenly count only 3?)
6-30: 1     3 (it never increases again)
Chris
  • 3,756
  • 7
  • 35
  • 54
  • What is your actual goal here? It seems like you're trying to use a screwdriver (PHP) when you should be using a hammer (MySQL, or whatever your DB engine is). – Brian Driscoll Mar 20 '12 at 18:48
  • My goal is to output a calendar. I have one table with bookings and the calendar build in php... – Chris Mar 20 '12 at 18:50
  • furthermore, I only have start date and end date in the database – Chris Mar 20 '12 at 18:51
  • Your code is very confusing to me. I think you have made some mistakes on array_splice. It would help if you could make some mock output of how you think it SHOULD be, so I can determine what method to use. – Jordan Mack Mar 20 '12 at 18:52
  • $they are so many calendar application .. i can recommend a simpler version that would work with your date database if you want – Baba Mar 20 '12 at 18:55
  • thank you Baba, I know, but there are so many things attached to it, it is only one skeleton of code here... – Chris Mar 20 '12 at 18:57
  • Sorry, I was not specific enough before. Could you add the output of how the $total_dates array should be when you are done? I see you have the output of the before. If you show me the output of how it should be after I can help you with the splice statement. – Jordan Mack Mar 20 '12 at 19:06
  • Thank you JMack, I just probably don't really get what you mean, I am afraid... I just mean, as soon as the last key of a $total_dates[$subarray[I am the last key]] is reached...?? maybe it should be like this, no? – Chris Mar 20 '12 at 19:10
  • Something funny happens, when I use `if ( (count($total_dates[$array_i])-1)+1==$i) {$array_i++;}´, I don't know how to explain, but it increases the key, but in a strange way... – Chris Mar 20 '12 at 19:11
  • I kind of get it now. You do not want to use array_splice. This is modifying your array. – Jordan Mack Mar 20 '12 at 19:22

1 Answers1

1

I know that I don't have your complete code, so I rewrote it heavily so that it would execute stand alone. I hope that this will help you to find an answer to your question.

<?php
$total_dates = array();
$total_dates[]=array('2012-04-01','2012-04-02','2012-04-03','2012-04-04','2012-04-05');
$total_dates[]=array('2012-04-24','2012-04-25','2012-04-26','2012-04-27');

$this_maxdays_month = 30;
$year = "2012";
$month = "04";

function date_is_first_in_set($date, $total_dates)
{
    $ret = false;

    for($i = 0; $i < count($total_dates); $i++)
    {
        if($date == $total_dates[$i][0])
        {
            $ret = true;
            break;
        }
    }

    return $ret;
}

function date_is_last_in_set($date, $total_dates)
{
    $ret = false;

    for($i = 0; $i < count($total_dates); $i++)
    {
        if($date == end($total_dates[$i]))
        {
            $ret = true;
            break;
        }
    }

    return $ret;
}

function date_available($date, $total_dates)
{
    $ret = true;

    for($i = 0; $i < count($total_dates); $i++)
    {
        if(in_array($date, $total_dates[$i]))
        {
            $ret = false;
            break;
        }
    }

    return $ret;
}

for($i = 1; $i <= $this_maxdays_month; $i++)
{
    $date = $year.'-'.$month.'-'.str_pad($i, 2, '0', STR_PAD_LEFT);

    echo $date.': ';

    if(date_available($date, $total_dates))
    {
        echo 'available';
    }
    else
    {
        echo 'unavailable';
    }

    if(date_is_first_in_set($date, $total_dates))
    {
        echo ' FIRST!';
    }
    if(date_is_last_in_set($date, $total_dates))
    {
        echo ' LAST!';
    }

    echo "<br>\n";
}
?>

The output from this will be:

2012-04-01: unavailable FIRST!
2012-04-02: unavailable
2012-04-03: unavailable
2012-04-04: unavailable
2012-04-05: unavailable LAST!
2012-04-06: available
2012-04-07: available
2012-04-08: available
2012-04-09: available
2012-04-10: available
2012-04-11: available
2012-04-12: available
2012-04-13: available
2012-04-14: available
2012-04-15: available
2012-04-16: available
2012-04-17: available
2012-04-18: available
2012-04-19: available
2012-04-20: available
2012-04-21: available
2012-04-22: available
2012-04-23: available
2012-04-24: unavailable FIRST!
2012-04-25: unavailable
2012-04-26: unavailable
2012-04-27: unavailable LAST!
2012-04-28: available
2012-04-29: available
2012-04-30: available
Jordan Mack
  • 8,223
  • 7
  • 30
  • 29
  • thank you JMack, this looks great, but unfortunately it does not work, meaning till row 5 it does nothing, but after that it does not even echo 0 for array_i... strange.. – Chris Mar 20 '12 at 19:28
  • well, JMack, can it simply be, that I try to count and increase the key of the main array instead of the subarray?? the main array contains 5 sub arrays, so it is correct, if it outputs 5 but does not increase... – Chris Mar 20 '12 at 19:37
  • I think the problem is that I'm still understanding your logic wrong. I made a guess based on what I thought you were trying to do with that splice line, but I probably got it wrong. – Jordan Mack Mar 20 '12 at 19:39
  • oh, maybe I don't understand my logic anymore either... but I have an array which contains subarrays. each subarray contains a dateRange, for each day as value one key. If I am on the last key (the last day) in this subarray, I want to go to the next subarray, starting with the first day there... – Chris Mar 20 '12 at 19:44
  • Ok, last try for me then I have to go. Updating now. – Jordan Mack Mar 20 '12 at 19:52
  • wow, thank you so much, JMack! I can learn a lot from the code you wrote, it really helped so much. I really don't know how to thank you!! I just need to figure out now how those dates in between, e.g. not only 1st and 5th but also 2nd, 3rd and 4th, would be unavailable too... ? – Chris Mar 20 '12 at 22:29
  • oh, sure! the dates between are not in the array! omg.. blindness, sorry. THANK YOU again JMack!! – Chris Mar 20 '12 at 23:32
  • Would it be very impertinent to ask for another problem... I would still need to find out if each day is the first or last entry (start date and end date), as those need special CSS style... so in the case: $total_dates[]=array('2012-04-01','2012-04-05'); 1st April is first day and 5th April is last day... – Chris Mar 21 '12 at 16:33
  • I added two more functions to detect if the date is the first or last in the set. These two functions could have been combined into one, but I left them separate because it is easier to understand that way. – Jordan Mack Mar 21 '12 at 19:06
  • wow... it is so beautifully simple code, so easy to understand and use! again, thank you for helping JMack... even if I can't up vote again anymore! thx! – Chris Mar 22 '12 at 17:40