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