mirror of https://github.com/nextcloud/calendar
251 lines
8.0 KiB
PHP
251 lines
8.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Calendar App
|
|
*
|
|
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
|
|
*
|
|
* @author Anna Larch <anna.larch@gmx.net>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
* License as published by the Free Software Foundation; either
|
|
* version 3 of the License, or any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
namespace OCA\Calendar\Service\Appointments;
|
|
|
|
use Exception;
|
|
use OC\URLGenerator;
|
|
use OCA\Calendar\Db\AppointmentConfig;
|
|
use OCA\Calendar\Db\Booking;
|
|
use OCA\Calendar\Exception\ServiceException;
|
|
use OCP\Defaults;
|
|
use OCP\IDateTimeFormatter;
|
|
use OCP\IL10N;
|
|
use OCP\IUserManager;
|
|
use OCP\L10N\IFactory;
|
|
use OCP\Mail\IEMailTemplate;
|
|
use OCP\Mail\IMailer;
|
|
use Psr\Log\LoggerInterface;
|
|
use function implode;
|
|
|
|
class MailService {
|
|
/** @var IUserManager */
|
|
private $userManager;
|
|
/** @var IMailer */
|
|
private $mailer;
|
|
/** @var IL10N */
|
|
private $l10n;
|
|
/** @var Defaults */
|
|
private $defaults;
|
|
/** @var LoggerInterface */
|
|
private $logger;
|
|
/** @var URLGenerator */
|
|
private $urlGenerator;
|
|
/** @var IDateTimeFormatter */
|
|
private $dateFormatter;
|
|
/** @var IFactory */
|
|
private $lFactory;
|
|
|
|
public function __construct(IMailer $mailer,
|
|
IUserManager $userManager,
|
|
IL10N $l10n,
|
|
Defaults $defaults,
|
|
LoggerInterface $logger,
|
|
URLGenerator $urlGenerator,
|
|
IDateTimeFormatter $dateFormatter,
|
|
IFactory $lFactory) {
|
|
$this->userManager = $userManager;
|
|
$this->mailer = $mailer;
|
|
$this->l10n = $l10n;
|
|
$this->defaults = $defaults;
|
|
$this->logger = $logger;
|
|
$this->urlGenerator = $urlGenerator;
|
|
$this->dateFormatter = $dateFormatter;
|
|
$this->lFactory = $lFactory;
|
|
}
|
|
|
|
/**
|
|
* @param Booking $booking
|
|
* @param AppointmentConfig $config
|
|
* @throws ServiceException
|
|
*/
|
|
public function sendConfirmationEmail(Booking $booking, AppointmentConfig $config): void {
|
|
$user = $this->userManager->get($config->getUserId());
|
|
|
|
if ($user === null) {
|
|
throw new ServiceException('Could not find organizer');
|
|
}
|
|
|
|
$fromEmail = $user->getEMailAddress();
|
|
$fromName = $user->getDisplayName();
|
|
|
|
|
|
$sys = $this->getSysEmail();
|
|
$message = $this->mailer->createMessage()
|
|
->setFrom([$sys => $fromName])
|
|
->setTo([$booking->getEmail() => $booking->getDisplayName()])
|
|
->setReplyTo([$fromEmail => $fromName]);
|
|
|
|
|
|
$template = $this->mailer->createEMailTemplate('calendar.confirmAppointment');
|
|
$template->addHeader();
|
|
|
|
//Subject
|
|
$subject = $this->l10n->t('Your appointment "%s" with %s needs confirmation', [$config->getName(), $user->getDisplayName()]);
|
|
$template->setSubject($subject);
|
|
|
|
// Heading
|
|
$summary = $this->l10n->t("Dear %s, please confirm your booking", [$booking->getDisplayName()]);
|
|
$template->addHeading($summary);
|
|
|
|
$template->addBodyListItem($user->getDisplayName(), 'Appointment with:');
|
|
if (!empty($config->getDescription())) {
|
|
$template->addBodyListItem($config->getDescription(), 'Description:');
|
|
}
|
|
|
|
// Create Booking overview
|
|
$this->addBulletList($template, $this->l10n, $booking, $config->getLocation());
|
|
|
|
$bookingUrl = $this->urlGenerator->linkToRouteAbsolute('calendar.booking.confirmBooking', ['token' => $booking->getToken()]);
|
|
$template->addBodyButton($this->l10n->t('Confirm'), $bookingUrl);
|
|
|
|
$bodyText = $this->l10n->t('This confirmation link expires in %s hours.', [(BookingService::EXPIRY / 3600)]);
|
|
$template->addBodyText($bodyText);
|
|
|
|
$bodyText = $this->l10n->t('If you wish to cancel the appointment after all, please contact your organizer by replying to this email or by visiting their profile page.');
|
|
$template->addBodyText($bodyText);
|
|
|
|
$template->addFooter();
|
|
|
|
$message->useTemplate($template);
|
|
|
|
|
|
try {
|
|
$failed = $this->mailer->send($message);
|
|
if (count($failed) > 0) {
|
|
$this->logger->warning('Mail delivery failed for some recipients.');
|
|
foreach ($failed as $fail) {
|
|
$this->logger->debug('Failed to deliver email to ' . $fail);
|
|
}
|
|
throw new ServiceException('Could not send mail for recipient(s) ' . implode(', ', $failed));
|
|
}
|
|
} catch (Exception $ex) {
|
|
$this->logger->error($ex->getMessage(), ['exception' => $ex]);
|
|
throw new ServiceException('Could not send mail: ' . $ex->getMessage(), $ex->getCode(), $ex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param Booking $booking
|
|
* @param AppointmentConfig $config
|
|
* @throws ServiceException
|
|
*/
|
|
public function sendBookingInformationEmail(Booking $booking, AppointmentConfig $config, string $calendar): void {
|
|
$user = $this->userManager->get($config->getUserId());
|
|
|
|
if ($user === null) {
|
|
throw new ServiceException('Could not find organizer');
|
|
}
|
|
|
|
$fromEmail = $user->getEMailAddress();
|
|
$fromName = $user->getDisplayName();
|
|
|
|
$sys = $this->getSysEmail();
|
|
$message = $this->mailer->createMessage()
|
|
->setFrom([$sys => $fromName])
|
|
->setTo([$booking->getEmail() => $booking->getDisplayName()])
|
|
->setReplyTo([$fromEmail => $fromName]);
|
|
|
|
|
|
$template = $this->mailer->createEMailTemplate('calendar.confirmAppointment');
|
|
$template->addHeader();
|
|
|
|
//Subject
|
|
$subject = $this->l10n->t('Your appointment "%s" with %s has been accepted', [$config->getName(), $user->getDisplayName()]);
|
|
$template->setSubject($subject);
|
|
|
|
// Heading
|
|
$summary = $this->l10n->t('Dear %s, your booking has been accepted.', [$booking->getDisplayName()]);
|
|
$template->addHeading($summary);
|
|
|
|
$template->addBodyListItem($user->getDisplayName(), 'Appointment with:');
|
|
if (!empty($config->getDescription())) {
|
|
$template->addBodyListItem($config->getDescription(), 'Description:');
|
|
}
|
|
|
|
// Create Booking overview
|
|
$this->addBulletList($template, $this->l10n, $booking, $config->getLocation());
|
|
|
|
$bodyText = $this->l10n->t('If you wish to cancel the appointment after all, please contact your organizer by replying to this email or by visiting their profile page.');
|
|
$template->addBodyText($bodyText);
|
|
|
|
$template->addFooter();
|
|
|
|
$attachment = $this->mailer->createAttachment($calendar, "appointment.ics", "text/calendar");
|
|
$message->attach($attachment);
|
|
$message->useTemplate($template);
|
|
|
|
|
|
try {
|
|
$failed = $this->mailer->send($message);
|
|
if (count($failed) > 0) {
|
|
$this->logger->warning('Mail delivery failed for some recipients.');
|
|
foreach ($failed as $fail) {
|
|
$this->logger->debug('Failed to deliver email to ' . $fail);
|
|
}
|
|
throw new ServiceException('Could not send mail for recipient(s) ' . implode(', ', $failed));
|
|
}
|
|
} catch (Exception $ex) {
|
|
$this->logger->error($ex->getMessage(), ['exception' => $ex]);
|
|
throw new ServiceException('Could not send mail: ' . $ex->getMessage(), $ex->getCode(), $ex);
|
|
}
|
|
}
|
|
|
|
private function addBulletList(IEMailTemplate $template,
|
|
IL10N $l10n,
|
|
Booking $booking,
|
|
?string $location = null):void {
|
|
$template->addBodyListItem($booking->getDisplayName(), $l10n->t('Appointment for:'));
|
|
|
|
$l = $this->lFactory->findGenericLanguage();
|
|
$relativeDateTime = $this->dateFormatter->formatDateTimeRelativeDay(
|
|
$booking->getStart(),
|
|
'long',
|
|
'short',
|
|
new \DateTimeZone($booking->getTimezone()),
|
|
$this->lFactory->get('calendar', $l)
|
|
);
|
|
|
|
$template->addBodyListItem($relativeDateTime, $l10n->t('Date:'));
|
|
|
|
if (!empty($location)) {
|
|
$template->addBodyListItem($location, $l10n->t('Where:'));
|
|
}
|
|
|
|
if (!empty($booking->getDescription())) {
|
|
$template->addBodyListItem($booking->getDescription(), $l10n->t('Your Comment:'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
private function getSysEmail(): string {
|
|
$instanceName = $this->defaults->getName();
|
|
return \OCP\Util::getDefaultEmailAddress('appointments-noreply');
|
|
}
|
|
}
|