<?php
namespace Cms\CoreBundle\EventSubscriber\OneRoster;
use Cms\CoreBundle\Entity\AbstractOneRosterEntity;
use Cms\CoreBundle\Entity\OneRosterJob;
use Cms\CoreBundle\Events\OneRosterAdhocEvent;
use Cms\CoreBundle\Events\OneRosterEvents;
use Platform\QueueBundle\Event\AsyncEvent;
/**
* Class OneRosterPrepareSubscriber
* @package Cms\CoreBundle\EventSubscriber\OneRoster
*/
final class OneRosterPrepareSubscriber extends AbstractOneRosterSubscriber
{
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents(): array
{
return [
OneRosterEvents::EVENT__PREPARE => [
['discardableDisable', self::PRIORITY__FIRST],
['phaseStart', self::PRIORITY__FIRST],
['markStashed', 1],
['cleanStashed', 1],
['phaseFin', self::PRIORITY__LAST],
['phaseTrigger', self::PRIORITY__LAST],
['discardableEnable', self::PRIORITY__LAST],
],
OneRosterEvents::EVENT__PREPARE__ADHOC => [
['discardableDisable', self::PRIORITY__FIRST],
['adhoc', 0],
['phaseFin', self::PRIORITY__LAST],
['phaseTrigger', self::PRIORITY__LAST],
['discardableEnable', self::PRIORITY__LAST],
],
];
}
/**
* In case we skip the stash phase, will update all the stash entries to be tied to this current job.
*
* @param AsyncEvent $event
* @return void
*/
public function markStashed(AsyncEvent $event): void
{
// data should be an array with an id of a sync
$job = $this->loadJob($event);
// we only want to mark entities if we skipped the stash phase
// TODO: do we need to worry about signed/unsigned here at some point?
if ($job->getStartPhase() <= OneRosterJob::PHASES__STASH) {
return;
}
// run bulk query
$marks = $this->em->createQueryBuilder()
->update(AbstractOneRosterEntity::class, 'entities')
->set('entities.job', ':job')
->setParameter('job', $job->getId())
->andWhere('entities.tenant = :tenant')
->setParameter('tenant', $job->getTenant()->getId())
->andWhere('entities.sync = :sync')
->setParameter('sync', $job->getSync()->getId())
->getQuery()
->execute();
// DEBUGGING
$event->getOutput()->writeln(sprintf(
'Marked %s stashed objects (stash phase was skipped) for sync #%s',
$marks,
$job->getIdentifier()
));
}
/**
* Removes "old" data from the stashed entities that are no longer valid based on this current sync.
*
* @param AsyncEvent $event
* @return void
*/
public function cleanStashed(AsyncEvent $event): void
{
// data should be an array with an id of a sync
$job = $this->loadJob($event);
// run bulk query
$removals = $this->em->createQueryBuilder()
->delete(AbstractOneRosterEntity::class, 'entities')
->andWhere('entities.tenant = :tenant')
->setParameter('tenant', $job->getTenant()->getId())
->andWhere('entities.sync = :sync')
->setParameter('sync', $job->getSync()->getId())
->andWhere('entities.job != :job')
->setParameter('job', $job->getId())
->getQuery()
->execute();
// DEBUGGING
$event->getOutput()->writeln(sprintf(
'Removed %s stashed objects for sync #%s',
$removals,
$job->getIdentifier()
));
}
/**
* In case we skip the stash phase, will update all the stash entries to be tied to this current job.
*
* @param AsyncEvent $event
* @return void
*/
public function adhoc(AsyncEvent $event): void
{
// data should be an array with an id of a sync
$job = $this->loadJob($event);
// trigger the event to do further processing
$this->dispatcher->dispatch(
new OneRosterAdhocEvent(
$event->getParam('payload'),
$job,
$event->getOutput()
),
$event->getParam('event'),
);
// DEBUGGING
$event->getOutput()->writeln(sprintf(
'Dispatched adhoc event "%s" for sync #%s',
$event->getParam('event'),
$job->getIdentifier()
));
}
/**
* {@inheritDoc}
*/
public function phase(): int
{
return OneRosterJob::PHASES__PREPARE;
}
/**
* {@inheritDoc}
*/
public function next(): ?int
{
return OneRosterJob::PHASES__PROCESS;
}
}