Source for file timeslotrule.php
Documentation is available at timeslotrule.php
* Timeslot validation based on rules passed to us (presumably from an SQL entry)
* @author Stuart Prescott
* @copyright Copyright Stuart Prescott
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
/** Load ancillary functions */
require_once 'inc/typeinfo.php';
/** date manipulation routines */
require_once 'inc/date.php';
/** timeslot object for bookings/vacancies */
require_once 'timeslot.php';
/** date-time operation control: look for match with start of slot */
/** date-time operation control: look for match with end of slot */
/** date-time operation control: look for slot where this time is within the slot */
/** date-time operation control: look for slot following this time */
/** number of extra elements that will be in the array created from the slot rules */
/** flag that slot was not found by the slot finding routines */
define('TS_SLOT_NOT_FOUND', -
10000);
* Timeslot validation based on rules passed to us (presumably from an SQL entry)
* @todo //TODO: more documentation
* timeslot picture syntax (concatinate onto one line, no spaces)
* specify the day of week (or range of days). 0=Sunday, 6=Saturday
* around the comma-separated slot specifications for that day. All times from 00:00 to 24:00
* must be included in the list
* starttime-stoptime/num_slots-discount%,comment
* HH:MM time slots with the length of each slot.
* e.g. 09:00-17:00/1 specifies a slot starting at 9am and finishing 5pm.
* both 00:00 and 24:00 are valid, also 32:00 for 8am the next day (o'night)
* num_slots is integer, or wildcard of * for freely adjustable time
* e.g. 09:00-12:00/3 specifies 3 slots 9-10, 10-11 and 11-12.
* discount (optional) is the percentage discount applied to bookings in that slot
* comment (optional) is displayed in vacant or unavailable slots
* [0-6]<00:00-08:00/*;08:00-13:00/1;13:00-18:00/1;18:00-24:00/*>
* Available all days, free booking until 8am and after 6pm, other slots as defined
* [0]<00:00-24:00/0,Unavailable>[1-5]<09:00-17:00/01:00>[6]<00:00-24:00/0,Unavailable>
* Not available Sunday and Saturday. Only available weekdays 9am till 5pm with 1hr booking
* granularity. Calendar views of Sat & Sun will see message "Unavailable"
* [0]<>[1-5]<00:00-09:00/*;09:00-17:00/8;17:00-24:00/*-50%>[6]<>
* Not available Sunday and Saturday. Available weekdays 9am till 5pm with 1hr booking
* granularity, before 9am and after 5pm with no granularity and at a 50% discount.
* [0]<>[1-5]<09:00-13:00/4;13:00-17:00/2;17:00-33:00/1>[6]<>
* Not available Sunday and Saturday. Available weekdays 9am till 5pm with 1hr booking
* granularity, before 9am and after 5pm with no granularity
for ($dow=
0; $dow<=
6; $dow++
) {
$this->slots[$dow] =
array();
for ($dow=
0; $dow<=
6; $dow++
) {
foreach ($daylines[0] as $d) {
#echo "considering $d\n";
#echo "found match: ".$day[1]."\n";
$this->slots[$day[1]]['picture']=
$d;
#echo "found multimatch: ".$day[1].'.'.$day[2]."\n";
for ($i=
$day[1]; $i<=
$day[2]; $i++
) {
$this->slots[$i]['picture']=
$d;
#preDump($this->slots[$dow]['picture']);
$times[1]=
'00:00-24:00/0';
#echo "found slot=$slot\n";
#$this->slots[$dow][$i] = array();
if (preg_match('/(\d\d:\d\d)-(\d\d:\d\d)\/(\d+|\*)(-\d+%)?(?:,(.+))?/', $slot, $tmp)) {
/* regexp: HH:MM - HH:MM /n -x% ,comment
x is optional and can be one or more digits
,comment is optional and the comma is not included in the captured pattern
?: means don't capture the contents of that subpattern () to $tmp
$discount =
0; $comment =
'';
while (isset
($tmp[$optional])) {
if (substr($tmp[$optional], 0, 1) ==
'-' &&
substr($tmp[$optional], -
1, 1) ==
'%') {
$discount =
substr($tmp[$optional],1,-
1);
// then it's the comment at the end
$comment =
$tmp[$optional];
//echo "(start,stop,slots) = ($start,$stop,$numslots)\n";
//echo "(discount,comment) = ($discount,$comment)<br />\n";
if ($numslots !=
'*' &&
$numslots !=
'0') {
#echo "Trying to interpolate timeslots\n";
$tgran =
new SimpleTime($tstop->subtract($tstart)/
$numslots);
for ($time =
clone($tstart); $time->ticks <
$tstop->ticks; $time->addTime($tgran)) {
//echo $time->timeString().' '. $tstop->timeString().' '.$tgran->timeString()."<br />\n";
$this->slots[$dow][$i] =
new RuleSlot($slot, $start, $stop, clone($time), $sstop, $tgran);
$this->slots[$dow][$i]->numslotsInGroup =
1;
$this->slots[$dow][$i]->numslotsFollowing =
$numslots -
$siblingSlot;
$this->slots[$dow][$i]->comment =
$comment;
$this->slots[$dow][$i]->discount =
$discount;
if ($time->ticks !=
$tstart->ticks) {
$this->slots[$dow][$i-
1]->nextSlot =
&$this->slots[$dow][$i];
#echo "No need to interpolate\n";
$this->slots[$dow][$i] =
new RuleSlot($slot, $start, $stop, $tstart, $tstop);
$this->slots[$dow][$i]->numslotsInGroup =
1;
$this->slots[$dow][$i]->numslotsFollowing =
0;
$this->slots[$dow][$i]->isFreeForm =
$numslots ==
'*';
$this->slots[$dow][$i]->isAvailable =
$numslots !=
'0';
$this->slots[$dow][$i]->comment =
$comment;
$this->slots[$dow][$i]->discount =
$discount;
/* function allSlotStart() {
echo "STUB: ". __FILE__ .' '. __LINE__;
return array('09:00','10:00','15:00');
* return true if the specified date & time correspond to a valid starting time according
* to this object's slot rules.
* return true if the specified date & time correspond to a valid stopping time according
* to this object's slot rules.
$startday =
clone($date);
//echo "$startday->dateTimeString() =? $date->dateTimeString()\n";
if ($startday->ticks ==
$date->ticks) {
//echo "$startday->dateTimeString() + $time->timeString()\n";
* perform the above operations with no code duplication
* return true if the specified dates & times are valid start/stop times
* to this object's slot rules.
* return true if the specified dates & times are valid as above, but only occupy one slot
return $slot->stop->ticks ==
$stopdate->ticks;
* return the corresponding the slot specified by the given start date.
* ASSUMES that the specified date is a valid start, else behaviour is undefined.
* @param mixed SimpleDate $date the date to match or SimpleTime to match
* @param mixed optional SimpleDate iff $date was a SimpleTime. Provide the date component
* return the corresponding startdate/time to a time that is possibly within a slot
* returns the slot that starts >= the date specified.
* return the corresponding slot number of the starting or stopping date-time $date
* returns -1 if no matching slot found.
* $match is TSSTART, TSSTOP, TSWITHIN, TSNEXT depending on what matching is queried.
* $return is TSSTART or TSSTOP depending on the required return value
* this function will return a slot from the previous day if the slot spans days and
* that is the appropriate slot.
* WARNING: There be dragons....
function _findSlot($date, $match, $datetime=
0) {
//$this->log("TimeSlotRule::_findSlot:($date->dateTimeString(), $match, $datetime)", 10);
//preDump(debug_backtrace());
$time =
$date->timePart();
//echo "Found $time->timeString(), $dow, $day->dateTimeString()\n";
#preDump($this->slots[$dow]);
$this->log("TimeSlotRule::_findSlot:(".
$time->timeString().
", ".
$this->slots[$dow][0]->$startvar->ticks.
", $time->ticks, $dow)", 10);
if ($time->ticks <
$this->slots[$dow][0]->$startvar->ticks
||
$match ==
TSSTOP &&
$time->ticks <=
$this->slots[$dow][0]->$startvar->ticks) {
$time->addSecs(24*
60*
60);
$this->log("Stepped back a day to do the comparison");
/* $this->log("TimeSlotRule::_findSlot:($time->timeString(), ".$this->slots[$dow][0]->$stopvar->ticks.", $time->ticks, $dow)", 10);
if ($time->ticks > $this->slots[$dow][count($this->slots[$dow])-1-TSARRAYMIN]->$stopvar->ticks) {
$time->addSecs(-24*60*60);
$this->log("Stepped forward a day to do the comparison");
$this->log("Asking for ($dow, $slot, $timecmp, $match)", 10);
//preDump($this->slots[$dow]);
//print_r("Asking for ($dow, $slot, $match)<br />") &&
&&
$time->ticks >=
$this->slots[$dow][$slot]->$timecmp->ticks) {
//echo $time->ticks .'#'. $this->slots[$dow][$slot]->$timecmp->ticks."\n";
//echo $slot .'#'.(count($this->slots[$dow])-TSARRAYMIN)."\n";
#echo count($this->slots[$dow])-TSARRAYMIN."/";
#echo $time->ticks .', '. $this->slots[$dow][$slot-1]->$timecmp->ticks."\n";
$this->log("Final ($dow, $slot, $match)",10);
&&
$time->ticks ==
$this->slots[$dow][$slot]->$timecmp->ticks)
&&
$time->ticks >=
$this->slots[$dow][$slot]->$a->ticks
&&
$time->ticks <
$this->slots[$dow][$slot]->$b->ticks)
//echo "Found containing slot: $finalslot\n";
//echo "Looking for next slot in overflow:\n";
//echo "($dow, $day->dateTimeString(),".count($this->slots[$dow]).")\n";
//echo "($dow, $day->dateTimeString(),".TSARRAYMIN.")\n".count($this->slots[$dow]);
$this->log("ReallyFinal ($dow, $finalslot, $match)",10);
//trigger_error('Could not find a match to this time slot.', E_USER_NOTICE);
$returnSlot =
clone($this->slots[$dow][$finalslot]);
#echo $day->datetimestring();
$returnSlot->setDate($day);
#preDump($returnSlot->dump());
$eol =
$html ?
"<br />\n" :
"\n";
$s .=
"Initial Pattern = '".
$this->picture .
"'".
$eol;
for ($day=
0; $day<=
6; $day++
) {
$s .=
"Day Pattern[$day] = '".
$this->slots[$day]['picture'] .
"'".
$eol;
//for ($j=0; $j<count($this->slots[$day]) && isset($this->slots[$day][$j]); $j++) {
foreach ($this->slots[$day] as $k =>
$v) {
// $s .= "\t" . $v->tstart->timeString()
// ." - ". $v->tstop->timeString() .$eol;
function log($logstring, $prio=
10) {
if ($prio <=
$this->DEBUG) {
echo
$logstring.
"<br />\n";
* Data object for an individual time slot defined by the time slot picture
* @author Stuart Prescott
* @copyright Copyright Stuart Prescott
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @todo //TODO: more documentation
function RuleSlot($picture, $startStr, $stopStr, $tstart, $tstop, $tgran=
NULL) {
$this->tgran =
type_is_a($tgran, 'SimpleTime') ?
$tgran :
new SimpleTime(0);
$this->start =
clone($date);
$this->stop =
clone($date);
$eol =
$html ?
"<br />\n" :
"\n";
.
$this->tstart->timeString().
' - '
.
$this->tstop->timeString().
' : '
#echo $i.': length='.$cslot->tgran->timeString().', sum='.$cdur->timeString()."<br />\n";
$duration[] =
clone($cdur);
$cdur->addTime($cslot->tgran);
$cslot =
$cslot->nextSlot;
$cslot->setDate($this->start);
$ends[] =
clone($cslot->stop);
$cslot =
$cslot->nextSlot;
Documentation generated on Tue, 06 Mar 2007 10:02:04 +0000 by phpDocumentor 1.3.0