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