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 * VTodo component 9*a1a3b679SAndreas Boehler * 10*a1a3b679SAndreas Boehler * This component contains some additional functionality specific for VTODOs. 11*a1a3b679SAndreas Boehler * 12*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/). 13*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/) 14*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License 15*a1a3b679SAndreas Boehler */ 16*a1a3b679SAndreas Boehlerclass VTodo extends VObject\Component { 17*a1a3b679SAndreas Boehler 18*a1a3b679SAndreas Boehler /** 19*a1a3b679SAndreas Boehler * Returns true or false depending on if the event falls in the specified 20*a1a3b679SAndreas Boehler * time-range. This is used for filtering purposes. 21*a1a3b679SAndreas Boehler * 22*a1a3b679SAndreas Boehler * The rules used to determine if an event falls within the specified 23*a1a3b679SAndreas Boehler * time-range is based on the CalDAV specification. 24*a1a3b679SAndreas Boehler * 25*a1a3b679SAndreas Boehler * @param DateTime $start 26*a1a3b679SAndreas Boehler * @param DateTime $end 27*a1a3b679SAndreas Boehler * @return bool 28*a1a3b679SAndreas Boehler */ 29*a1a3b679SAndreas Boehler public function isInTimeRange(\DateTime $start, \DateTime $end) { 30*a1a3b679SAndreas Boehler 31*a1a3b679SAndreas Boehler $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null; 32*a1a3b679SAndreas Boehler $duration = isset($this->DURATION)?VObject\DateTimeParser::parseDuration($this->DURATION):null; 33*a1a3b679SAndreas Boehler $due = isset($this->DUE)?$this->DUE->getDateTime():null; 34*a1a3b679SAndreas Boehler $completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null; 35*a1a3b679SAndreas Boehler $created = isset($this->CREATED)?$this->CREATED->getDateTime():null; 36*a1a3b679SAndreas Boehler 37*a1a3b679SAndreas Boehler if ($dtstart) { 38*a1a3b679SAndreas Boehler if ($duration) { 39*a1a3b679SAndreas Boehler $effectiveEnd = clone $dtstart; 40*a1a3b679SAndreas Boehler $effectiveEnd->add($duration); 41*a1a3b679SAndreas Boehler return $start <= $effectiveEnd && $end > $dtstart; 42*a1a3b679SAndreas Boehler } elseif ($due) { 43*a1a3b679SAndreas Boehler return 44*a1a3b679SAndreas Boehler ($start < $due || $start <= $dtstart) && 45*a1a3b679SAndreas Boehler ($end > $dtstart || $end >= $due); 46*a1a3b679SAndreas Boehler } else { 47*a1a3b679SAndreas Boehler return $start <= $dtstart && $end > $dtstart; 48*a1a3b679SAndreas Boehler } 49*a1a3b679SAndreas Boehler } 50*a1a3b679SAndreas Boehler if ($due) { 51*a1a3b679SAndreas Boehler return ($start < $due && $end >= $due); 52*a1a3b679SAndreas Boehler } 53*a1a3b679SAndreas Boehler if ($completed && $created) { 54*a1a3b679SAndreas Boehler return 55*a1a3b679SAndreas Boehler ($start <= $created || $start <= $completed) && 56*a1a3b679SAndreas Boehler ($end >= $created || $end >= $completed); 57*a1a3b679SAndreas Boehler } 58*a1a3b679SAndreas Boehler if ($completed) { 59*a1a3b679SAndreas Boehler return ($start <= $completed && $end >= $completed); 60*a1a3b679SAndreas Boehler } 61*a1a3b679SAndreas Boehler if ($created) { 62*a1a3b679SAndreas Boehler return ($end > $created); 63*a1a3b679SAndreas Boehler } 64*a1a3b679SAndreas Boehler return true; 65*a1a3b679SAndreas Boehler 66*a1a3b679SAndreas Boehler } 67*a1a3b679SAndreas Boehler 68*a1a3b679SAndreas Boehler /** 69*a1a3b679SAndreas Boehler * A simple list of validation rules. 70*a1a3b679SAndreas Boehler * 71*a1a3b679SAndreas Boehler * This is simply a list of properties, and how many times they either 72*a1a3b679SAndreas Boehler * must or must not appear. 73*a1a3b679SAndreas Boehler * 74*a1a3b679SAndreas Boehler * Possible values per property: 75*a1a3b679SAndreas Boehler * * 0 - Must not appear. 76*a1a3b679SAndreas Boehler * * 1 - Must appear exactly once. 77*a1a3b679SAndreas Boehler * * + - Must appear at least once. 78*a1a3b679SAndreas Boehler * * * - Can appear any number of times. 79*a1a3b679SAndreas Boehler * * ? - May appear, but not more than once. 80*a1a3b679SAndreas Boehler * 81*a1a3b679SAndreas Boehler * @var array 82*a1a3b679SAndreas Boehler */ 83*a1a3b679SAndreas Boehler public function getValidationRules() { 84*a1a3b679SAndreas Boehler 85*a1a3b679SAndreas Boehler return array( 86*a1a3b679SAndreas Boehler 'UID' => 1, 87*a1a3b679SAndreas Boehler 'DTSTAMP' => 1, 88*a1a3b679SAndreas Boehler 89*a1a3b679SAndreas Boehler 'CLASS' => '?', 90*a1a3b679SAndreas Boehler 'COMPLETED' => '?', 91*a1a3b679SAndreas Boehler 'CREATED' => '?', 92*a1a3b679SAndreas Boehler 'DESCRIPTION' => '?', 93*a1a3b679SAndreas Boehler 'DTSTART' => '?', 94*a1a3b679SAndreas Boehler 'GEO' => '?', 95*a1a3b679SAndreas Boehler 'LAST-MODIFIED' => '?', 96*a1a3b679SAndreas Boehler 'LOCATION' => '?', 97*a1a3b679SAndreas Boehler 'ORGANIZER' => '?', 98*a1a3b679SAndreas Boehler 'PERCENT' => '?', 99*a1a3b679SAndreas Boehler 'PRIORITY' => '?', 100*a1a3b679SAndreas Boehler 'RECURRENCE-ID' => '?', 101*a1a3b679SAndreas Boehler 'SEQUENCE' => '?', 102*a1a3b679SAndreas Boehler 'STATUS' => '?', 103*a1a3b679SAndreas Boehler 'SUMMARY' => '?', 104*a1a3b679SAndreas Boehler 'URL' => '?', 105*a1a3b679SAndreas Boehler 106*a1a3b679SAndreas Boehler 'RRULE' => '?', 107*a1a3b679SAndreas Boehler 'DUE' => '?', 108*a1a3b679SAndreas Boehler 'DURATION' => '?', 109*a1a3b679SAndreas Boehler 110*a1a3b679SAndreas Boehler 'ATTACH' => '*', 111*a1a3b679SAndreas Boehler 'ATTENDEE' => '*', 112*a1a3b679SAndreas Boehler 'CATEGORIES' => '*', 113*a1a3b679SAndreas Boehler 'COMMENT' => '*', 114*a1a3b679SAndreas Boehler 'CONTACT' => '*', 115*a1a3b679SAndreas Boehler 'EXDATE' => '*', 116*a1a3b679SAndreas Boehler 'REQUEST-STATUS' => '*', 117*a1a3b679SAndreas Boehler 'RELATED-TO' => '*', 118*a1a3b679SAndreas Boehler 'RESOURCES' => '*', 119*a1a3b679SAndreas Boehler 'RDATE' => '*', 120*a1a3b679SAndreas Boehler ); 121*a1a3b679SAndreas Boehler 122*a1a3b679SAndreas Boehler } 123*a1a3b679SAndreas Boehler 124*a1a3b679SAndreas Boehler /** 125*a1a3b679SAndreas Boehler * Validates the node for correctness. 126*a1a3b679SAndreas Boehler * 127*a1a3b679SAndreas Boehler * The following options are supported: 128*a1a3b679SAndreas Boehler * Node::REPAIR - May attempt to automatically repair the problem. 129*a1a3b679SAndreas Boehler * 130*a1a3b679SAndreas Boehler * This method returns an array with detected problems. 131*a1a3b679SAndreas Boehler * Every element has the following properties: 132*a1a3b679SAndreas Boehler * 133*a1a3b679SAndreas Boehler * * level - problem level. 134*a1a3b679SAndreas Boehler * * message - A human-readable string describing the issue. 135*a1a3b679SAndreas Boehler * * node - A reference to the problematic node. 136*a1a3b679SAndreas Boehler * 137*a1a3b679SAndreas Boehler * The level means: 138*a1a3b679SAndreas Boehler * 1 - The issue was repaired (only happens if REPAIR was turned on) 139*a1a3b679SAndreas Boehler * 2 - An inconsequential issue 140*a1a3b679SAndreas Boehler * 3 - A severe issue. 141*a1a3b679SAndreas Boehler * 142*a1a3b679SAndreas Boehler * @param int $options 143*a1a3b679SAndreas Boehler * @return array 144*a1a3b679SAndreas Boehler */ 145*a1a3b679SAndreas Boehler public function validate($options = 0) { 146*a1a3b679SAndreas Boehler 147*a1a3b679SAndreas Boehler $result = parent::validate($options); 148*a1a3b679SAndreas Boehler if (isset($this->DUE) && isset($this->DTSTART)) { 149*a1a3b679SAndreas Boehler 150*a1a3b679SAndreas Boehler $due = $this->DUE; 151*a1a3b679SAndreas Boehler $dtStart = $this->DTSTART; 152*a1a3b679SAndreas Boehler 153*a1a3b679SAndreas Boehler if ($due->getValueType() !== $dtStart->getValueType()) { 154*a1a3b679SAndreas Boehler 155*a1a3b679SAndreas Boehler $result[] = array( 156*a1a3b679SAndreas Boehler 'level' => 3, 157*a1a3b679SAndreas Boehler 'message' => 'The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART', 158*a1a3b679SAndreas Boehler 'node' => $due, 159*a1a3b679SAndreas Boehler ); 160*a1a3b679SAndreas Boehler 161*a1a3b679SAndreas Boehler } elseif ($due->getDateTime() < $dtStart->getDateTime()) { 162*a1a3b679SAndreas Boehler 163*a1a3b679SAndreas Boehler $result[] = array( 164*a1a3b679SAndreas Boehler 'level' => 3, 165*a1a3b679SAndreas Boehler 'message' => 'DUE must occur after DTSTART', 166*a1a3b679SAndreas Boehler 'node' => $due, 167*a1a3b679SAndreas Boehler ); 168*a1a3b679SAndreas Boehler 169*a1a3b679SAndreas Boehler } 170*a1a3b679SAndreas Boehler 171*a1a3b679SAndreas Boehler } 172*a1a3b679SAndreas Boehler 173*a1a3b679SAndreas Boehler return $result; 174*a1a3b679SAndreas Boehler 175*a1a3b679SAndreas Boehler } 176*a1a3b679SAndreas Boehler 177*a1a3b679SAndreas Boehler} 178