Merge branch '3.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / condition / TimeCondition.class.php
1 <?php
2 namespace wcf\system\condition;
3 use wcf\data\condition\Condition;
4 use wcf\system\exception\UserInputException;
5 use wcf\system\WCF;
6 use wcf\util\DateUtil;
7 use wcf\util\StringUtil;
8
9 /**
10 * Condition implementation for the current time.
11 *
12 * @author Matthias Schmidt
13 * @copyright 2001-2018 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15 * @package WoltLabSuite\Core\System\Condition
16 */
17 class TimeCondition extends AbstractMultipleFieldsCondition implements IContentCondition {
18 /**
19 * end time
20 * @var string
21 */
22 protected $endTime = '00:00';
23
24 /**
25 * @inheritDoc
26 */
27 protected $labels = [
28 'time' => 'wcf.date.time',
29 'timezone' => 'wcf.date.timezone'
30 ];
31
32 /**
33 * start time
34 * @var string
35 */
36 protected $startTime = '00:00';
37
38 /**
39 * timezone used to evaluate the start/end time
40 * @var string
41 */
42 protected $timezone = 0;
43
44 /**
45 * @inheritDoc
46 */
47 public function getData() {
48 $data = [];
49
50 if ($this->startTime) {
51 $data['startTime'] = $this->startTime;
52 }
53 if ($this->endTime) {
54 $data['endTime'] = $this->endTime;
55 }
56
57 if (!empty($data) && $this->timezone) {
58 $data['timezone'] = $this->timezone;
59 }
60
61 if (!empty($data)) {
62 return $data;
63 }
64
65 return null;
66 }
67
68 /**
69 * @inheritDoc
70 */
71 public function getHTML() {
72 $start = WCF::getLanguage()->get('wcf.date.period.start');
73 $end = WCF::getLanguage()->get('wcf.date.period.end');
74
75 return <<<HTML
76 <dl>
77 <dt>{$this->getLabel('time')}</dt>
78 <dd>
79 <input type="datetime" data-ignore-timezone="1" data-time-only="1" id="startTime" name="startTime" value="{$this->startTime}" placeholder="{$start}">
80 <input type="datetime" data-ignore-timezone="1" data-time-only="1" id="endTime" name="endTime" value="{$this->endTime}" placeholder="{$end}">
81 {$this->getDescriptionElement('time')}
82 {$this->getErrorMessageElement('time')}
83 </dd>
84 </dl>
85 <dl>
86 <dt>{$this->getLabel('timezone')}</dt>
87 <dd>
88 {$this->getTimezoneFieldElement()}
89 {$this->getDescriptionElement('timezone')}
90 {$this->getErrorMessageElement('timezone')}
91 </dd>
92 </dl>
93 HTML;
94 }
95
96 /**
97 * Returns the select element with all available timezones.
98 *
99 * @return string
100 */
101 protected function getTimezoneFieldElement() {
102 $fieldElement = '<select name="timezone" id="timezone"><option value="0"'.($this->timezone ? ' selected' : '').'>'.WCF::getLanguage()->get('wcf.date.timezone.user').'</option>';
103 foreach (DateUtil::getAvailableTimezones() as $timezone) {
104 $fieldElement .= '<option value="'.$timezone.'"'.($this->timezone === $timezone ? ' selected' : '').'>'.WCF::getLanguage()->get('wcf.date.timezone.'.str_replace('/', '.', strtolower($timezone))).'</option>';
105 }
106 $fieldElement .= '</select>';
107
108 return $fieldElement;
109 }
110
111 /**
112 * @inheritDoc
113 */
114 public function readFormParameters() {
115 if (isset($_POST['endTime'])) $this->endTime = StringUtil::trim($_POST['endTime']);
116 if (isset($_POST['startTime'])) $this->startTime = StringUtil::trim($_POST['startTime']);
117 if (isset($_POST['timezone'])) $this->timezone = StringUtil::trim($_POST['timezone']);
118 }
119
120 /**
121 * @inheritDoc
122 */
123 public function reset() {
124 $this->endTime = '00:00';
125 $this->startTime = '00:00';
126 $this->timezone = 0;
127 }
128
129 /**
130 * @inheritDoc
131 */
132 public function setData(Condition $condition) {
133 /** @noinspection PhpUndefinedFieldInspection */
134 $endTime = $condition->endTime;
135 if ($endTime) {
136 $this->endTime = $endTime;
137 }
138
139 /** @noinspection PhpUndefinedFieldInspection */
140 $startTime = $condition->startTime;
141 if ($startTime) {
142 $this->startTime = $startTime;
143 }
144
145 /** @noinspection PhpUndefinedFieldInspection */
146 $timezone = $condition->timezone;
147 if ($timezone) {
148 $this->timezone = $timezone;
149 }
150 }
151
152 /**
153 * @inheritDoc
154 */
155 public function validate() {
156 if ($this->startTime == '00:00' && $this->endTime == '00:00') {
157 $this->startTime = $this->endTime = '';
158 return;
159 }
160
161 $startDateTime = $endDateTime = null;
162 if ($this->startTime) {
163 $startDateTime = \DateTime::createFromFormat('H:i', $this->startTime);
164 if ($startDateTime === false) {
165 $this->errorMessages['time'] = 'wcf.date.startTime.error.invalid';
166
167 throw new UserInputException('startTime', 'invalid');
168 }
169 }
170 if ($this->endTime) {
171 $endDateTime = \DateTime::createFromFormat('H:i', $this->endTime);
172 if ($endDateTime === false) {
173 $this->errorMessages['time'] = 'wcf.date.endTime.error.invalid';
174
175 throw new UserInputException('endTime', 'invalid');
176 }
177 }
178
179 if ($startDateTime !== null && $endDateTime !== null) {
180 if ($startDateTime->getTimestamp() >= $endDateTime->getTimestamp()) {
181 $this->errorMessages['time'] = 'wcf.date.endTime.error.beforeStartTime';
182
183 throw new UserInputException('endTime', 'beforeStartTime');
184 }
185 }
186
187 if ($this->timezone && !in_array($this->timezone, DateUtil::getAvailableTimezones())) {
188 $this->errorMessages['timezone'] = 'wcf.global.form.error.noValidSelection';
189
190 throw new UserInputException('timezone', 'noValidSelection');
191 }
192 }
193
194 /**
195 * @inheritDoc
196 */
197 public function showContent(Condition $condition) {
198 $timezone = WCF::getUser()->getTimeZone();
199 /** @noinspection PhpUndefinedFieldInspection */
200 $conditionTimezone = $condition->timezone;
201 if ($conditionTimezone) {
202 $timezone = new \DateTimeZone($conditionTimezone);
203 }
204
205 /** @noinspection PhpUndefinedFieldInspection */
206 $startTime = $condition->startTime;
207 if ($startTime) {
208 $dateTime = \DateTime::createFromFormat('H:i', $startTime, $timezone);
209 if ($dateTime->getTimestamp() > TIME_NOW) {
210 return false;
211 }
212 }
213
214 /** @noinspection PhpUndefinedFieldInspection */
215 $endTime = $condition->endTime;
216 if ($endTime) {
217 $dateTime = \DateTime::createFromFormat('H:i', $endTime, $timezone);
218 if ($dateTime->getTimestamp() < TIME_NOW) {
219 return false;
220 }
221 }
222
223 return true;
224 }
225 }