<?php
namespace Products\NotificationsBundle\Subscriber\OneRoster;
use Cms\CoreBundle\Entity\OneRoster\OneRosterUser;
use Cms\CoreBundle\Entity\OneRosterSync;
use Cms\CoreBundle\Events\OneRosterTweakEvent;
use Doctrine\Common\Util\ClassUtils;
use Products\NotificationsBundle\Entity\Profile;
use Products\NotificationsBundle\Entity\Student;
use Products\NotificationsBundle\Util\Reachability;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class OneRosterUserTweakSubscriber
* @package Products\NotificationsBundle\Subscriber\OneRoster
*/
final class OneRosterUserTweakSubscriber extends AbstractNotificationsOneRosterSubscriber implements EventSubscriberInterface
{
/**
* {@inheritdoc}
*/
static public function getSubscribedEvents(): array
{
return [
OneRosterTweakEvent::EVENT__USER => [
//['discardableEnable', 0],
['calculateStudentReachability', 0],
//['discardableDisable', 0],
],
];
}
/**
* @param OneRosterTweakEvent $event
*/
public function calculateStudentReachability(OneRosterTweakEvent $event): void
{
// ensure we are meant to process this
if ( ! $this->checkTypes($event->getJob(), [
OneRosterSync::STRATEGIES__NOTIFICATIONS__FAMILY,
OneRosterSync::STRATEGIES__NOTIFICATIONS__STUDENTS,
])) {
return;
}
// get the user
$user = $event->getEntity();
if ( ! $user instanceof OneRosterUser) {
throw new \Exception(sprintf(
'User is not of proper type, got "%s".',
ClassUtils::getClass($user)
));
}
// branch on the role type
switch (true) {
case $this->checkTypes($event->getJob(), [OneRosterSync::STRATEGIES__NOTIFICATIONS__FAMILY]) && $user->isRoleStudent():
case $this->checkTypes($event->getJob(), [OneRosterSync::STRATEGIES__NOTIFICATIONS__STUDENTS]) && $user->isRoleStudent():
// noop, code will continue after the switch statement
break;
default:
// DEBUGGING
$event->getOutput()->writeln(sprintf(
'User role for #%s is "%s", skipping...',
$user->getSourcedId(),
$user->getRole()
));
// quit early
return;
}
// load up the student, this must match something, and it should at this point...
$student = $this->em->getRepository(Student::class)->findOneBy([
'onerosterId' => $user->getSourcedId(),
]);
// if we don't have a profile we have a problem
if ( ! $student) {
throw new \Exception(sprintf(
'Could not load student "%s".',
$user->getSourcedId()
));
}
// get all the profiles for this student, should be attached now
/** @var array|Profile[] $profiles */
$profiles = $this->em->getRepository(Profile::class)->createQueryBuilder('profiles')
->leftJoin('profiles.relationships', 'relationships')
->andWhere('relationships.student = :student')
->setParameter('student', $student)
->getQuery()
->getResult();
// reset the students standing
$student->setStanding(Reachability::STANDINGS__NONE);
// loop over all the profiles
foreach ($profiles as $profile) {
// merge the standing into the student
$student->mergeStanding($profile->getStanding());
}
// save the student
$this->em->save(
$student
);
}
}