Source for file calendar.php

Documentation is available at calendar.php

  1. <?php
  2. /**
  3. * View a bookings calendar and make bookings
  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: calendar.php,v 1.10 2007/02/09 00:19:48 themill Exp $
  9. * @package    Bumblebee
  10. * @subpackage Actions
  11. *
  12. *  path (bumblebee root)/inc/actions/calendar.php
  13. */
  14.  
  15. /** Load ancillary functions */
  16. require_once 'inc/typeinfo.php';
  17.  
  18. require_once 'inc/bb/configreader.php';
  19.  
  20. /** calendar object */
  21. require_once 'inc/bb/calendar.php';
  22. /** date maniuplation objects */
  23. require_once 'inc/date.php';
  24. /** parent object */
  25. require_once 'inc/actions/viewbase.php';
  26. /** Data reflector object */
  27. require_once 'inc/formslib/datareflector.php';
  28.  
  29. /**
  30. * View a bookings calendar and make bookings
  31. * @package    Bumblebee
  32. * @subpackage Actions
  33. */
  34. class ActionCalendar extends ActionViewBase {
  35.   /** @var boolean   logged in user can modify booking  */
  36.   var $_haveWriteAccess = false;
  37.  
  38.   /**
  39.   * Initialising the class
  40.   *
  41.   * @param  BumblebeeAuth $auth  Authorisation object
  42.   * @param  array $pdata   extra state data from the call path
  43.   * @return void nothing
  44.   */
  45.   function ActionCalendar($auth, $PDATA) {
  46.     parent::ActionViewBase($auth, $PDATA);
  47.     #$this->mungeInputData();
  48.  
  49.     // catch bad arguments and send them back to the front page straight away
  50.     if (! isset($this->PD['instrid'])
  51.           || $this->PD['instrid'] < 1
  52.           || $this->PD['instrid'] == '') {
  53.       redirectUser(makeAbsURL());
  54.       // never returns
  55.     }
  56.   }
  57.  
  58.   function go() {
  59.     if (! $this->auth->permitted(BBROLE_VIEW_CALENDAR, $this->instrument)) {
  60.       $this->_viewCalendarForbidden();
  61.       return;
  62.     }
  63.  
  64.     if (! $this->_loadMultiInstrument()) return;
  65.  
  66.     echo $this->_makeCalendarConfigDialogue();
  67.     if (isset($this->PD['isodate']) &&
  68.                     ! isset($this->PD['bookid']) && ! isset($this->PD['startticks']) ) {
  69.       $this->instrumentDay();
  70.       echo $this->_calendarViewLink($this->instrument);
  71.       echo "<br /><br /><a href='".makeURL('view')."'>". T_('Return to instrument list') ."</a>";
  72.     } else {
  73.       $this->instrumentMonth();
  74.       echo "<br /><br /><a href='".makeURL('view')."'>". T_('Return to instrument list') ."</a>";
  75.     }
  76.   }
  77.  
  78.   function mungeInputData() {
  79.     parent::mungeInputData();
  80.     if (isset($this->PD['caloffset']) && preg_match("/\d\d\d\d-\d\d-\d\d/", $this->PD['caloffset'])) {
  81.       $then = new SimpleDate($this->PD['caloffset']);
  82.       $now = new SimpleDate(time());
  83.       $this->PD['caloffset'] = floor($then->dsDaysBetween($now));
  84.     }
  85.     if (strpos($this->instrument, ',')) {
  86.       $this->instrument = explode(',', $this->instrument);
  87.     } else {
  88.       $this->instrument = array($this->instrument);
  89.     }
  90.     if (isset($this->PD['configureview'])) {
  91.       $this->instrument = array($this->instrument[0]);
  92.       foreach ($this->PD as $key => $value) {
  93.         if (preg_match('@^Instrument-(\d+)-include$@', $key, $matches)) {
  94.           $id = $matches[1];
  95.           if ($value && isset($this->PD["Instrument-$id-instrument"])) {
  96.             $this->instrument[] = $this->PD["Instrument-$id-instrument"];
  97.           }
  98.         }
  99.         $data = array();
  100.       }
  101.  
  102.       /// FIXME: forcing a reload with a Location: header seems ugly and possibly fragile.
  103.       // force a reload of the page, converting from a POST to a GET so that
  104.       // later refreshes of the calendar can happen without generating a warning to the user
  105.       if (isset($this->PD['caloffset'])) {
  106.         $d['caloffset'] = $this->PD['caloffset'];
  107.       }
  108.       $d['instrid'] = join($this->instrument, ',');
  109.       redirectUser(makeURL('calendar', $d, false));
  110.       // never returns
  111.     }
  112.     echoData($this->PD, 0);
  113.   }
  114.  
  115.   /**
  116.   * Display the monthly calendar for the selected instrument
  117.   */
  118.   function instrumentMonth() {
  119.     $conf = ConfigReader::getInstance();
  120.     // Show a window $row['calendarlength'] weeks long starting $row['calendarhistory'] weeks
  121.     // before the current date. Displayed week starts on configured day of week.
  122.     $offset = issetSet($this->PD, 'caloffset');
  123.     if ($offset == 'today') $offset = 0;
  124.  
  125.     $now = new SimpleDate(time());
  126.     $now->dayRound();
  127.     $start = clone($now);
  128.     $start->addDays($offset);
  129.  
  130.     $callength = 7 * $this->row['callength'];
  131.  
  132.     $week_offset = $conf->value('language', 'week_offset', 1);
  133.     $start->weekRound();
  134.     if ($now->dow() < $week_offset) $start->addDays(-7);
  135.     $start->addDays($week_offset - 7*$this->row['calhistory']);
  136.  
  137.     $stop = clone($start);
  138.     $stop->addDays($callength);
  139.  
  140.     // check to see if this is an allowable calendar view (not too far into the future)
  141.     $futureView = $this->BookingPastNormalCalendar($stop);
  142.  
  143.     if ($futureView < 0 && ! $this->auth->permitted(BBROLE_VIEW_CALENDAR_FUTURE, $this->instrument)) {
  144.       $off = ceil($futureView / 7) * 7;
  145.       $start->addDays($off);
  146.       $stop->addDays($off);
  147.       $offset += $off;
  148.     }
  149.  
  150. //     $totaloffset = $offset + $callength - 7*$row['calhistory'] - $start->dow();
  151. //     $this->log("Found total offset of $totaloffset, calfuture=".$row['calfuture']." calhistory=".$row['calhistory']);
  152. //
  153. //     //admin users are allowed to see further into the future.
  154. //     $this->_checkBookingAuth(-1);
  155. //     $futureView = false;
  156. //     echo  ! ($this->auth->permitted(BBROLE_VIEW_CALENDAR_FUTURE, $this->instrument));
  157. //     if (($totaloffset > $row['calfuture']) &&
  158. //         ! ($this->auth->permitted(BBROLE_VIEW_CALENDAR_FUTURE, $this->instrument))) {
  159. //       #echo "Found total offset of $totaloffset, but only ".$row['calfuture']." is permitted. ";
  160. //       $start = clone($now);
  161. //       $offset = $row['calfuture'] - $callength + 7*$row['calhistory'] + 7;
  162. //       $start->addDays($offset);
  163. //       #echo $start->dateTimeString();
  164. //       $futureView = true;
  165. //     }
  166.  
  167.     // jump backwards to the start of that week.
  168.     //$day = $start->dow(); // the day of the week, 0=Sun, 6=Sat
  169.  
  170.     $cal = new Calendar($start, $stop, $this->instrument);
  171.  
  172.     $daystart    = new SimpleTime($this->row['usualopen']);
  173.     $daystop     = new SimpleTime($this->row['usualclose']);
  174.     //configure the calendar view granularity (not the same as booking granularity)
  175.     $granularity = $this->row['calprecision'];
  176.     $timelines   = $this->row['caltimemarks'];
  177.     $cal->setTimeSlotPicture($this->row['timeslotpicture']);
  178.     #$granularity = 60*60;
  179. //     echo $cal->display();
  180.  
  181. /*    if ($this->auth->permitted($futureView<-$callength ? BBROLE_MAKE_BOOKINGS_FUTURE : BBROLE_MAKE_BOOKINGS, $this->instrument)) {
  182.       $cal->bookhref = makeURL('book', array('instrid'=>$this->instrument));
  183.     } else {
  184.       $cal->bookhref = makeURL('bookcontact', array('instrid'=>$this->instrument));
  185.     }*/
  186.     $cal->bookhrefCallback = array(&$this, 'MakeBookingHref');
  187.  
  188.     $cal->zoomhref = makeURL('calendar', array('instrid'=>$this->instrument));
  189.  
  190.     $cal->freeBusyOnly = ! $this->auth->permitted(BBROLE_VIEW_BOOKINGS, $this->instrument);
  191.     $cal->isAdminView = $this->auth->permitted(BBROLE_MAKE_BOOKINGS_FREE, $this->instrument);
  192.     $cal->setOutputStyles('', $conf->value('calendar', 'todaystyle'),
  193.                 preg_split('{/}',$conf->value('calendar', 'monthstyle')), 'm');
  194.     echo $this->displayInstrumentHeader();
  195.     echo $this->_linksForwardBack($start,
  196.                                   ($offset-$callength),
  197.                                   ($offset+$callength),
  198.                                   $callength);
  199.     echo $cal->displayMonthAsTable($daystart,$daystop,$granularity,$timelines);
  200.     echo $this->displayInstrumentFooter();
  201.   }
  202.  
  203.   /**
  204.   * Generate back | today | forward links for the calendar
  205.   * @return string html for links
  206.   */
  207.   function _linksForwardBack($centre, $back, $forward, $calLength, $extra=array()) {
  208.     $links = array();
  209.     $script = 'JumpCalendarTo';
  210.     $today = new SimpleDate(time());
  211.     $today->dayRound();
  212.     $centreOffset = $today->dsDaysBetween($centre);
  213.  
  214.     $links[] = '<a href="'
  215.                   .makeURL('calendar',
  216.                             array_merge(
  217.                             array('instrid'=>$this->instrument, 'caloffset'=>$back),
  218.                             $extra)
  219.                            )
  220.                 .'">&laquo; '. T_('earlier') .'</a>';
  221.  
  222.     $links[] = $this->_makeQuickJumpLinks(T_('jump back to:'), -1, $calLength, $centre, $centreOffset, $script);
  223.  
  224.     $links[] = '<a href="'
  225.                   .makeURL('calendar',
  226.                           array_merge(
  227.                               array('instrid'=>$this->instrument, 'caloffset'=>'today'),
  228.                               $extra)
  229.                            )
  230.               .'">'. T_('today') .'</a> ';
  231.  
  232.     if ($this->ViewCalendarPermitted($forward)) {
  233.       $select = $this->_makeQuickJumpLinks(T_('jump forward to:'), 1, $calLength, $centre, $centreOffset, $script);
  234.  
  235.       if ($select !== '') $links[] = $select;
  236.  
  237.       $links[] = '<a href="'
  238.                   .makeURL('calendar',
  239.                           array_merge(
  240.                               array('instrid'=>$this->instrument, 'caloffset'=>$forward),
  241.                               $extra)
  242.                            )
  243.                   .'">'. T_('later') .' &raquo;</a>';
  244.     }
  245.  
  246.     $linkList = join($links, ' | ');
  247.     $location = makeURL('calendar',
  248.                         array_merge(
  249.                             array('instrid'=>$this->instrument),
  250.                             $extra),
  251.                          false);
  252.     $js = "
  253.           <script type='text/javascript'>
  254.             function $script(offset) {
  255.               newLocation = '$location' + '&caloffset=' + offset;
  256.               document.location.href = newLocation;
  257.             }
  258.           </script>";
  259.     return '<div style="text-align:center">' . $js . $linkList . '</div>';
  260.   }
  261.  
  262.  
  263.   function _makeQuickJumpLinks($caption, $direction, $calLength, $centre, $centreOffset, $script) {
  264.     $nonEmpty = false;
  265.     $backJumps = array('<option value="0">'. $caption .'</option>');
  266.     for ($i=1; $i <= 20; $i++) {
  267.       $offset = $direction * $i * $calLength;
  268.       $offsetDate = clone($centre);
  269.       $offsetDate->addDays($offset);
  270.       $offset -= $centreOffset;
  271.       if ($direction < 0 || $this->ViewCalendarPermitted($offset)) {
  272.         $nonEmpty = true;
  273.         $date = $offsetDate->dateString();
  274.         $backJumps[] = "<option value='$offset'>$date</option>";
  275.       } else {
  276.         break;
  277.       }
  278.     }
  279.     if ($nonEmpty) {
  280.       return "<select name='backLink' onChange='$script(this.value)'>"
  281.                   .join($backJumps, "\n")
  282.                   .'</select>';
  283.     } else {
  284.       return '';
  285.     }
  286.   }
  287.  
  288.   function _makeCalendarConfigDialogue() {
  289.     $t = '';
  290.     $reflector = new DataReflector();
  291.     $reflector->excludeLogin();
  292.     $reflector->excludeRegex('@^Instrument-(\d+)-.+@');
  293.     $t .= $reflector->display($this->PD);
  294.  
  295.     $div = 'bumblebeeCalendarControls';
  296.     $func = $div.'_toggler';
  297.     $t .=  "
  298.       <script type='text/javascript'>
  299.         function $func(show) {
  300.           if (show) {
  301.             hideDiv('toggle$div');
  302.             showDiv('$div');
  303.           } else {
  304.             hideDiv('$div');
  305.             showDiv('toggle$div');
  306.           }
  307.         }
  308.       </script>";
  309.  
  310.     $t .= '<div id="bumblebeeCalendarControls" style="display: none;">';
  311.  
  312.     $t .= "<div style='text-align: right'><a href='javascript:$func(false)'>".T_('close').'</a></div>';
  313.  
  314.     $t .= '<fieldset>'
  315.           .'<legend>'.T_('Select Instruments').'</legend>'
  316.           . $this->_makeInstrumentAddDialogue()
  317.           .'</fieldset>'
  318.           . '<input type="submit" name="configureview" value="'.T_('Apply').'" />';
  319.  
  320.     $t .= '</div>';
  321.  
  322.     $t .= '<div id="bumblebeeCalendarControlsSwitch">';
  323.     $t .= "<div id='toggle$div'>"
  324.           ."<a href='javascript:$func(true)'>".T_('Calendar controls').'</a>'
  325.           ."</div>";
  326.     $t .= '</div>';
  327.     return $t;
  328.   }
  329.  
  330.   function _makeInstrumentAddDialogue() {
  331.     $t = '';
  332.     $selectRow = new nonDBRow('instrumentselect', NULL,
  333.               T_('Select which instruments you want to add to this calendar'));
  334.     $select = new CheckBoxTableList(T_('Instrument'), T_('Select which instruments to add'));
  335.     $hidden = new TextField('instrument');
  336.     $select->addFollowHidden($hidden);
  337.     $include = new CheckBox('include', T_('Show'));
  338.     $select->addCheckBox($include);
  339.     $select->connectDB('instruments', array('id', 'name'),
  340.                    "id != {$this->instrument[0]}");
  341.     $select->setFormat('id', '%s', array('name'));
  342.     $select->valueList = $this->instrument;
  343.     $selectRow->addElement($select);
  344.  
  345.     return $selectRow->displayInTable(4);
  346.   }
  347.  
  348.   /**
  349.   * Display a single day's calendar for the selected instrument
  350.   *
  351.   * @todo ///TODO: combine this function with instrumentMonth to reduce duplication
  352.   */
  353.   function instrumentDay() {
  354.     $granularity = $this->row['calprecision'];
  355.     $timelines   = $this->row['caltimemarks'];
  356.  
  357.     $offset = issetSet($this->PD, 'caloffset');
  358.     $today = new SimpleDate(time());
  359.     $today->dayRound();
  360.  
  361.     if ($offset == 'today') {
  362.       $start = clone($today);
  363.       $offset = 0;
  364.     } else {
  365.       $start = new SimpleDate($this->PD['isodate']);
  366.       $start->dayRound();
  367.       $start->addDays($offset);
  368.     }
  369.  
  370.     $stop = clone($start);
  371.     $stop->addDays(1);
  372.  
  373.     // check to see if this is an allowable calendar view (not too far into the future)
  374.     $futureView = $this->BookingPastNormalCalendar($start);
  375.  
  376.     if ($futureView < 0 && ! $this->auth->permitted(BBROLE_VIEW_CALENDAR_FUTURE, $this->instrument)) {
  377.       $start->addDays($futureView);
  378.       $stop->addDays($futureView);
  379.       $offset += $futureView;
  380.     }
  381.  
  382.  
  383. /*
  384.     $totaloffset = $start->daysBetween($today);
  385.     $maxfuture = $row['calfuture'] + 7 - $today->dow();
  386.     //admin users are allowed to see further into the future.
  387.     $this->_checkBookingAuth(-1);
  388.     $this->log("Found total offset of $totaloffset, $maxfuture");
  389.  
  390.     $futureView = false;
  391.     if ($totaloffset > $maxfuture && ! $this->auth->permitted(BBROLE_VIEW_CALENDAR_FUTURE, $this->instrument)) {
  392.       #echo "Found total offset of $totaloffset, but only ".$row['calfuture']." is permitted. ";
  393.       $delta = $maxfuture-$totaloffset;
  394.       #echo "Changing offset by $delta\n";
  395.       $start->addDays($delta);
  396.       $futureView = true;
  397.     }*/
  398.     $cal = new Calendar($start, $stop, $this->instrument);
  399.     $cal->setTimeSlotPicture($this->row['timeslotpicture']);
  400.  
  401.     /// FIXME: get this from the instrument table?
  402.     $daystart    = new SimpleTime('00:00:00');
  403.     $daystop     = new SimpleTime('24:00:00');
  404. //     echo $cal->display();
  405.     $cal->bookhrefCallback = array(&$this, 'MakeBookingHref');
  406.  
  407.     $cal->freeBusyOnly = ! $this->auth->permitted(BBROLE_VIEW_BOOKINGS, $this->instrument);
  408.     $cal->isAdminView = $this->auth->permitted(BBROLE_MAKE_BOOKINGS_FREE, $this->instrument);
  409.     $cal->setOutputStyles('', 'caltoday', array('monodd', 'moneven'), 'm');
  410.     echo $this->displayInstrumentHeader();
  411.     echo $this->_linksForwardBack($start,
  412.                                   '-1', '+1', 1,
  413.                                   array('isodate'=>$start->dateString()));
  414.     echo $cal->displayDayAsTable($daystart,$daystop,$granularity,$timelines);
  415.     echo $this->displayInstrumentFooter();
  416.   }
  417.  
  418.   function _viewCalendarForbidden() {
  419.     $this->_Forbidden(T_('Sorry, you are not permitted to view this instrument\'s calendar.'));
  420.   }
  421.  
  422. } // class ActionCalendar
  423. ?>

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