1<?php
2
3namespace Sabre\VObject\Component;
4
5use Sabre\VObject;
6
7/**
8 * The Available sub-component.
9 *
10 * This component adds functionality to a component, specific for AVAILABLE
11 * components.
12 *
13 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
14 * @author Ivan Enderlin
15 * @license http://sabre.io/license/ Modified BSD License
16 */
17class Available extends VObject\Component {
18
19    /**
20     * Returns the 'effective start' and 'effective end' of this VAVAILABILITY
21     * component.
22     *
23     * We use the DTSTART and DTEND or DURATION to determine this.
24     *
25     * The returned value is an array containing DateTimeImmutable instances.
26     * If either the start or end is 'unbounded' its value will be null
27     * instead.
28     *
29     * @return array
30     */
31    function getEffectiveStartEnd() {
32
33        $effectiveStart = $this->DTSTART->getDateTime();
34        if (isset($this->DTEND)) {
35            $effectiveEnd = $this->DTEND->getDateTime();
36        } else {
37            $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
38        }
39
40        return [$effectiveStart, $effectiveEnd];
41
42    }
43
44    /**
45     * A simple list of validation rules.
46     *
47     * This is simply a list of properties, and how many times they either
48     * must or must not appear.
49     *
50     * Possible values per property:
51     *   * 0 - Must not appear.
52     *   * 1 - Must appear exactly once.
53     *   * + - Must appear at least once.
54     *   * * - Can appear any number of times.
55     *   * ? - May appear, but not more than once.
56     *
57     * @var array
58     */
59    function getValidationRules() {
60
61        return [
62            'UID'     => 1,
63            'DTSTART' => 1,
64            'DTSTAMP' => 1,
65
66            'DTEND'    => '?',
67            'DURATION' => '?',
68
69            'CREATED'       => '?',
70            'DESCRIPTION'   => '?',
71            'LAST-MODIFIED' => '?',
72            'RECURRENCE-ID' => '?',
73            'RRULE'         => '?',
74            'SUMMARY'       => '?',
75
76            'CATEGORIES' => '*',
77            'COMMENT'    => '*',
78            'CONTACT'    => '*',
79            'EXDATE'     => '*',
80            'RDATE'      => '*',
81
82            'AVAILABLE' => '*',
83        ];
84
85    }
86
87    /**
88     * Validates the node for correctness.
89     *
90     * The following options are supported:
91     *   Node::REPAIR - May attempt to automatically repair the problem.
92     *   Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
93     *   Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.
94     *
95     * This method returns an array with detected problems.
96     * Every element has the following properties:
97     *
98     *  * level - problem level.
99     *  * message - A human-readable string describing the issue.
100     *  * node - A reference to the problematic node.
101     *
102     * The level means:
103     *   1 - The issue was repaired (only happens if REPAIR was turned on).
104     *   2 - A warning.
105     *   3 - An error.
106     *
107     * @param int $options
108     *
109     * @return array
110     */
111    function validate($options = 0) {
112
113        $result = parent::validate($options);
114
115        if (isset($this->DTEND) && isset($this->DURATION)) {
116            $result[] = [
117                'level'   => 3,
118                'message' => 'DTEND and DURATION cannot both be present',
119                'node'    => $this
120            ];
121        }
122
123        return $result;
124
125    }
126}
127