Passed
Push — master ( 9ed379...6656e2 )
by Julius
14:08 queued 25s
created
apps/user_status/lib/Service/PredefinedStatusService.php 1 patch
Indentation   +148 added lines, -148 removed lines patch added patch discarded remove patch
@@ -36,152 +36,152 @@
 block discarded – undo
36 36
  * @package OCA\UserStatus\Service
37 37
  */
38 38
 class PredefinedStatusService {
39
-	private const MEETING = 'meeting';
40
-	private const COMMUTING = 'commuting';
41
-	private const SICK_LEAVE = 'sick-leave';
42
-	private const VACATIONING = 'vacationing';
43
-	private const REMOTE_WORK = 'remote-work';
44
-
45
-	/** @var IL10N */
46
-	private $l10n;
47
-
48
-	/**
49
-	 * DefaultStatusService constructor.
50
-	 *
51
-	 * @param IL10N $l10n
52
-	 */
53
-	public function __construct(IL10N $l10n) {
54
-		$this->l10n = $l10n;
55
-	}
56
-
57
-	/**
58
-	 * @return array
59
-	 */
60
-	public function getDefaultStatuses(): array {
61
-		return [
62
-			[
63
-				'id' => self::MEETING,
64
-				'icon' => '
Please login to merge, or discard this patch.
apps/dav/lib/CalDAV/BirthdayService.php 2 patches
Indentation   +450 added lines, -450 removed lines patch added patch discarded remove patch
@@ -52,454 +52,454 @@
 block discarded – undo
52 52
  * @package OCA\DAV\CalDAV
53 53
  */
54 54
 class BirthdayService {
55
-	public const BIRTHDAY_CALENDAR_URI = 'contact_birthdays';
56
-
57
-	/** @var GroupPrincipalBackend */
58
-	private $principalBackend;
59
-
60
-	/** @var CalDavBackend  */
61
-	private $calDavBackEnd;
62
-
63
-	/** @var CardDavBackend  */
64
-	private $cardDavBackEnd;
65
-
66
-	/** @var IConfig */
67
-	private $config;
68
-
69
-	/** @var IDBConnection */
70
-	private $dbConnection;
71
-
72
-	/** @var IL10N */
73
-	private $l10n;
74
-
75
-	/**
76
-	 * BirthdayService constructor.
77
-	 *
78
-	 * @param CalDavBackend $calDavBackEnd
79
-	 * @param CardDavBackend $cardDavBackEnd
80
-	 * @param GroupPrincipalBackend $principalBackend
81
-	 * @param IConfig $config
82
-	 * @param IDBConnection $dbConnection
83
-	 * @param IL10N $l10n
84
-	 */
85
-	public function __construct(CalDavBackend $calDavBackEnd,
86
-								CardDavBackend $cardDavBackEnd,
87
-								GroupPrincipalBackend $principalBackend,
88
-								IConfig $config,
89
-								IDBConnection $dbConnection,
90
-								IL10N $l10n) {
91
-		$this->calDavBackEnd = $calDavBackEnd;
92
-		$this->cardDavBackEnd = $cardDavBackEnd;
93
-		$this->principalBackend = $principalBackend;
94
-		$this->config = $config;
95
-		$this->dbConnection = $dbConnection;
96
-		$this->l10n = $l10n;
97
-	}
98
-
99
-	/**
100
-	 * @param int $addressBookId
101
-	 * @param string $cardUri
102
-	 * @param string $cardData
103
-	 */
104
-	public function onCardChanged(int $addressBookId,
105
-								  string $cardUri,
106
-								  string $cardData) {
107
-		if (!$this->isGloballyEnabled()) {
108
-			return;
109
-		}
110
-
111
-		$targetPrincipals = $this->getAllAffectedPrincipals($addressBookId);
112
-		$book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
113
-		$targetPrincipals[] = $book['principaluri'];
114
-		$datesToSync = [
115
-			['postfix' => '', 'field' => 'BDAY'],
116
-			['postfix' => '-death', 'field' => 'DEATHDATE'],
117
-			['postfix' => '-anniversary', 'field' => 'ANNIVERSARY'],
118
-		];
119
-
120
-		foreach ($targetPrincipals as $principalUri) {
121
-			if (!$this->isUserEnabled($principalUri)) {
122
-				continue;
123
-			}
124
-
125
-			$calendar = $this->ensureCalendarExists($principalUri);
126
-			foreach ($datesToSync as $type) {
127
-				$this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type);
128
-			}
129
-		}
130
-	}
131
-
132
-	/**
133
-	 * @param int $addressBookId
134
-	 * @param string $cardUri
135
-	 */
136
-	public function onCardDeleted(int $addressBookId,
137
-								  string $cardUri) {
138
-		if (!$this->isGloballyEnabled()) {
139
-			return;
140
-		}
141
-
142
-		$targetPrincipals = $this->getAllAffectedPrincipals($addressBookId);
143
-		$book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
144
-		$targetPrincipals[] = $book['principaluri'];
145
-		foreach ($targetPrincipals as $principalUri) {
146
-			if (!$this->isUserEnabled($principalUri)) {
147
-				continue;
148
-			}
149
-
150
-			$calendar = $this->ensureCalendarExists($principalUri);
151
-			foreach (['', '-death', '-anniversary'] as $tag) {
152
-				$objectUri = $book['uri'] . '-' . $cardUri . $tag .'.ics';
153
-				$this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri);
154
-			}
155
-		}
156
-	}
157
-
158
-	/**
159
-	 * @param string $principal
160
-	 * @return array|null
161
-	 * @throws \Sabre\DAV\Exception\BadRequest
162
-	 */
163
-	public function ensureCalendarExists(string $principal):?array {
164
-		$calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
165
-		if (!is_null($calendar)) {
166
-			return $calendar;
167
-		}
168
-		$this->calDavBackEnd->createCalendar($principal, self::BIRTHDAY_CALENDAR_URI, [
169
-			'{DAV:}displayname' => $this->l10n->t('Contact birthdays'),
170
-			'{http://apple.com/ns/ical/}calendar-color' => '#E9D859',
171
-			'components' => 'VEVENT',
172
-		]);
173
-
174
-		return $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
175
-	}
176
-
177
-	/**
178
-	 * @param $cardData
179
-	 * @param $dateField
180
-	 * @param $postfix
181
-	 * @return VCalendar|null
182
-	 * @throws InvalidDataException
183
-	 */
184
-	public function buildDateFromContact(string $cardData,
185
-										 string $dateField,
186
-										 string $postfix):?VCalendar {
187
-		if (empty($cardData)) {
188
-			return null;
189
-		}
190
-		try {
191
-			$doc = Reader::read($cardData);
192
-			// We're always converting to vCard 4.0 so we can rely on the
193
-			// VCardConverter handling the X-APPLE-OMIT-YEAR property for us.
194
-			if (!$doc instanceof VCard) {
195
-				return null;
196
-			}
197
-			$doc = $doc->convert(Document::VCARD40);
198
-		} catch (Exception $e) {
199
-			return null;
200
-		}
201
-
202
-		if (!isset($doc->{$dateField})) {
203
-			return null;
204
-		}
205
-		if (!isset($doc->FN)) {
206
-			return null;
207
-		}
208
-		$birthday = $doc->{$dateField};
209
-		if (!(string)$birthday) {
210
-			return null;
211
-		}
212
-		// Skip if the BDAY property is not of the right type.
213
-		if (!$birthday instanceof DateAndOrTime) {
214
-			return null;
215
-		}
216
-
217
-		// Skip if we can't parse the BDAY value.
218
-		try {
219
-			$dateParts = DateTimeParser::parseVCardDateTime($birthday->getValue());
220
-		} catch (InvalidDataException $e) {
221
-			return null;
222
-		}
223
-
224
-		$unknownYear = false;
225
-		$originalYear = null;
226
-		if (!$dateParts['year']) {
227
-			$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
228
-
229
-			$unknownYear = true;
230
-		} else {
231
-			$parameters = $birthday->parameters();
232
-			if (isset($parameters['X-APPLE-OMIT-YEAR'])) {
233
-				$omitYear = $parameters['X-APPLE-OMIT-YEAR'];
234
-				if ($dateParts['year'] === $omitYear) {
235
-					$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
236
-					$unknownYear = true;
237
-				}
238
-			} else {
239
-				$originalYear = (int)$dateParts['year'];
240
-				// 'X-APPLE-OMIT-YEAR' is not always present, at least iOS 12.4 uses the hard coded date of 1604 (the start of the gregorian calendar) when the year is unknown
241
-				if ($originalYear == 1604) {
242
-					$originalYear = null;
243
-					$unknownYear = true;
244
-					$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
245
-				}
246
-				if ($originalYear < 1970) {
247
-					$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
248
-				}
249
-			}
250
-		}
251
-
252
-		try {
253
-			if ($birthday instanceof DateAndOrTime) {
254
-				$date = $birthday->getDateTime();
255
-			} else {
256
-				$date = new \DateTimeImmutable($birthday);
257
-			}
258
-		} catch (Exception $e) {
259
-			return null;
260
-		}
261
-
262
-		$summary = $this->formatTitle($dateField, $doc->FN->getValue(), $originalYear, $this->dbConnection->supports4ByteText());
263
-
264
-		$vCal = new VCalendar();
265
-		$vCal->VERSION = '2.0';
266
-		$vCal->PRODID = '-//IDN nextcloud.com//Birthday calendar//EN';
267
-		$vEvent = $vCal->createComponent('VEVENT');
268
-		$vEvent->add('DTSTART');
269
-		$vEvent->DTSTART->setDateTime(
270
-			$date
271
-		);
272
-		$vEvent->DTSTART['VALUE'] = 'DATE';
273
-		$vEvent->add('DTEND');
274
-
275
-		$dtEndDate = (new \DateTime())->setTimestamp($date->getTimeStamp());
276
-		$dtEndDate->add(new \DateInterval('P1D'));
277
-		$vEvent->DTEND->setDateTime(
278
-			$dtEndDate
279
-		);
280
-
281
-		$vEvent->DTEND['VALUE'] = 'DATE';
282
-		$vEvent->{'UID'} = $doc->UID . $postfix;
283
-		$vEvent->{'RRULE'} = 'FREQ=YEARLY';
284
-		$vEvent->{'SUMMARY'} = $summary;
285
-		$vEvent->{'TRANSP'} = 'TRANSPARENT';
286
-		$vEvent->{'X-NEXTCLOUD-BC-FIELD-TYPE'} = $dateField;
287
-		$vEvent->{'X-NEXTCLOUD-BC-UNKNOWN-YEAR'} = $unknownYear ? '1' : '0';
288
-		if ($originalYear !== null) {
289
-			$vEvent->{'X-NEXTCLOUD-BC-YEAR'} = (string) $originalYear;
290
-		}
291
-		$alarm = $vCal->createComponent('VALARM');
292
-		$alarm->add($vCal->createProperty('TRIGGER', '-PT0M', ['VALUE' => 'DURATION']));
293
-		$alarm->add($vCal->createProperty('ACTION', 'DISPLAY'));
294
-		$alarm->add($vCal->createProperty('DESCRIPTION', $vEvent->{'SUMMARY'}));
295
-		$vEvent->add($alarm);
296
-		$vCal->add($vEvent);
297
-		return $vCal;
298
-	}
299
-
300
-	/**
301
-	 * @param string $user
302
-	 */
303
-	public function resetForUser(string $user):void {
304
-		$principal = 'principals/users/'.$user;
305
-		$calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
306
-		$calendarObjects = $this->calDavBackEnd->getCalendarObjects($calendar['id'], CalDavBackend::CALENDAR_TYPE_CALENDAR);
307
-
308
-		foreach ($calendarObjects as $calendarObject) {
309
-			$this->calDavBackEnd->deleteCalendarObject($calendar['id'], $calendarObject['uri'], CalDavBackend::CALENDAR_TYPE_CALENDAR);
310
-		}
311
-	}
312
-
313
-	/**
314
-	 * @param string $user
315
-	 * @throws \Sabre\DAV\Exception\BadRequest
316
-	 */
317
-	public function syncUser(string $user):void {
318
-		$principal = 'principals/users/'.$user;
319
-		$this->ensureCalendarExists($principal);
320
-		$books = $this->cardDavBackEnd->getAddressBooksForUser($principal);
321
-		foreach ($books as $book) {
322
-			$cards = $this->cardDavBackEnd->getCards($book['id']);
323
-			foreach ($cards as $card) {
324
-				$this->onCardChanged((int) $book['id'], $card['uri'], $card['carddata']);
325
-			}
326
-		}
327
-	}
328
-
329
-	/**
330
-	 * @param string $existingCalendarData
331
-	 * @param VCalendar $newCalendarData
332
-	 * @return bool
333
-	 */
334
-	public function birthdayEvenChanged(string $existingCalendarData,
335
-										VCalendar $newCalendarData):bool {
336
-		try {
337
-			$existingBirthday = Reader::read($existingCalendarData);
338
-		} catch (Exception $ex) {
339
-			return true;
340
-		}
341
-
342
-		return (
343
-			$newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
344
-			$newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
345
-		);
346
-	}
347
-
348
-	/**
349
-	 * @param integer $addressBookId
350
-	 * @return mixed
351
-	 */
352
-	protected function getAllAffectedPrincipals(int $addressBookId) {
353
-		$targetPrincipals = [];
354
-		$shares = $this->cardDavBackEnd->getShares($addressBookId);
355
-		foreach ($shares as $share) {
356
-			if ($share['{http://owncloud.org/ns}group-share']) {
357
-				$users = $this->principalBackend->getGroupMemberSet($share['{http://owncloud.org/ns}principal']);
358
-				foreach ($users as $user) {
359
-					$targetPrincipals[] = $user['uri'];
360
-				}
361
-			} else {
362
-				$targetPrincipals[] = $share['{http://owncloud.org/ns}principal'];
363
-			}
364
-		}
365
-		return array_values(array_unique($targetPrincipals, SORT_STRING));
366
-	}
367
-
368
-	/**
369
-	 * @param string $cardUri
370
-	 * @param string $cardData
371
-	 * @param array $book
372
-	 * @param int $calendarId
373
-	 * @param array $type
374
-	 * @throws InvalidDataException
375
-	 * @throws \Sabre\DAV\Exception\BadRequest
376
-	 */
377
-	private function updateCalendar(string $cardUri,
378
-									string $cardData,
379
-									array $book,
380
-									int $calendarId,
381
-									array $type):void {
382
-		$objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics';
383
-		$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']);
384
-		$existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri);
385
-		if ($calendarData === null) {
386
-			if ($existing !== null) {
387
-				$this->calDavBackEnd->deleteCalendarObject($calendarId, $objectUri);
388
-			}
389
-		} else {
390
-			if ($existing === null) {
391
-				// not found by URI, but maybe by UID
392
-				// happens when a contact with birthday is moved to a different address book
393
-				$calendarInfo = $this->calDavBackEnd->getCalendarById($calendarId);
394
-				$extraData = $this->calDavBackEnd->getDenormalizedData($calendarData->serialize());
395
-
396
-				if ($calendarInfo && array_key_exists('principaluri', $calendarInfo)) {
397
-					$existing2path = $this->calDavBackEnd->getCalendarObjectByUID($calendarInfo['principaluri'], $extraData['uid']);
398
-					if ($existing2path !== null && array_key_exists('uri', $calendarInfo)) {
399
-						// delete the old birthday entry first so that we do not get duplicate UIDs
400
-						$existing2objectUri = substr($existing2path, strlen($calendarInfo['uri']) + 1);
401
-						$this->calDavBackEnd->deleteCalendarObject($calendarId, $existing2objectUri);
402
-					}
403
-				}
404
-
405
-				$this->calDavBackEnd->createCalendarObject($calendarId, $objectUri, $calendarData->serialize());
406
-			} else {
407
-				if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) {
408
-					$this->calDavBackEnd->updateCalendarObject($calendarId, $objectUri, $calendarData->serialize());
409
-				}
410
-			}
411
-		}
412
-	}
413
-
414
-	/**
415
-	 * checks if the admin opted-out of birthday calendars
416
-	 *
417
-	 * @return bool
418
-	 */
419
-	private function isGloballyEnabled():bool {
420
-		return $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes') === 'yes';
421
-	}
422
-
423
-	/**
424
-	 * Checks if the user opted-out of birthday calendars
425
-	 *
426
-	 * @param string $userPrincipal The user principal to check for
427
-	 * @return bool
428
-	 */
429
-	private function isUserEnabled(string $userPrincipal):bool {
430
-		if (strpos($userPrincipal, 'principals/users/') === 0) {
431
-			$userId = substr($userPrincipal, 17);
432
-			$isEnabled = $this->config->getUserValue($userId, 'dav', 'generateBirthdayCalendar', 'yes');
433
-			return $isEnabled === 'yes';
434
-		}
435
-
436
-		// not sure how we got here, just be on the safe side and return true
437
-		return true;
438
-	}
439
-
440
-	/**
441
-	 * Formats title of Birthday event
442
-	 *
443
-	 * @param string $field Field name like BDAY, ANNIVERSARY, ...
444
-	 * @param string $name Name of contact
445
-	 * @param int|null $year Year of birth, anniversary, ...
446
-	 * @param bool $supports4Byte Whether or not the database supports 4 byte chars
447
-	 * @return string The formatted title
448
-	 */
449
-	private function formatTitle(string $field,
450
-								 string $name,
451
-								 int $year = null,
452
-								 bool $supports4Byte = true):string {
453
-		if ($supports4Byte) {
454
-			switch ($field) {
455
-				case 'BDAY':
456
-					return implode('', [
457
-						'
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -149,7 +149,7 @@  discard block
 block discarded – undo
149 149
 
150 150
 			$calendar = $this->ensureCalendarExists($principalUri);
151 151
 			foreach (['', '-death', '-anniversary'] as $tag) {
152
-				$objectUri = $book['uri'] . '-' . $cardUri . $tag .'.ics';
152
+				$objectUri = $book['uri'].'-'.$cardUri.$tag.'.ics';
153 153
 				$this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri);
154 154
 			}
155 155
 		}
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
 	 * @return array|null
161 161
 	 * @throws \Sabre\DAV\Exception\BadRequest
162 162
 	 */
163
-	public function ensureCalendarExists(string $principal):?array {
163
+	public function ensureCalendarExists(string $principal): ?array {
164 164
 		$calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI);
165 165
 		if (!is_null($calendar)) {
166 166
 			return $calendar;
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
 	 */
184 184
 	public function buildDateFromContact(string $cardData,
185 185
 										 string $dateField,
186
-										 string $postfix):?VCalendar {
186
+										 string $postfix): ?VCalendar {
187 187
 		if (empty($cardData)) {
188 188
 			return null;
189 189
 		}
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
 			return null;
207 207
 		}
208 208
 		$birthday = $doc->{$dateField};
209
-		if (!(string)$birthday) {
209
+		if (!(string) $birthday) {
210 210
 			return null;
211 211
 		}
212 212
 		// Skip if the BDAY property is not of the right type.
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
 		$unknownYear = false;
225 225
 		$originalYear = null;
226 226
 		if (!$dateParts['year']) {
227
-			$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
227
+			$birthday = '1970-'.$dateParts['month'].'-'.$dateParts['date'];
228 228
 
229 229
 			$unknownYear = true;
230 230
 		} else {
@@ -232,19 +232,19 @@  discard block
 block discarded – undo
232 232
 			if (isset($parameters['X-APPLE-OMIT-YEAR'])) {
233 233
 				$omitYear = $parameters['X-APPLE-OMIT-YEAR'];
234 234
 				if ($dateParts['year'] === $omitYear) {
235
-					$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
235
+					$birthday = '1970-'.$dateParts['month'].'-'.$dateParts['date'];
236 236
 					$unknownYear = true;
237 237
 				}
238 238
 			} else {
239
-				$originalYear = (int)$dateParts['year'];
239
+				$originalYear = (int) $dateParts['year'];
240 240
 				// 'X-APPLE-OMIT-YEAR' is not always present, at least iOS 12.4 uses the hard coded date of 1604 (the start of the gregorian calendar) when the year is unknown
241 241
 				if ($originalYear == 1604) {
242 242
 					$originalYear = null;
243 243
 					$unknownYear = true;
244
-					$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
244
+					$birthday = '1970-'.$dateParts['month'].'-'.$dateParts['date'];
245 245
 				}
246 246
 				if ($originalYear < 1970) {
247
-					$birthday = '1970-' . $dateParts['month'] . '-' . $dateParts['date'];
247
+					$birthday = '1970-'.$dateParts['month'].'-'.$dateParts['date'];
248 248
 				}
249 249
 			}
250 250
 		}
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
 		);
280 280
 
281 281
 		$vEvent->DTEND['VALUE'] = 'DATE';
282
-		$vEvent->{'UID'} = $doc->UID . $postfix;
282
+		$vEvent->{'UID'} = $doc->UID.$postfix;
283 283
 		$vEvent->{'RRULE'} = 'FREQ=YEARLY';
284 284
 		$vEvent->{'SUMMARY'} = $summary;
285 285
 		$vEvent->{'TRANSP'} = 'TRANSPARENT';
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
 									array $book,
380 380
 									int $calendarId,
381 381
 									array $type):void {
382
-		$objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics';
382
+		$objectUri = $book['uri'].'-'.$cardUri.$type['postfix'].'.ics';
383 383
 		$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']);
384 384
 		$existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri);
385 385
 		if ($calendarData === null) {
@@ -456,20 +456,20 @@  discard block
 block discarded – undo
456 456
 					return implode('', [
457 457
 						'
Please login to merge, or discard this patch.