<?php
declare(strict_types=1);
namespace App\Component\CompanyMatch\EventSubscriber;
use App\Component\CompanyMatch\ApproachStrategy;
use App\Component\CompanyMatch\Calculator\ApproachCalculator;
use App\Component\CompanyMatch\Event\CompanyMatchUserEvent;
use App\Component\CompanyMatch\Message\InvalidateCompanyMatchUserCompanies;
use App\Component\CompanyMatch\Message\MailCompaniesToApproach;
use App\Component\CompanyMatch\Util\CompanyMatchUserHistorian;
use App\Entity\Company;
use App\Entity\CompanyMatchUser;
use App\Entity\SiteUserData;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\PersistentCollection;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
class CompanyMatchUserSubscriber implements EventSubscriberInterface
{
public function __construct(
protected readonly ApproachCalculator $approachCalculator,
protected readonly MessageBusInterface $messageBus,
protected readonly CompanyMatchUserHistorian $companyMatchUserHistorian,
protected readonly EntityManagerInterface $entityManager,
) {
}
public static function getSubscribedEvents(): array
{
return [
CompanyMatchUserEvent::class => 'preUpdate',
];
}
public function preUpdate(CompanyMatchUserEvent $event): void
{
$this->checkCompanies($event);
}
private function checkCompanies(CompanyMatchUserEvent $event): void
{
$siteUserData = $event->getUser();
if (!\is_int($siteUserData->getId())) {
return;
}
$companyCollection = $this->approachCalculator->calculateApproachableCompaniesCollection($siteUserData);
$this->messageBus->dispatch(new MailCompaniesToApproach($companyCollection, $siteUserData->getId()));
$removableCompanies = $this->calculateRemoveableCompanies($siteUserData);
if (0 !== \count($removableCompanies)) {
$this->messageBus->dispatch(new InvalidateCompanyMatchUserCompanies($removableCompanies, $siteUserData->getId()));
}
$this->entityManager->persist($siteUserData);
$this->entityManager->flush();
}
/**
* @return Collection<int, Company>
*/
private function calculateRemoveableCompanies(SiteUserData $siteUserData): Collection
{
$relatedCompaniesMatches = $this->companyMatchUserHistorian->findHistoryForUser($siteUserData);
$companies = $relatedCompaniesMatches->map(fn (CompanyMatchUser $companyMatchUser) => $companyMatchUser->getCompany());
if (ApproachStrategy::NotApproachable === $siteUserData->getApproachStrategy()) {
return $companies;
}
if (ApproachStrategy::SpecificallyApproachable === $siteUserData->getApproachStrategy()) {
if (!$siteUserData->hasCompaniesAllowedToApproach()) {
return $companies;
}
/** @var PersistentCollection<int, Company> $collection */
$collection = $siteUserData->getCompaniesAllowedToApproach();
/** @var Company[] $deleteDiff */
$deleteDiff = $collection->getDeleteDiff();
return new ArrayCollection($deleteDiff);
}
return new ArrayCollection();
}
}