Skip to content

Commit

Permalink
Fix issue with mods lost on update
Browse files Browse the repository at this point in the history
  • Loading branch information
jskowronski39 committed Aug 26, 2023
1 parent 78c5f9b commit 7c9f49c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 60 deletions.
47 changes: 6 additions & 41 deletions src/EventSubscriber/Doctrine/ModGroupUpdatedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,36 @@
namespace App\EventSubscriber\Doctrine;

use App\Entity\ModGroup\ModGroupInterface;
use App\Entity\ModList\ModList;
use App\Entity\User\User;
use App\Repository\ModList\ModListRepository;
use App\Service\ModListUpdateService\ModListUpdateServiceInterface;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Doctrine\ORM\Events;
use Symfony\Component\Security\Core\Security;

class ModGroupUpdatedSubscriber implements EventSubscriber
{
private ?ModGroupInterface $updatedModGroup = null;

public function __construct(
private Security $security
private EntityManagerInterface $entityManager,
private ModListUpdateServiceInterface $modListUpdateService,
) {
}

public function getSubscribedEvents(): array
{
return [
Events::preUpdate,
Events::postFlush,
];
}

public function preUpdate(LifecycleEventArgs $args): void
{
$entityManager = $args->getEntityManager();
$modGroup = $args->getObject();

// Do nothing if updated entity is not a Mod Group or no changes were made to the entity
if (!$modGroup instanceof ModGroupInterface || !$entityManager->getUnitOfWork()->getEntityChangeSet($modGroup)) {
return;
}

// Save Mod Group for update of associated Mod Lists
$this->updatedModGroup = $modGroup;
}

public function postFlush(PostFlushEventArgs $args): void
{
// Do nothing if no Mod Group updated
if (!$this->updatedModGroup) {
if (!$modGroup instanceof ModGroupInterface || !$this->entityManager->getUnitOfWork()->getEntityChangeSet($modGroup)) {
return;
}

$entityManager = $args->getEntityManager();

/** @var ModListRepository $modListRepository */
$modListRepository = $entityManager->getRepository(ModList::class);

/** @var null|User $currentUser */
$currentUser = $this->security->getUser();

// Get Mod Lists that use this Mod Group and update their "last changed by/at" properties
$modLists = $modListRepository->findModListsContainingModGroup($this->updatedModGroup);
foreach ($modLists as $modList) {
$modList->setLastUpdatedAt(new \DateTimeImmutable());
$modList->setLastUpdatedBy($currentUser);
}

// Clear updated Mod Group. This prevents executing this method after next flush
$this->updatedModGroup = null;

$entityManager->flush();
$this->modListUpdateService->updateModListsAssociatedWithModGroup($modGroup);
}
}
19 changes: 0 additions & 19 deletions src/Repository/ModList/ModListRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace App\Repository\ModList;

use App\Entity\ModGroup\ModGroupInterface;
use App\Entity\ModList\ModList;
use App\Entity\ModList\ModListInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
Expand All @@ -22,22 +21,4 @@ public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, ModList::class);
}

/**
* @return ModListInterface[]
*/
public function findModListsContainingModGroup(ModGroupInterface $modGroup): array
{
$qb = $this->getEntityManager()->createQueryBuilder();
$expr = $qb->expr();

$qb
->addSelect('ml')
->from(ModList::class, 'ml')
->join('ml.modGroups', 'mg')
->andWhere($expr->eq('mg.id', $expr->literal($modGroup->getId()->toString())))
;

return $qb->getQuery()->getResult();
}
}
46 changes: 46 additions & 0 deletions src/Service/ModListUpdateService/ModListUpdateService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace App\Service\ModListUpdateService;

use App\Entity\ModGroup\ModGroupInterface;
use App\Entity\ModList\ModList;
use App\Entity\User\UserInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security;

class ModListUpdateService implements ModListUpdateServiceInterface
{
public function __construct(
private EntityManagerInterface $entityManager,
private Security $security,
) {
}

public function updateModListsAssociatedWithModGroup(ModGroupInterface $modGroup): void
{
$currentUser = $this->security->getUser();
if (!$currentUser instanceof UserInterface) {
return;
}

$queryBuilder = $this->entityManager->createQueryBuilder();
$expr = $queryBuilder->expr();

$queryBuilder
->update(ModList::class, 'ml')

->set('ml.lastUpdatedAt', ':dateTime')
->setParameter('dateTime', new \DateTimeImmutable())

->set('ml.lastUpdatedBy', ':user')
->setParameter('user', $currentUser)

->andWhere($expr->isMemberOf(':modGroupId', 'ml.modGroups'))
->setParameter('modGroupId', $modGroup->getId()->toString())
;

$queryBuilder->getQuery()->execute();
}
}
12 changes: 12 additions & 0 deletions src/Service/ModListUpdateService/ModListUpdateServiceInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace App\Service\ModListUpdateService;

use App\Entity\ModGroup\ModGroupInterface;

interface ModListUpdateServiceInterface
{
public function updateModListsAssociatedWithModGroup(ModGroupInterface $modGroup): void;
}

0 comments on commit 7c9f49c

Please sign in to comment.