예제 #1
0
 public function process(MassMailQueue $entry, $batchSize = 100)
 {
     $this->debugOut->writeln('-----------------------------------');
     $this->debugOut->writeln("Starting entry: " . $entry->getSubject());
     $start = $entry->getPosition();
     // Don't change (reduce) our original total after the first time it's
     // set as that could cause us to not send to the complete list of users
     // we originally found with our filter
     $total = max($this->countUsers($entry), $entry->getTotal());
     $this->debugOut->writeln("Found total: {$total}");
     if (!$this->simulate) {
         $entry->setTotal($total);
         $entry->setStatus(MassMailQueue::STATUS_PROCESSING);
         $this->em->flush();
     }
     $complete = false;
     // loop through, constantly fetching from the last user + 1, until nothing left.
     // LIMIT x,y would be slow (needs to look at *all* results even before offset),
     // and prone to duplicate/missing sends if a user changes their preferences mid-process.
     while (true) {
         $currentDate = new \DateTime();
         $userLimit = $batchSize;
         // if not a preview, apply batch limiting
         if ($entry->getType() !== MassMailQueue::TYPE_PREVIEW) {
             $remaining = $this->limiter->getMessagesRemaining($currentDate);
             if ($remaining <= 0) {
                 $this->debugOut->writeln('Reached batch limitations, breaking');
                 break;
             }
             $userLimit = min($userLimit, $remaining);
         }
         // allow pausing
         $this->em->refresh($entry);
         if ($entry->getStatus() === MassMailQueue::STATUS_PAUSED) {
             $this->debugOut->writeln('Entry paused, breaking');
             break;
         }
         $users = $this->fetchUsers($entry, $start, $userLimit);
         if (empty($users)) {
             $this->debugOut->writeln('No more users found, breaking loop');
             // Make sure we're not here because we're over our limit
             if ($remaining > 0) {
                 $complete = true;
             }
             break;
         }
         foreach ($users as $user) {
             $this->debugOut->writeln("User #{$user['id']}; un={$user['username']}; em={$user['email']}; " . "fn={$user['properties']['FirstName']} {$user['properties']['LastName']}");
             if (!$this->simulate) {
                 $html = $this->renderTemplate($entry, $user);
                 $message = \Swift_Message::newInstance($entry->getSubject(), $html, 'text/html', 'utf-8');
                 $message->setFrom('*****@*****.**');
                 try {
                     $message->setTo($user['email']);
                 } catch (\Swift_RfcComplianceException $e) {
                     // Just skip over bad e-mail addresses
                     $this->debugOut->writeln("Skipping badly formatted e-mail address: {$user['email']}");
                     continue;
                 }
                 $headers = $message->getHeaders();
                 $headers->addTextHeader('X-Gc-Type', 'mass');
                 $unsub = $this->getUnsubscribeLink($entry, $user);
                 if ($unsub) {
                     $headers->addTextHeader('List-Unsubscribe', '<' . $this->getUnsubscribeLink($entry, $user) . '>');
                 }
                 $this->mailer->send($message);
             }
             $start = $user['id'] + 1;
         }
         if (!$this->simulate) {
             $entry->setPosition($start);
             $entry->setSent($entry->getSent() + count($users));
             $this->em->flush();
         }
         if ($entry->getType() === MassMailQueue::TYPE_PREVIEW) {
             $complete = true;
             break;
         } else {
             $this->limiter->addMessagesSent($currentDate, count($users));
         }
     }
     if (!$this->simulate) {
         if ($complete) {
             // This is more accurate than the reverse, I think.
             $entry->setTotal($entry->getSent());
             $entry->setStatus(MassMailQueue::STATUS_COMPLETE);
         }
         $this->em->flush();
     }
 }