commit
						427acdc7b1
					
				@ -0,0 +1,300 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
declare(strict_types=1); | 
				
			||||
 | 
				
			||||
/* For licensing terms, see /license.txt */ | 
				
			||||
 | 
				
			||||
namespace Chamilo\CoreBundle\Command; | 
				
			||||
 | 
				
			||||
use Chamilo\CoreBundle\Repository\CourseRelUserRepository; | 
				
			||||
use Chamilo\CoreBundle\Repository\ExtraFieldValuesRepository; | 
				
			||||
use Chamilo\CoreBundle\Repository\Node\CourseRepository; | 
				
			||||
use Chamilo\CoreBundle\Repository\Node\UserRepository; | 
				
			||||
use Chamilo\CoreBundle\Repository\SessionRelCourseRelUserRepository; | 
				
			||||
use Chamilo\CoreBundle\Repository\TrackEDefaultRepository; | 
				
			||||
use Chamilo\CoreBundle\ServiceHelper\MessageHelper; | 
				
			||||
use DateTime; | 
				
			||||
use DateTimeZone; | 
				
			||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | 
				
			||||
use Symfony\Contracts\Translation\TranslatorInterface; | 
				
			||||
use Twig\Environment; | 
				
			||||
use Symfony\Component\Console\Command\Command; | 
				
			||||
use Symfony\Component\Console\Input\InputInterface; | 
				
			||||
use Symfony\Component\Console\Input\InputOption; | 
				
			||||
use Symfony\Component\Console\Output\OutputInterface; | 
				
			||||
 | 
				
			||||
