Ejemplo n.º 1
0
 /**
  * @param $queue
  *
  * @return int
  */
 public function processMessageQueue($queue)
 {
     if (!is_array($queue)) {
         if (!$queue instanceof MessageQueue) {
             throw new \InvalidArgumentException('$queue must be an instance of ' . MessageQueue::class);
         }
         $queue = [$queue->getId() => $queue];
     }
     $counter = 0;
     $contacts = [];
     $byChannel = [];
     // Lead entities will not have profile fields populated due to the custom field use - therefore to optimize resources,
     // get a list of leads to fetch details all at once along with company details for dynamic email content, etc
     /** @var MessageQueue $message */
     foreach ($queue as $message) {
         $contacts[$message->getId()] = $message->getLead()->getId();
     }
     $contactData = $this->leadModel->getRepository()->getContacts($contacts);
     $companyData = $this->companyModel->getRepository()->getCompaniesForContacts($contacts);
     foreach ($contacts as $messageId => $contactId) {
         $contactData[$contactId]['companies'] = $companyData[$contactId];
         $queue[$messageId]->getLead()->setFields($contactData[$contactId]);
     }
     // Group queue by channel and channel ID - this make it possible for processing listeners to batch process such as
     // sending emails in batches to 3rd party transactional services via HTTP APIs
     foreach ($queue as $key => $message) {
         if (MessageQueue::STATUS_SENT == $message->getStatus()) {
             unset($queue[$key]);
             continue;
         }
         $messageChannel = $message->getChannel();
         $messageChannelId = $message->getChannelId();
         if (!$messageChannelId) {
             $messageChannelId = 0;
         }
         if (!isset($byChannel[$messageChannel])) {
             $byChannel[$messageChannel] = [];
         }
         if (!isset($byChannel[$messageChannel][$messageChannelId])) {
             $byChannel[$messageChannel][$messageChannelId] = [];
         }
         $byChannel[$messageChannel][$messageChannelId][] = $message;
     }
     // First try to batch process each channel
     foreach ($byChannel as $messageChannel => $channelMessages) {
         foreach ($channelMessages as $messageChannelId => $messages) {
             $event = new MessageQueueBatchProcessEvent($messages, $messageChannel, $messageChannelId);
             $ignore = null;
             $this->dispatchEvent('process_batch_message_queue', $ignore, false, $event);
         }
     }
     unset($byChannel);
     // Now check to see if the message was processed by the listener and if not
     // send it through a single process event listener
     foreach ($queue as $message) {
         if (!$message->isProcessed()) {
             $event = new MessageQueueProcessEvent($message);
             $this->dispatchEvent('process_message_queue', $message, false, $event);
         }
         if ($message->isSuccess()) {
             ++$counter;
             $message->setSuccess();
             $message->setLastAttempt(new \DateTime());
             $message->setDateSent(new \DateTime());
             $message->setStatus(MessageQueue::STATUS_SENT);
         } elseif ($message->isFailed()) {
             // Failure such as email delivery issue or something so retry in a short time
             $this->rescheduleMessage($message, '15M');
         }
         // otherwise assume the listener did something such as rescheduling the message
     }
     //add listener
     $this->saveEntities($queue);
     return $counter;
 }