mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
send first calendar on ms graph
This commit is contained in:
parent
f962b7543f
commit
782436ee2e
@ -12,7 +12,6 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Entity;
|
namespace Chill\CalendarBundle\Entity;
|
||||||
|
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||||
@ -38,7 +37,7 @@ use function in_array;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Table(name="chill_calendar.calendar", indexes={@ORM\Index(name="idx_calendar_remote", columns={"remoteId"})}))
|
* @ORM\Table(name="chill_calendar.calendar", indexes={@ORM\Index(name="idx_calendar_remote", columns={"remoteId"})}))
|
||||||
* @ORM\Entity(repositoryClass=CalendarRepository::class)
|
* @ORM\Entity
|
||||||
*/
|
*/
|
||||||
class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
||||||
{
|
{
|
||||||
@ -54,6 +53,24 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
public const STATUS_VALID = 'valid';
|
public const STATUS_VALID = 'valid';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a list of invite which have been added during this session.
|
||||||
|
*
|
||||||
|
* @var array|Invite[]
|
||||||
|
*/
|
||||||
|
public array $newInvites = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a list of invite which have been removed during this session.
|
||||||
|
*
|
||||||
|
* @var array|Invite[]
|
||||||
|
*/
|
||||||
|
public array $oldInvites = [];
|
||||||
|
|
||||||
|
public ?CalendarRange $previousCalendarRange = null;
|
||||||
|
|
||||||
|
public ?User $previousMainUser = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod")
|
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod")
|
||||||
* @Serializer\Groups({"read"})
|
* @Serializer\Groups({"read"})
|
||||||
@ -118,7 +135,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
|
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
|
||||||
* @Serializer\Groups({"calendar:read", "read"})
|
* @Serializer\Groups({"calendar:read", "read"})
|
||||||
*/
|
*/
|
||||||
private ?User $mainUser;
|
private ?User $mainUser = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(
|
* @ORM\ManyToMany(
|
||||||
@ -162,6 +179,9 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
$this->invites = new ArrayCollection();
|
$this->invites = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal Use {@link (Calendar::addUser)} instead
|
||||||
|
*/
|
||||||
public function addInvite(Invite $invite): self
|
public function addInvite(Invite $invite): self
|
||||||
{
|
{
|
||||||
if ($invite->getCalendar() instanceof Calendar && $invite->getCalendar() !== $this) {
|
if ($invite->getCalendar() instanceof Calendar && $invite->getCalendar() !== $this) {
|
||||||
@ -169,6 +189,8 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->invites[] = $invite;
|
$this->invites[] = $invite;
|
||||||
|
$this->newInvites[] = $invite;
|
||||||
|
|
||||||
$invite->setCalendar($this);
|
$invite->setCalendar($this);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -338,6 +360,11 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this->getInvites()->map(static function (Invite $i) { return $i->getUser(); });
|
return $this->getInvites()->map(static function (Invite $i) { return $i->getUser(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasCalendarRange(): bool
|
||||||
|
{
|
||||||
|
return null !== $this->calendarRange;
|
||||||
|
}
|
||||||
|
|
||||||
public static function loadValidatorMetadata(ClassMetadata $metadata): void
|
public static function loadValidatorMetadata(ClassMetadata $metadata): void
|
||||||
{
|
{
|
||||||
$metadata->addPropertyConstraint('startDate', new NotBlank());
|
$metadata->addPropertyConstraint('startDate', new NotBlank());
|
||||||
@ -352,10 +379,14 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal Use {@link (Calendar::removeUser)} instead
|
||||||
|
*/
|
||||||
public function removeInvite(Invite $invite): self
|
public function removeInvite(Invite $invite): self
|
||||||
{
|
{
|
||||||
if ($this->invites->removeElement($invite)) {
|
if ($this->invites->removeElement($invite)) {
|
||||||
$invite->setCalendar(null);
|
$invite->setCalendar(null);
|
||||||
|
$this->oldInvites[] = $invite;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -405,8 +436,15 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
public function setCalendarRange(?CalendarRange $calendarRange): self
|
public function setCalendarRange(?CalendarRange $calendarRange): self
|
||||||
{
|
{
|
||||||
$this->calendarRange = $calendarRange;
|
if ($this->calendarRange !== $calendarRange) {
|
||||||
|
$this->previousCalendarRange = $this->calendarRange;
|
||||||
|
|
||||||
|
if (null !== $this->previousCalendarRange) {
|
||||||
|
$this->previousCalendarRange->setCalendar(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->calendarRange = $calendarRange;
|
||||||
$this->calendarRange->setCalendar($this);
|
$this->calendarRange->setCalendar($this);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -442,6 +480,10 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
public function setMainUser(?User $mainUser): self
|
public function setMainUser(?User $mainUser): self
|
||||||
{
|
{
|
||||||
|
if ($this->mainUser !== $mainUser) {
|
||||||
|
$this->previousMainUser = $this->mainUser;
|
||||||
|
}
|
||||||
|
|
||||||
$this->mainUser = $mainUser;
|
$this->mainUser = $mainUser;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -93,7 +93,7 @@ class CalendarRange implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
/**
|
/**
|
||||||
* @internal use {@link (Calendar::setCalendarRange)} instead
|
* @internal use {@link (Calendar::setCalendarRange)} instead
|
||||||
*/
|
*/
|
||||||
public function setCalendar(Calendar $calendar): void
|
public function setCalendar(?Calendar $calendar): void
|
||||||
{
|
{
|
||||||
$this->calendar = $calendar;
|
$this->calendar = $calendar;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\CalendarBundle\Entity;
|
namespace Chill\CalendarBundle\Entity;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Repository\InviteRepository;
|
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||||
@ -23,7 +22,7 @@ use Symfony\Component\Serializer\Annotation as Serializer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Table(name="chill_calendar.invite")
|
* @ORM\Table(name="chill_calendar.invite")
|
||||||
* @ORM\Entity(repositoryClass=InviteRepository::class)
|
* @ORM\Entity
|
||||||
*/
|
*/
|
||||||
class Invite implements TrackUpdateInterface, TrackCreationInterface
|
class Invite implements TrackUpdateInterface, TrackCreationInterface
|
||||||
{
|
{
|
||||||
|
@ -11,8 +11,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\CalendarBundle\Messenger\Handler;
|
namespace Chill\CalendarBundle\Messenger\Handler;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Invite;
|
||||||
use Chill\CalendarBundle\Messenger\Message\CalendarMessage;
|
use Chill\CalendarBundle\Messenger\Message\CalendarMessage;
|
||||||
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
|
||||||
|
use Chill\CalendarBundle\Repository\CalendarRangeRepository;
|
||||||
|
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||||
|
use Chill\CalendarBundle\Repository\InviteRepository;
|
||||||
|
use Chill\MainBundle\Repository\UserRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
||||||
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||||
@ -24,9 +29,63 @@ class CalendarToRemoteHandler implements MessageHandlerInterface
|
|||||||
{
|
{
|
||||||
private RemoteCalendarConnectorInterface $calendarConnector;
|
private RemoteCalendarConnectorInterface $calendarConnector;
|
||||||
|
|
||||||
private EntityManagerInterface $em;
|
private CalendarRangeRepository $calendarRangeRepository;
|
||||||
|
|
||||||
|
private CalendarRepository $calendarRepository;
|
||||||
|
|
||||||
|
private EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
private InviteRepository $inviteRepository;
|
||||||
|
|
||||||
|
private UserRepository $userRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
CalendarRangeRepository $calendarRangeRepository,
|
||||||
|
CalendarRepository $calendarRepository,
|
||||||
|
EntityManagerInterface $entityManager,
|
||||||
|
InviteRepository $inviteRepository,
|
||||||
|
RemoteCalendarConnectorInterface $calendarConnector,
|
||||||
|
UserRepository $userRepository
|
||||||
|
) {
|
||||||
|
$this->calendarConnector = $calendarConnector;
|
||||||
|
$this->calendarRepository = $calendarRepository;
|
||||||
|
$this->calendarRangeRepository = $calendarRangeRepository;
|
||||||
|
$this->entityManager = $entityManager;
|
||||||
|
$this->userRepository = $userRepository;
|
||||||
|
$this->inviteRepository = $inviteRepository;
|
||||||
|
}
|
||||||
|
|
||||||
public function __invoke(CalendarMessage $calendarMessage)
|
public function __invoke(CalendarMessage $calendarMessage)
|
||||||
{
|
{
|
||||||
|
$calendar = $this->calendarRepository->find($calendarMessage->getCalendarId());
|
||||||
|
|
||||||
|
if (null !== $calendarMessage->getPreviousCalendarRangeId()) {
|
||||||
|
$previousCalendarRange = $this->calendarRangeRepository
|
||||||
|
->find($calendarMessage->getPreviousCalendarRangeId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $calendarMessage->getPreviousMainUserId()) {
|
||||||
|
$previousMainUser = $this->userRepository
|
||||||
|
->find($calendarMessage->getPreviousMainUserId());
|
||||||
|
}
|
||||||
|
$newInvites = array_filter(
|
||||||
|
array_map(
|
||||||
|
function ($id) { return $this->inviteRepository->find($id); },
|
||||||
|
$calendarMessage->getNewInvitesIds(),
|
||||||
|
),
|
||||||
|
static function (?Invite $invite) { return null !== $invite; }
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->calendarConnector->syncCalendar(
|
||||||
|
$calendar,
|
||||||
|
$calendarMessage->getAction(),
|
||||||
|
$previousCalendarRange ?? null,
|
||||||
|
$previousMainUser ?? null,
|
||||||
|
$calendarMessage->getOldInvites(),
|
||||||
|
$newInvites
|
||||||
|
);
|
||||||
|
|
||||||
|
$calendar->preventEnqueueChanges = true;
|
||||||
|
$this->entityManager->flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Messenger\Message;
|
namespace Chill\CalendarBundle\Messenger\Message;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Entity\Invite;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
|
|
||||||
class CalendarMessage
|
class CalendarMessage
|
||||||
@ -26,11 +27,38 @@ class CalendarMessage
|
|||||||
|
|
||||||
private int $calendarId;
|
private int $calendarId;
|
||||||
|
|
||||||
public function __construct(Calendar $calendar, string $action, User $byUser)
|
private array $newInvitesIds = [];
|
||||||
{
|
|
||||||
|
/**
|
||||||
|
* @var array<array{inviteId: int, userId: int, userEmail: int, userLabel: string}>
|
||||||
|
*/
|
||||||
|
private array $oldInvites = [];
|
||||||
|
|
||||||
|
private ?int $previousCalendarRangeId = null;
|
||||||
|
|
||||||
|
private ?int $previousMainUserId = null;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
Calendar $calendar,
|
||||||
|
string $action,
|
||||||
|
User $byUser
|
||||||
|
) {
|
||||||
$this->calendarId = $calendar->getId();
|
$this->calendarId = $calendar->getId();
|
||||||
$this->byUserId = $byUser->getId();
|
$this->byUserId = $byUser->getId();
|
||||||
$this->action = $action;
|
$this->action = $action;
|
||||||
|
$this->previousCalendarRangeId = null !== $calendar->previousCalendarRange ?
|
||||||
|
$calendar->previousCalendarRange->getId() : null;
|
||||||
|
$this->previousMainUserId = null !== $calendar->previousMainUser ?
|
||||||
|
$calendar->previousMainUser->getId() : null;
|
||||||
|
$this->newInvitesIds = array_map(static fn (Invite $i) => $i->getId(), $calendar->newInvites);
|
||||||
|
$this->oldInvites = array_map(static function (Invite $i) {
|
||||||
|
return [
|
||||||
|
'inviteId' => $i->getId(),
|
||||||
|
'userId' => $i->getUser()->getId(),
|
||||||
|
'userEmail' => $i->getUser()->getEmail(),
|
||||||
|
'userLabel' => $i->getUser()->getLabel(),
|
||||||
|
];
|
||||||
|
}, $calendar->oldInvites);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAction(): string
|
public function getAction(): string
|
||||||
@ -47,4 +75,30 @@ class CalendarMessage
|
|||||||
{
|
{
|
||||||
return $this->calendarId;
|
return $this->calendarId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|int[]|null[]
|
||||||
|
*/
|
||||||
|
public function getNewInvitesIds(): array
|
||||||
|
{
|
||||||
|
return $this->newInvitesIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<array{inviteId: int, userId: int, userEmail: int, userLabel: string}>
|
||||||
|
*/
|
||||||
|
public function getOldInvites(): array
|
||||||
|
{
|
||||||
|
return $this->oldInvites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviousCalendarRangeId(): ?int
|
||||||
|
{
|
||||||
|
return $this->previousCalendarRangeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviousMainUserId(): ?int
|
||||||
|
{
|
||||||
|
return $this->previousMainUserId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph;
|
namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Entity\CalendarRange;
|
use Chill\CalendarBundle\Entity\CalendarRange;
|
||||||
|
use Chill\CalendarBundle\Entity\Invite;
|
||||||
use Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent;
|
use Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use DateTimeZone;
|
use DateTimeZone;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
@ -29,13 +33,16 @@ class RemoteEventConverter
|
|||||||
|
|
||||||
private DateTimeZone $defaultDateTimeZone;
|
private DateTimeZone $defaultDateTimeZone;
|
||||||
|
|
||||||
|
private PersonRenderInterface $personRender;
|
||||||
|
|
||||||
private DateTimeZone $remoteDateTimeZone;
|
private DateTimeZone $remoteDateTimeZone;
|
||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator)
|
public function __construct(PersonRenderInterface $personRender, TranslatorInterface $translator)
|
||||||
{
|
{
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->personRender = $personRender;
|
||||||
$this->defaultDateTimeZone = (new DateTimeImmutable())->getTimezone();
|
$this->defaultDateTimeZone = (new DateTimeImmutable())->getTimezone();
|
||||||
$this->remoteDateTimeZone = self::getRemoteTimeZone();
|
$this->remoteDateTimeZone = self::getRemoteTimeZone();
|
||||||
}
|
}
|
||||||
@ -71,6 +78,42 @@ class RemoteEventConverter
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function calendarToEvent(Calendar $calendar): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'subject' => '[Chill] ' .
|
||||||
|
implode(
|
||||||
|
', ',
|
||||||
|
$calendar->getPersons()->map(function (Person $p) {
|
||||||
|
return $this->personRender->renderString($p, []);
|
||||||
|
})->toArray()
|
||||||
|
),
|
||||||
|
'start' => [
|
||||||
|
'dateTime' => $calendar->getStartDate()->setTimezone($this->remoteDateTimeZone)
|
||||||
|
->format(self::REMOTE_DATE_FORMAT),
|
||||||
|
'timeZone' => 'UTC',
|
||||||
|
],
|
||||||
|
'end' => [
|
||||||
|
'dateTime' => $calendar->getEndDate()->setTimezone($this->remoteDateTimeZone)
|
||||||
|
->format(self::REMOTE_DATE_FORMAT),
|
||||||
|
'timeZone' => 'UTC',
|
||||||
|
],
|
||||||
|
'allowNewTimeProposals' => false,
|
||||||
|
'attendees' => $calendar->getInvites()->map(
|
||||||
|
static function (Invite $i) {
|
||||||
|
return [
|
||||||
|
'emailAddress' => [
|
||||||
|
'address' => $i->getUser()->getEmail(),
|
||||||
|
'name' => $i->getUser()->getLabel(),
|
||||||
|
],
|
||||||
|
'type' => 'Required',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)->toArray(),
|
||||||
|
'transactionId' => 'calendar_' . $calendar->getId(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function convertAvailabilityToRemoteEvent(array $event): RemoteEvent
|
public function convertAvailabilityToRemoteEvent(array $event): RemoteEvent
|
||||||
{
|
{
|
||||||
$startDate =
|
$startDate =
|
||||||
|
@ -21,6 +21,7 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter;
|
|||||||
use Chill\CalendarBundle\Repository\CalendarRangeRepository;
|
use Chill\CalendarBundle\Repository\CalendarRangeRepository;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
use Exception;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
@ -137,9 +138,45 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
$this->removeEvent($remoteId, $user);
|
$this->removeEvent($remoteId, $user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncCalendar(Calendar $calendar, string $action): void
|
public function syncCalendar(Calendar $calendar, string $action, ?CalendarRange $previousCalendarRange, ?User $previousMainUser, ?array $oldInvites, ?array $newInvites): void
|
||||||
{
|
{
|
||||||
// TODO: Implement syncCalendar() method.
|
/*
|
||||||
|
* cases to support:
|
||||||
|
*
|
||||||
|
* * a calendar range is created:
|
||||||
|
* * create on remote
|
||||||
|
* * if calendar range is associated: remove the range
|
||||||
|
* * a Calendar change the CalendarRange:
|
||||||
|
* * re-create the previous calendar range;
|
||||||
|
* * remove the current calendar range
|
||||||
|
* * a calendar change the mainUser
|
||||||
|
* * cancel the calendar in the previous mainUser
|
||||||
|
* * recreate the previous calendar range in the previousMainUser, if any
|
||||||
|
* * delete the current calendar range in the current mainUser, if any
|
||||||
|
* * create the calendar in the current mainUser
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!$calendar->hasRemoteId()) {
|
||||||
|
$this->createCalendarOnRemote($calendar);
|
||||||
|
} else {
|
||||||
|
if (null !== $previousMainUser) {
|
||||||
|
// cancel event in previousMainUserCalendar
|
||||||
|
// CREATE event in currentMainUser
|
||||||
|
}
|
||||||
|
// PATCH event in currentMainUer
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($calendar->hasCalendarRange() && $calendar->getCalendarRange()->hasRemoteId()) {
|
||||||
|
$this->removeEvent(
|
||||||
|
$calendar->getCalendarRange()->getRemoteId(),
|
||||||
|
$calendar->getCalendarRange()->getUser()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $previousCalendarRange) {
|
||||||
|
// create previousCalendarRange
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncCalendarRange(CalendarRange $calendarRange): void
|
public function syncCalendarRange(CalendarRange $calendarRange): void
|
||||||
@ -151,6 +188,72 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createCalendarOnRemote(Calendar $calendar): void
|
||||||
|
{
|
||||||
|
$eventData = $this->remoteEventConverter->calendarToEvent($calendar);
|
||||||
|
|
||||||
|
[
|
||||||
|
'id' => $id,
|
||||||
|
'lastModifiedDateTime' => $lastModified,
|
||||||
|
'changeKey' => $changeKey
|
||||||
|
] = $this->createOnRemote($eventData, $calendar->getMainUser(), 'calendar_' . $calendar->getId());
|
||||||
|
|
||||||
|
if (null === $id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$calendar
|
||||||
|
->setRemoteId($id)
|
||||||
|
->addRemoteAttributes([
|
||||||
|
'lastModifiedDateTime' => $lastModified,
|
||||||
|
'changeKey' => $changeKey,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $identifier an identifier for logging in case of something does not work
|
||||||
|
*
|
||||||
|
* @return array{?id: string, ?lastModifiedDateTime: int, ?changeKey: string}
|
||||||
|
*/
|
||||||
|
private function createOnRemote(array $eventData, User $user, string $identifier): array
|
||||||
|
{
|
||||||
|
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||||
|
|
||||||
|
if (null === $userId) {
|
||||||
|
$this->logger->warning('user does not have userId nor calendarId', [
|
||||||
|
'user_id' => $user->getId(),
|
||||||
|
'calendar_identifier' => $identifier,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
dump($eventData);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$event = $this->machineHttpClient->request(
|
||||||
|
'POST',
|
||||||
|
'users/' . $userId . '/calendar/events',
|
||||||
|
[
|
||||||
|
'json' => $eventData,
|
||||||
|
]
|
||||||
|
)->toArray();
|
||||||
|
} catch (ClientExceptionInterface $e) {
|
||||||
|
$this->logger->warning('could not save calendar range to remote', [
|
||||||
|
'exception' => $e->getTraceAsString(),
|
||||||
|
'content' => $e->getResponse()->getContent(),
|
||||||
|
'calendar_identifier' => $identifier,
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $event['id'],
|
||||||
|
'lastModifiedDateTime' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
|
||||||
|
'changeKey' => $event['changeKey'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private function createRemoteCalendarRange(CalendarRange $calendarRange): void
|
private function createRemoteCalendarRange(CalendarRange $calendarRange): void
|
||||||
{
|
{
|
||||||
$userId = $this->mapCalendarToUser->getUserId($calendarRange->getUser());
|
$userId = $this->mapCalendarToUser->getUserId($calendarRange->getUser());
|
||||||
@ -191,6 +294,31 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getOnRemote(User $user, string $remoteId): array
|
||||||
|
{
|
||||||
|
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||||
|
|
||||||
|
if (null === $userId) {
|
||||||
|
throw new Exception('no remote calendar for this user', [
|
||||||
|
'user' => $user->getId(),
|
||||||
|
'remoteId' => $remoteId,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->machineHttpClient->request(
|
||||||
|
'GET',
|
||||||
|
'users/' . $userId . '/calendar/events/' . $remoteId
|
||||||
|
)->toArray();
|
||||||
|
} catch (ClientExceptionInterface $e) {
|
||||||
|
$this->logger->warning('Could not get event from calendar', [
|
||||||
|
'remoteId' => $remoteId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function getScheduleTimesForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): array
|
private function getScheduleTimesForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): array
|
||||||
{
|
{
|
||||||
$userId = $this->mapCalendarToUser->getUserId($user);
|
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||||
@ -236,6 +364,48 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $identifier an identifier for logging in case of something does not work
|
||||||
|
*
|
||||||
|
* @return array{?id: string, ?lastModifiedDateTime: int, ?changeKey: string}
|
||||||
|
*/
|
||||||
|
private function patchOnRemote(string $remoteId, array $eventData, User $user, string $identifier): array
|
||||||
|
{
|
||||||
|
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||||
|
|
||||||
|
if (null === $userId) {
|
||||||
|
$this->logger->warning('user does not have userId nor calendarId', [
|
||||||
|
'user_id' => $user->getId(),
|
||||||
|
'calendar_identifier' => $identifier,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$event = $this->machineHttpClient->request(
|
||||||
|
'PATCH',
|
||||||
|
'users/' . $userId . '/calendar/events/' . $remoteId,
|
||||||
|
[
|
||||||
|
'json' => $eventData,
|
||||||
|
]
|
||||||
|
)->toArray();
|
||||||
|
} catch (ClientExceptionInterface $e) {
|
||||||
|
$this->logger->warning('could not update calendar range to remote', [
|
||||||
|
'exception' => $e->getTraceAsString(),
|
||||||
|
'calendarRangeId' => $identifier,
|
||||||
|
]);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $event['id'],
|
||||||
|
'lastModifiedDateTime' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
|
||||||
|
'changeKey' => $event['changeKey'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private function removeEvent($remoteId, User $user): void
|
private function removeEvent($remoteId, User $user): void
|
||||||
{
|
{
|
||||||
$userId = $this->mapCalendarToUser->getUserId($user);
|
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||||
|
@ -39,7 +39,7 @@ class NullRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncCalendar(Calendar $calendar, string $action): void
|
public function syncCalendar(Calendar $calendar, string $action, ?CalendarRange $previousCalendarRange, ?User $previousMainUser, ?array $oldInvites, ?array $newInvites): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,10 @@ interface RemoteCalendarConnectorInterface
|
|||||||
|
|
||||||
public function removeCalendarRange(string $remoteId, array $remoteAttributes, User $user): void;
|
public function removeCalendarRange(string $remoteId, array $remoteAttributes, User $user): void;
|
||||||
|
|
||||||
public function syncCalendar(Calendar $calendar, string $action): void;
|
/**
|
||||||
|
* @param array<array{inviteId: int, userId: int, userEmail: int, userLabel: string}> $oldInvites
|
||||||
|
*/
|
||||||
|
public function syncCalendar(Calendar $calendar, string $action, ?CalendarRange $previousCalendarRange, ?User $previousMainUser, ?array $oldInvites, ?array $newInvites): void;
|
||||||
|
|
||||||
public function syncCalendarRange(CalendarRange $calendarRange): void;
|
public function syncCalendarRange(CalendarRange $calendarRange): void;
|
||||||
}
|
}
|
||||||
|
@ -150,13 +150,15 @@ class CalendarRangeRepository implements ObjectRepository
|
|||||||
{
|
{
|
||||||
$qb = $this->repository->createQueryBuilder('cr');
|
$qb = $this->repository->createQueryBuilder('cr');
|
||||||
|
|
||||||
|
$qb->leftJoin('cr.calendar', 'calendar');
|
||||||
|
|
||||||
return $qb
|
return $qb
|
||||||
->where(
|
->where(
|
||||||
$qb->expr()->andX(
|
$qb->expr()->andX(
|
||||||
$qb->expr()->eq('cr.user', ':user'),
|
$qb->expr()->eq('cr.user', ':user'),
|
||||||
$qb->expr()->gte('cr.startDate', ':startDate'),
|
$qb->expr()->gte('cr.startDate', ':startDate'),
|
||||||
$qb->expr()->lte('cr.endDate', ':endDate'),
|
$qb->expr()->lte('cr.endDate', ':endDate'),
|
||||||
$qb->expr()->eq(0, 'SIZE(cr.calendars)')
|
$qb->expr()->isNull('calendar')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->setParameters([
|
->setParameters([
|
||||||
|
@ -12,52 +12,68 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Repository;
|
namespace Chill\CalendarBundle\Repository;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
/**
|
class CalendarRepository implements ObjectRepository
|
||||||
* @method Calendar|null find($id, $lockMode = null, $lockVersion = null)
|
|
||||||
* @method Calendar|null findOneBy(array $criteria, array $orderBy = null)
|
|
||||||
* @method Calendar[] findAll()
|
|
||||||
* @method Calendar[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
|
||||||
*/
|
|
||||||
class CalendarRepository extends ServiceEntityRepository
|
|
||||||
{
|
{
|
||||||
// private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
public function __construct(EntityManagerInterface $entityManager)
|
||||||
{
|
{
|
||||||
parent::__construct($registry, Calendar::class);
|
$this->repository = $entityManager->getRepository(Calendar::class);
|
||||||
// $this->repository = $entityManager->getRepository(AccompanyingPeriodWork::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
public function countByAccompanyingPeriod(AccompanyingPeriod $period): int
|
||||||
// * @return Calendar[] Returns an array of Calendar objects
|
|
||||||
// */
|
|
||||||
/*
|
|
||||||
public function findByExampleField($value)
|
|
||||||
{
|
{
|
||||||
return $this->createQueryBuilder('c')
|
return $this->repository->count(['accompanyingPeriod' => $period]);
|
||||||
->andWhere('c.exampleField = :val')
|
|
||||||
->setParameter('val', $value)
|
|
||||||
->orderBy('c.id', 'ASC')
|
|
||||||
->setMaxResults(10)
|
|
||||||
->getQuery()
|
|
||||||
->getResult()
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function find($id): ?Calendar
|
||||||
|
{
|
||||||
|
return $this->repository->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Calendar[]
|
||||||
*/
|
*/
|
||||||
|
public function findAll(): array
|
||||||
/*
|
|
||||||
public function findOneBySomeField($value): ?Calendar
|
|
||||||
{
|
{
|
||||||
return $this->createQueryBuilder('c')
|
return $this->repository->findAll();
|
||||||
->andWhere('c.exampleField = :val')
|
|
||||||
->setParameter('val', $value)
|
|
||||||
->getQuery()
|
|
||||||
->getOneOrNullResult()
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Calendar[]
|
||||||
*/
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
|
||||||
|
{
|
||||||
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Calendar[]
|
||||||
|
*/
|
||||||
|
public function findByAccompanyingPeriod(AccompanyingPeriod $period, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
|
||||||
|
{
|
||||||
|
return $this->findBy(
|
||||||
|
[
|
||||||
|
'accompanyingPeriod' => $period,
|
||||||
|
],
|
||||||
|
$orderBy,
|
||||||
|
$limit,
|
||||||
|
$orderBy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?Calendar
|
||||||
|
{
|
||||||
|
return $this->repository->findOneBy($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClassName()
|
||||||
|
{
|
||||||
|
return Calendar::class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,48 +12,47 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Repository;
|
namespace Chill\CalendarBundle\Repository;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Invite;
|
use Chill\CalendarBundle\Entity\Invite;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
/**
|
class InviteRepository implements ObjectRepository
|
||||||
* @method Invite|null find($id, $lockMode = null, $lockVersion = null)
|
|
||||||
* @method Invite|null findOneBy(array $criteria, array $orderBy = null)
|
|
||||||
* @method Invite[] findAll()
|
|
||||||
* @method Invite[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
|
||||||
*/
|
|
||||||
class InviteRepository extends ServiceEntityRepository
|
|
||||||
{
|
{
|
||||||
public function __construct(ManagerRegistry $registry)
|
private EntityRepository $entityRepository;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
parent::__construct($registry, Invite::class);
|
$this->entityRepository = $em->getRepository(Invite::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
public function find($id): ?Invite
|
||||||
// * @return Invite[] Returns an array of Invite objects
|
|
||||||
// */
|
|
||||||
/*
|
|
||||||
public function findByExampleField($value)
|
|
||||||
{
|
{
|
||||||
return $this->createQueryBuilder('i')
|
return $this->entityRepository->find($id);
|
||||||
->andWhere('i.exampleField = :val')
|
|
||||||
->setParameter('val', $value)
|
|
||||||
->orderBy('i.id', 'ASC')
|
|
||||||
->setMaxResults(10)
|
|
||||||
->getQuery()
|
|
||||||
->getResult()
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
public function findOneBySomeField($value): ?Invite
|
* @return array|Invite[]
|
||||||
{
|
|
||||||
return $this->createQueryBuilder('i')
|
|
||||||
->andWhere('i.exampleField = :val')
|
|
||||||
->setParameter('val', $value)
|
|
||||||
->getQuery()
|
|
||||||
->getOneOrNullResult()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
public function findAll(): array
|
||||||
|
{
|
||||||
|
return $this->entityRepository->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|Invite[]
|
||||||
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null)
|
||||||
|
{
|
||||||
|
return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findOneBy(array $criteria): ?Invite
|
||||||
|
{
|
||||||
|
return $this->entityRepository->findOneBy($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClassName(): string
|
||||||
|
{
|
||||||
|
return Invite::class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,18 +172,13 @@ export default {
|
|||||||
},
|
},
|
||||||
setMainUser({commit, dispatch, state}, mainUser) {
|
setMainUser({commit, dispatch, state}, mainUser) {
|
||||||
console.log('setMainUser', mainUser);
|
console.log('setMainUser', mainUser);
|
||||||
if (state.activity.mainUser.id !== mainUser.id) {
|
|
||||||
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
|
|
||||||
mainUserInput.value = Number(mainUser.id);
|
|
||||||
|
|
||||||
if (state.activity.calendarRange !== null || state.activity.startDate !== null || state.acdtivity.endDate !== null) {
|
let mainUserInput = document.getElementById("chill_activitybundle_activity_mainUser");
|
||||||
dispatch('associateCalendarToRange', { range: null });
|
mainUserInput.value = Number(mainUser.id);
|
||||||
}
|
|
||||||
|
|
||||||
|
return dispatch('associateCalendarToRange', { range: null }).then(() => {
|
||||||
commit('setMainUser', mainUser);
|
commit('setMainUser', mainUser);
|
||||||
}
|
});
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Location
|
// Location
|
||||||
|
Loading…
x
Reference in New Issue
Block a user