1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
calendar_webservice.php
См. документацию.
1<?
2if (!\Bitrix\Main\Loader::includeModule('webservice'))
3{
4 return;
5}
6
8{
10 'free' => 0, 'quest' => 1, 'busy' => 2, 'absent' => 3,
11 );
12
14 'low' => -1, 'normal' => 0, 'high' => 1,
15 );
16
18 {
19 $obFields = new CXMLCreator('Fields');
20
21 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="ID" ColName="tp_ID" RowOrdinal="0" ReadOnly="TRUE" Type="Counter" Name="ID" PrimaryKey="TRUE" DisplayName="ID" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="ID" FromBaseType="TRUE"'));
22 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="OWSHIDDENVERSION" ColName="tp_Version" RowOrdinal="0" Hidden="TRUE" ReadOnly="TRUE" Type="Integer" SetAs="owshiddenversion" Name="owshiddenversion" DisplayName="owshiddenversion" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="owshiddenversion" FromBaseType="TRUE"'));
23 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="FSOBJTYPE" Name="FSObjType" DisplaceOnUpgrade="TRUE" ReadOnly="TRUE" Hidden="TRUE" ShowInFileDlg="FALSE" Type="Lookup" DisplayName="Item Type" List="Docs" FieldRef="ID" ShowField="FSType" JoinColName="DoclibRowId" JoinRowOrdinal="0" JoinType="INNER" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="FSObjType" FromBaseType="TRUE"'));
24 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="UNIQUEID" Name="UniqueId" DisplaceOnUpgrade="TRUE" ReadOnly="TRUE" Hidden="TRUE" ShowInFileDlg="FALSE" Type="Lookup" DisplayName="Unique Id" List="Docs" FieldRef="ID" ShowField="UniqueId" JoinColName="DoclibRowId" JoinRowOrdinal="0" JoinType="INNER" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="UniqueId" FromBaseType="TRUE"'));
25 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="CONTENTTYPEID" ColName="tp_ContentTypeId" Sealed="TRUE" Hidden="TRUE" RowOrdinal="0" ReadOnly="TRUE" Type="ContentTypeId" Name="ContentTypeId" DisplaceOnUpgrade="TRUE" DisplayName="Content Type ID" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="ContentTypeId" FromBaseType="TRUE"'));
26 //$obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="CONTENTTYPE" ColName="tp_ContentType" RowOrdinal="0" ReadOnly="TRUE" Type="Text" Name="ContentType" DisplaceOnUpgrade="TRUE" DisplayName="Content Type" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="ContentType" FromBaseType="TRUE" PITarget="MicrosoftWindowsSharePointServices" PIAttribute="ContentTypeID"'));
27 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="METAINFO" Name="MetaInfo" DisplaceOnUpgrade="TRUE" Hidden="TRUE" ShowInFileDlg="FALSE" Type="Lookup" DisplayName="Property Bag" List="Docs" FieldRef="ID" ShowField="MetaInfo" JoinColName="DoclibRowId" JoinType="INNER" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="MetaInfo" FromBaseType="TRUE"'));
28
29 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="PERMMASK" Name="PermMask" DisplaceOnUpgrade="TRUE" ReadOnly="TRUE" Hidden="TRUE" RenderXMLUsingPattern="TRUE" ShowInFileDlg="FALSE" Type="Computed" DisplayName="Effective Permissions Mask" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="PermMask" FromBaseType="TRUE"'));
30
31 $obField->addChild($obFieldRefs = new CXMLCreator('FieldRefs'));
32 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="ID"'));
33
34 $obField->addChild($obDisplayPattern = new CXMLCreator('DisplayPattern'));
35 $obDisplayPattern->addChild(new CXMLCreator('CurrentRights'));
36
37 //
38 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Type="Text" Name="Title" DisplayName="Title" Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Title" FromBaseType="TRUE" ColName="nvarchar1"'));
39
40 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="LOCATION" Type="Text" Name="Location" DisplayName="Location" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Location" ColName="nvarchar3"'));
41
42 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field Type="Note" ID="DESCRIPTION" Name="Description" RichText="TRUE" DisplayName="Description" Sortable="FALSE" Sealed="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Description" ColName="ntext2"'));
43 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="MODIFIED" ColName="tp_Modified" RowOrdinal="0" ReadOnly="TRUE" Type="DateTime" Name="Modified" DisplayName="Modified" StorageTZ="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Modified" FromBaseType="TRUE"'));
44 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="AUTHOR" ColName="tp_Author" RowOrdinal="0" ReadOnly="TRUE" Type="User" List="UserInfo" Name="Author" DisplayName="Created By" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Author" FromBaseType="TRUE"'));
45
46 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="EDITOR" ColName="tp_Editor" RowOrdinal="0" ReadOnly="TRUE" Type="User" List="UserInfo" Name="Editor" DisplayName="Modified By" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Editor" FromBaseType="TRUE" '));
47
48 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field Type="DateTime" ID="DATE_FROM" Name="EventDate" DisplayName="Start Time" Format="DateTime" Sealed="TRUE" Required="TRUE" FromBaseType="TRUE" Filterable="FALSE" FilterableNoRecurrence="FALSE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="EventDate" ColName="datetime1"'));
49 $obField->addChild(CXMLCreator::createTagAttributed('Default', '[today]'));
50 $obField->addChild($obFieldRefs = new CXMLCreator('FieldRefs'));
51 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="fAllDayEvent" RefType="AllDayEvent"'));
52 $obField->addChild(CXMLCreator::createTagAttributed('DefaultFormulaValue', $this->__makeDateTime(strtotime(date('Y-m-d')))));
53
54 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="DATE_TO" Type="DateTime" Name="EndDate" DisplayName="End Time" Format="DateTime" Sealed="TRUE" Required="TRUE" Filterable="FALSE" FilterableNoRecurrence="FALSE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="EndDate" ColName="datetime2"'));
55 $obField->addChild(CXMLCreator::createTagAttributed('Default', '[today]'));
56 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="DURATION" Type="Integer" Name="Duration" DisplayName="Duration" Hidden="TRUE" Sealed="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Duration" ColName="int2"'));
57
58 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="ALLDAYEVENT" Type="AllDayEvent" Name="fAllDayEvent" DisplaceOnUpgrade="TRUE" DisplayName="All Day Event" Sealed="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="fAllDayEvent" ColName="bit1"'));
59
60 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="EVENTTYPE" Type="Integer" Name="EventType" DisplayName="Event Type" Sealed="TRUE" Hidden="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="EventType" ColName="int1"'));
61
62 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="UID" Type="Guid" Name="UID" DisplayName="UID" Sealed="TRUE" Hidden="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="UID" ColName="uniqueidentifier1"'));
63
64 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="RECURENCE_DATA" Type="Note" Name="RecurrenceData" DisplayName="RecurrenceData" Hidden="TRUE" Sealed="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="RecurrenceData" ColName="ntext3"'));
65
66 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="TIMEZONE" Type="Integer" Name="TimeZone" DisplayName="TimeZone" Sealed="TRUE" Hidden="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="TimeZone" ColName="int3"'));
67
68 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="XMLTZONE" Type="Note" Name="XMLTZone" DisplayName="XMLTZone" Hidden="TRUE" Sealed="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="XMLTZone" ColName="ntext4"'));
69
70 $obFields->addChild($obField = CXMLCreator::createTagAttributed('Field ID="RECURRENCE" Type="Recurrence" Name="fRecurrence" DisplayName="Recurrence" Title="Recurrence" Sealed="TRUE" NoEditFormBreak="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="fRecurrence" ColName="bit2"'));
71 $obField->addChild(CXMLCreator::createTagAttributed('Default', 'FALSE'));
72 $obField->addChild($obFieldRefs = new CXMLCreator('FieldRefs'));
73 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="RecurrenceData" RefType="RecurData"'));
74 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="EventType" RefType="EventType"'));
75 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="UID" RefType="UID"'));
76 //$obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="RecurrenceID" RefType="RecurrenceId"'));
77 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="EventDate" RefType="StartDate"'));
78 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="EndDate" RefType="EndDate"'));
79 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="Duration" RefType="Duration"'));
80 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="TimeZone" RefType="TimeZone"'));
81 $obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="XMLTZone" RefType="XMLTZone"'));
82 //$obFieldRefs->addChild(CXMLCreator::createTagAttributed('FieldRef Name="MasterSeriesItemID" RefType="MasterSeriesItemID"'));
83
84 return $obFields;
85 }
86
87 function __makeDateTime($ts = null)
88 {
89 if (null === $ts)
90 {
91 $ts = time();
92 }
93
94 return date('Y-m-d', $ts).'T'.date('H:i:s', $ts).'Z';
95 }
96
97 function __makeTS($datetime = null)
98 {
99 if (null === $datetime)
100 {
101 return time();
102 }
103
104 if ((int)mb_substr($datetime, 0, 4) >= 2037)
105 {
106 $datetime = '2037' . mb_substr($datetime, 4);
107 }
108
109 return MakeTimeStamp(mb_substr($datetime, 0, 10).' '.mb_substr($datetime, 11, -1), 'YYYY-MM-DD HH:MI:SS');
110 }
111
112 function GetList($listName)
113 {
114 if (!$listName_original = CIntranetUtils::checkGUID($listName))
115 {
116 return new CSoapFault(
117 'Data error',
118 'Wrong GUID - '.$listName
119 );
120 }
121
122 $listName = mb_strtoupper(CIntranetUtils::makeGUID($listName_original));
123 $arSections = CCalendarSect::GetList(
124 array(
125 'arFilter' => array('XML_ID' => mb_strtolower($listName_original))
126 )
127 );
128
129 if (!$arSections || !is_array($arSections[0]))
130 {
131 return new CSoapFault(
132 'List not found', 'List with ' . $listName . ' GUID not found'
133 );
134 }
135 $arSection = $arSections[0];
136
137 $data = new CXMLCreator('List');
138 $data->setAttribute('ID', $listName);
139 $data->setAttribute('Name', $listName);
140 $data->setAttribute('Title', $arSection['NAME']);
141
142 $data->setAttribute('Direction', 'none'); // RTL, LTR
143 $data->setAttribute('ReadSecurity', '2');
144 $data->setAttribute('WriteSecurity', '2');
145
146 $data->setAttribute('Author', $arSection['CREATED_BY'].';#'.CCalendar::GetUserName($arSection['CREATED_BY']));
147
148 $data->addChild($this->__getFieldsDefinition());
149
150 $data->addChild($obNode = new CXMLCreator('RegionalSettings'));
151
152 $obNode->addChild(CXMLCreator::createTagAttributed('Language', '1049'));
153 $obNode->addChild(CXMLCreator::createTagAttributed('Locale', '1049'));
154 $obNode->addChild(CXMLCreator::createTagAttributed('SortOrder', '1026'));
155 // TODO: replace following code with commented line below
156 $obNode->addChild(CXMLCreator::createTagAttributed('TimeZone', -(intval(date('Z')) + \CTimeZone::GetOffset(null, true))/60));
157 //$obNode->addChild(CXMLCreator::createTagAttributed('TimeZone', \CIntranetUtils::getOutlookTimeZone()));
158
159 $obNode->addChild(CXMLCreator::createTagAttributed('AdvanceHijri', '0'));
160 $obNode->addChild(CXMLCreator::createTagAttributed('CalendarType', '1'));
161 $obNode->addChild(CXMLCreator::createTagAttributed('Time24', 'True'));
162 $obNode->addChild(CXMLCreator::createTagAttributed('Presence', 'True'));
163
164 $data->addChild($obNode = new CXMLCreator('ServerSettings'));
165
166 $obNode->addChild(CXMLCreator::createTagAttributed('ServerVersion', '12.0.0.6219'));
167 $obNode->addChild(CXMLCreator::createTagAttributed('RecycleBinEnabled', 'False'));
168 $obNode->addChild(CXMLCreator::createTagAttributed('ServerRelativeUrl', '/timeman/'));
169
170 return array('GetListResult' => $data);
171 }
172
173 function __getRow($event, $listName, &$last_change)
174 {
177
178 $first_week_day = COption::GetOptionString('calendar', 'week_start', 'MO');
179 $first_week_day = mb_strtolower($first_week_day);
180
181 $change = MakeTimeStamp($event['TIMESTAMP_X']);
182 if ($last_change < $change)
183 {
184 $last_change = $change;
185 }
186
187 $bRecurrent = (isset($event['RRULE']) && $event['RRULE'] != "") ? 1 : 0;
188 $rrule = CCalendarEvent::ParseRRULE($event['RRULE']);
189
190 $bAllDay = $event['DT_SKIP_TIME'] !== 'N' ? 1 : 0;
191 $ts_start = CCalendar::Timestamp($event['DATE_FROM'], false, !$bAllDay);
192 $ts_finish = CCalendar::Timestamp($event['DATE_TO'], false, !$bAllDay);
193 if (!$bAllDay)
194 {
195 $ts_start -= $event['~USER_OFFSET_FROM'];
196 $ts_finish -= $event['~USER_OFFSET_FROM'];
197 }
198
199 $TZBias = (int)date('Z');
200 $duration = $event['DT_LENGTH'];
201 if ($bAllDay)
202 {
203 $duration -= 20;
204 }
205
206 if (!$bAllDay || defined('OLD_OUTLOOK_VERSION'))
207 {
208 $ts_start = $event['DATE_FROM_TS_UTC']; // We need time in UTC
209 $ts_finish = $event['DATE_TO_TS_UTC'];
210 }
211
212 $obRow = new CXMLCreator('z:row');
213 $obRow->setAttribute('ows_ID', $event['ID']);
214 $obRow->setAttribute('ows_Title', htmlspecialcharsback($event['NAME'])); // we have data htmlspecialchared yet
215 $version = $event['VERSION'] ?: 1;
216 $obRow->setAttribute('ows_Attachments', 0);
217 $obRow->setAttribute('ows_owshiddenversion', $version);
218 $obRow->setAttribute('ows_MetaInfo_vti_versionhistory', md5($event['ID']).':'.$version);
219
220 /*
221 ows_MetaInfo_BusyStatus='2' - Editor
222 ows_MetaInfo_IntendedBusyStatus='-1' - Creator
223
224 values:
225 -1 - Unspecified busy status. Protocol clients can choose to display one of the other values if BusyStatus is -1.
226 0 - Free - ACCESSIBILITY => 'free'
227 1 - Tentative - ACCESSIBILITY => 'quest'
228 2 - Busy - ACCESSIBILITY => 'busy'
229 3 - Out of Office - ACCESSIBILITY => 'absent'
230 */
231
232 $status = $arStatusValues[$event['ACCESSIBILITY']];
233 $obRow->setAttribute('ows_MetaInfo_BusyStatus', $status ?? -1);
234 $obRow->setAttribute('ows_MetaInfo_Priority', (int)$arPriorityValues[$event['IMPORTANCE']]);
235 $obRow->setAttribute('ows_Created', $this->__makeDateTime(MakeTimeStamp($event['DATE_CREATE']) - $TZBias));
236 $obRow->setAttribute('ows_Modified', $this->__makeDateTime($change - $TZBias));
237 $obRow->setAttribute('ows_EventType', $bRecurrent ? 1 : 0);
238 $obRow->setAttribute('ows_Location', CCalendar::GetTextLocation($event['LOCATION']));
239 $obRow->setAttribute('ows_Description', $event['~DESCRIPTION']); // Description parsed from BB-codes to HTML
240 $obRow->setAttribute('ows_EventDate', $this->__makeDateTime($ts_start));
241 $obRow->setAttribute('ows_EndDate', $this->__makeDateTime($ts_start + $event['DT_LENGTH']));
242
243 $obRow->setAttribute('ows_fAllDayEvent', $bAllDay);
244
245 /* Recurrence */
246 $obRow->setAttribute('ows_fRecurrence', $bRecurrent);
247 if ($bRecurrent)
248 {
249 $isDaylightSavingTime = self::isDaylightSavingTime($event['TZ_FROM'] ?? null);
250
251 $obRow->setAttribute('ows_UID', CIntranetUtils::makeGUID(md5($event['ID'].'_'.$change)));
252 $tz_data = '<timeZoneRule>';
253 $tz_data .= '<standardBias>'.(-(int)(($TZBias - (date('I') ? 3600 : 0)) / 60)).'</standardBias>';
254
255 if ($isDaylightSavingTime)
256 {
257 $tz_data .= '<additionalDaylightBias>-60</additionalDaylightBias>';
258 }
259
260 $bUseTransition = COption::GetOptionString('intranet', 'tz_transition', 'Y') === 'Y';
261
262 if ($bUseTransition && !$isDaylightSavingTime)
263 {
264 $transition_standard = COption::GetOptionString('intranet', 'tz_transition_standard', '');
265 if (!$transition_standard)
266 {
267 $transition_standard = '<transitionRule month="10" day="su" weekdayOfMonth="last" /><transitionTime>3:0:0</transitionTime>';
268 }
269 $tz_data .= '<standardDate>'.$transition_standard.'</standardDate>';
270
271 $transition_daylight = COption::GetOptionString('intranet', 'tz_transition_daylight', '');
272 if (!$transition_daylight)
273 {
274 $transition_daylight = '<transitionRule month="3" day="su" weekdayOfMonth="last" /><transitionTime>2:0:0</transitionTime>';
275 }
276 $tz_data .= '<daylightDate>'.$transition_daylight.'</daylightDate>';
277 }
278
279 $tz_data .= '</timeZoneRule>';
280 $obRow->setAttribute('ows_XMLTZone', $tz_data);
281
282 $recurence_data = '<recurrence>';
283 $recurence_data .= '<rule>';
284 $recurence_data .= '<firstDayOfWeek>'.$first_week_day.'</firstDayOfWeek>';
285
286 $recurence_data .= '<repeat>';
287 switch($rrule['FREQ'])
288 {
289 case 'DAILY':
290 $recurence_data .= '<daily dayFrequency="'.$rrule['INTERVAL'].'" />';
291 break;
292
293 case 'WEEKLY':
294 $days = '';
295 foreach ($rrule['BYDAY'] as $day)
296 {
297 $days .= mb_strtolower($day) . '="TRUE" ';
298 }
299 $recurence_data .= '<weekly '.$days.'weekFrequency="'.$rrule['INTERVAL'].'" />';
300 break;
301
302 case 'MONTHLY':
303 $recurence_data .= '<monthly monthFrequency="'.$rrule['INTERVAL'].'" day="'.date('d', $ts_start).'" />';
304 break;
305
306 case 'YEARLY':
307 $recurence_data .= '<yearly yearFrequency="'.$rrule['INTERVAL'].'" month="'.date('m', $ts_start).'" day="'.date('d', $ts_start).'" />';
308 break;
309 }
310 $recurence_data .= '</repeat>';
311
312 if ($rrule['COUNT'])
313 {
314 $recurence_data .= '<repeatInstances>'.intval($rrule['COUNT']).'</repeatInstances>';
315 }
316 elseif($rrule['~UNTIL'])
317 {
318 $recurence_data .= '<windowEnd>'.$this->__makeDateTime(CCalendar::Timestamp($rrule['UNTIL'])).'</windowEnd>';
319 }
320 else
321 {
322 $recurence_data .= '<repeatForever>FALSE</repeatForever>';
323 }
324 $recurence_data .= '</rule>';
325 $recurence_data .= '</recurrence>';
326
327 $obRow->setAttribute('ows_RecurrenceData', $recurence_data);
328 }
329 $obRow->setAttribute('ows_Duration', $duration);
330
331 $obRow->setAttribute('ows_UniqueId', $event['ID'].';#'.$listName);
332 $obRow->setAttribute('ows_FSObjType', $event['ID'].';#0');
333 $obRow->setAttribute('ows_Editor', $event['CREATED_BY'].';#'.CCalendar::GetUserName($event['CREATED_BY']));
334 $obRow->setAttribute('ows_PermMask', '0x7fffffffffffffff');
335 $obRow->setAttribute('ows_ContentTypeId', '0x01020005CE290982A58C439E00342702139D1A');
336
337
338
339 return $obRow;
340 }
341
342 function GetListItemChanges($listName, $viewFields = '', $since = '', $contains = '')
343 {
344 define ('OLD_OUTLOOK_VERSION', true);
345
346 $res = $this->GetListItemChangesSinceToken($listName, $viewFields, '', 0, $since ? $this->__makeTS($since) : '');
347
348 if (is_object($res))
349 {
350 return $res;
351 }
352
353 return array('GetListItemChangesResult' => $res['GetListItemChangesSinceTokenResult']);
354 }
355
356 function GetListItemChangesSinceToken($listName, $viewFields = '', $query = '', $rowLimit = 0, $changeToken = '')
357 {
358 global $USER;
359
360 if (!$listName_original = CIntranetUtils::checkGUID($listName))
361 {
362 return new CSoapFault('Data error', 'Wrong GUID - '.$listName);
363 }
364
365 $listName = mb_strtoupper(CIntranetUtils::makeGUID($listName_original));
366
367 $arSections = CCalendarSect::GetList(array('arFilter' => array('XML_ID' => $listName_original)));
368 if (!$arSections || !is_array($arSections[0]))
369 {
370 return new CSoapFault('List not found', 'List with ' . $listName . ' GUID not found!');
371 }
372
373 $arSection = $arSections[0];
374
375 $userId = (is_object($USER) && $USER->GetID()) ? $USER->GetID() : 1;
376
377 $fetchMeetings = $arSection['CAL_TYPE'] === 'user' && CCalendar::GetMeetingSection($arSection['OWNER_ID']) == $arSection['ID'];
378 $arEvents = CCalendarEvent::GetList(
379 array(
380 'arFilter' => array(
381 'CAL_TYPE' => $arSection['CAL_TYPE'],
382 'OWNER_ID' => $arSection['OWNER_ID'],
383 'SECTION' => $arSection['ID'],
384 'DELETED' => '' // We fetch all deleted and current events
385 ),
386 'getUserfields' => false,
387 'parseRecursion' => false,
388 'fetchAttendees' => false,
389 'fetchMeetings' => $fetchMeetings,
390 'userId' => $userId
391 )
392 );
393
394 $last_change = 0;
395 $data = new CXMLCreator('listitems');
396 $data->setAttribute('MinTimeBetweenSyncs', 0);
397 $data->setAttribute('RecommendedTimeBetweenSyncs', 180);
398 $data->setAttribute('TimeStamp', $this->__makeDateTime());
399 $data->setAttribute('EffectivePermMask', 'FullMask');
400
401 $data->addChild($obChanges = new CXMLCreator('Changes'));
402
403 if (!$changeToken && !defined('OLD_OUTLOOK_VERSION'))
404 {
405 $obChanges->addChild($this->__getFieldsDefinition());
406 }
407
408 $data->addChild($obData = new CXMLCreator('rs:data'));
409
410 $count = 0;
411 foreach ($arEvents as $event)
412 {
413 if ($event['DELETED'] !== 'N' || ($event['IS_MEETING'] && $event['MEETING_STATUS'] === 'N'))
414 {
415 $obId = new CXMLCreator('Id');
416 $obId->setAttribute('ChangeType', 'Delete');
417 $obId->setData($event['ID']);
418 $obChanges->addChild($obId);
419 }
420 elseif (!$changeToken || $changeToken < CCalendar::Timestamp($event['TIMESTAMP_X'], false))
421 {
422 $obData->addChild($this->__getRow($event, $listName, $last_change));
423 $count++;
424 }
425 }
426
427 $last_change = time();
428 $obData->setAttribute('ItemCount', $count);
429
430 $data->setAttribute('xmlns:rs', 'urn:schemas-microsoft-com:rowset');
431 $data->setAttribute('xmlns:z', '#RowsetSchema');
432
433 if ($last_change > 0)
434 {
435 $obChanges->setAttribute('LastChangeToken', $last_change);
436 }
437
438 CCalendar::SaveMultipleSyncDate($userId, 'outlook', $arSection['ID']);
439
440 return array('GetListItemChangesSinceTokenResult' => $data);
441 }
442
443 function UpdateListItems($listName, $updates)
444 {
445 global $USER;
446
447 $arStatusValues = array_flip($this->arStatusValues);
448 $arPriorityValues = array_flip($this->arPriorityValues);
449
450 if (!$listName_original = CIntranetUtils::checkGUID($listName))
451 {
452 return new CSoapFault('Data error', 'Wrong GUID - ' . $listName);
453 }
454
455 $obResponse = new CXMLCreator('Results');
456
457 $listName = mb_strtoupper(CIntranetUtils::makeGUID($listName_original));
458 $arSections = CCalendarSect::GetList(array('arFilter' => array('XML_ID' => $listName_original)));
459 if (!$arSections || !is_array($arSections[0]))
460 {
461 return new CSoapFault(
462 'List not found',
463 'List with ' . $listName . ' GUID not found'
464 );
465 }
466
467 $arSection = $arSections[0];
468
469 $bGroup = $arSection['CAL_TYPE'] === 'group';
470 $calType = $arSection['CAL_TYPE'];
471 $ownerId = $arSection['OWNER_ID'];
472
473 if ($bGroup)
474 {
475 if (\Bitrix\Main\Loader::includeModule('socialnetwork'))
476 {
477 $arGroupTmp = CSocNetGroup::GetByID($arSection['SOCNET_GROUP_ID']);
478
479 if (
480 ($arGroupTmp["CLOSED"] === "Y")
481 && COption::GetOptionString("socialnetwork", "work_with_closed_groups", "N") !== "Y"
482 )
483 {
484 return new CSoapFault(
485 'Cannot modify archive group calendar',
486 'Cannot modify archive group calendar'
487 );
488 }
489 }
490 }
491
492 $obBatch = $updates->children[0];
493// $atrONERROR = $obBatch->getAttribute('OnError');
494// $atrDATEINUTC = $obBatch->getAttribute('DateInUtc');
495// $atrPROPERTIES = $obBatch->getAttribute('Properties');
496
497 $arChanges = $obBatch->children;
498
499 //$arResultIDs = array();
500 //$dateStart = ConvertTimeStamp(strtotime('-1 hour'), 'FULL');
501 $responseRows = array();
502 $replicationId = array();
503
504 foreach ($arChanges as $obMethod)
505 {
506 $arData = array('_command' => $obMethod->getAttribute('Cmd'));
507
508 foreach ($obMethod->children as $obField)
509 {
510 $name = $obField->getAttribute('Name');
511 if ($name === 'MetaInfo')
512 {
513 $name .= '_' . $obField->getAttribute('Property');
514 }
515
516 $arData[$name] = $obField->content;
517 }
518
519 if ($arData['_command'] === 'Delete')
520 {
521 $obRes = new CXMLCreator('Result');
522 $obRes->setAttribute('ID', $obMethod->getAttribute('ID').','.$arData['_command']);
523 $obRes->setAttribute('List', $listName);
524 $obRes->addChild($obNode = new CXMLCreator('ErrorCode'));
525
526 $res = CCalendar::DeleteEvent($arData['ID']);
527 if ($res === true)
528 {
529 $obNode->setData('0x00000000');
530 }
531 else
532 {
533 $obNode->setData('0x81020014');
534 }
535
536 /*
537 0x00000000 - ok
538 0x81020015 - data conflict
539 0x81020014 - generic error such as invalid value for Field
540 0x81020016 - item does not exist
541 */
542 $obResponse->addChild($obRes);
543 }
544 elseif ($arData['_command'] === 'New' || $arData['_command'] === 'Update')
545 {
546 $arData['Location'] = trim($arData['Location']);
547 $arData['EventType'] = (int)$arData['EventType'];
548
549 if ((int)$arData['EventType'] === 2)
550 {
551 $arData['EventType'] = 0;
552 }
553
554 if ($arData['EventType'] > 2 /* || ($arData['EventType'] == 1 && !$arData['RecurrenceData'])*/)
555 {
556 return new CSoapFault(
557 'Unsupported event type',
558 'Event type unsupported'
559 );
560 }
561
562 $id = $arData['_command'] === 'New' ? 0 : (int)$arData['ID'];
563
564 $arData['fRecurrence'] = (int)$arData['fRecurrence'];
565 $arData['RRULE'] = '';
566
567 if (isset($arData['EventDate']))
568 {
569 $fromTsUTC = $this->__makeTS($arData['EventDate']);
570 if ($arData['RecurrenceData'] && $arData['fAllDayEvent'])
571 {
572 $toTsUTC = $fromTsUTC;
573 }
574 elseif (!$arData['RecurrenceData'] && $arData['fAllDayEvent'])
575 {
576 $toTsUTC = $this->__makeTS($arData['EndDate']) - 86340;
577 }
578 else
579 {
580 $toTsUTC = $this->__makeTS($arData['EndDate']);
581 }
582
583 $skipTime = $arData['fAllDayEvent'] ? 'Y' : 'N';
584 $fromTs = $fromTsUTC;
585 $toTs = $toTsUTC;
586 }
587 else
588 {
589 $fromTs = $toTs = $fromTsUTC = $toTsUTC = false;
590 $skipTime = false;
591 }
592
593 if ($arData['RecurrenceData'] && isset($arData['EventDate']))
594 {
595 $xmlstr = $arData['RecurrenceData'];
596 $obRecurData = new CDataXML();
597 $obRecurData->LoadString($xmlstr);
598
599 $obRecurRule = $obRecurData->tree->children[0]->children[0];
600 $obRecurRepeat = $obRecurRule->children[1];
601 $obNode = $obRecurRepeat->children[0];
602
603 $arData['RRULE'] = [];
604 switch($obNode->name)
605 {
606 case 'daily':
607 // hack. we have no "work days" daily recurrence
608 if ($obNode->getAttribute('weekday') === 'TRUE')
609 {
610 $arData['RRULE']['FREQ'] = 'WEEKLY';
611 $arData['RRULE']['BYDAY'] = 'MO,TU,WE,TH,FR';
612 $arData['RRULE']['INTERVAL'] = 1;
613 }
614 else
615 {
616 $arData['RRULE']['FREQ'] = 'DAILY';
617 $arData['RRULE']['INTERVAL'] = $obNode->getAttribute('dayFrequency');
618 }
619
620 $time_end = strtotime(
621 date(date('Y-m-d', $fromTsUTC).' H:i:s', $toTsUTC)
622 );
623
624 $arData['DT_LENGTH'] = $time_end - $fromTsUTC;
625 break;
626
627 case 'weekly':
628 $arData['RRULE']['FREQ'] = 'WEEKLY';
629 $arData['RRULE']['BYDAY'] = [];
630
631 $arWeekDays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'];
632 foreach ($arWeekDays as $day => $value)
633 {
634 if ($obNode->getAttribute($value))
635 {
636 $arData['RRULE']['BYDAY'][] = mb_strtoupper($value);
637 }
638 }
639
640 $arData['RRULE']['BYDAY'] = implode(',', $arData['RRULE']['BYDAY']);
641 $arData['RRULE']['INTERVAL'] = $obNode->getAttribute('weekFrequency');
642
643 $time_end = strtotime(date(date('Y-m-d', $fromTsUTC).' H:i:s', $toTsUTC));
644
645 $arData['DT_LENGTH'] = $time_end - $fromTsUTC;
646 break;
647
648 case 'monthly':
649 $arData['RRULE']['FREQ'] = 'MONTHLY';
650 $arData['RRULE']['INTERVAL'] = $obNode->getAttribute('monthFrequency');
651 $time_end = strtotime(date(date('Y-m', $fromTsUTC).'-d H:i:s', $toTsUTC));
652
653 $arData['DT_LENGTH'] = $time_end - $fromTsUTC;
654 break;
655
656 case 'yearly':
657 $arData['RRULE']['FREQ'] = 'YEARLY';
658 $arData['RRULE']['INTERVAL'] = $obNode->getAttribute('yearFrequency');
659
660 $time_end = strtotime(date(date('Y', $fromTsUTC).'-m-d H:i:s', $toTsUTC));
661
662 $arData['DT_LENGTH'] = $time_end - $fromTsUTC;
663 break;
664 }
665
666 if ((int)$arData['DT_LENGTH'] === 0 && isset($arData['RRULE']['FREQ']))
667 {
668 $arData['DT_LENGTH'] = 86400;
669 }
670
671 $obWhile = $obRecurRule->children[2];
672 if ($obWhile->name === 'repeatForever')
673 {
674 $arData['RRULE']['UNTIL'] = MakeTimeStamp('');
675 }
676 elseif ($obWhile->name === 'windowEnd')
677 {
678 $toTsUTC = $this->__makeTS($obWhile->textContent());
679 $arData['RRULE']['UNTIL'] = ConvertTimeStamp($toTsUTC, 'FULL');
680 }
681 elseif ($obWhile->name === 'repeatInstances')
682 {
683 $arData['RRULE']['COUNT'] = (int)$obWhile->textContent();
684 }
685 }
686 elseif(($arData['fRecurrence'] === -1) && ($id > 0))
687 {
688 $arData['RRULE'] = -1;
689 }
690
691 $arFields = [
692 'ID' => $id,
693 'CAL_TYPE' => $calType,
694 'OWNER_ID' => $ownerId,
695 'CREATED_BY' => $ownerId,
696 'NAME' => $arData['Title'],
697 'DESCRIPTION' => self::ClearOutlookHtml($arData['Description']),
698 'SECTIONS' => [$arSection['ID']],
699 'ACCESSIBILITY' => $arStatusValues[$arData['MetaInfo_BusyStatus']],
700 'IMPORTANCE' => $arPriorityValues[$arData['MetaInfo_Priority']],
701 'RRULE' => $arData['RRULE'],
702 'LOCATION' => Bitrix\Calendar\Rooms\Util::unParseTextLocation($arData['Location'])
703 ];
704
705 if ($fromTs && $toTs)
706 {
707 $arFields['DATE_FROM'] = CCalendar::Date($fromTs, $skipTime === 'N');
708 $arFields['DATE_TO'] = CCalendar::Date($toTs, $skipTime === 'N');
709 $arFields['TZ_FROM'] = 'UTC';
710 $arFields['TZ_TO'] = 'UTC';
711 $arFields['DT_SKIP_TIME'] = $skipTime;
712 }
713
714 if (isset($arData['DT_LENGTH']) && $arData['DT_LENGTH'] > 0)
715 {
716 $arFields['DT_LENGTH'] = $arData['DT_LENGTH'];
717 }
718
719 $eventId = CCalendar::SaveEvent([
720 'arFields' => $arFields,
721 'fromWebservice' => true
722 ]);
723
724 if ($eventId && ((int)$eventId) > 0)
725 {
726 $eventId = (int)$eventId;
727 $replicationId[$eventId] = $arData['MetaInfo_ReplicationID'];
728
729 $responseRows[$eventId] = new CXMLCreator('Result');
730 $responseRows[$eventId]->setAttribute('ID', $obMethod->getAttribute('ID').','.$arData['_command']);
731 $responseRows[$eventId]->setAttribute('List', $listName);
732
733 $responseRows[$eventId]->addChild($obNode = new CXMLCreator('ErrorCode'));
734 $obNode->setData('0x00000000');
735 //$responseRows[$eventId]->setAttribute('Version', 3);
736 }
737 }
738 }
739
740 $userId = (is_object($USER) && $USER->GetID()) ? $USER->GetID() : 1;
741 $fetchMeetings = (int)CCalendar::GetMeetingSection($userId) === (int)$arSection['ID'];
742 $arEvents = CCalendarEvent::GetList([
743 'arFilter' => [
744 'CAL_TYPE' => $calType,
745 'OWNER_ID' => $ownerId,
746 'SECTION' => $arSection['ID']
747 ],
748 'getUserfields' => false,
749 'parseRecursion' => false,
750 'fetchAttendees' => false,
751 'fetchMeetings' => $fetchMeetings,
752 'userId' => $userId
753 ]);
754
755 foreach ($arEvents as $event)
756 {
757 if ($responseRows[$event['ID']])
758 {
759 $last_change = 0;
760 $obRow = $this->__getRow($event, $listName, $last_change);
761 $obRow->setAttribute('xmlns:z', "#RowsetSchema");
762
763 if ($replicationId[$event['ID']])
764 {
765 $obRow->setAttribute('MetaInfo_ReplicationID', $replicationId[$event['ID']]);
766 }
767
768 $responseRows[$event['ID']]->addChild($obRow);
769 }
770
771 $obResponse->addChild($responseRows[$event['ID']]);
772 }
773
774 return ['UpdateListItemsResult' => $obResponse];
775 }
776
777 public static function GetWebServiceDesc()
778 {
779 $wsdesc = new CWebServiceDesc();
780 $wsdesc->wsname = "bitrix.webservice.calendar";
781 $wsdesc->wsclassname = "CCalendarWebService";
782 $wsdesc->wsdlauto = true;
783 $wsdesc->wsendpoint = CWebService::GetDefaultEndpoint();
784 $wsdesc->wstargetns = CWebService::GetDefaultTargetNS();
785 $wsdesc->classTypes = array();
786 $wsdesc->structTypes = array();
787
788 $wsdesc->classes = array(
789 "CCalendarWebService" => array(
790 "GetList" => array(
791 "type" => "public",
792 "name" => "GetList",
793 "input" => array(
794 "listName" => array("varType" => "string"),
795 ),
796 "output" => array(
797 "GetListResult" => array("varType" => 'any'),
798 ),
799 'httpauth' => 'Y'
800 ),
801 'GetListItemChanges' => array(
802 'type' => 'public',
803 'name' => 'GetListItemChanges',
804 'input' => array(
805 "listName" => array("varType" => "string"),
806 "viewFields" => array("varType" => "any", 'strict'=> 'no'),
807 'since' => array('varType' => 'string', 'strict' => 'no'),
808 ),
809 'output' => array(
810 'GetListItemChangesResult' => array('varType' => 'any'),
811 ),
812 'httpauth' => 'Y'
813 ),
814 'GetListItemChangesSinceToken' => array(
815 'type' => 'public',
816 'name' => 'GetListItemChangesSinceToken',
817 'input' => array(
818 "listName" => array("varType" => "string"),
819 "viewFields" => array("varType" => "any", 'strict'=> 'no'),
820 'query' => array('varType' => 'any', 'strict' => 'no'),
821 'rowLimit' => array('varType' => 'string', 'strict' => 'no'),
822 'changeToken' => array('varType' => 'string', 'strict' => 'no'),
823 ),
824 'output' => array(
825 'GetListItemChangesSinceTokenResult' => array('varType' => 'any'),
826 ),
827 'httpauth' => 'Y'
828 ),
829 'UpdateListItems' => array(
830 'type' => 'public',
831 'name' => 'UpdateListItems',
832 'input' => array(
833 "listName" => array("varType" => "string"),
834 'updates' => array('varType' => 'any', 'strict' => 'no'),
835 ),
836 'output' => array(
837 'UpdateListItemsResult' => array('varType' => 'any')
838 ),
839 'httpauth' => 'Y'
840
841 ),
842 ),
843 );
844
845 return $wsdesc;
846 }
847
848 public static function ClearOutlookHtml($html)
849 {
850 $q = mb_strtolower($html);
851 if (($pos = mb_strrpos($q, '</head>')) !== false)
852 {
853 $html = mb_substr($html, $pos + 7);
854 $q = mb_strtolower($html);
855 }
856
857 if (str_contains($q, '<body'))
858 {
859 $html = preg_replace("/((\s|\S)*)<body[^>]*>((\s|\S)*)/is", "$3", $html);
860 $q = mb_strtolower($html);
861 }
862
863 if (($pos = mb_strrpos($q, '</body>')) !== false)
864 {
865 $html = mb_substr($html, 0, $pos);
866 }
867
868 $html = str_replace(array('</DIV>', "&#10;", "&#13;"), array("\r\n</DIV>", "", ""), $html);
869 $html = preg_replace("/<![^>]*>/", '', $html);
870 $html = trim($html);
871
872 $html = preg_replace("/(\s|\S)*<a\s*name=\"bm_begin\"><\/a>/isu","", $html);
873 $html = preg_replace("/<br>(\n|\r)+/isu","<br>", $html);
874
875 // mantis: 75493
876 $html = preg_replace("/.*\/\*\s*Style\s*Definitions\s*\*\/\s.+?;\}/isu","", $html);
877
878 return CCalendar::ParseHTMLToBB($html);
879 }
880
881 public static function isDaylightSavingTime($timezone): bool
882 {
883 if (empty($timezone))
884 {
885 return false;
886 }
887
888 try
889 {
890 $dateTimeZone = new DateTimeZone($timezone);
891 }
892 catch (\Throwable)
893 {
894 return false;
895 }
896
897 $dateTime = new DateTime('15.06.2024', $dateTimeZone);
898 $transitions = $dateTimeZone->getTransitions($dateTime->getTimestamp(), $dateTime->getTimestamp());
899
900 return !empty($transitions) && $transitions[0]['isdst'];
901 }
902}
903?>
$count
Определения admin_tab.php:4
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
UpdateListItems($listName, $updates)
Определения calendar_webservice.php:443
__getFieldsDefinition()
Определения calendar_webservice.php:17
GetListItemChangesSinceToken($listName, $viewFields='', $query='', $rowLimit=0, $changeToken='')
Определения calendar_webservice.php:356
__makeTS($datetime=null)
Определения calendar_webservice.php:97
__makeDateTime($ts=null)
Определения calendar_webservice.php:87
static ClearOutlookHtml($html)
Определения calendar_webservice.php:848
__getRow($event, $listName, &$last_change)
Определения calendar_webservice.php:173
static GetWebServiceDesc()
Определения calendar_webservice.php:777
GetListItemChanges($listName, $viewFields='', $since='', $contains='')
Определения calendar_webservice.php:342
static isDaylightSavingTime($timezone)
Определения calendar_webservice.php:881
GetList($listName)
Определения calendar_webservice.php:112
Определения xml.php:396
Определения webservice.php:9
static GetDefaultTargetNS()
Определения webservice.php:244
static GetDefaultEndpoint()
Определения webservice.php:237
Определения xmlcreator.php:3
static createTagAttributed($heavyTag, $value=null)
Определения xmlcreator.php:21
Определения webservice.php:52
$arFields
Определения dblapprove.php:5
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$query
Определения get_search.php:11
global $USER
Определения csv_new_run.php:40
$status
Определения session.php:10
htmlspecialcharsback($str)
Определения tools.php:2693
MakeTimeStamp($datetime, $format=false)
Определения tools.php:538
$name
Определения menu_edit.php:35
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$arSections
Определения yandex_run.php:805