1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\VObject\Component; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse Sabre\VObject; 6*a1a3b679SAndreas Boehler 7*a1a3b679SAndreas Boehler/** 8*a1a3b679SAndreas Boehler * The VFreeBusy component 9*a1a3b679SAndreas Boehler * 10*a1a3b679SAndreas Boehler * This component adds functionality to a component, specific for VFREEBUSY 11*a1a3b679SAndreas Boehler * components. 12*a1a3b679SAndreas Boehler * 13*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/). 14*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/) 15*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License 16*a1a3b679SAndreas Boehler */ 17*a1a3b679SAndreas Boehlerclass VFreeBusy extends VObject\Component { 18*a1a3b679SAndreas Boehler 19*a1a3b679SAndreas Boehler /** 20*a1a3b679SAndreas Boehler * Checks based on the contained FREEBUSY information, if a timeslot is 21*a1a3b679SAndreas Boehler * available. 22*a1a3b679SAndreas Boehler * 23*a1a3b679SAndreas Boehler * @param DateTime $start 24*a1a3b679SAndreas Boehler * @param Datetime $end 25*a1a3b679SAndreas Boehler * @return bool 26*a1a3b679SAndreas Boehler */ 27*a1a3b679SAndreas Boehler public function isFree(\DateTime $start, \Datetime $end) { 28*a1a3b679SAndreas Boehler 29*a1a3b679SAndreas Boehler foreach($this->select('FREEBUSY') as $freebusy) { 30*a1a3b679SAndreas Boehler 31*a1a3b679SAndreas Boehler // We are only interested in FBTYPE=BUSY (the default), 32*a1a3b679SAndreas Boehler // FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE. 33*a1a3b679SAndreas Boehler if (isset($freebusy['FBTYPE']) && strtoupper(substr((string)$freebusy['FBTYPE'],0,4))!=='BUSY') { 34*a1a3b679SAndreas Boehler continue; 35*a1a3b679SAndreas Boehler } 36*a1a3b679SAndreas Boehler 37*a1a3b679SAndreas Boehler // The freebusy component can hold more than 1 value, separated by 38*a1a3b679SAndreas Boehler // commas. 39*a1a3b679SAndreas Boehler $periods = explode(',', (string)$freebusy); 40*a1a3b679SAndreas Boehler 41*a1a3b679SAndreas Boehler foreach($periods as $period) { 42*a1a3b679SAndreas Boehler // Every period is formatted as [start]/[end]. The start is an 43*a1a3b679SAndreas Boehler // absolute UTC time, the end may be an absolute UTC time, or 44*a1a3b679SAndreas Boehler // duration (relative) value. 45*a1a3b679SAndreas Boehler list($busyStart, $busyEnd) = explode('/', $period); 46*a1a3b679SAndreas Boehler 47*a1a3b679SAndreas Boehler $busyStart = VObject\DateTimeParser::parse($busyStart); 48*a1a3b679SAndreas Boehler $busyEnd = VObject\DateTimeParser::parse($busyEnd); 49*a1a3b679SAndreas Boehler if ($busyEnd instanceof \DateInterval) { 50*a1a3b679SAndreas Boehler $tmp = clone $busyStart; 51*a1a3b679SAndreas Boehler $tmp->add($busyEnd); 52*a1a3b679SAndreas Boehler $busyEnd = $tmp; 53*a1a3b679SAndreas Boehler } 54*a1a3b679SAndreas Boehler 55*a1a3b679SAndreas Boehler if($start < $busyEnd && $end > $busyStart) { 56*a1a3b679SAndreas Boehler return false; 57*a1a3b679SAndreas Boehler } 58*a1a3b679SAndreas Boehler 59*a1a3b679SAndreas Boehler } 60*a1a3b679SAndreas Boehler 61*a1a3b679SAndreas Boehler } 62*a1a3b679SAndreas Boehler 63*a1a3b679SAndreas Boehler return true; 64*a1a3b679SAndreas Boehler 65*a1a3b679SAndreas Boehler } 66*a1a3b679SAndreas Boehler 67*a1a3b679SAndreas Boehler /** 68*a1a3b679SAndreas Boehler * A simple list of validation rules. 69*a1a3b679SAndreas Boehler * 70*a1a3b679SAndreas Boehler * This is simply a list of properties, and how many times they either 71*a1a3b679SAndreas Boehler * must or must not appear. 72*a1a3b679SAndreas Boehler * 73*a1a3b679SAndreas Boehler * Possible values per property: 74*a1a3b679SAndreas Boehler * * 0 - Must not appear. 75*a1a3b679SAndreas Boehler * * 1 - Must appear exactly once. 76*a1a3b679SAndreas Boehler * * + - Must appear at least once. 77*a1a3b679SAndreas Boehler * * * - Can appear any number of times. 78*a1a3b679SAndreas Boehler * * ? - May appear, but not more than once. 79*a1a3b679SAndreas Boehler * 80*a1a3b679SAndreas Boehler * @var array 81*a1a3b679SAndreas Boehler */ 82*a1a3b679SAndreas Boehler public function getValidationRules() { 83*a1a3b679SAndreas Boehler 84*a1a3b679SAndreas Boehler return array( 85*a1a3b679SAndreas Boehler 'UID' => 1, 86*a1a3b679SAndreas Boehler 'DTSTAMP' => 1, 87*a1a3b679SAndreas Boehler 88*a1a3b679SAndreas Boehler 'CONTACT' => '?', 89*a1a3b679SAndreas Boehler 'DTSTART' => '?', 90*a1a3b679SAndreas Boehler 'DTEND' => '?', 91*a1a3b679SAndreas Boehler 'ORGANIZER' => '?', 92*a1a3b679SAndreas Boehler 'URL' => '?', 93*a1a3b679SAndreas Boehler 94*a1a3b679SAndreas Boehler 'ATTENDEE' => '*', 95*a1a3b679SAndreas Boehler 'COMMENT' => '*', 96*a1a3b679SAndreas Boehler 'FREEBUSY' => '*', 97*a1a3b679SAndreas Boehler 'REQUEST-STATUS' => '*', 98*a1a3b679SAndreas Boehler ); 99*a1a3b679SAndreas Boehler 100*a1a3b679SAndreas Boehler } 101*a1a3b679SAndreas Boehler 102*a1a3b679SAndreas Boehler} 103*a1a3b679SAndreas Boehler 104