class LpProgressReminderCommand extends Command | 
				
			||||
{ | 
				
			||||
    protected static $defaultName = 'app:lp-progress-reminder'; | 
				
			||||
 | 
				
			||||
    private const NUMBER_OF_DAYS_TO_RESEND_NOTIFICATION = 3; | 
				
			||||
 | 
				
			||||
    public function __construct( | 
				
			||||
        private readonly CourseRepository $courseRepository, | 
				
			||||
        private readonly CourseRelUserRepository $courseRelUserRepository, | 
				
			||||
        private readonly SessionRelCourseRelUserRepository $sessionRelCourseRelUserRepository, | 
				
			||||
        private readonly ExtraFieldValuesRepository $extraFieldValuesRepository, | 
				
			||||
        private readonly TrackEDefaultRepository $trackEDefaultRepository, | 
				
			||||
        private readonly UserRepository $userRepository, | 
				
			||||
        private readonly Environment $twig, | 
				
			||||
        private readonly TranslatorInterface $translator, | 
				
			||||
        private readonly MessageHelper $messageHelper, | 
				
			||||
        private readonly UrlGeneratorInterface $urlGenerator | 
				
			||||
    ) { | 
				
			||||
        parent::__construct(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    protected function configure() | 
				
			||||
    { | 
				
			||||
        $this | 
				
			||||
            ->setDescription('Send LP progress reminders to users based on "number_of_days_for_completion".') | 
				
			||||
            ->addOption( | 
				
			||||
                'debug', | 
				
			||||
                null, | 
				
			||||
                InputOption::VALUE_NONE, | 
				
			||||
                'If set, will output detailed debug information' | 
				
			||||
            ); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected function execute(InputInterface $input, OutputInterface $output): int | 
				
			||||
    { | 
				
			||||
        $debugMode = $input->getOption('debug'); | 
				
			||||
        $output->writeln('Starting the LP progress reminder process...'); | 
				
			||||
 | 
				
			||||
        // Retrieve LPs with completion days | 
				
			||||
        $lpItems = $this->extraFieldValuesRepository->getLpIdWithDaysForCompletion(); | 
				
			||||
        if ($debugMode && !empty($lpItems)) { | 
				
			||||
            $output->writeln('LP Items retrieved: ' . print_r($lpItems, true)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (empty($lpItems)) { | 
				
			||||
            $output->writeln('No learning paths with days for completion found.'); | 
				
			||||
            return Command::SUCCESS; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $lpMap = []; | 
				
			||||
        foreach ($lpItems as $lpItem) { | 
				
			||||
            $lpMap[$lpItem['lp_id']] = $lpItem['ndays']; | 
				
			||||
        } | 
				
			||||
        $lpIds = array_keys($lpMap); | 
				
			||||
 | 
				
			||||
        // Retrieve all courses from the CourseRepository | 
				
			||||
        $courses = $this->courseRepository->findAll(); | 
				
			||||
        if ($debugMode && !empty($courses)) { | 
				
			||||
            $output->writeln('Courses retrieved: ' . count($courses)); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        foreach ($courses as $course) { | 
				
			||||
            $courseId = $course->getId(); | 
				
			||||
 | 
				
			||||
            // Retrieve users for the course (without session) | 
				
			||||
            $courseUsers = $this->courseRelUserRepository->getCourseUsers($courseId, $lpIds); | 
				
			||||
            // Retrieve users for the course session | 
				
			||||
            $sessionCourseUsers = $this->sessionRelCourseRelUserRepository->getSessionCourseUsers($courseId, $lpIds); | 
				
			||||
 | 
				
			||||
            if ($debugMode && (!empty($courseUsers) || !empty($sessionCourseUsers))) { | 
				
			||||
                $output->writeln('Processing course ID: ' . $courseId); | 
				
			||||
                if (!empty($courseUsers)) { | 
				
			||||
                    $output->writeln('Course users retrieved: ' . count($courseUsers)); | 
				
			||||
                    //$output->writeln('Course retrieved: ' . print_r($courseUsers, true)); | 
				
			||||
                } | 
				
			||||
                if (!empty($sessionCourseUsers)) { | 
				
			||||
                    $output->writeln('Session users retrieved: ' . count($sessionCourseUsers)); | 
				
			||||
                    //$output->writeln('Session retrieved: ' . print_r($sessionCourseUsers, true)); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            // Process users from the main course (sessionId = 0 or null) | 
				
			||||
            $this->processCourseUsers($courseUsers, $lpMap, $courseId, $debugMode); | 
				
			||||
 | 
				
			||||
            // Process users from the course session (sessionId > 0) | 
				
			||||
            $this->processCourseUsers($sessionCourseUsers, $lpMap, $courseId, $debugMode, true); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $output->writeln('LP progress reminder process finished.'); | 
				
			||||
        return Command::SUCCESS; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Processes users from a course or session to check if a reminder needs to be sent. | 
				
			||||
     */ | 
				
			||||
    private function processCourseUsers(array $users, array $lpItems, int $courseId, bool $debugMode = false, bool $checkSession = false): void | 
				
			||||
    { | 
				
			||||
        foreach ($users as $user) { | 
				
			||||
            $userId = $user['userId']; | 
				
			||||
            $courseTitle = $user['courseTitle']; | 
				
			||||
            $lpId = $user['lpId']; | 
				
			||||
            $progress = (int) $user['progress']; | 
				
			||||
 | 
				
			||||
            $sessionId = $checkSession ? ($user['sessionId'] ?? 0) : 0; | 
				
			||||
 | 
				
			||||
            if ($lpId === null) { | 
				
			||||
                foreach ($lpItems as $lpId => $nbDaysForLpCompletion) { | 
				
			||||
                    $this->sendReminderIfNeeded( | 
				
			||||
                        $userId, | 
				
			||||
                        $courseTitle, | 
				
			||||
                        $courseId, | 
				
			||||
                        $sessionId, | 
				
			||||
                        (int) $nbDaysForLpCompletion, | 
				
			||||
                        $debugMode, | 
				
			||||
                        $lpId, | 
				
			||||
                        $progress | 
				
			||||
                    ); | 
				
			||||
                } | 
				
			||||
            } else { | 
				
			||||
                $nbDaysForLpCompletion = (int) ($lpItems[$lpId] ?? self::NUMBER_OF_DAYS_TO_RESEND_NOTIFICATION); | 
				
			||||
                $this->sendReminderIfNeeded( | 
				
			||||
                    $userId, | 
				
			||||
                    $courseTitle, | 
				
			||||
                    $courseId, | 
				
			||||
                    $sessionId, | 
				
			||||
                    $nbDaysForLpCompletion, | 
				
			||||
                    $debugMode, | 
				
			||||
                    $lpId, | 
				
			||||
                    $progress | 
				
			||||
                ); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sends a progress reminder to a user if the conditions for reminder timing are met, | 
				
			||||
     * based on their registration date and learning path completion criteria. | 
				
			||||
     */ | 
				
			||||
    private function sendReminderIfNeeded( | 
				
			||||
        int $userId, | 
				
			||||
        string $courseTitle, | 
				
			||||
        int $courseId, | 
				
			||||
        int $sessionId, | 
				
			||||
        int $nbDaysForLpCompletion, | 
				
			||||
        bool $debugMode, | 
				
			||||
        ?int $lpId, | 
				
			||||
        int $progress | 
				
			||||
    ): void { | 
				
			||||
        $registrationDate = $this->trackEDefaultRepository->getUserCourseRegistrationAt($courseId, $userId, $sessionId); | 
				
			||||
        if (!$registrationDate) { | 
				
			||||
            if ($debugMode) { | 
				
			||||
                echo "No registration date found for user $userId in course $courseId (session ID: $sessionId).\n"; | 
				
			||||
            } | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($debugMode) { | 
				
			||||
            $sessionInfo = $sessionId > 0 ? "in session ID $sessionId" : "without a session"; | 
				
			||||
            echo "Registration date: {$registrationDate->format('Y-m-d H:i:s')}, Days for completion: $nbDaysForLpCompletion, LP ID: {$lpId}, $sessionInfo\n"; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if ($this->isTimeToRemindUser($registrationDate, $nbDaysForLpCompletion)) { | 
				
			||||
            $nbRemind = $this->getNbReminder($registrationDate, $nbDaysForLpCompletion); | 
				
			||||
 | 
				
			||||
            if ($debugMode) { | 
				
			||||
                echo "Sending reminder to user $userId for course $courseTitle (LP ID: {$lpId})\n"; | 
				
			||||
            } | 
				
			||||
            $this->logReminderSent($userId, $courseTitle, $nbRemind, $debugMode, $lpId, $sessionId); | 
				
			||||
            $this->sendLpReminder($userId, $courseTitle, $progress, $registrationDate, $nbRemind); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Logs the reminder details if debug mode is enabled. | 
				
			||||
     */ | 
				
			||||
    private function logReminderSent(int $userId, string $courseTitle, int $nbRemind, bool $debugMode, int $lpId, int $sessionId = 0): void | 
				
			||||
    { | 
				
			||||
        if ($debugMode) { | 
				
			||||
            $sessionInfo = $sessionId > 0 ? sprintf("in session ID %d", $sessionId) : "without a session"; | 
				
			||||
            echo sprintf( | 
				
			||||
                "Reminder number %d sent to user ID %d for the course %s (LP ID: %d) %s.\n", | 
				
			||||
                $nbRemind, | 
				
			||||
                $userId, | 
				
			||||
                $courseTitle, | 
				
			||||
                $lpId, | 
				
			||||
                $sessionInfo | 
				
			||||
            ); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Calculates the number of reminders to be sent based on registration date and days for completion. | 
				
			||||
     */ | 
				
			||||
    private function getNbReminder(DateTime $registrationDate, int $nbDaysForLpCompletion): int | 
				
			||||
    { | 
				
			||||
        $reminderStartDate = (clone $registrationDate)->modify("+$nbDaysForLpCompletion days"); | 
				
			||||
        $currentDate = new DateTime('now', new DateTimeZone('UTC')); | 
				
			||||
        $reminderStartDate->setTime(0, 0, 0); | 
				
			||||
        $currentDate->setTime(0, 0, 0); | 
				
			||||
 | 
				
			||||
        $interval = $reminderStartDate->diff($currentDate); | 
				
			||||
        $diffDays = (int) $interval->format('%a'); | 
				
			||||
 | 
				
			||||
        return (int) floor($diffDays / self::NUMBER_OF_DAYS_TO_RESEND_NOTIFICATION) + 1; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Checks if it is time to remind the user based on their registration date and LP completion days. | 
				
			||||
     */ | 
				
			||||
    private function isTimeToRemindUser(DateTime $registrationDate, int $nbDaysForLpCompletion): bool | 
				
			||||
    { | 
				
			||||
        $reminderStartDate = (clone $registrationDate)->modify("+$nbDaysForLpCompletion days"); | 
				
			||||
        $reminderStartDate->setTime(0, 0, 0); | 
				
			||||
 | 
				
			||||
        $currentDate = new DateTime('now', new DateTimeZone('UTC')); | 
				
			||||
        $currentDate->setTime(0, 0, 0); | 
				
			||||
 | 
				
			||||
        $interval = $reminderStartDate->diff($currentDate); | 
				
			||||
        $diffDays = (int) $interval->format('%a'); | 
				
			||||
 | 
				
			||||
        return ($diffDays >= self::NUMBER_OF_DAYS_TO_RESEND_NOTIFICATION && | 
				
			||||
            $diffDays % self::NUMBER_OF_DAYS_TO_RESEND_NOTIFICATION === 0) || $diffDays === 0; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Sends a reminder email to the user regarding their LP progress. | 
				
			||||
     */ | 
				
			||||
    private function sendLpReminder(int $toUserId, string $courseName, int $lpProgress, DateTime $registrationDate, int $nbRemind): bool | 
				
			||||
    { | 
				
			||||
        $user = $this->userRepository->find($toUserId); | 
				
			||||
        if (!$user) { | 
				
			||||
            throw new \Exception("User not found"); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $platformUrl = $this->urlGenerator->generate('index', [], UrlGeneratorInterface::ABSOLUTE_URL); | 
				
			||||
        $recoverPasswordUrl = $platformUrl.'/main/auth/lostPassword.php'; | 
				
			||||
 | 
				
			||||
        $trainingCenterName = 'Your Training Center'; | 
				
			||||
        $trainers = 'Trainer Name'; | 
				
			||||
 | 
				
			||||
        $hello = $this->translator->trans("Hello %s"); | 
				
			||||
        $youAreRegCourse = $this->translator->trans("You are registered in the training %s since the %s"); | 
				
			||||
        $thisMessageIsAbout = $this->translator->trans("You are receiving this message because you have completed a learning path with a %s progress of your training.<br/>Your progress must be 100 to consider that your training was carried out.<br/>If you have the slightest problem, you should contact with your trainer."); | 
				
			||||
        $stepsToRemind = $this->translator->trans("As a reminder, to access the training platform:<br/>1. Connect to the platform at the address: %s <br/>2. Then enter: <br/>Your username: %s <br/>Your password: This was emailed to you.<br/>if you forgot it and can't find it, you can retrieve it by going to %s <br/><br/>Thank you for doing what is necessary."); | 
				
			||||
        $lpRemindFooter = $this->translator->trans("The training center<p>%s</p>Trainers:<br/>%s"); | 
				
			||||
 | 
				
			||||
        $hello = sprintf($hello, $user->getFullName()); | 
				
			||||
        $youAreRegCourse = sprintf($youAreRegCourse, $courseName, $registrationDate->format('Y-m-d')); | 
				
			||||
        $thisMessageIsAbout = sprintf($thisMessageIsAbout, $lpProgress); | 
				
			||||
        $stepsToRemind = sprintf($stepsToRemind, $platformUrl, $user->getUsername(), $recoverPasswordUrl); | 
				
			||||
        $lpRemindFooter = sprintf($lpRemindFooter, $trainingCenterName, $trainers); | 
				
			||||
 | 
				
			||||
        $messageContent = $this->twig->render('@ChamiloCore/Mailer/Legacy/lp_progress_reminder_body.html.twig', [ | 
				
			||||
            'HelloX' => $hello, | 
				
			||||
            'YouAreRegCourseXFromDateX' => $youAreRegCourse, | 
				
			||||
            'ThisMessageIsAboutX' => $thisMessageIsAbout, | 
				
			||||
            'StepsToRemindX' => $stepsToRemind, | 
				
			||||
            'LpRemindFooterX' => $lpRemindFooter, | 
				
			||||
        ]); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            $this->messageHelper->sendMessageSimple( | 
				
			||||
                $toUserId, | 
				
			||||
                sprintf("Reminder number %d for the course %s", $nbRemind, $courseName), | 
				
			||||
                $messageContent | 
				
			||||
            ); | 
				
			||||
 | 
				
			||||
            return true; | 
				
			||||
        } catch (\Exception $e) { | 
				
			||||
            throw new \Exception('Error sending reminder: ' . $e->getMessage()); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,42 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
declare(strict_types=1); | 
				
			||||
 | 
				
			||||
/* For licensing terms, see /license.txt */ | 
				
			||||
 | 
				
			||||
namespace Chamilo\CoreBundle\Repository; | 
				
			||||
 | 
				
			||||
use Chamilo\CoreBundle\Entity\CourseRelUser; | 
				
			||||
use Chamilo\CourseBundle\Entity\CLp; | 
				
			||||
use Chamilo\CourseBundle\Entity\CLpView; | 
				
			||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | 
				
			||||
use Doctrine\Persistence\ManagerRegistry; | 
				
			||||
 | 
				
			||||
class CourseRelUserRepository extends ServiceEntityRepository | 
				
			||||
{ | 
				
			||||
    public function __construct(ManagerRegistry $registry) | 
				
			||||
    { | 
				
			||||
        parent::__construct($registry, CourseRelUser::class); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Retrieves users from a course and their LP progress (without session). | 
				
			||||
     */ | 
				
			||||
    public function getCourseUsers(int $courseId, array $lpIds): array | 
				
			||||
    { | 
				
			||||
        $qb = $this->createQueryBuilder('cu') | 
				
			||||
            ->select('u.id AS userId, c.title AS courseTitle, lp.iid AS lpId, COALESCE(lpv.progress, 0) AS progress') | 
				
			||||
            ->innerJoin('cu.user', 'u') | 
				
			||||
            ->innerJoin('cu.course', 'c') | 
				
			||||
            ->leftJoin(CLpView::class, 'lpv', 'WITH', 'lpv.user = u.id AND lpv.course = cu.course AND lpv.lp IN (:lpIds)') | 
				
			||||
            ->leftJoin(CLp::class, 'lp', 'WITH', 'lp.iid IN (:lpIds)') | 
				
			||||
            ->innerJoin('lp.resourceNode', 'rn') | 
				
			||||
            ->where('cu.course = :courseId') | 
				
			||||
            ->andWhere('rn.parent = c.resourceNode') | 
				
			||||
            ->andWhere('(lpv.progress < 100 OR lpv.progress IS NULL)') | 
				
			||||
            ->setParameter('courseId', $courseId) | 
				
			||||
            ->setParameter('lpIds', $lpIds); | 
				
			||||
 | 
				
			||||
        return $qb->getQuery()->getResult(); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,42 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
declare(strict_types=1); | 
				
			||||
 | 
				
			||||
/* For licensing terms, see /license.txt */ | 
				
			||||
 | 
				
			||||
namespace Chamilo\CoreBundle\Repository; | 
				
			||||
 | 
				
			||||
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser; | 
				
			||||
use Chamilo\CourseBundle\Entity\CLp; | 
				
			||||
use Chamilo\CourseBundle\Entity\CLpView; | 
				
			||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | 
				
			||||
use Doctrine\Persistence\ManagerRegistry; | 
				
			||||
 | 
				
			||||
class SessionRelCourseRelUserRepository extends ServiceEntityRepository | 
				
			||||
{ | 
				
			||||
    public function __construct(ManagerRegistry $registry) | 
				
			||||
    { | 
				
			||||
        parent::__construct($registry, SessionRelCourseRelUser::class); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Retrieves users from a course session and their LP progress. | 
				
			||||
     */ | 
				
			||||
    public function getSessionCourseUsers(int $courseId, array $lpIds): array | 
				
			||||
    { | 
				
			||||
        $qb = $this->createQueryBuilder('scu') | 
				
			||||
            ->select('u.id AS userId, c.title AS courseTitle, lp.iid AS lpId, COALESCE(lpv.progress, 0) AS progress, IDENTITY(scu.session) AS sessionId') | 
				
			||||
            ->innerJoin('scu.user', 'u') | 
				
			||||
            ->innerJoin('scu.course', 'c') | 
				
			||||
            ->leftJoin(CLpView::class, 'lpv', 'WITH', 'lpv.user = u.id AND lpv.course = scu.course AND lpv.lp IN (:lpIds)') | 
				
			||||
            ->leftJoin(CLp::class, 'lp', 'WITH', 'lp.iid IN (:lpIds)') | 
				
			||||
            ->innerJoin('lp.resourceNode', 'rn') | 
				
			||||
            ->where('scu.course = :courseId') | 
				
			||||
            ->andWhere('rn.parent = c.resourceNode') | 
				
			||||
            ->andWhere('(lpv.progress < 100 OR lpv.progress IS NULL)') | 
				
			||||
            ->setParameter('courseId', $courseId) | 
				
			||||
            ->setParameter('lpIds', $lpIds); | 
				
			||||
 | 
				
			||||
        return $qb->getQuery()->getResult(); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,64 @@ | 
				
			||||
<?php | 
				
			||||
 | 
				
			||||
declare(strict_types=1); | 
				
			||||
 | 
				
			||||
/* For licensing terms, see /license.txt */ | 
				
			||||
 | 
				
			||||
namespace Chamilo\CoreBundle\Repository; | 
				
			||||
 | 
				
			||||
use Chamilo\CoreBundle\Entity\TrackEDefault; | 
				
			||||
use DateTime; | 
				
			||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | 
				
			||||
use Doctrine\Persistence\ManagerRegistry; | 
				
			||||
 | 
				
			||||
class TrackEDefaultRepository extends ServiceEntityRepository | 
				
			||||
{ | 
				
			||||
    public function __construct(ManagerRegistry $registry) | 
				
			||||
    { | 
				
			||||
        parent::__construct($registry, TrackEDefault::class); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Retrieves the registration date of a user in a specific course or session. | 
				
			||||
     */ | 
				
			||||
    public function getUserCourseRegistrationAt(int $courseId, int $userId, ?int $sessionId = 0): ?\DateTime | 
				
			||||
    { | 
				
			||||
        $serializedPattern = sprintf('s:2:"id";i:%d;', $userId); | 
				
			||||
 | 
				
			||||
        $qb = $this->createQueryBuilder('te') | 
				
			||||
            ->select('te.defaultDate') | 
				
			||||
            ->where('te.cId = :courseId') | 
				
			||||
            ->andWhere('te.defaultValueType = :valueType') | 
				
			||||
            ->andWhere('te.defaultEventType = :eventType') | 
				
			||||
            ->andWhere('te.defaultValue LIKE :serializedPattern') | 
				
			||||
            ->setParameter('courseId', $courseId) | 
				
			||||
            ->setParameter('valueType', 'user_object') | 
				
			||||
            ->setParameter('eventType', 'user_subscribed') | 
				
			||||
            ->setParameter('serializedPattern', '%' . $serializedPattern . '%'); | 
				
			||||
 | 
				
			||||
        if ($sessionId > 0) { | 
				
			||||
            $qb->andWhere('te.sessionId = :sessionId') | 
				
			||||
                ->setParameter('sessionId', $sessionId); | 
				
			||||
        } elseif ($sessionId === 0) { | 
				
			||||
            $qb->andWhere('te.sessionId = 0'); | 
				
			||||
        } else { | 
				
			||||
            $qb->andWhere('te.sessionId IS NULL'); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        $qb->setMaxResults(1); | 
				
			||||
        $query = $qb->getQuery(); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            $result = $query->getOneOrNullResult(); | 
				
			||||
            if ($result && isset($result['defaultDate'])) { | 
				
			||||
                return $result['defaultDate'] instanceof \DateTime | 
				
			||||
                    ? $result['defaultDate'] | 
				
			||||
                    : new \DateTime($result['defaultDate']); | 
				
			||||
            } | 
				
			||||
        } catch (\Exception $e) { | 
				
			||||
            throw new \RuntimeException('Error fetching registration date: ' . $e->getMessage()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return null; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,16 @@ | 
				
			||||
<p> | 
				
			||||
    {{HelloX}} | 
				
			||||
</p> | 
				
			||||
 | 
				
			||||
<p> | 
				
			||||
    {{YouAreRegCourseXFromDateX}}<br /> | 
				
			||||
    {{ThisMessageIsAboutX}} | 
				
			||||
</p> | 
				
			||||
 | 
				
			||||
<p> | 
				
			||||
    {{StepsToRemindX}} | 
				
			||||
</p> | 
				
			||||
 | 
				
			||||
<p> | 
				
			||||
    {{LpRemindFooterX}} | 
				
			||||
</p> | 
				
			||||
@ -0,0 +1 @@ | 
				
			||||
{{RemindXLpCourseX}} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue