Source

Portfolio / oncall / www / php / cron / generateCalendars.php

Full commit
<?php

require_once('../conf/setup.php');
require_once('../db/Connection.php');
require_once('../db/Query.php');
require_once('../fpdf/Calendar.php');

// Run Query
$connection = new Connection($database,$host,$password,$port,$type,$username);
$handle = $connection->get();
$query = new Query();

if (file_exists(STORAGE_PATH))
{
    // ALGORITHM:
    //     -- calculate current day as start
    //     -- calculate number of days left in year
    //     -- calculate slot count using desired length and previous numbers
    //     -- get number of people in the system
    //     -- assign slots serially and build dictionary
    //     -- upload slot information to database
    //     -- generate calendars using the database
    //     

    date_default_timezone_set(TIMEZONE);

    // 11072011
    $today = date("mdY");
    $current_day_of_present_year = date('z');

    // Check if leap year
    $days_in_present_year = 0;
    if (date('L'))
    {
        $days_in_present_year = DAYS_IN_LEAP_YEAR; 
    } else {
        $days_in_present_year = DAYS_IN_YEAR;
    }

    // Days left
    $number_of_days_left = $days_in_present_year - $current_day_of_present_year;

    $query->set_table('people');
    $get_count = $query->get_query_by_name('people_get_count');
    $statement = $query->prepare_query($handle,$get_count);
    $statement->execute();
    $people = $statement->fetchAll(PDO::FETCH_ASSOC);

    // Check results
    $number_people = 0;
    if (count($people))
    {
        $number_people = $people[0]['number'];
    } else {
        die("ERROR: There are no people in the list.\n");    
    } 

    // How many slots do we have to generate?
    $number_slots = floor($number_of_days_left / DAYS_ONCALL);
    $partial_slot = FALSE;
    if (fmod($number_of_days_left, DAYS_ONCALL))
    {
        $partial_slot = TRUE;
    }

    // Special case if we have one person.
    if (($number_people == 1) && (ONE_PERSON == FALSE))
    {
       print "One person is \"on call?\" Really?\n";
       print "If this is correct set ONE_PERSON = TRUE in settings.ini.\n";
       print "Once this is done, please run this script again.\n";
    }
    
    $query->set_table('people');
    $get_people = $query->get_query_by_name('people_get_all');
    $statement = $query->prepare_query($handle,$get_people);
    $statement->execute();
    $oncall_people = $statement->fetchAll(PDO::FETCH_ASSOC);
    $oncall_people_name_list = array();
    $oncall_list = array();
    foreach ($oncall_people as $oncall_person)
    {
        $oncall_people_name_list[] = $oncall_person['fname']; 
        $oncall_list[$oncall_person['fname']] = array();
    }

    // We have loop conditions to serially assign slots from today onward.
    // 
    // Need: Slot Length, Start Day, Start Month, End Day, End Month, Person Assigned
    //
    $slot_length = DAYS_ONCALL;
    $oncall_people_index = 0;
    $oncall_people_max = count($oncall_people_name_list) - 1;
    $used_slot_count = 0;
    $oncall_monthly_slots = array();
    while ($number_slots > 0)
    {
        $start_date_pieces = getdate(mktime(0,0,0, date('m'), date('d') + ($used_slot_count * $slot_length), date('Y')));
        $new_slot['start_day'] = $start_date_pieces["mday"];
        $new_slot['start_month'] = $start_date_pieces["mon"];
        $used_slot_count++;
        $end_date_pieces = getdate(mktime(0,0,0, $new_slot['start_month'], $new_slot['start_day'] + $slot_length - 1, date('Y')));
        $new_slot['end_day'] = $end_date_pieces["mday"];
        $new_slot['end_month'] = $end_date_pieces["mon"];
        array_push($oncall_list[$oncall_people_name_list[$oncall_people_index]],$new_slot);

        if ($new_slot['start_month'] == $new_slot['end_month'])
        {
            foreach(range($new_slot['start_day'],$new_slot['end_day']) as $day)
            { 
                $oncall_monthly_slots[$new_slot['start_month']][$day] = $oncall_people_name_list[$oncall_people_index];
            }
        } else {
            foreach(range($new_slot['start_day'],date('t',mktime(0,0,0,$new_slot['start_month'],1,date('Y')))) as $day)
            {
                $oncall_monthly_slots[$new_slot['start_month']][$day] = $oncall_people_name_list[$oncall_people_index];
            } 
            foreach(range($new_slot['end_day'],date('t',mktime(0,0,0,$new_slot['end_month'],1,date('Y')))) as $day)
            {
                $oncall_monthly_slots[$new_slot['end_month']][$day] = $oncall_people_name_list[$oncall_people_index];
            } 
        }

        $number_slots--;
        if ($oncall_people_index == $oncall_people_max)
        {
            $oncall_people_index = 0;
        } else {
            
            $oncall_people_index++;
        }
    }

    // DEBUG
    //print_r($oncall_list);

    $months_with_entries = array_keys($oncall_monthly_slots);
    // Supports any size paper FPDF does
    $pdf = new Calendar("L", "Letter", $oncall_monthly_slots);

    // you can set margins and line width here. PDF_USA_Calendar uses the current settings.
    $pdf->SetMargins(7,7);
    $pdf->SetAutoPageBreak(false, 0);
    // set fill color for non-weekend holidays
    $greyValue = 190;
    $pdf->SetFillColor($greyValue,$greyValue,$greyValue);

    // for the months with oncall assignments save a calendar 
    // we'll need to add peoples names to the calendar too
    $year = gmdate("Y");
    foreach($months_with_entries as $month)
    {
        $date = $pdf->MDYtoJD($month, 1, $year);
        $pdf->printMonth($date);
    }
    $pdf->Output("../../calendars/oncall_calendar_" . date('Y') . ".pdf",'F');


} else {
    // FIXME - Catch exists errors and other things?
    try 
    {
        mkdir(STORAGE_PATH, 0755);
        print "Created " . STORAGE_PATH . ". Please run again to generate calendars.\n";
    } catch (Exception $ex) {
        die("ERROR: Cannot create " . STORAGE_PATH . ".\n");
    }
}

?>