VTodo.php 5.3 KB

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