Files
chill-bundles/packages/ChillZimbraBundle/src/Calendar/Connector/ZimbraConnector/CreateZimbraComponent.php

137 lines
5.3 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ZimbraBundle\Calendar\Connector\ZimbraConnector;
use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Entity\CalendarRange;
use Chill\CalendarBundle\Entity\Invite;
use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Templating\Entity\AddressRender;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
use Zimbra\Common\Enum\FreeBusyStatus;
use Zimbra\Common\Enum\InviteClass;
use Zimbra\Common\Enum\InviteStatus;
use Zimbra\Common\Enum\Transparency;
use Zimbra\Mail\Struct\InviteComponent;
/**
* Class responsible for creating Zimbra invite components based on calendar data.
*/
final readonly class CreateZimbraComponent
{
public function __construct(
private PersonRenderInterface $personRender,
private AddressRender $addressRender,
private DateConverter $dateConverter,
private TranslatorInterface $translator,
private Environment $twig,
) {}
/**
* Creates a Zimbra invite component from the provided calendar object.
*
* The method initializes a new InviteComponent object, sets its properties
* including name, free/busy status, status, classification, transparency,
* all-day and draft status, as well as start and end times. If the calendar
* contains a location, it also sets the location for the invite component.
*
* @param Calendar|CalendarRange|Invite $calendar a calendar object containing event data
*
* @return InviteComponent the configured Zimbra invite component
*/
public function createZimbraInviteComponentFromCalendar(Calendar|CalendarRange|Invite $calendar): InviteComponent
{
if ($calendar instanceof Calendar) {
$subject = '[Chill] '.
implode(
', ',
$calendar->getPersons()->map(fn (Person $p) => $this->personRender->renderString($p, ['addAge' => false]))->toArray()
);
$content = $this->twig->render('@ChillZimbra/ZimbraComponent/calendar_content.txt.twig', ['calendar' => $calendar]);
} elseif ($calendar instanceof Invite) {
$subject = '[Chill] '.
'('.$this->translator->trans('remote_calendar.calendar_invite_statement_in_calendar').') '.
implode(
', ',
$calendar->getCalendar()->getPersons()->map(fn (Person $p) => $this->personRender->renderString($p, ['addAge' => false]))->toArray()
);
$content = $this->twig->render('@ChillZimbra/ZimbraComponent/invitation_content.txt.twig', ['calendar' => $calendar->getCalendar()]);
} else {
// $calendar is an instanceof CalendarRange
$subject = $this->translator->trans('remote_calendar.calendar_range_title');
$content = '';
}
if ($calendar instanceof Invite) {
$startDate = $calendar->getCalendar()->getStartDate();
$endDate = $calendar->getCalendar()->getEndDate();
$location = $calendar->getCalendar()->getLocation();
$hasLocation = $calendar->getCalendar()->hasLocation();
$isPrivate = $calendar->getCalendar()->getAccompanyingPeriod()?->isConfidential() ?? false;
} elseif ($calendar instanceof Calendar) {
$startDate = $calendar->getStartDate();
$endDate = $calendar->getEndDate();
$location = $calendar->getLocation();
$hasLocation = $calendar->hasLocation();
$isPrivate = $calendar->getAccompanyingPeriod()?->isConfidential() ?? false;
} else {
// Calendar range case
$startDate = $calendar->getStartDate();
$endDate = $calendar->getEndDate();
$location = $calendar->getLocation();
$hasLocation = $calendar->hasLocation();
$isPrivate = false;
}
$comp = new InviteComponent();
$comp->setName($subject);
$comp->setDescription($content);
$comp->setFreeBusy(FreeBusyStatus::BUSY);
$comp->setStatus(InviteStatus::CONFIRMED);
$comp->setCalClass($isPrivate ? InviteClass::PRI : InviteClass::PUB);
$comp->setTransparency(Transparency::OPAQUE);
$comp->setIsAllDay(false);
$comp->setIsDraft(false);
$comp->setDtStart($this->dateConverter->phpToZimbraDateTime($startDate));
$comp->setDtEnd($this->dateConverter->phpToZimbraDateTime($endDate));
if ($hasLocation) {
$comp
->setLocation($this->createLocationString($location));
}
return $comp;
}
private function createLocationString(Location $location): string
{
$str = '';
if ('' !== ($loc = (string) $location->getName())) {
$str .= $loc;
}
if ($location->hasAddress()) {
if ('' !== $str) {
$str .= ', ';
}
$str .= $this->addressRender->renderString($location->getAddress(), ['separator' => ', ']);
}
return $str;
}
}