From 2ac24d525c1ffc0f61345effb871b54f734183f4 Mon Sep 17 00:00:00 2001 From: Richard Steinmetz Date: Tue, 8 Aug 2023 14:51:08 +0200 Subject: [PATCH] feat(caldav): linkify location in scheduling mails Signed-off-by: Richard Steinmetz --- apps/dav/lib/CalDAV/Schedule/IMipService.php | 44 +++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/Schedule/IMipService.php b/apps/dav/lib/CalDAV/Schedule/IMipService.php index 8596500f32009..e6d1bbcd875b9 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipService.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipService.php @@ -6,6 +6,7 @@ * @copyright 2022 Anna Larch * * @author Anna Larch + * @author Richard Steinmetz * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -105,6 +106,40 @@ private function generateDiffString(VEvent $vevent, VEvent $oldVEvent, string $p return $newstring; } + /** + * Like generateDiffString() but linkifies the property values if they are urls. + */ + private function generateLinkifiedDiffString(VEvent $vevent, VEvent $oldVEvent, string $property, string $default): ?string { + if (!isset($vevent->$property)) { + return $default; + } + /** @var string|null $newString */ + $newString = $vevent->$property->getValue(); + $oldString = isset($oldVEvent->$property) ? $oldVEvent->$property->getValue() : null; + if ($oldString !== $newString) { + return sprintf( + "%s
%s", + $this->linkify($oldString) ?? $oldString ?? '', + $this->linkify($newString) ?? $newString ?? '' + ); + } + return $this->linkify($newString) ?? $newString; + } + + /** + * Convert a given url to a html link element or return null otherwise. + */ + private function linkify(?string $url): ?string { + if ($url === null) { + return null; + } + if (!str_starts_with($url, 'http://') && !str_starts_with($url, 'https://')) { + return null; + } + + return sprintf('%1$s', htmlspecialchars($url)); + } + /** * @param VEvent $vEvent * @param VEvent|null $oldVEvent @@ -121,11 +156,15 @@ public function buildBodyData(VEvent $vEvent, ?VEvent $oldVEvent): array { $data['meeting_url_html'] = self::readPropertyWithDefault($vEvent, 'URL', $defaultVal); + if (($locationHtml = $this->linkify($data['meeting_location'])) !== null) { + $data['meeting_location_html'] = $locationHtml; + } + if(!empty($oldVEvent)) { $oldMeetingWhen = $this->generateWhenString($oldVEvent); $data['meeting_title_html'] = $this->generateDiffString($vEvent, $oldVEvent, 'SUMMARY', $data['meeting_title']); $data['meeting_description_html'] = $this->generateDiffString($vEvent, $oldVEvent, 'DESCRIPTION', $data['meeting_description']); - $data['meeting_location_html'] = $this->generateDiffString($vEvent, $oldVEvent, 'LOCATION', $data['meeting_location']); + $data['meeting_location_html'] = $this->generateLinkifiedDiffString($vEvent, $oldVEvent, 'LOCATION', $data['meeting_location']); $oldUrl = self::readPropertyWithDefault($oldVEvent, 'URL', $defaultVal); $data['meeting_url_html'] = !empty($oldUrl) && $oldUrl !== $data['meeting_url'] ? sprintf('%1$s', $oldUrl) : $data['meeting_url']; @@ -246,6 +285,7 @@ public function buildCancelledBodyData(VEvent $vEvent): array { $newDescription = isset($vEvent->DESCRIPTION) && (string)$vEvent->DESCRIPTION !== '' ? (string)$vEvent->DESCRIPTION : $defaultVal; $newUrl = isset($vEvent->URL) && (string)$vEvent->URL !== '' ? sprintf('%1$s', $vEvent->URL) : $defaultVal; $newLocation = isset($vEvent->LOCATION) && (string)$vEvent->LOCATION !== '' ? (string)$vEvent->LOCATION : $defaultVal; + $newLocationHtml = $this->linkify($newLocation) ?? $newLocation; $data = []; $data['meeting_when_html'] = $newMeetingWhen === '' ?: sprintf($strikethrough, $newMeetingWhen); @@ -256,7 +296,7 @@ public function buildCancelledBodyData(VEvent $vEvent): array { $data['meeting_description'] = $newDescription; $data['meeting_url_html'] = $newUrl !== '' ? sprintf($strikethrough, $newUrl) : ''; $data['meeting_url'] = isset($vEvent->URL) ? (string)$vEvent->URL : ''; - $data['meeting_location_html'] = $newLocation !== '' ? sprintf($strikethrough, $newLocation) : ''; + $data['meeting_location_html'] = $newLocationHtml !== '' ? sprintf($strikethrough, $newLocationHtml) : ''; $data['meeting_location'] = $newLocation; return $data; }