suivi/src/Command/CaldavSyncCommand.php

120 lines
3.5 KiB
PHP

<?php
namespace App\Command;
use App\Entity\Project;
use App\Repository\ProjectRepositoryQuery;
use App\Repository\SpeakerRepositoryQuery;
use App\Security\OpenSSL;
use App\Webdav\CaldavClient;
use App\Webdav\Event as CalEvent;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use App\Core\Manager\EntityManager;
use App\Repository\EventRepositoryQuery;
use App\Factory\EventFactory;
use App\Entity\Speaker;
#[AsCommand(
name: 'caldav:sync',
description: 'Sync caldav events',
)]
class CaldavSyncCommand extends Command
{
protected SpeakerRepositoryQuery $speakerQuery;
protected ProjectRepositoryQuery $projectQuery;
protected EventRepositoryQuery $eventQuery;
protected EventFactory $eventFactory;
protected OpenSSL $openSSL;
public function __construct(
SpeakerRepositoryQuery $speakerQuery,
ProjectRepositoryQuery $projectQuery,
EventRepositoryQuery $eventQuery,
EventFactory $eventFactory,
EntityManager $manager,
OpenSSL $openSSL
) {
parent::__construct();
$this->speakerQuery = $speakerQuery;
$this->projectQuery = $projectQuery;
$this->eventQuery = $eventQuery;
$this->eventFactory = $eventFactory;
$this->manager = $manager;
$this->openSSL = $openSSL;
}
protected function getSpeakers(): array
{
$speakers = $this->speakerQuery->withCalendar()->find();
foreach ($speakers as $speaker) {
$this->openSSL->decryptEntity($speaker);
}
return $speakers;
}
protected function getProjects(): array
{
return $this->projectQuery->find();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$speakers = $this->getSpeakers();
$projects = $this->getProjects();
foreach ($speakers as $speaker) {
$client = new CaldavClient(
$speaker->getCaldavHost(),
$speaker->getCaldavUsername(),
$speaker->getCaldavPassword()
);
$this->openSSL->encryptEntity($speaker);
$calEvents = $client->getEvents($speaker->getCaldavCalendarUri());
foreach ($projects as $project) {
foreach ($calEvents as $calEvent) {
$regex = sprintf('/%s/', preg_quote($project->getCaldavEventTag()));
if (!preg_match($regex, $calEvent->getDescription())) {
continue;
}
$this->addEvent($project, $calEvent, $speaker);
}
}
}
return Command::SUCCESS;
}
protected function addEvent(Project $project, CalEvent $calEvent, Speaker $speaker)
{
$event = $this->eventQuery->create()
->where('.uid = :uid')
->setParameter('uid', $calEvent->getUid())
->findOne();
if (!$event) {
$event = $this->eventFactory->createFromEvent($calEvent);
} else {
$this->eventFactory->updateFromEvent($event, $calEvent);
}
$project->addEvent($event);
$speaker->addEvent($event);
$this->manager->update($event);
$this->manager->update($speaker);
}
}