Merge pull request #5843 from christianbeeznest/scheduled-announcement01
Session: Allow scheduled announcements to session userspull/5781/head^2
commit
2f5b7970a2
@ -0,0 +1,74 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Command; |
||||
|
||||
use Chamilo\CoreBundle\Framework\Container; |
||||
use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository; |
||||
use Chamilo\CoreBundle\Service\ScheduledAnnouncementService; |
||||
use Database; |
||||
use Doctrine\ORM\EntityManager; |
||||
use Symfony\Component\Console\Command\Command; |
||||
use Symfony\Component\Console\Input\InputInterface; |
||||
use Symfony\Component\Console\Output\OutputInterface; |
||||
use Symfony\Component\Console\Style\SymfonyStyle; |
||||
|
||||
class SendScheduledAnnouncementsCommand extends Command |
||||
{ |
||||
protected static $defaultName = 'app:send-scheduled-announcements'; |
||||
|
||||
public function __construct( |
||||
private readonly AccessUrlRepository $accessUrlRepository, |
||||
private readonly ScheduledAnnouncementService $scheduledAnnouncementService, |
||||
private readonly EntityManager $em |
||||
) { |
||||
parent::__construct(); |
||||
} |
||||
|
||||
protected function configure(): void |
||||
{ |
||||
$this |
||||
->setDescription('Send scheduled announcements to all users.') |
||||
->addOption('debug', null, null, 'If set, debug messages will be shown.'); |
||||
} |
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int |
||||
{ |
||||
Database::setManager($this->em); |
||||
|
||||
$container = $this->getApplication()->getKernel()->getContainer(); |
||||
Container::setContainer($container); |
||||
|
||||
$io = new SymfonyStyle($input, $output); |
||||
$debug = (bool) $input->getOption('debug'); |
||||
$urlList = $this->accessUrlRepository->findAll(); |
||||
|
||||
if (empty($urlList)) { |
||||
$io->warning('No access URLs found.'); |
||||
return Command::SUCCESS; |
||||
} |
||||
|
||||
foreach ($urlList as $url) { |
||||
$urlId = $url->getId(); |
||||
$io->writeln("Portal: #".$urlId." - ".$url->getUrl()); |
||||
|
||||
try { |
||||
$messagesSent = $this->scheduledAnnouncementService->sendPendingMessages($urlId, $debug); |
||||
$io->writeln("Messages sent: $messagesSent"); |
||||
|
||||
if ($debug) { |
||||
$io->writeln("Debug: Processed portal with ID ".$urlId); |
||||
} |
||||
} catch (\Exception $e) { |
||||
$io->error('Error processing portal with ID ' . $urlId . ': ' . $e->getMessage()); |
||||
return Command::FAILURE; |
||||
} |
||||
} |
||||
|
||||
$io->success('All scheduled announcements have been sent.'); |
||||
return Command::SUCCESS; |
||||
} |
||||
} |
@ -0,0 +1,31 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Repository; |
||||
|
||||
use Chamilo\CoreBundle\Entity\ScheduledAnnouncement; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
class ScheduledAnnouncementRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, ScheduledAnnouncement::class); |
||||
} |
||||
|
||||
/** |
||||
* Mark an announcement as sent. |
||||
* |
||||
* @param ScheduledAnnouncement $announcement |
||||
*/ |
||||
public function markAsSent(ScheduledAnnouncement $announcement): void |
||||
{ |
||||
$announcement->setSent(true); |
||||
$this->_em->persist($announcement); |
||||
$this->_em->flush(); |
||||
} |
||||
} |
@ -0,0 +1,327 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\Service; |
||||
|
||||
use Chamilo\CoreBundle\Entity\Session; |
||||
use Chamilo\CoreBundle\Entity\User; |
||||
use Chamilo\CoreBundle\Repository\Node\AccessUrlRepository; |
||||
use Chamilo\CoreBundle\Repository\ScheduledAnnouncementRepository; |
||||
use Chamilo\CoreBundle\Repository\SessionRepository; |
||||
use Chamilo\CoreBundle\ServiceHelper\MessageHelper; |
||||
use Chamilo\CoreBundle\Settings\SettingsManager; |
||||
use Chamilo\CoreBundle\Entity\Course; |
||||
use Doctrine\ORM\EntityManager; |
||||
use ExtraField; |
||||
use ExtraFieldValue; |
||||
use Symfony\Contracts\Translation\TranslatorInterface; |
||||
use Tracking; |
||||
|
||||
class ScheduledAnnouncementService |
||||
{ |
||||
public function __construct( |
||||
private readonly ScheduledAnnouncementRepository $announcementRepository, |
||||
private readonly AccessUrlRepository $accessUrlRepository, |
||||
private readonly EntityManager $em, |
||||
private readonly SettingsManager $settingsManager, |
||||
private readonly SessionRepository $sessionRepository, |
||||
private readonly MessageHelper $messageHelper, |
||||
private readonly TranslatorInterface $translator |
||||
) {} |
||||
|
||||
/** |
||||
* Sends pending announcements to users and coaches. |
||||
*/ |
||||
public function sendPendingMessages(int $urlId, bool $debug = false): int |
||||
{ |
||||
if (!$this->allowed()) { |
||||
if ($debug) { |
||||
error_log("Announcements not allowed."); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
$messagesSent = 0; |
||||
$now = new \DateTime(); |
||||
|
||||
if ($debug) { |
||||
error_log("Current time: " . $now->format('Y-m-d H:i:s')); |
||||
} |
||||
|
||||
$announcements = $this->announcementRepository->findBy(['sent' => false]); |
||||
|
||||
if ($debug) { |
||||
error_log(count($announcements) . " pending announcements found."); |
||||
} |
||||
|
||||
$extraField = new ExtraField('user'); |
||||
$extraFields = $extraField->get_all(['filter = ? AND visible_to_self = ?' => [1, 1]]); |
||||
|
||||
foreach ($announcements as $announcement) { |
||||
if (!$announcement->isSent() && $announcement->getDate() < $now) { |
||||
if ($debug) { |
||||
error_log("Processing announcement ID: " . $announcement->getId()); |
||||
} |
||||
|
||||
$sessionId = $announcement->getSessionId(); |
||||
$session = $this->sessionRepository->find($sessionId); |
||||
|
||||
if (!$session) { |
||||
if ($debug) { |
||||
error_log("Session not found for session ID: $sessionId"); |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
$accessUrl = $this->accessUrlRepository->find($urlId); |
||||
$sessionRelUsers = $this->sessionRepository->getUsersByAccessUrl($session, $accessUrl); |
||||
$generalCoaches = $session->getGeneralCoaches(); |
||||
|
||||
if (empty($sessionRelUsers) || $generalCoaches->count() === 0) { |
||||
if ($debug) { |
||||
error_log("No users or general coaches found for session ID: $sessionId"); |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
$coachId = $generalCoaches->first()->getId(); |
||||
if ($debug) { |
||||
error_log("Coach ID: $coachId"); |
||||
} |
||||
|
||||
$coachList = []; |
||||
|
||||
$sendToCoaches = $this->shouldSendToCoaches($announcement->getId()); |
||||
|
||||
$courseList = $session->getCourses(); |
||||
|
||||
if ($debug) { |
||||
error_log("Number of courses in session: " . count($courseList)); |
||||
foreach ($courseList as $sessionRelCourse) { |
||||
$course = $sessionRelCourse->getCourse(); |
||||
error_log("Course ID: " . $course->getId() . ", Course Title: " . $course->getTitle()); |
||||
} |
||||
} |
||||
|
||||
if ($sendToCoaches) { |
||||
foreach ($courseList as $course) { |
||||
$coaches = $session->getGeneralCoaches(); |
||||
$coachList = array_merge($coachList, $coaches->toArray()); |
||||
} |
||||
$coachList = array_unique($coachList); |
||||
} |
||||
|
||||
$announcement->setSent(true); |
||||
$this->em->persist($announcement); |
||||
$this->em->flush(); |
||||
|
||||
$attachments = ''; |
||||
$subject = $announcement->getSubject(); |
||||
|
||||
foreach ($sessionRelUsers as $sessionRelUser) { |
||||
$user = $sessionRelUser->getUser(); |
||||
|
||||
if ($debug) { |
||||
error_log('User ::: ' . $user->getId()); |
||||
} |
||||
|
||||
if ($user->getId() !== $coachId) { |
||||
$courseInfo = $this->getCourseInfo($courseList); |
||||
$progress = $this->getUserProgress($user->getId(), $courseInfo, $session); |
||||
|
||||
$message = $this->buildMessage( |
||||
$announcement, |
||||
$session, |
||||
$user, |
||||
$courseInfo, |
||||
$attachments, |
||||
$progress |
||||
); |
||||
|
||||
if (!empty($extraFields)) { |
||||
$extraFieldValue = new ExtraFieldValue('user'); |
||||
foreach ($extraFields as $extraField) { |
||||
$valueExtra = $extraFieldValue->get_values_by_handler_and_field_variable($user->getId(), $extraField['variable'], true); |
||||
$tags['(('.strtolower($extraField['variable']).'))'] = $valueExtra['value'] ?? ''; |
||||
} |
||||
$message = str_replace(array_keys($tags), $tags, $message); |
||||
} |
||||
|
||||
if ($debug) { |
||||
error_log("Sending email to user ID: " . $user->getId()); |
||||
} |
||||
|
||||
$this->sendEmail($user->getId(), $subject, $message, $coachId); |
||||
} |
||||
} |
||||
|
||||
$coachMessage = $this->buildCoachMessage($announcement, $generalCoaches, $message); |
||||
foreach ($coachList as $courseCoach) { |
||||
if ($debug) { |
||||
error_log("Sending email to coach ID: " . $courseCoach->getId()); |
||||
} |
||||
$this->sendEmail($courseCoach->getId(), $subject, $coachMessage, $coachId); |
||||
} |
||||
|
||||
$messagesSent++; |
||||
|
||||
if ($debug) { |
||||
error_log("Messages sent for announcement ID: " . $announcement->getId()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ($debug) { |
||||
error_log("Total messages sent: $messagesSent"); |
||||
} |
||||
|
||||
return $messagesSent; |
||||
} |
||||
|
||||
/** |
||||
* Checks if the announcement should be sent to coaches. |
||||
*/ |
||||
private function shouldSendToCoaches(int $announcementId): bool |
||||
{ |
||||
$extraFieldValue = new ExtraFieldValue('scheduled_announcement'); |
||||
$sendToCoaches = $extraFieldValue->get_values_by_handler_and_field_variable($announcementId, 'send_to_coaches'); |
||||
return !empty($sendToCoaches) && !empty($sendToCoaches['value']) && (int)$sendToCoaches['value'] === 1; |
||||
} |
||||
|
||||
/** |
||||
* Verifies if sending scheduled announcements is allowed. |
||||
*/ |
||||
private function allowed(): bool |
||||
{ |
||||
return 'true' === $this->settingsManager->getSetting('announcement.allow_scheduled_announcements'); |
||||
} |
||||
|
||||
/** |
||||
* Builds the announcement message for the user. |
||||
*/ |
||||
private function buildMessage($announcement, Session $session, User $user, $courseInfo, $attachments, $progress): string |
||||
{ |
||||
$generalCoaches = $session->getGeneralCoaches(); |
||||
$generalCoachName = []; |
||||
$generalCoachEmail = []; |
||||
|
||||
foreach ($generalCoaches as $coach) { |
||||
$generalCoachName[] = $coach->getFullname(); |
||||
$generalCoachEmail[] = $coach->getEmail(); |
||||
} |
||||
|
||||
$startTime = $this->getLocalTime($session->getAccessStartDate()); |
||||
$endTime = $this->getLocalTime($session->getAccessEndDate()); |
||||
|
||||
$tags = [ |
||||
'((session_name))' => $session->getTitle(), |
||||
'((session_start_date))' => $startTime, |
||||
'((general_coach))' => implode(' - ', $generalCoachName), |
||||
'((general_coach_email))' => implode(' - ', $generalCoachEmail), |
||||
'((session_end_date))' => $endTime, |
||||
'((user_complete_name))' => $user->getFirstname() . ' ' . $user->getLastname(), |
||||
'((user_firstname))' => $user->getFirstname(), |
||||
'((user_lastname))' => $user->getLastname(), |
||||
'((lp_progress))' => $progress, |
||||
]; |
||||
|
||||
$message = str_replace(array_keys($tags), $tags, $announcement->getMessage()); |
||||
|
||||
return $message . $attachments; |
||||
} |
||||
|
||||
/** |
||||
* Builds the announcement message for the coach. |
||||
*/ |
||||
private function buildCoachMessage($announcement, $generalCoaches, $message): string |
||||
{ |
||||
$coachNames = []; |
||||
foreach ($generalCoaches as $coach) { |
||||
$coachNames[] = $coach->getFullname(); |
||||
} |
||||
|
||||
$coachMessageIntro = count($generalCoaches) > 1 |
||||
? $this->translator->trans('You are receiving a copy because you are one of the course coaches') |
||||
: $this->translator->trans('You are receiving a copy because you are the course coach'); |
||||
|
||||
$coachMessage = $coachMessageIntro . ': ' . implode(', ', $coachNames); |
||||
|
||||
return $coachMessage . '<br /><br />' . $message; |
||||
} |
||||
|
||||
/** |
||||
* Sends an email with the announcement to a user or coach. |
||||
*/ |
||||
private function sendEmail(int $userId, string $subject, string $message, int $coachId): void |
||||
{ |
||||
$user = $this->em->getRepository(User::class)->find($userId); |
||||
$coach = $this->em->getRepository(User::class)->find($coachId); |
||||
|
||||
if (!$user || !$coach) { |
||||
throw new \Exception("User or coach not found."); |
||||
} |
||||
|
||||
$this->messageHelper->sendMessageSimple( |
||||
$userId, |
||||
$subject, |
||||
$message, |
||||
$coachId |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Retrieves course information from a list of courses. |
||||
*/ |
||||
private function getCourseInfo($courseList) |
||||
{ |
||||
if (!empty($courseList) && current($courseList) instanceof Course) { |
||||
$courseId = current($courseList)->getId(); |
||||
return $this->getCourseInfoById($courseId); |
||||
} else { |
||||
return []; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Retrieves course information by course ID. |
||||
*/ |
||||
private function getCourseInfoById(int $courseId) |
||||
{ |
||||
$course = $this->em->getRepository(Course::class)->find($courseId); |
||||
|
||||
if ($course) { |
||||
return [ |
||||
'real_id' => $course->getId(), |
||||
'title' => $course->getTitle(), |
||||
'code' => $course->getCode(), |
||||
'description' => $course->getDescription(), |
||||
'tutor_name' => $course->getTutorName(), |
||||
]; |
||||
} |
||||
|
||||
return []; |
||||
} |
||||
|
||||
/** |
||||
* Gets the user's progress for a specific course and session. |
||||
*/ |
||||
private function getUserProgress(int $userId, $courseInfo, Session $session): string |
||||
{ |
||||
if (!empty($courseInfo) && $session) { |
||||
$progress = Tracking::get_avg_student_progress($userId, $courseInfo['real_id'], [], $session->getId()); |
||||
return is_numeric($progress) ? $progress . '%' : '0%'; |
||||
} |
||||
return '0%'; |
||||
} |
||||
|
||||
/** |
||||
* Formats a DateTime object to a string. |
||||
*/ |
||||
private function getLocalTime(?\DateTime $datetime): string |
||||
{ |
||||
return $datetime ? $datetime->format('Y-m-d H:i:s') : ''; |
||||
} |
||||
} |
@ -0,0 +1,319 @@ |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
namespace Chamilo\CoreBundle\ServiceHelper; |
||||
|
||||
use Chamilo\CoreBundle\Entity\Message; |
||||
use Chamilo\CoreBundle\Entity\MessageAttachment; |
||||
use Chamilo\CoreBundle\Entity\MessageRelUser; |
||||
use Chamilo\CoreBundle\Entity\User; |
||||
use Chamilo\CoreBundle\Entity\Usergroup; |
||||
use Chamilo\CoreBundle\Repository\MessageRepository; |
||||
use Chamilo\CoreBundle\Repository\Node\UserRepository; |
||||
use Chamilo\CoreBundle\Settings\SettingsManager; |
||||
use Doctrine\ORM\EntityManagerInterface; |
||||
use Symfony\Component\HttpFoundation\File\UploadedFile; |
||||
use Symfony\Component\HttpFoundation\RequestStack; |
||||
use Symfony\Component\Mailer\MailerInterface; |
||||
use Symfony\Component\Mime\Email; |
||||
|
||||
class MessageHelper |
||||
{ |
||||
private $session; |
||||
|
||||
public function __construct( |
||||
private readonly EntityManagerInterface $entityManager, |
||||
private readonly MessageRepository $messageRepository, |
||||
private readonly UserRepository $userRepository, |
||||
private readonly RequestStack $requestStack, |
||||
private readonly AccessUrlHelper $accessUrlHelper, |
||||
private readonly SettingsManager $settingsManager, |
||||
private readonly MailerInterface $mailer |
||||
) { |
||||
if (php_sapi_name() !== 'cli') { |
||||
$this->session = $this->requestStack->getSession(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Sends a simple message with optional attachments and notifications to HR users. |
||||
*/ |
||||
public function sendMessageSimple( |
||||
int $receiverUserId, |
||||
string $subject, |
||||
string $message, |
||||
int $senderId = 0, |
||||
bool $sendCopyToDrhUsers = false, |
||||
bool $uploadFiles = true, |
||||
array $attachmentList = [] |
||||
): ?int { |
||||
$files = $_FILES ? $_FILES : []; |
||||
if (false === $uploadFiles) { |
||||
$files = []; |
||||
} |
||||
|
||||
if (!empty($attachmentList)) { |
||||
$files = $attachmentList; |
||||
} |
||||
|
||||
$result = $this->sendMessage( |
||||
$receiverUserId, |
||||
$subject, |
||||
$message, |
||||
$files, |
||||
[], |
||||
0, |
||||
0, |
||||
0, |
||||
$senderId |
||||
); |
||||
|
||||
if ($sendCopyToDrhUsers) { |
||||
$accessUrl = $this->accessUrlHelper->getCurrent(); |
||||
if ($accessUrl !== null) { |
||||
$drhList = $this->userRepository->getDrhListFromUser($receiverUserId, $accessUrl->getId()); |
||||
if (!empty($drhList)) { |
||||
$receiverInfo = $this->userRepository->find($receiverUserId); |
||||
|
||||
foreach ($drhList as $drhUser) { |
||||
$drhMessage = sprintf( |
||||
'Copy of message sent to %s', |
||||
$receiverInfo->getFirstname() . ' ' . $receiverInfo->getLastname() |
||||
) . ' <br />' . $message; |
||||
|
||||
$this->sendMessageSimple( |
||||
$drhUser->getId(), |
||||
$subject, |
||||
$drhMessage, |
||||
$senderId |
||||
); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $result; |
||||
} |
||||
|
||||
/** |
||||
* Sends a message with attachments, forwards, and additional settings. |
||||
*/ |
||||
public function sendMessage( |
||||
int $receiverUserId, |
||||
string $subject, |
||||
string $content, |
||||
array $attachments = [], |
||||
array $fileCommentList = [], |
||||
int $groupId = 0, |
||||
int $parentId = 0, |
||||
int $editMessageId = 0, |
||||
int $senderId = 0, |
||||
int $forwardId = 0, |
||||
bool $checkCurrentAudioId = false, |
||||
bool $forceTitleWhenSendingEmail = false, |
||||
?int $msgType = null |
||||
): ?int { |
||||
|
||||
$sender = $this->userRepository->find($senderId); |
||||
$receiver = $this->userRepository->find($receiverUserId); |
||||
|
||||
if (!$sender || !$receiver || !$receiver->isActive()) { |
||||
return null; |
||||
} |
||||
|
||||
$totalFileSize = 0; |
||||
$attachmentList = $this->processAttachments($attachments, $fileCommentList, $totalFileSize); |
||||
|
||||
if ($totalFileSize > (int) $this->settingsManager->getSetting('message.message_max_upload_filesize')) { |
||||
throw new \Exception('Files size exceeds allowed limit.'); |
||||
} |
||||
|
||||
$parent = $this->messageRepository->find($parentId); |
||||
|
||||
if ($editMessageId) { |
||||
$message = $this->messageRepository->find($editMessageId); |
||||
if ($message) { |
||||
$message->setTitle($subject); |
||||
$message->setContent($content); |
||||
} |
||||
} else { |
||||
$message = new Message(); |
||||
$message->setSender($sender) |
||||
->addReceiverTo($receiver) |
||||
->setTitle($subject) |
||||
->setContent($content) |
||||
->setGroup($groupId ? $this->getGroupById($groupId) : null) |
||||
->setParent($parent); |
||||
|
||||
if ($msgType !== null) { |
||||
$message->setMsgType($msgType); |
||||
} |
||||
} |
||||
|
||||
$this->entityManager->persist($message); |
||||
$this->entityManager->flush(); |
||||
|
||||
if ($forwardId) { |
||||
$this->forwardAttachments($forwardId, $message); |
||||
} |
||||
|
||||
if ($checkCurrentAudioId) { |
||||
$this->attachAudioMessage($message); |
||||
} |
||||
|
||||
$this->saveAttachments($attachmentList, $message); |
||||
|
||||
$this->addSenderAsReceiver($message, $sender); |
||||
|
||||
if ($forceTitleWhenSendingEmail) { |
||||
$this->sendEmailNotification($receiver, $sender, $subject, $content, $attachmentList); |
||||
} |
||||
|
||||
return $message->getId(); |
||||
} |
||||
|
||||
/** |
||||
* Processes attachments, calculates total file size, and returns the attachment list. |
||||
*/ |
||||
private function processAttachments(array $attachments, array $fileCommentList, &$totalFileSize): array |
||||
{ |
||||
$attachmentList = []; |
||||
foreach ($attachments as $index => $attachment) { |
||||
$comment = $fileCommentList[$index] ?? ''; |
||||
$size = $attachment['size'] ?? 0; |
||||
|
||||
if (is_array($size)) { |
||||
foreach ($size as $s) { |
||||
$totalFileSize += $s; |
||||
} |
||||
} else { |
||||
$totalFileSize += $size; |
||||
} |
||||
|
||||
$attachmentList[] = [ |
||||
'file' => $attachment, |
||||
'comment' => $comment, |
||||
]; |
||||
} |
||||
return $attachmentList; |
||||
} |
||||
|
||||
/** |
||||
* Forwards attachments from one message to another. |
||||
*/ |
||||
private function forwardAttachments(int $forwardId, Message $message): void |
||||
{ |
||||
$forwardMessage = $this->messageRepository->find($forwardId); |
||||
if ($forwardMessage) { |
||||
foreach ($forwardMessage->getAttachments() as $attachment) { |
||||
$message->addAttachment($attachment); |
||||
} |
||||
$this->entityManager->persist($message); |
||||
$this->entityManager->flush(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Attaches an audio message from the current session to the message. |
||||
*/ |
||||
private function attachAudioMessage(Message $message): void |
||||
{ |
||||
if ($this->session && $this->session->has('current_audio')) { |
||||
$audio = $this->session->get('current_audio'); |
||||
|
||||
if (!empty($audio['name'])) { |
||||
$attachment = new MessageAttachment(); |
||||
$attachment->setFilename($audio['name']) |
||||
->setComment('audio_message') |
||||
->setMessage($message); |
||||
|
||||
$message->addAttachment($attachment); |
||||
|
||||
$this->entityManager->persist($attachment); |
||||
$this->entityManager->flush(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Saves the provided attachments and links them to the message. |
||||
*/ |
||||
private function saveAttachments(array $attachments, Message $message): void |
||||
{ |
||||
foreach ($attachments as $attachment) { |
||||
$file = $attachment['file']; |
||||
$comment = $attachment['comment'] ?? ''; |
||||
|
||||
if ($file instanceof UploadedFile && $file->getError() === UPLOAD_ERR_OK) { |
||||
$attachmentEntity = new MessageAttachment(); |
||||
$attachmentEntity->setFilename($file->getClientOriginalName()) |
||||
->setSize($file->getSize()) |
||||
->setPath($file->getRealPath()) |
||||
->setMessage($message) |
||||
->setComment($comment); |
||||
|
||||
$message->addAttachment($attachmentEntity); |
||||
$this->entityManager->persist($attachmentEntity); |
||||
} |
||||
} |
||||
$this->entityManager->flush(); |
||||
} |
||||
|
||||
/** |
||||
* Adds the sender as a receiver in the message to keep track of the sent message. |
||||
*/ |
||||
private function addSenderAsReceiver(Message $message, User $sender): void |
||||
{ |
||||
$messageRelUserRepository = $this->entityManager->getRepository(MessageRelUser::class); |
||||
$existingRelation = $messageRelUserRepository->findOneBy([ |
||||
'message' => $message, |
||||
'receiver' => $sender, |
||||
'receiverType' => MessageRelUser::TYPE_SENDER |
||||
]); |
||||
|
||||
if (!$existingRelation) { |
||||
$messageRelUserSender = new MessageRelUser(); |
||||
$messageRelUserSender->setMessage($message) |
||||
->setReceiver($sender) |
||||
->setReceiverType(MessageRelUser::TYPE_SENDER); |
||||
$this->entityManager->persist($messageRelUserSender); |
||||
$this->entityManager->flush(); |
||||
} |
||||
} |
||||
|
||||
private function sendEmailNotification(User $receiver, User $sender, string $subject, string $content, array $attachmentList): void |
||||
{ |
||||
if (empty($receiver->getEmail())) { |
||||
throw new \Exception('The receiver does not have a valid email address.'); |
||||
} |
||||
|
||||
$email = (new Email()) |
||||
->from($sender->getEmail()) |
||||
->to($receiver->getEmail()) |
||||
->subject($subject) |
||||
->text($content) |
||||
->html($content); |
||||
|
||||
foreach ($attachmentList as $attachment) { |
||||
if ($attachment instanceof UploadedFile) { |
||||
$email->attachFromPath($attachment->getRealPath(), $attachment->getClientOriginalName()); |
||||
} |
||||
} |
||||
|
||||
try { |
||||
$this->mailer->send($email); |
||||
} catch (\Exception $e) { |
||||
error_log('Failed to send email: ' . $e->getMessage()); |
||||
} |
||||
} |
||||
/** |
||||
* Retrieves a user group by its ID. |
||||
*/ |
||||
private function getGroupById(int $groupId) |
||||
{ |
||||
return $this->entityManager->getRepository(Usergroup::class)->find($groupId); |
||||
} |
||||
} |
Loading…
Reference in new issue