Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
icsbuilder.php
1<?php
3
5use \Bitrix\Main\Type\DateTime;
6
7class IcsBuilder {
8 //const DT_FORMAT = 'Ymd\THis\Z';
9 const
10 PRODID = '-//Bitrix//Bitrix Calendar//EN',
11 DATE_FORMAT = 'Ymd',
12 DATETIME_FORMAT = 'Ymd\THis';
13
14 protected
15 $fullDayMode = false,
21
22 private
23 $availableProperties = [
24 'summary',
25 'description',
26 'dtstart',
27 'dtend',
28 'dtstamp',
29 'location',
30 'url',
31 'alarm',
32 'transp',
33 'status',
34 'uid',
35 'attendee',
36 'created',
37 'last-modified',
38 'sequence',
39 'transp'
40 ];
41 private static
42 $METHOD = 'REQUEST';
43
44
50 public function __construct($properties = [], $config = [])
51 {
53 $this->setConfig($config);
54 }
55
56 public function setProperties($properties)
57 {
58 if (is_array($properties))
59 {
60 foreach ($properties as $key => $value)
61 {
62 if (in_array($key, $this->availableProperties) && !empty($value))
63 {
64 $this->properties[$key] = $this->prepareValue($value, $key);
65 }
66 }
67 }
68 }
69
70 public function setConfig($config)
71 {
72 if (is_array($config))
73 {
74 if (isset($config['timezoneFrom']))
75 {
76 $this->timezoneFrom = $config['timezoneFrom'];
77 }
78 if (isset($config['timezoneTo']))
79 {
80 $this->timezoneTo = $config['timezoneTo'];
81 }
82 }
83 }
84
85 public function setFullDayMode($value)
86 {
87 $this->fullDayMode = $value;
88 }
89
90 public function setOrganizer($name, $email, $phone)
91 {
92 $this->organizer = ['name' => $name, 'email' => $email, 'phone' => $phone];
93 }
94
95 public function setAttendees($attendeeDataList = [])
96 {
97 if (is_array($attendeeDataList))
98 {
99 foreach($attendeeDataList as $attendeeData)
100 {
101 $this->attendees[] = $attendeeData;
102 }
103 }
104 }
105
106 public function render()
107 {
108 return implode("\r\n", $this->buildBody());
109 }
110
111 private function buildBody()
112 {
113 // Build ICS properties - add header
114 $ics_props = [
115 'BEGIN:VCALENDAR',
116 'PRODID:'.self::PRODID,
117 'VERSION:2.0',
118 'CALSCALE:GREGORIAN',
119 'METHOD:'.self::$METHOD,
120 'BEGIN:VEVENT'
121 ];
122
123 $props = [];
124
125 // Add organizer field
126 if (isset($this->organizer['email']))
127 {
128 $props[self::formatOrganizerKey($this->organizer)] = self::formatEmailValue($this->organizer['email']);
129 }
130 else if (isset($this->organizer['phone']))
131 {
132 $props[self::formatOrganizerKey($this->organizer)] = self::formatPhoneValue($this->organizer['phone']);
133 }
134
135 // Add attendees
136 if (is_array($this->attendees))
137 {
138 foreach($this->attendees as $k => $attendee)
139 {
140 $props[self::formatAttendeeKey($attendee)] = self::formatEmailValue($attendee['email']);
141 }
142 }
143
144 // Build ICS properties - add header
145 foreach($this->properties as $k => $v)
146 {
147 if ($k === 'dtstamp')
148 {
149 $props['DTSTAMP'] = self::formatDateTimeValue($v);
150 continue;
151 }
152 if ($k === 'url' )
153 {
154 $props['URL;VALUE=URI'] = $v;
155 }
156 else if ($k === 'dtstart' || $k === 'dtend')
157 {
158 if ($this->fullDayMode)
159 {
160 $props[mb_strtoupper($k).';VALUE=DATE'] = self::formatDateValue($v);
161 }
162 else
163 {
164 $tzid = ($k === 'dtstart') ? $this->timezoneFrom : $this->timezoneTo;
165 $props[mb_strtoupper($k).';TZID='.$tzid] = self::formatDateTimeValue($v);
166 }
167 }
168 else
169 {
170 $props[mb_strtoupper($k)] = $v;
171 }
172 }
173
174 // Append properties
175 foreach ($props as $k => $v)
176 {
177 if ($k !== 'ALARM')
178 {
179 $ics_props[] = "$k:$v";
180 }
181 else
182 {
183 $ics_props[] = 'BEGIN:VALARM';
184 $ics_props[] = 'TRIGGER:-PT' . $props['ALARM'];
185 $ics_props[] = 'ACTION:DISPLAY';
186 $ics_props[] = 'END:VALARM';
187 }
188 }
189
190 // Build ICS properties - add footer
191 $ics_props[] = 'END:VEVENT';
192 $ics_props[] = 'END:VCALENDAR';
193
194 return $ics_props;
195 }
196
197 private function prepareValue($val, $key = false)
198 {
199 switch($key)
200 {
201// case 'dtstamp':
202// case 'dtstart':
203// case 'dtend':
204// $val = $this->formatDateValue($val);
205// break;
206 default:
207 $val = $this->escapeString($val);
208 }
209 return $val;
210 }
211
212 private static function formatDateValue($timestamp)
213 {
214 $dt = new \DateTime();
215 $dt->setTimestamp($timestamp);
216 return $dt->format(self::DATE_FORMAT);
217 }
218
219 private static function formatDateTimeValue($timestamp)
220 {
221 $dt = new \DateTime();
222 if ($timestamp)
223 {
224 $dt->setTimestamp($timestamp);
225 }
226 return $dt->format(self::DATETIME_FORMAT);
227 }
228
229 private static function formatEmailValue($email)
230 {
231 return 'mailto:'.$email;
232 }
233
234 private static function formatPhoneValue($phone): string
235 {
236 return 'tel:'.$phone;
237 }
238
239
240 private static function formatAttendeeKey($attendee)
241 {
242 $key = 'ATTENDEE';
243 $key .= ';CUTYPE=INDIVIDUAL';
244 //$key .= ';PARTSTAT=ACCEPTED'; // NEEDS-ACTION
245 $key .= ';RSVP=TRUE';
246 $key .= ';CN='.$attendee['email'];
247 return $key;
248 }
249
250 private static function formatOrganizerKey($organizer)
251 {
252 $key = 'ORGANIZER';
253 if ($organizer['name'])
254 {
255 $key .= ';CN='.$organizer['name'];
256 }
257 return $key;
258 }
259
260 private static function escapeString($str)
261 {
262 return preg_replace('/([\,;])/','\\\$1', $str);
263 }
264}
__construct($properties=[], $config=[])
setOrganizer($name, $email, $phone)
setAttendees($attendeeDataList=[])