Loading Dockerfile +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ ARG ECLOUD_LAUNCHER_JOB_ID="345049" ARG GOOGLE_INTEGRATION_VERSION="1.0.6" ARG LDAP_WRITE_SUPPORT_VERSION="1.4.0" RUN sed -i 's/22,2,9,1/22,2,9,2/' ${BASE_DIR}/version.php RUN sed -i 's/22,2,9,1/22,2,9,3/' ${BASE_DIR}/version.php COPY custom_entrypoint.sh / RUN chmod +x /custom_entrypoint.sh RUN mkdir -p /var/www/skeleton/Documents && mkdir -p /var/www/skeleton/Images Loading patches/015-email-mail-template.patch +192 −34 Original line number Diff line number Diff line Loading @@ -32,20 +32,114 @@ /** --- ./apps/dav/lib/CalDAV/Schedule/IMipPlugin.php 2022-07-04 12:41:03.228533600 +0530 +++ ./apps/dav/lib/CalDAV/Schedule/IMipPlugin-new.php 2022-07-04 14:42:56.208533600 +0530 @@ -419,23 +419,33 @@ --- apps/dav/lib/CalDAV/Schedule/IMipPlugin.php 2022-07-27 13:21:50.294113800 +0530 +++ apps/dav/lib/CalDAV/Schedule/IMipPlugin-New.php 2022-08-16 16:29:16.531866700 +0530 @@ -151,15 +151,6 @@ */ public function schedule(Message $iTipMessage) { - // Not sending any emails if the system considers the update - // insignificant. - if (!$iTipMessage->significantChange) { - if (!$iTipMessage->scheduleStatus) { - $iTipMessage->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email'; - } - return; - } - $summary = $iTipMessage->message->VEVENT->SUMMARY; if (parse_url($iTipMessage->sender, PHP_URL_SCHEME) !== 'mailto') { @@ -252,9 +243,25 @@ $summary = ((string) $summary !== '') ? (string) $summary : $l10n->t('Untitled event'); - $this->addSubjectAndHeading($template, $l10n, $method, $summary); + if( count($vevent)>1){ + $this->addSubjectAndHeadingUpdated($template, $l10n, $method, $summary); + + }else{ + $this->addSubjectAndHeading($template, $l10n, $method, $summary); + } + if ($method === self::METHOD_CANCEL) { + $template->addHeadingBanner('#FFC2B9','#7D1000',$l10n->t('The invitation has been cancelled')); + } + if ($method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vevent)>1) { + $template->addHeadingBanner('#EFFFDB','#293618',$l10n->t('This recurring event has been updated, please review the information below:')); + } + $sequence = $vevent->SEQUENCE->getValue(); + if ($method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vevent)==1 && ($sequence > 2)) { + $template->addHeadingBanner('#EFFFDB','#293618',$l10n->t('This event has been updated, please review the information below:')); + } $this->addBulletList($template, $l10n, $vevent); + // Only add response buttons to invitation requests: Fix Issue #11230 if (($method == self::METHOD_REQUEST) && $this->getAttendeeRsvpOrReqForParticipant($attendee)) { @@ -414,7 +421,7 @@ return false; } - /** + /** * @param IL10N $l10n * @param VEvent $vevent */ private function generateWhenString(IL10N $l10n, VEvent $vevent) { - $dtstart = $vevent->DTSTART; - if (isset($vevent->DTEND)) { - $dtend = $vevent->DTEND; - } elseif (isset($vevent->DURATION)) { - $isFloating = $vevent->DTSTART->isFloating(); - $dtend = clone $vevent->DTSTART; @@ -525,38 +532,99 @@ private function addSubjectAndHeading(IEMailTemplate $template, IL10N $l10n, $method, $summary) { if ($method === self::METHOD_CANCEL) { - $template->setSubject('Canceled: ' . $summary); + //TRANSLATORS Subject for email, when an invitation is cancelled. Ex: "Cancelled: {{Event Name}}" + $template->setSubject($l10n->t('Cancelled: %1$s', [$summary])); $template->addHeading($l10n->t('Invitation canceled')); } elseif ($method === self::METHOD_REPLY) { - $template->setSubject('Re: ' . $summary); + // TRANSLATORS Subject for email, when an invitation is updated. Ex: "Re: {{Event Name}}" + $template->setSubject($l10n->t('Re: %1$s', [$summary])); $template->addHeading($l10n->t('Invitation updated')); } else { - $template->setSubject('Invitation: ' . $summary); + // TRANSLATORS Subject for email, when an invitation is sent. Ex: "Invitation: {{Event Name}}" + $template->setSubject($l10n->t('Invitation: %1$s', [$summary])); $template->addHeading($l10n->t('Invitation')); } } - + /** + * @param IEMailTemplate $template + * @param IL10N $l10n + * @param string $method + * @param string $summary + */ + private function addSubjectAndHeadingUpdated(IEMailTemplate $template, IL10N $l10n, + $method, $summary) { + if ($method === self::METHOD_CANCEL) { + //TRANSLATORS Subject for email, when an invitation is cancelled. Ex: "Cancelled: {{Event Name}}" + $template->setSubject($l10n->t('Cancelled: %1$s', [$summary])); + $template->addHeading($l10n->t('Invitation canceled')); + } elseif ($method === self::METHOD_REPLY) { + // TRANSLATORS Subject for email, when an invitation is updated. Ex: "Re: {{Event Name}}" + $template->setSubject($l10n->t('Re: %1$s', [$summary])); + $template->addHeading($l10n->t('Invitation updated')); + } else { + // TRANSLATORS Subject for email, when an invitation is sent. Ex: "Invitation: {{Event Name}}" + $template->setSubject($l10n->t('Invitation: %1$s', [$summary])); + $template->addHeading($l10n->t('Invitation Update')); + } + } /** * @param IEMailTemplate $template * @param IL10N $l10n * @param VEVENT $vevent */ private function addBulletList(IEMailTemplate $template, IL10N $l10n, $vevent) { - if ($vevent->SUMMARY) { - $template->addBodyListItem($vevent->SUMMARY, $l10n->t('Title:'), - $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); + $lastmodified=0; + $selectedEvent = $vevent; + $selectedEvent = $parentevent = $vevent; + foreach( $vevent as $currentevent){ + $dtstamp= $currentevent->{'LAST-MODIFIED'}; + $dtstampTime = strtotime($dtstamp); Loading @@ -54,30 +148,94 @@ + $selectedEvent = $currentevent; + } + } + $dtstart = $selectedEvent->DTSTART; + if (isset($selectedEvent->DTEND)) { + $dtend = $selectedEvent->DTEND; + } elseif (isset($selectedEvent->DURATION)) { + $isFloating = $selectedEvent->DTSTART->isFloating(); + $dtend = clone $selectedEvent->DTSTART; $endDateTime = $dtend->getDateTime(); - $endDateTime = $endDateTime->add(DateTimeParser::parse($vevent->DURATION->getValue())); + $endDateTime = $endDateTime->add(DateTimeParser::parse($selectedEvent->DURATION->getValue())); $dtend->setDateTime($endDateTime, $isFloating); - } elseif (!$vevent->DTSTART->hasTime()) { - $isFloating = $vevent->DTSTART->isFloating(); - $dtend = clone $vevent->DTSTART; + } elseif (!$selectedEvent->DTSTART->hasTime()) { + $isFloating = $selectedEvent->DTSTART->isFloating(); + $dtend = clone $selectedEvent->DTSTART; $endDateTime = $dtend->getDateTime(); $endDateTime = $endDateTime->modify('+1 day'); $dtend->setDateTime($endDateTime, $isFloating); } else { - $dtend = clone $vevent->DTSTART; + $dtend = clone $selectedEvent->DTSTART; + + + if ($selectedEvent->SUMMARY) { + + if(trim($selectedEvent->SUMMARY)==trim($parentevent->SUMMARY)){ + $template->addBodyListItem($selectedEvent->SUMMARY, $l10n->t('Title:'), + $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($selectedEvent->SUMMARY, $l10n->t('Updated Title:'), + $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); + } } - $meetingWhen = $this->generateWhenString($l10n, $vevent); + $meetingWhen = $this->generateWhenString($l10n, $selectedEvent); if ($meetingWhen) { - $template->addBodyListItem($meetingWhen, $l10n->t('Time:'), - $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + $selectedtimestart= substr(($selectedEvent->DTSTART), strpos(($selectedEvent->DTSTART), "T") + 1); + $parenttimestart= substr(($parentevent->DTSTART), strpos(($parentevent->DTSTART), "T") + 1); + $selectedtimeend= substr(($selectedEvent->DTEND), strpos(($selectedEvent->DTEND), "T") + 1); + $parenttimeend= substr(($parentevent->DTEND), strpos(($parentevent->DTEND), "T") + 1); + + if(trim($selectedtimestart)==trim($parenttimestart) && trim($selectedtimeend)==trim($parenttimeend)){ + $template->addBodyListItem($meetingWhen, $l10n->t('Time:'), + $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($meetingWhen, $l10n->t('Updated Time:'), + $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + } + + } - if ($vevent->LOCATION) { - $template->addBodyListItem($vevent->LOCATION, $l10n->t('Location:'), - $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); + if ($selectedEvent->LOCATION) { + if(trim($selectedEvent->LOCATION)==trim($parentevent->LOCATION)){ + $template->addBodyListItem($selectedEvent->LOCATION, $l10n->t('Location:'), + $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($selectedEvent->LOCATION, $l10n->t('Updated Location:'), + $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); + } + + } - if ($vevent->URL) { - $url = $vevent->URL->getValue(); + if ($selectedEvent->URL) { + $url = $selectedEvent->URL->getValue(); $template->addBodyListItem(sprintf('<a href="%s">%s</a>', htmlspecialchars($url), htmlspecialchars($url)), @@ -565,12 +633,18 @@ $url,'',self::IMIP_INDENT); } - $this->addAttendees($template, $l10n, $vevent); + $this->addAttendees($template, $l10n, $selectedEvent); /* Put description last, like an email body, since it can be arbitrarily long */ - if ($vevent->DESCRIPTION) { - $template->addBodyListItem($vevent->DESCRIPTION->getValue(), $l10n->t('Description:'), - $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); + if ($selectedEvent->DESCRIPTION) { + if(trim($selectedEvent->DESCRIPTION)==trim($parentevent->DESCRIPTION)){ + $template->addBodyListItem($selectedEvent->DESCRIPTION->getValue(), $l10n->t('Description:'), + $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($selectedEvent->DESCRIPTION, $l10n->t('Updated Description:'), + $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); + } + } } $isAllDay = $dtstart instanceof Property\ICalendar\Date; @@ -671,7 +745,6 @@ $l10n->t('Maybe'), $this->urlGenerator->getAbsoluteUrl('apps/calendar/invitation/tentative/'.$token) ); - } /** @@ -716,4 +789,4 @@ return $token; } -} +} \ No newline at end of file Loading
Dockerfile +1 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ ARG ECLOUD_LAUNCHER_JOB_ID="345049" ARG GOOGLE_INTEGRATION_VERSION="1.0.6" ARG LDAP_WRITE_SUPPORT_VERSION="1.4.0" RUN sed -i 's/22,2,9,1/22,2,9,2/' ${BASE_DIR}/version.php RUN sed -i 's/22,2,9,1/22,2,9,3/' ${BASE_DIR}/version.php COPY custom_entrypoint.sh / RUN chmod +x /custom_entrypoint.sh RUN mkdir -p /var/www/skeleton/Documents && mkdir -p /var/www/skeleton/Images Loading
patches/015-email-mail-template.patch +192 −34 Original line number Diff line number Diff line Loading @@ -32,20 +32,114 @@ /** --- ./apps/dav/lib/CalDAV/Schedule/IMipPlugin.php 2022-07-04 12:41:03.228533600 +0530 +++ ./apps/dav/lib/CalDAV/Schedule/IMipPlugin-new.php 2022-07-04 14:42:56.208533600 +0530 @@ -419,23 +419,33 @@ --- apps/dav/lib/CalDAV/Schedule/IMipPlugin.php 2022-07-27 13:21:50.294113800 +0530 +++ apps/dav/lib/CalDAV/Schedule/IMipPlugin-New.php 2022-08-16 16:29:16.531866700 +0530 @@ -151,15 +151,6 @@ */ public function schedule(Message $iTipMessage) { - // Not sending any emails if the system considers the update - // insignificant. - if (!$iTipMessage->significantChange) { - if (!$iTipMessage->scheduleStatus) { - $iTipMessage->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email'; - } - return; - } - $summary = $iTipMessage->message->VEVENT->SUMMARY; if (parse_url($iTipMessage->sender, PHP_URL_SCHEME) !== 'mailto') { @@ -252,9 +243,25 @@ $summary = ((string) $summary !== '') ? (string) $summary : $l10n->t('Untitled event'); - $this->addSubjectAndHeading($template, $l10n, $method, $summary); + if( count($vevent)>1){ + $this->addSubjectAndHeadingUpdated($template, $l10n, $method, $summary); + + }else{ + $this->addSubjectAndHeading($template, $l10n, $method, $summary); + } + if ($method === self::METHOD_CANCEL) { + $template->addHeadingBanner('#FFC2B9','#7D1000',$l10n->t('The invitation has been cancelled')); + } + if ($method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vevent)>1) { + $template->addHeadingBanner('#EFFFDB','#293618',$l10n->t('This recurring event has been updated, please review the information below:')); + } + $sequence = $vevent->SEQUENCE->getValue(); + if ($method !== self::METHOD_CANCEL && $method !== self::METHOD_REPLY && count($vevent)==1 && ($sequence > 2)) { + $template->addHeadingBanner('#EFFFDB','#293618',$l10n->t('This event has been updated, please review the information below:')); + } $this->addBulletList($template, $l10n, $vevent); + // Only add response buttons to invitation requests: Fix Issue #11230 if (($method == self::METHOD_REQUEST) && $this->getAttendeeRsvpOrReqForParticipant($attendee)) { @@ -414,7 +421,7 @@ return false; } - /** + /** * @param IL10N $l10n * @param VEvent $vevent */ private function generateWhenString(IL10N $l10n, VEvent $vevent) { - $dtstart = $vevent->DTSTART; - if (isset($vevent->DTEND)) { - $dtend = $vevent->DTEND; - } elseif (isset($vevent->DURATION)) { - $isFloating = $vevent->DTSTART->isFloating(); - $dtend = clone $vevent->DTSTART; @@ -525,38 +532,99 @@ private function addSubjectAndHeading(IEMailTemplate $template, IL10N $l10n, $method, $summary) { if ($method === self::METHOD_CANCEL) { - $template->setSubject('Canceled: ' . $summary); + //TRANSLATORS Subject for email, when an invitation is cancelled. Ex: "Cancelled: {{Event Name}}" + $template->setSubject($l10n->t('Cancelled: %1$s', [$summary])); $template->addHeading($l10n->t('Invitation canceled')); } elseif ($method === self::METHOD_REPLY) { - $template->setSubject('Re: ' . $summary); + // TRANSLATORS Subject for email, when an invitation is updated. Ex: "Re: {{Event Name}}" + $template->setSubject($l10n->t('Re: %1$s', [$summary])); $template->addHeading($l10n->t('Invitation updated')); } else { - $template->setSubject('Invitation: ' . $summary); + // TRANSLATORS Subject for email, when an invitation is sent. Ex: "Invitation: {{Event Name}}" + $template->setSubject($l10n->t('Invitation: %1$s', [$summary])); $template->addHeading($l10n->t('Invitation')); } } - + /** + * @param IEMailTemplate $template + * @param IL10N $l10n + * @param string $method + * @param string $summary + */ + private function addSubjectAndHeadingUpdated(IEMailTemplate $template, IL10N $l10n, + $method, $summary) { + if ($method === self::METHOD_CANCEL) { + //TRANSLATORS Subject for email, when an invitation is cancelled. Ex: "Cancelled: {{Event Name}}" + $template->setSubject($l10n->t('Cancelled: %1$s', [$summary])); + $template->addHeading($l10n->t('Invitation canceled')); + } elseif ($method === self::METHOD_REPLY) { + // TRANSLATORS Subject for email, when an invitation is updated. Ex: "Re: {{Event Name}}" + $template->setSubject($l10n->t('Re: %1$s', [$summary])); + $template->addHeading($l10n->t('Invitation updated')); + } else { + // TRANSLATORS Subject for email, when an invitation is sent. Ex: "Invitation: {{Event Name}}" + $template->setSubject($l10n->t('Invitation: %1$s', [$summary])); + $template->addHeading($l10n->t('Invitation Update')); + } + } /** * @param IEMailTemplate $template * @param IL10N $l10n * @param VEVENT $vevent */ private function addBulletList(IEMailTemplate $template, IL10N $l10n, $vevent) { - if ($vevent->SUMMARY) { - $template->addBodyListItem($vevent->SUMMARY, $l10n->t('Title:'), - $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); + $lastmodified=0; + $selectedEvent = $vevent; + $selectedEvent = $parentevent = $vevent; + foreach( $vevent as $currentevent){ + $dtstamp= $currentevent->{'LAST-MODIFIED'}; + $dtstampTime = strtotime($dtstamp); Loading @@ -54,30 +148,94 @@ + $selectedEvent = $currentevent; + } + } + $dtstart = $selectedEvent->DTSTART; + if (isset($selectedEvent->DTEND)) { + $dtend = $selectedEvent->DTEND; + } elseif (isset($selectedEvent->DURATION)) { + $isFloating = $selectedEvent->DTSTART->isFloating(); + $dtend = clone $selectedEvent->DTSTART; $endDateTime = $dtend->getDateTime(); - $endDateTime = $endDateTime->add(DateTimeParser::parse($vevent->DURATION->getValue())); + $endDateTime = $endDateTime->add(DateTimeParser::parse($selectedEvent->DURATION->getValue())); $dtend->setDateTime($endDateTime, $isFloating); - } elseif (!$vevent->DTSTART->hasTime()) { - $isFloating = $vevent->DTSTART->isFloating(); - $dtend = clone $vevent->DTSTART; + } elseif (!$selectedEvent->DTSTART->hasTime()) { + $isFloating = $selectedEvent->DTSTART->isFloating(); + $dtend = clone $selectedEvent->DTSTART; $endDateTime = $dtend->getDateTime(); $endDateTime = $endDateTime->modify('+1 day'); $dtend->setDateTime($endDateTime, $isFloating); } else { - $dtend = clone $vevent->DTSTART; + $dtend = clone $selectedEvent->DTSTART; + + + if ($selectedEvent->SUMMARY) { + + if(trim($selectedEvent->SUMMARY)==trim($parentevent->SUMMARY)){ + $template->addBodyListItem($selectedEvent->SUMMARY, $l10n->t('Title:'), + $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($selectedEvent->SUMMARY, $l10n->t('Updated Title:'), + $this->getAbsoluteImagePath('caldav/title.png'),'','',self::IMIP_INDENT); + } } - $meetingWhen = $this->generateWhenString($l10n, $vevent); + $meetingWhen = $this->generateWhenString($l10n, $selectedEvent); if ($meetingWhen) { - $template->addBodyListItem($meetingWhen, $l10n->t('Time:'), - $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + $selectedtimestart= substr(($selectedEvent->DTSTART), strpos(($selectedEvent->DTSTART), "T") + 1); + $parenttimestart= substr(($parentevent->DTSTART), strpos(($parentevent->DTSTART), "T") + 1); + $selectedtimeend= substr(($selectedEvent->DTEND), strpos(($selectedEvent->DTEND), "T") + 1); + $parenttimeend= substr(($parentevent->DTEND), strpos(($parentevent->DTEND), "T") + 1); + + if(trim($selectedtimestart)==trim($parenttimestart) && trim($selectedtimeend)==trim($parenttimeend)){ + $template->addBodyListItem($meetingWhen, $l10n->t('Time:'), + $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($meetingWhen, $l10n->t('Updated Time:'), + $this->getAbsoluteImagePath('caldav/time.png'),'','',self::IMIP_INDENT); + } + + } - if ($vevent->LOCATION) { - $template->addBodyListItem($vevent->LOCATION, $l10n->t('Location:'), - $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); + if ($selectedEvent->LOCATION) { + if(trim($selectedEvent->LOCATION)==trim($parentevent->LOCATION)){ + $template->addBodyListItem($selectedEvent->LOCATION, $l10n->t('Location:'), + $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($selectedEvent->LOCATION, $l10n->t('Updated Location:'), + $this->getAbsoluteImagePath('caldav/location.png'),'','',self::IMIP_INDENT); + } + + } - if ($vevent->URL) { - $url = $vevent->URL->getValue(); + if ($selectedEvent->URL) { + $url = $selectedEvent->URL->getValue(); $template->addBodyListItem(sprintf('<a href="%s">%s</a>', htmlspecialchars($url), htmlspecialchars($url)), @@ -565,12 +633,18 @@ $url,'',self::IMIP_INDENT); } - $this->addAttendees($template, $l10n, $vevent); + $this->addAttendees($template, $l10n, $selectedEvent); /* Put description last, like an email body, since it can be arbitrarily long */ - if ($vevent->DESCRIPTION) { - $template->addBodyListItem($vevent->DESCRIPTION->getValue(), $l10n->t('Description:'), - $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); + if ($selectedEvent->DESCRIPTION) { + if(trim($selectedEvent->DESCRIPTION)==trim($parentevent->DESCRIPTION)){ + $template->addBodyListItem($selectedEvent->DESCRIPTION->getValue(), $l10n->t('Description:'), + $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); + }else{ + $template->addBodyListItemModified($selectedEvent->DESCRIPTION, $l10n->t('Updated Description:'), + $this->getAbsoluteImagePath('caldav/description.png'),'','',self::IMIP_INDENT); + } + } } $isAllDay = $dtstart instanceof Property\ICalendar\Date; @@ -671,7 +745,6 @@ $l10n->t('Maybe'), $this->urlGenerator->getAbsoluteUrl('apps/calendar/invitation/tentative/'.$token) ); - } /** @@ -716,4 +789,4 @@ return $token; } -} +} \ No newline at end of file