Source for file calendar.php

Documentation is available at calendar.php

  1. <?php
  2. /**
  3. * Calendar object
  4. *
  5. @author    Stuart Prescott
  6. @copyright  Copyright Stuart Prescott
  7. @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  8. @version    $Id$
  9. @package    Bumblebee
  10. @subpackage DBObjects
  11. *
  12. *  path (bumblebee root)/inc/bb/calendar.php
  13. */
  14.  
  15. /** Load ancillary functions */
  16. require_once 'inc/typeinfo.php';
  17.  
  18. /** date manipulation routines */
  19. require_once 'inc/date.php';
  20. /** Booking object */
  21. require_once 'inc/bookings/booking.php';
  22. /** Vacancy object */
  23. require_once 'inc/bookings/vacancy.php';
  24. /** Cell object */
  25. require_once 'inc/bookings/cell.php';
  26. /** BookingMatrix object */
  27. require_once 'inc/bookings/matrix.php';
  28. /** BookingData object (list of bookings) */
  29. require_once 'inc/bookings/bookingdata.php';
  30. /** TimeSlot and TimeSlotRule objects */
  31. require_once 'inc/bookings/timeslotrule.php';
  32.  
  33. /**
  34. * use start and end times from defined slots
  35. @see Calender::_breakAccordingToList
  36. */
  37. define('CAL_TIME_SLOTRULE',    1);
  38. /**
  39. * use start and end times from the bookings
  40. @see Calender::_breakAccordingToList
  41. */
  42. define('CAL_TIME_BOOKING',     2);
  43.  
  44. /**
  45. * Calendar object
  46. *
  47. * Retrives, sorts and displays bookings for an instrument over a given period of time
  48. *
  49. @package    Bumblebee
  50. @subpackage DBObjects
  51. @todo //TODO: display bugs for off-slot bookings?
  52. @todo //TODO: week-long / multi-day bookings
  53. */
  54. class Calendar {
  55.   /** @var SimpleDate  start date/time for the calendar    */
  56.   var $start;
  57.   /** @var SimpleDate  stop date/time for the calendar    */
  58.   var $stop;
  59.   /** @var integer     number of days in the calendar  */
  60.   var $numDays;
  61.   /** @var integer     instrument id number for which the calendar is being displayed    */
  62.   var $instrument;
  63.   /** @var array       list of instrument ids for which the calendar is being displayed    */
  64.   var $instrumentlist = null;
  65.   /** @var boolean     sql errors are fatal   */
  66.   var $fatal_sql = 1;
  67.   /** @var BookingData list of bookings  */
  68.   var $bookinglist;
  69.   /** @var string      prepended to all zoom hrefs generated by in the calendar    */
  70.   var $zoomhref = '';
  71.   /** @var string      callback function used to make URLs for booking hrefs in the calendar */
  72.   var $bookhrefCallback = '';
  73.   /** @var string      html/css class to be used for all table cells corresponding to a day    */
  74.   var $dayClass = '';
  75.   /** @var string      html/css class to be used for all table cells corresponding today    */
  76.   var $todayClass = '';
  77.   /** @var mixed       array or string. list of html/css class to be rotated through month by month for the time periods in the calendar   */
  78.   var $rotateDayClass = '';
  79.   /** @var mixed       array or string. list of html/css class to be rotated through month by month for the day header   */
  80.   var $rotateDayClassDatePart = '';
  81.   /** @var TimeSlotRule  time slots that govern this calendar    */
  82.   var $timeslots;
  83.   /** @var boolean     generate the calendar with an admin view (i.e. all times are bookable)  */
  84.   var $isAdminView = 0;
  85.   /** @var boolean    only show free/busy information and not the details of the bookings */
  86.   var $freeBusyOnly = false;
  87.   /** @var boolean    show a popup layer with extra details on it on the page */
  88.   var $showDetails = true;
  89.   /** @var integer    time after which the calendar should automatically reload itself (in milliseconds) */
  90.   var $reloadInterval = 300000;  //    5 * 60 * 1000
  91.  
  92.   
  93.   /** @var integer    debug level (0=off, 10=verbose)  */
  94.   var $DEBUG = 0;
  95.  
  96.   /**
  97.   * Create a calendar object, can display bookings in calendar format
  98.   *
  99.   * @param SimpleDate $start    start time to display bookings from
  100.   * @param SimpleDate $stop     stop time to display bookings until
  101.   * @param mixed      $instrument  what instrument number (or list of instrumets) to display bookings for
  102.   */
  103.   function Calendar($start$stop$instrument{
  104.     $this->start = $start;
  105.     $this->stop  = $stop;
  106.     if (is_array($instrument)) {
  107.       $this->instrument = $instrument[0];
  108.       if (count($instrument1$this->instrumentlist = $instrument;
  109.     else {
  110.       $this->instrument = $instrument;
  111.     }
  112.     $this->log('Creating calendar from '.$start->dateString().' to '.$stop->dateString()5);
  113.     $this->_fill();
  114.     $this->_insertVacancies();
  115.     //print $this->displayAsTable();
  116.   }
  117.  
  118.   /**
  119.   * set the CSS style names by which
  120.   *
  121.   * @param string $dayClass   class to use in every day header
  122.   * @param string $today      class to use on today's date
  123.   * @param mixed  $day        string for class on each day, or array to rotate through
  124.   * @param string $dayrotate  time-part ('m', 'd', 'y' etc) on which day CDD should be rotated
  125.   */
  126.   function setOutputStyles($dayClass$today$day$dayrotate='m'{
  127.     $this->dayClass = $dayClass;
  128.     $this->todayClass = $today;
  129.     $this->rotateDayClass = is_array($day$day array($day);
  130.     $this->rotateDayClassDatePart = $dayrotate;
  131.   }
  132.  
  133.   /**
  134.    * set the time slot picture (passed straight to a TimeSlotRule object) to apply
  135.    *
  136.    * @param string $pic   timeslot picture for this instrument and this calendar
  137.    */
  138.   function setTimeSlotPicture($pic{
  139.     $this->timeslots = new TimeSlotRule($pic);
  140.     //break bookings over the predefined pictures
  141.     $this->log('Breaking up bookings according to defined rules');
  142.     //print $this->displayAsTable();
  143.   }
  144.  
  145.   /**
  146.   * Obtain the booking data for this time period
  147.   *
  148.   * @access private
  149.   */
  150.   function _fill({
  151.     if ($this->instrumentlist !== null{
  152.       $bookdata $this->_getBookingData($this->instrumentlist);
  153.       $this->bookinglist = $this->_reduceList($bookdata->dataArray());
  154.     else {
  155.       $bookdata $this->_getBookingData($this->instrument);
  156.       $this->bookinglist = $bookdata->dataArray();
  157.     }
  158.     //preDump($this->bookinglist);
  159.   }
  160.  
  161.   function _getBookingData($instrument{
  162.     $bookdata new BookingData (
  163.         array(
  164.           'instrument' => $instrument,
  165.           'start'      => $this->start,
  166.           'stop'       => $this->stop
  167.               )
  168.       );
  169.     return $bookdata;
  170.   }
  171.  
  172.   function _reduceList($list{
  173.     $cleandata array();
  174.     $numBookings count($list);
  175.     if ($numBookings <= 1return $list;
  176.  
  177.     $cleandata[0$list[0];
  178.     $cleandata[0]->children[$list[0];
  179.     $now clone($list[0]->start);
  180.     $idx=0;
  181.  
  182.     for ($i=1$i $numBookings$i++{
  183.       $booking $list[$i];
  184.       #print "<br/>".$booking->generateBookingTitle()."<br />";
  185.  
  186.       // bookings are sorted by:
  187.       //   start (ascending) and then duration (descending)
  188.       if ($now->ticks == $booking->start->ticks{
  189.         $cleandata[$idx]->children[$booking;
  190.         $this->log("ignored booking because starts match"8);
  191.         continue;
  192.       }
  193.  
  194.       if ($cleandata[$idx]->stop->ticks <= $booking->start->ticks{
  195.         $this->log("copied booking across"8);
  196.         $idx++;
  197.         $cleandata[$idx$booking;
  198.         $cleandata[$idx]->children[$booking;
  199.         $now clone($booking->start);
  200.         continue;
  201.       }
  202.  
  203.       if ($cleandata[$idx]->stop->ticks $booking->stop->ticks{
  204.         $this->log("adjusted previous booking because of overlap"8);
  205.         $cleandata[$idx]->children[$booking;
  206.         $cleandata[$idx]->stop $booking->stop;
  207.         continue;
  208.       }
  209.  
  210.       $cleandata[$idx]->children[$booking;
  211.       $this->log("did nothing with this booking"8);
  212.     }
  213.     return $cleandata;
  214.   }
  215.  
  216.   /**
  217.   * Create pseudo-bookings for all vacancies between the start
  218.   * of this calendar and the end.
  219.   *
  220.   * For example, if we were constructing a calendar from 00:00 on 2004-01-01 to
  221.   *   23:59 on 2004-01-02, but there was only a booking from 10:00 to 11:00
  222.   *   on 2004-01-01, then we should create vacancy pseudo-bookings from:
  223.   *   - 2004-01-01-00:00 to 2004-01-01-10:00 and from
  224.   *   - 2004-01-01-11:00 to 2004-01-01-24:00 and from
  225.   *   - 2004-01-02-00:00 to 2004-01-02-24:00.
  226.   *
  227.   * Bookings are NOT restricted to remaining on one day (i.e. a booking from
  228.   * 20:00:00 until 10:00:00 the next day is OK.
  229.   *
  230.   */
  231.   function _insertVacancies({
  232.     $this->numDays = $this->stop->partDaysBetween($this->start);
  233.     $this->log('Creating calendar for '.$this->numDays.' days'5);
  234.     //blat over the booking list so we can create the normalised list
  235.     $bookings $this->bookinglist;
  236.     $this->bookinglist = array();
  237.  
  238.     // put a vacancy at the end so we don't run off the end of the list.
  239.     $v new Vacancy();
  240.     $v->setTimes(clone($this->stop),clone($this->stop));
  241.     $bookings[$v;
  242.  
  243.     //insert a vacancy between each non-consecutive booking
  244.     $bvlist array();
  245.     $booking 0;
  246.     $now clone($this->start);
  247.     $this->log('Normalising bookings');
  248.     while ($now->ticks $this->stop->ticks{
  249.       if ($now->ticks $bookings[$booking]->start->ticks{
  250.         // then we should create a pseudobooking
  251.         $v new Vacancy();
  252.         $stoptime new SimpleDate($bookings[$booking]->start->ticks);
  253.         $v->setTimes(clone($now)clone($stoptime));
  254.         $bvlist[$v;
  255.         $now $stoptime;
  256.         $this->log('Created vacancy: '.$v->start->dateTimeString()
  257.                   .' to '.$v->stop->dateTimeString()9);
  258.       else {
  259.         // then this is the current timeslot
  260.         $bvlist[$bookings[$booking];
  261.         $now $bookings[$booking]->stop;
  262.         $this->log('Included booking: '.
  263.                 $bookings[$booking]->start->dateTimeString(.' to '
  264.                .$bookings[$booking]->stop->dateTimeString()9);
  265.         $booking++;
  266.       }
  267.     }
  268.     $this->bookinglist = $bvlist;
  269.     $this->bookinglist[0]->arb_start true;
  270.     $this->bookinglist[count($bvlist)-1]->arb_stop true;
  271.   }
  272.  
  273.   /**
  274.   * Break up bookings that span days (for display purposes only)
  275.   *
  276.   * For example, if we had a vacancy pseudo-bookings from
  277.   * 2004-01-01-11:00 to 2004-01-02-24:00, then we would
  278.   * break it up into two bookings as follows:
  279.   *   -  2004-01-01-11:00 to 2004-01-01-24:00 and
  280.   *   -  2004-01-02-00:00 to 2004-01-02-24:00.
  281.   */
  282.   function _breakAcrossDays({
  283.     $this->log('Breaking up bookings across days');
  284.     //break bookings over day boundaries
  285.     $daylist new TimeSlotRule('[0-6]<00:00-24:00/*>');
  286.   }
  287.  
  288.   /**
  289.   * Break up bookings that span elements of a defined list (e.g. allowable times or
  290.   * days). A TimeSlotRule ($list) is used to define how the times should be broken up
  291.   *
  292.   * $keepTimes(Vacant|Book) are set to CAL_TIME_BOOKING, CAL_TIME_SLOTRULE
  293.   *
  294.   * CAL_TIME_BOOKING:
  295.   *   start|stop are set according to the timeslotrule and will be used to
  296.   *      display the timeslot in a graphica display (i.e. calculating height of boxes)
  297.   *    display(Start|Stop) are set to the values of the original vacancy or booking being examined.
  298.   *
  299.   * CAL_TIME_SLOTRULE:
  300.   *   display(Start|Stop) variables are set to the values of the timeslot rule that breaks up the slots
  301.   *      with the exception of slots that overlap a booking, where min() or max() is used
  302.   *   start|stop are set to the same as the start/stop vars
  303.   *   Note: vacancies that are at the start or end of the booking list are a corner case
  304.   *   that is handled respectively as: start = slotrule->stop and stop = slotrule->stop
  305.   *
  306.   * @param $list TimeSlotRule Object   set of rules used to break up booking stream
  307.   * @param $keepTimesVacant enum       how should the display(Start|Stop) and (start|stop)
  308.   * @param $keepTimesBook   enum       .. variables be set for Vacancy and Booking slots
  309.   */
  310.   function _breakAccordingToList($list$keepTimesVacant$keepTimesBook{
  311.     $bl $this->bookinglist;
  312.     $this->bookinglist = array();
  313.     $this->log('Breaking up bookings according to list');
  314.     $this->log($list->dump());
  315.     $booking=0;
  316.     for ($bv=0$bv count($bl)$bv++{
  317. /*      $this->log('considering timeslot #'.$bv.': '
  318.                       .$bl[$bv]->start->dateTimeString().' - '.$bl[$bv]->stop->dateTimeString(), 8);*/
  319.       $cbook =$bl[$bv];
  320.       $cbook->original clone($cbook);
  321.       $isStart START_BOOKING;
  322.       $slotrule $list->findSlotFromWithin($bl[$bv]->start);
  323.       #$start = $list->findSlotStart($bl[$bv]->start);
  324.       if (!is_object($slotrule&& $slotrule == 0{
  325.         // then the original start time must be outside the proper limits
  326.         $slotrule $list->findNextSlot($bl[$bv]->start);
  327.       }
  328.       do {  //until the current booking has been broken up across list boundaries
  329.         //echo "memusage=".memory_get_usage()."<br />";
  330.         $this->slotlog('bookingo'$bl[$bv]);
  331.         $this->slotlog('timeslot'$slotrule);
  332.         // push the new booking onto the stack; record if it's the start of a booking or not
  333.         $this->bookinglist[$bookingclone($cbook);
  334.         $realStart = isset($this->bookinglist[$booking]->displayStart$this->bookinglist[$booking]->displayStart $this->bookinglist[$booking]->start;
  335.         if ($isStart == MIDDLE_BOOKING && $slotrule->start->dow(!= $realStart->dow()) {
  336.           $this->bookinglist[$booking]->isStart |= START_BOOKING_DAY;
  337.         }
  338.         $next_isStart MIDDLE_BOOKING;
  339.  
  340.         $newstart clone($this->bookinglist[$booking]->start);
  341.         $newstart->max($slotrule->start);
  342.         $newstop clone($this->bookinglist[$booking]->stop);
  343.         $newstop->min($slotrule->stop);
  344.  
  345.         if ($this->bookinglist[$booking]->isVacant{
  346.           switch ($keepTimesBook{
  347.             case CAL_TIME_SLOTRULE:   // for bookings
  348.               if ($this->bookinglist[$booking]->arb_start{
  349.                 $newstart clone($this->bookinglist[$booking]->start);
  350.               }
  351.               if ($this->bookinglist[$booking]->arb_stop{
  352.                 $newstop clone($this->bookinglist[$booking]->stop);
  353.               }
  354.               $this->bookinglist[$booking]->displayStart $this->bookinglist[$booking]->original->start;
  355.               $this->bookinglist[$booking]->displayStop  $this->bookinglist[$booking]->original->stop;
  356.               $this->bookinglist[$booking]->start $newstart;
  357.               $this->bookinglist[$booking]->stop  $newstop;
  358. /*              $this->bookinglist[$booking]->displayStart = $newstart;
  359.               $this->bookinglist[$booking]->displayStop  = $newstop;*/
  360.               $this->bookinglist[$booking]->slotRule $slotrule;
  361.               $this->bookinglist[$booking]->isStart |= $isStart;
  362.               break;
  363.             case CAL_TIME_BOOKING:
  364.               $this->bookinglist[$booking]->start $newstart;
  365.               $this->bookinglist[$booking]->stop  $newstop;
  366. //               $this->bookinglist[$booking]->displayStart = $this->bookinglist[$booking]->original->start;
  367. //               $this->bookinglist[$booking]->displayStop  = $this->bookinglist[$booking]->original->stop;
  368.               break;
  369.           }
  370.         else {
  371.           switch ($keepTimesVacant{
  372.             case CAL_TIME_SLOTRULE:  // for vacancies
  373.               if ($this->bookinglist[$booking]->arb_start{
  374.                 $newstart clone($slotrule->start);
  375.               }
  376.               if ($this->bookinglist[$booking]->arb_stop{
  377.                 $newstop clone($slotrule->stop);
  378.               }
  379.               $this->bookinglist[$booking]->start $newstart;
  380.               $this->bookinglist[$booking]->stop  $newstop;
  381.               $this->bookinglist[$booking]->displayStart $newstart;
  382.               $this->bookinglist[$booking]->displayStop  $newstop;
  383.               $this->bookinglist[$booking]->isDisabled $slotrule->isAvailable;
  384.               $this->bookinglist[$booking]->slotRule $slotrule;
  385.               $this->bookinglist[$booking]->isStart |= $isStart;
  386.               break;
  387.             case CAL_TIME_BOOKING:
  388.               $this->bookinglist[$booking]->start $newstart;
  389.               $this->bookinglist[$booking]->stop  $newstop;
  390.               $this->bookinglist[$booking]->displayStart $this->bookinglist[$booking]->original->start;
  391.               $this->bookinglist[$booking]->displayStop  $this->bookinglist[$booking]->original->stop;
  392.               $this->bookinglist[$booking]->isStart |= $isStart;
  393.               break;
  394.           }
  395.         }
  396.  
  397.         // find the next TimeSlotRule to work out how to chop this booking up again (or how
  398.         // to chop up the next booking)
  399.         $nextslotrule $list->findNextSlot($slotrule->start);
  400.         $isStart $next_isStart;
  401.         $this->slotlog('displayv',$this->bookinglist[$booking]true);
  402.         $this->slotlog('realvalu',$this->bookinglist[$booking]);
  403.         $slotrule $nextslotrule;
  404.         $booking++;
  405.         //$this->log('oticks='.$this->bookinglist[$booking-1]->original->stop->ticks
  406.         //           .'nticks='.$slotrule->start->ticks,10);
  407.         $this->timelog('nextstart=',$slotrule->start);
  408.         //var_dump($this->bookinglist[$booking-1]->original);
  409.         //$this->log('ost='.$this->bookinglist[$booking-1]->original->stop->ticks,10);
  410.         //$this->log('tst='.$slotrule->start->ticks,10);
  411.         $this->log('');
  412.       while ($this->bookinglist[$booking-1]->original->stop->ticks $slotrule->start->ticks);
  413.     }
  414.   }
  415.  
  416.   /**
  417.   * Generate a booking matrix for all the days we are interested in
  418.   */
  419.   function _collectMatrix($daystart$daystop$granularity{
  420.     $matrixlist array();
  421.     // matrix calculation object is shared from day to day which permits caching of data
  422.     $matrix new BookingMatrix(clone($daystart)clone($daystop)$granularity$this->bookinglist);
  423.     for ($day 0$day $this->numDays$day++{
  424.       $today clone($this->start);
  425.       $today->addDays($day);
  426.       $matrix->setDate($today);
  427.       $matrix->prepareMatrix();
  428.       $matrixlist[$matrix->getMatrix();
  429.     }
  430.     return $matrixlist;
  431.   }
  432.  
  433.   /**
  434.   * work out what html/css class this date should be rendered as
  435.   *
  436.   * @param SimpleDate $today  today's date
  437.   * @param SimpleDate $t      the date to check
  438.   * @return string  space-separated css class list for use in class=""
  439.   */
  440.   function _getDayClass($today$t{
  441.     $class $this->dayClass;
  442.     $class .= ' '.$this->rotateDayClass[date($this->rotateDayClassDatePart$t->ticks)
  443.                       % count($this->rotateDayClass)];
  444.     if ($today->dateString()==$t->dateString()) {
  445.       $class .= ' '.$this->todayClass;
  446.     }
  447.     return $class;
  448.   }
  449.  
  450.   /**
  451.   * Display the booking details in a list
  452.   */
  453.   function display({
  454.     return $this->displayAsTable();
  455.   }
  456.  
  457.   /**
  458.   * Display the booking details in a list
  459.   */
  460.   function displayAsTable({
  461.     $t '<table class="tabularobject">';
  462.     foreach ($this->bookinglist as $v{
  463.       #$t .= '<tr><td>'.$v[0].'</td><td>'.$v[1].'</td></tr>'."\n";
  464.       $t .= $v->displayShort();
  465.     }
  466.     $t .= '</table>';
  467.     return $t;
  468.   }
  469.  
  470.   /**
  471.   * Generate html for the booking details in a table with rowspan based on the duration of the booking
  472.   *
  473.   * @param SimpleTime $daystart    time from which bookings should be displayed
  474.   * @param SimpleTime $daystop     time up until which bookings should be displayed
  475.   * @param integer    $granularity seconds per row in display
  476.   * @param integer    $reportPeriod  seconds between reporting the time in a column down the side
  477.   * @return string   html representation of the calendar
  478.   */
  479.   function displayMonthAsTable($daystart$daystop$granularity,
  480.                                     $reportPeriod{
  481.     $conf ConfigReader::getInstance();
  482.     $this->_breakAcrossDays();
  483. //     echo $this->display();
  484.     $matrix $this->_collectMatrix($daystart$daystop$granularity);
  485.     $numRowsPerDay =  $daystop->subtract($daystart$granularity;
  486.     $numRows ceil($this->numDays/7$numRowsPerDay;
  487.  
  488.     #report the time in a time column on the LHS every nth row:
  489.     $timecolumn array();
  490.     $time clone($daystart);
  491.     for ($row=0$row<$numRowsPerDay$row++{
  492.       $timecolumn[$rowclone($time);
  493.       $time->addSecs($granularity);
  494.     }
  495.  
  496.     if (is_array($this->instrumentlist)) {
  497.       $this->freeBusyOnly = true;
  498.     }
  499.  
  500.     $today new SimpleDate(time());
  501.  
  502.     $t $this->_makeRefreshScript();
  503.  
  504.     $t .= '<table class="tabularobject calendar" summary="'
  505.                     .T_('Extended view of instrument bookings').'">';
  506.     $weekstart clone($this->start);
  507.     $weekstart->addDays(-7);
  508.     $t .= '<tr><th colspan="2"></th>';
  509.     for ($day=0$day<7$day++{
  510.       $current clone($weekstart);
  511.       $current->addDays($day);
  512.       $t .= '<th class="caldow">'
  513.               .($conf->value('calendar''shortdaynames'true$current->dowShortStr()
  514.                                                                 : $current->dowStr())
  515.               .'</th>';
  516.     }
  517.     $t .= '</tr>';
  518.  
  519.     // load up this translation once outside the main loop
  520.     $zoomStr T_('Zoom in on %s');
  521.  
  522.     for ($row 0$row $numRows$row++{
  523.       $dayRow $row $numRowsPerDay;
  524.       if ($dayRow == 0{
  525.         $weekstart->addDays(7);
  526.         $t .= '<tr><td colspan="2"></td>';
  527.         for ($day=0$day<7$day++{
  528.           $current clone($weekstart);
  529.           $current->addDays($day);
  530.           $isodate $current->dateString();
  531.           $class $this->_getDayClass($today$current);
  532.           $zoomwords sprintf($zoomStr$isodate);
  533.           $t .= '<td class="caldatecell '.$class.'">';
  534.           $t .= '<div style="float:right;"><a href="'.$this->zoomhref.'&amp;isodate='.$isodate.'" '
  535.                   .'class="but" title="'.$zoomwords .'">'
  536.                .'<img src="'.$conf->BasePath.'/theme/images/zoom.png" '
  537.                   .'alt="'.$zoomwords .'" class="calicon" /></a></div>'."\n";
  538.           $t .= '<div class="caldate">'
  539.                   .$current->getShortDateString()
  540.                 .'</div>';
  541.           $t .= '</td>';
  542.         }
  543.         $t .= '</tr>';
  544.       }
  545.       $t .= '<tr><td class="dummy"></td>';
  546.       //$t .= '<tr><td class="dummy"><img src="/1x1.png" height="5" width="1" alt="" /></td>';
  547.       if ($dayRow $reportPeriod == 0{
  548.         //$t .= '<td colspan="2" rowspan="'.$reportPeriod.'">';
  549.         $t .= '<td rowspan="'.$reportPeriod.'" class="timemark">';
  550.         $t .= $timecolumn[$dayRow]->getShortString();
  551.         $t .= '</td>';
  552.       }
  553.       for ($day=0$day<7$day++{
  554.         $current clone($weekstart);
  555.         $current->addDays($day);
  556.         #$currentidx = $current->dsDaysBetween($this->start);
  557.         // calculate the day number directly from the cell information rather than
  558.         // using date-time functions. (add a small qty to the value so that floor doesn't
  559.         // round down to the next integer below due to fp precision)
  560.         $currentidx floor($row $numRowsPerDay 0.05$day;
  561.         if (isset($matrix[$currentidx][$dayRow])) {
  562.           #$t .= '<td>';
  563.           #preDump($matrix[$currentidx]->rows[$dayRow]);
  564.           $b =$matrix[$currentidx][$dayRow];
  565.           $b->booking->freeBusyOnly $this->freeBusyOnly;
  566.           $class $this->_getDayClass($today$b->booking->start);
  567.           $class .= ($b->booking->isDisabled ' disabled' '');
  568.           //echo "$class <br />\n";
  569.           $t .= "\n\t".$b->display($class,
  570.                                     call_user_func($this->bookhrefCallback$b->booking->start),
  571.                                     $this->showDetails,
  572.                                     $this->isAdminView)."\n";
  573.           #$t .= '</td>';
  574.         }
  575.       }
  576.       $t .= '</tr>';
  577.     }
  578.     $t .= '</table>';
  579.     return $t;
  580.   }
  581.  
  582.   /**
  583.   * Display the booking details in a table with rowspan based on the duration of the booking
  584.   *
  585.   * @param SimpleTime $daystart    time from which bookings should be displayed
  586.   * @param SimpleTime $daystop     time up until which bookings should be displayed
  587.   * @param integer    $granularity seconds per row in display
  588.   * @param integer    $reportPeriod  seconds between reporting the time in a column down the side
  589.   * @return string   html representation of the calendar
  590.   */
  591.   function displayDayAsTable($daystart$daystop$granularity,
  592.                                     $reportPeriod{
  593.     $this->_breakAcrossDays();
  594. //     echo $this->display();
  595.     $matrix $this->_collectMatrix($daystart$daystop$granularity);
  596.     $numRowsPerDay =  ceil($daystop->subtract($daystart$granularity);
  597.     $numRows $numRowsPerDay;
  598.  
  599.     #report the time in a time column on the LHS every nth row:
  600.     $timecolumn array();
  601.     $time $daystart;
  602.     for ($row=0$row<$numRowsPerDay$row++{
  603.       $timecolumn[$rowclone($time);
  604.       $time->addSecs($granularity);
  605.     }
  606.  
  607.     if (is_array($this->instrumentlist)) {
  608.       $this->freeBusyOnly = true;
  609.     }
  610.  
  611.     $today new SimpleDate(time());
  612.  
  613.     $t $this->_makeRefreshScript();
  614.  
  615.     $t .= '<table class="tabularobject calendar" summary="'.T_('Day view of instrument bookings').'">';
  616.     $t .= '<tr><td class="dummy"></td><th></th>';
  617.     $t .= '<td class="caldayzoom">';
  618.     $t .= '<div class="caldate">'
  619.             .$this->start->getLongDateString()
  620.           .'</div>';
  621.     $t .= '</td>';
  622.     $t .= '</tr>';
  623.     for ($row 0$row $numRows$row++{
  624.       $t .= '<tr><td class="dummy"></td>';
  625.       if ($row $reportPeriod == 0{
  626.         $t .= '<td rowspan="'.$reportPeriod.'">';
  627.         $t .= $timecolumn[$row]->timeString();
  628.         $t .= '</td>';
  629.       }
  630.       if (isset($matrix[0][$row])) {
  631.         #$t .= '<td>';
  632.         #preDump($matrix[$currentidx]->rows[$dayRow]);
  633.         $b =$matrix[0][$row];
  634.         $b->booking->freeBusyOnly $this->freeBusyOnly;
  635.         $class $this->_getDayClass($today$b->booking->start);
  636.         $t .= "\n\t".$b->display($class,
  637.                                     call_user_func($this->bookhrefCallback$b->booking->start),
  638.                                     $this->showDetails,
  639.                                     $this->isAdminView)."\n";
  640.         #$t .= '</td>';
  641.       }
  642.       $t .= '</tr>';
  643.     }
  644.     $t .= '</table>';
  645.     return $t;
  646.   }
  647.  
  648.   function _makeRefreshScript({
  649.     if ($this->reloadInterval <=0return '';
  650.  
  651.     return "
  652.       <script type='text/javascript'>
  653.         function ReloadPageCalendar() {
  654.           location.reload();
  655.         }
  656.         setTimeout('ReloadPageCalendar()', {$this->reloadInterval});
  657.       </script>";
  658.   }
  659.  
  660.  
  661.   /**
  662.   * logging function -- logs debug info to stdout
  663.   *
  664.   * The higher $priority, the more verbose (in the debugging sense) the output.
  665.   *
  666.   * @param string $string  text to be logged
  667.   * @param integer $priority (optional, default value 10) debug level of the message
  668.   */
  669.   function log ($string, $priority=10) {
  670.     if ($priority <= $this->DEBUG{
  671.       echo $string.'<br />'."\n";
  672.     }
  673.   }
  674.  
  675.   /**
  676.   * time logging function -- logs the start and stop time of a booking or slot
  677.   *
  678.   * @param string $string  prefix to text to be logged
  679.   * @param TimeSlot $slot    the slot whose start/stop is to be logged
  680.   * @param boolean $display (optional ) use the displayStart rather than the start data in  $slot
  681.   *
  682.   * The higher $prio, the more verbose (in the debugging sense) the output.
  683.   */
  684.   function slotlog ($string, $slot, $display=false) {
  685.     // Efficiency would suggest that &$slot would be better here, but bugs in PHP mean that we can't do that
  686.     // see http://bugs.php.net/bug.php?id=24485 and http://bugs.php.net/bug.php?id=30787
  687.     // short circuit the evaluation here -- if there's no logging going to be done then
  688.     // we don't want to make expensive dateTimeString() calls.
  689.     if ($this->DEBUG < 10return;
  690.  
  691.     if ($display{
  692.       $this->log($string.':start='.$slot->displayStart->dateTimeString()
  693.             .' '.$string.':stop='.$slot->displayStop->dateTimeString()10);
  694.     } else {
  695.       $this->log($string.':start='.$slot->start->dateTimeString()
  696.             .' '.$string.':stop='.$slot->stop->dateTimeString()10);
  697.     }
  698.   }
  699.  
  700.   /**
  701.   * time logging function
  702.   *
  703.   * @param string $string  prefix to text to be logged
  704.   * @param SimpleDate $slot    the time to be logged
  705.   *
  706.   * The higher $prio, the more verbose (in the debugging sense) the output.
  707.   */
  708.   function timelog ($string, $time) {
  709.     // Efficiency would suggest that &$time would be better here, but bugs in PHP mean that we can't do that
  710.     // see http://bugs.php.net/bug.php?id=24485 and http://bugs.php.net/bug.php?id=30787
  711.     // short circuit the evaluation here -- if there's no logging going to be done then
  712.     // we don't want to make expensive dateTimeString() calls.
  713.     if ($this->DEBUG < 10return;
  714.  
  715.     $this->log($string.' '.$time->dateTimeString()10);
  716.   }
  717.  
  718.  

Documentation generated on Tue, 06 Mar 2007 10:00:58 +0000 by phpDocumentor 1.3.0