|  | 
| 11 | 11 | use DateTimeInterface; | 
| 12 | 12 | use OC\AppFramework\Bootstrap\Coordinator; | 
| 13 | 13 | use OCA\DAV\CalDAV\Auth\CustomPrincipalPlugin; | 
|  | 14 | +use OCA\DAV\Db\PropertyMapper; | 
| 14 | 15 | use OCA\DAV\ServerFactory; | 
| 15 | 16 | use OCP\AppFramework\Utility\ITimeFactory; | 
| 16 | 17 | use OCP\Calendar\Exceptions\CalendarException; | 
| @@ -58,6 +59,7 @@ public function __construct( | 
| 58 | 59 | 		private ISecureRandom $random, | 
| 59 | 60 | 		private IUserManager $userManager, | 
| 60 | 61 | 		private ServerFactory $serverFactory, | 
|  | 62 | +		private PropertyMapper $propertyMapper, | 
| 61 | 63 | 	) { | 
| 62 | 64 | 	} | 
| 63 | 65 | 
 | 
| @@ -227,6 +229,7 @@ public function newQuery(string $principalUri): ICalendarQuery { | 
| 227 | 229 | 	protected function handleIMip( | 
| 228 | 230 | 		string $userId, | 
| 229 | 231 | 		string $message, | 
|  | 232 | +		array $options = [], | 
| 230 | 233 | 	): bool { | 
| 231 | 234 | 
 | 
| 232 | 235 | 		$userUri = 'principals/users/' . $userId; | 
| @@ -287,6 +290,30 @@ protected function handleIMip( | 
| 287 | 290 | 			} | 
| 288 | 291 | 		} | 
| 289 | 292 | 
 | 
|  | 293 | +		if ($options['absent'] === 'create') { | 
|  | 294 | +			// retrieve the primary calendar for the user | 
|  | 295 | +			$calendar = $this->getPrimaryCalendar($userId); | 
|  | 296 | +			if ($calendar !== null && ( | 
|  | 297 | +				!$calendar instanceof IHandleImipMessage || !$calendar instanceof ICalendarIsWritable || $calendar->isDeleted() || !$calendar->isWritable() | 
|  | 298 | +			)) { | 
|  | 299 | +				$calendar = null; | 
|  | 300 | +			} | 
|  | 301 | +			// if no primary calendar is set, use the first writable calendar | 
|  | 302 | +			if ($calendar === null) { | 
|  | 303 | +				foreach ($userCalendars as $userCalendar) { | 
|  | 304 | +					if ($userCalendar instanceof IHandleImipMessage && $userCalendar instanceof ICalendarIsWritable && !$userCalendar->isDeleted() && $userCalendar->isWritable()) { | 
|  | 305 | +						$calendar = $userCalendar; | 
|  | 306 | +						break; | 
|  | 307 | +					} | 
|  | 308 | +				} | 
|  | 309 | +			} | 
|  | 310 | +			if ($calendar === null) { | 
|  | 311 | +				$this->logger->warning('iMip message could not be processed because no writable calendar was found'); | 
|  | 312 | +				return false; | 
|  | 313 | +			} | 
|  | 314 | +			$calendar->handleIMipMessage($userId, $vObject->serialize()); | 
|  | 315 | +		} | 
|  | 316 | + | 
| 290 | 317 | 		$this->logger->warning('iMip message could not be processed because no corresponding event was found in any calendar'); | 
| 291 | 318 | 
 | 
| 292 | 319 | 		return false; | 
| @@ -437,4 +464,32 @@ public function checkAvailability( | 
| 437 | 464 | 
 | 
| 438 | 465 | 		return $result; | 
| 439 | 466 | 	} | 
|  | 467 | + | 
|  | 468 | +	public function getPrimaryCalendar(string $userId): ?ICalendar { | 
|  | 469 | +		// determine if the principal has a default calendar configured | 
|  | 470 | +		$properties = $this->propertyMapper->findPropertyByPathAndName( | 
|  | 471 | +			$userId, | 
|  | 472 | +			'principals/users/' . $userId, | 
|  | 473 | +			'{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL' | 
|  | 474 | +		); | 
|  | 475 | +		if ($properties === []) { | 
|  | 476 | +			return null; | 
|  | 477 | +		} | 
|  | 478 | +		// extract the calendar URI from the property value | 
|  | 479 | +		$propertyValue = $properties[0]->getPropertyvalue() ?? null; | 
|  | 480 | +		if (str_starts_with($propertyValue, 'calendars/' . $userId)) { | 
|  | 481 | +			$calendarUri = rtrim(str_replace('calendars/' . $userId . '/', '', $propertyValue), '/'); | 
|  | 482 | +		} | 
|  | 483 | +		if (empty($calendarUri)) { | 
|  | 484 | +			return null; | 
|  | 485 | +		} | 
|  | 486 | +		// retrieve the calendar by URI | 
|  | 487 | +		$calendars = $this->getCalendarsForPrincipal('principals/users/' . $userId, [$calendarUri]); | 
|  | 488 | +		if ($calendars === []) { | 
|  | 489 | +			return null; | 
|  | 490 | +		} | 
|  | 491 | + | 
|  | 492 | +		return $calendars[0]; | 
|  | 493 | +	} | 
|  | 494 | + | 
| 440 | 495 | } | 
0 commit comments