/** Send element stored in the queue * @return bool if the queue still have values to be sent then return true ( for manual send ) otherwise return false */ function sendQueue($showHTML = false, $mailingId = null, $onlyAutoRsponder = false, $manualSend = false) { $showHTML = true; $stillProcess = null; $maxTask = $manualSend ? $this->limitEmails : $this->maxQueue; if ($maxTask < 1) { $maxTask = 1; } if ($maxTask > 1000) { $maxTask = 1000; } //8889990 $arPRiority = empty($GLOBALS[JNEWS . 'ar_prior']) ? 1 : $GLOBALS[JNEWS . 'ar_prior']; //get all the queue $query = 'SELECT A.qid,A.subscriber_id,A.attempt, A.params as `qparams`, A.delay as `qdelay`, B.* FROM `#__jnews_queue` as A'; $query .= ' LEFT JOIN `#__jnews_mailings` as B on A.mailing_id = B.id '; $query .= ' WHERE A.send_date <= ' . time() . ' AND B.published > 0 AND A.type != 8 AND A.type != 99'; if (!empty($mailingId)) { $query .= ' AND A.mailing_id = ' . $mailingId; } if ($onlyAutoRsponder && $GLOBALS[JNEWS . 'level'] > 1) { $query .= ' AND A.`priority` = ' . $arPRiority; } //do not select the suspend $query .= ' AND `suspend`= 0'; //filter for unconfirmed subscribers $query .= ' AND `block` = 0'; //filter the entries are still being processed from the last sending/processing of the queue $query .= ' ORDER BY A.`priority` ASC, A.send_date ASC'; $query .= ' LIMIT ' . $maxTask; $this->db->setQuery($query); $allQueuedA = $this->db->loadObjectList(); $error = $this->db->getErrorMsg(); if (!empty($error)) { //prompt message if an error occured while retrieving entries from the queue echo '<br><br><span style="font-weight:bold; font-style:italic; color:blue;">' . _JNEWS_QUEUE_PROCESS_ERROR . '<span><br><br>'; echo $error; } if (empty($allQueuedA)) { echo '<br><br><span style="font-weight:bold; font-style:italic; color:blue;">' . _JNEWS_NO_MAILINGS_YET . '<span>'; // prompt message if there is nothing to send jNews_Queue::sendReport(); return false; } //we update the retrieved allQueuedA to blocked so that the entries will not be processed double foreach ($allQueuedA as $oneQueue) { $this->updateQueueBlock($oneQueue->qid, 1); } $totalSubscribers = count($allQueuedA); //make an array of all subscribers and all mailings $mySubcribersA = array(); $subscribersPerMailingsA = array(); foreach ($allQueuedA as $oneQueue) { $mySubcribersA[$oneQueue->subscriber_id] = true; } //get all the subcribers $query = 'SELECT A.`id`,A.`user_id`,A.`name`,A.`email`,A.`receive_html`,A.`confirmed`,A.`blacklist`, B.`id` AS \'user\' '; if ($GLOBALS[JNEWS . 'level'] > 2) { //check if the version of jnews is pro if ($GLOBALS[JNEWS . 'show_column1']) { $query .= ',A.`column1`'; } if ($GLOBALS[JNEWS . 'show_column2']) { $query .= ',A.`column2`'; } if ($GLOBALS[JNEWS . 'show_column3']) { $query .= ',A.`column3`'; } if ($GLOBALS[JNEWS . 'show_column4']) { $query .= ',A.`column4`'; } if ($GLOBALS[JNEWS . 'show_column5']) { $query .= ',A.`column5`'; } } $query .= ' FROM `#__jnews_subscribers` AS A '; $query .= ' LEFT JOIN `#__users` AS B ON A.id=B.id'; $query .= ' WHERE A.`id` IN (' . jnews::implode(',', array_keys($mySubcribersA)) . ' )'; $this->db->setQuery($query); $allSubcribersA = $this->db->loadObjectList('id'); if (empty($allSubcribersA)) { jNews_Queue::sendReport(); return false; } $mailerC = new jNews_ProcessMail(); $queueToBeDelted = array(); $queueToBeAttempted = array(); $queueSuccessfullySent = array(); $addToStatisticsA = array(); $log_detailed = ''; $message = ''; $screenMsg = ''; $maxAttempt = $GLOBALS[JNEWS . 'max_attempts'] < 1 ? 1 : $GLOBALS[JNEWS . 'max_attempts']; if ($this->total == 0) { $this->total = jNews_Queue::getQueueCount($mailingId); } //for manual sending processing if ($manualSend) { if (!headers_sent() and ob_get_level() > 0) { @ob_end_flush(); } $url = JURI::base() . jNews_Tools::completeLink('option=' . JNEWS_OPTION . '&act=mailing&task=continuesend&mailingid=' . $mailingId . '&totalsend=' . $this->total . '&alreadysent=', true, false, true); $screenMsg = "<div style='position:fixed; top:3px;left:3px;color:orange; padding : 3px;'>"; $screenMsg .= "<span id='waitinginfo' style='padding:10px;margin:5px;font-size:16px;font-weight:bold;display:none;background-color:#FFF8C6; color:red;'> </span>"; $screenMsg .= '<i>' . _JNEWS_SENDING_EMAIL . ' <span id="emailcounter"/><strong>' . $this->start . '</strong></span> out of <strong>' . $this->total . '</strong>... </i>'; $screenMsg .= "</div><div id='details' style='display:none; position:fixed; bottom:3px;left:3px;background-color : white; border : 1px solid grey; padding : 3px;'> </div><br /><br />"; $screenMsg .= '<script type="text/javascript" language="javascript">'; $screenMsg .= 'var myEmailCounter = document.getElementById("emailcounter");'; $screenMsg .= 'var details = document.getElementById("details"); var waitinginfo = document.getElementById("waitinginfo"); function setDetails(message){ details.style.display = \'block\';details.innerHTML=message; } function setWaitingInfo(waitingtime){ waitinginfo.style.display = \'\';waitinginfo.innerHTML="Waiting "+waitingtime+" seconds..."; } function setEmailCounter(val){ myEmailCounter.innerHTML=val;} var waitingtime = ' . intval($this->pause) . '; function setWaitingTime(){ setWaitingInfo(waitingtime); if(waitingtime > 0){ waitingtime = waitingtime - 1; setTimeout(\'setWaitingTime()\',1000); }else{ document.location.href=\'' . $url . '\'+myEmailCounter.innerHTML; } } </script>'; echo $screenMsg; if (function_exists('ob_flush')) { @ob_flush(); } else { @flush(); } } //we assign counter for the current email being processed $counterEmail = $this->start; //we determine if the mailings on the queue is lesser than the limit given per batch of manual sending if (count($allQueuedA) < $maxTask) { $stillProcess = false; } //get the size of the queue foreach ($allQueuedA as $oneQueue) { $counterEmail++; if ($manualSend) { echo '<script type="text/javascript" language="javascript">setEmailCounter(' . $counterEmail . ')</script>'; if (function_exists('ob_flush')) { @ob_flush(); } @flush(); } //attachements if (!empty($oneQueue->attachments)) { $oneQueue->attachments = explode("\n", $oneQueue->attachments); if (count($oneQueue->attachments) != 0 && trim($oneQueue->attachments[count($oneQueue->attachments) - 1]) == "") { array_pop($oneQueue->attachments); } } else { $oneQueue->attachments = array(); } //images if (!empty($oneQueue->images)) { $oneQueue->images = explode("\n", $oneQueue->images); } else { $oneQueue->images = array(); } //5 is maximun attempt if ($oneQueue->attempt >= $maxAttempt) { $queueToBeDelted[] = $oneQueue->qid; continue; } if (!isset($this->sentHTML[$oneQueue->id])) { $this->sentHTML[$oneQueue->id] = 0; } if (!isset($this->sentText[$oneQueue->id])) { $this->sentText[$oneQueue->id] = 0; } if (!isset($this->sentFailed[$oneQueue->id])) { $this->sentFailed[$oneQueue->id] = 0; } if (isset($allSubcribersA[$oneQueue->subscriber_id]) && is_object($allSubcribersA[$oneQueue->subscriber_id])) { $emailSentStatus = $mailerC->send($oneQueue, $allSubcribersA[$oneQueue->subscriber_id]); if ($emailSentStatus) { //we update the senddate of the newsletter jNews_Mailing::updatesenddate($oneQueue->id); } } else { continue; } if (!empty($allSubcribersA[$oneQueue->subscriber_id]->email)) { if ($GLOBALS[JNEWS . 'save_log']) { if (!$emailSentStatus) { $log_detailed .= '[' . $oneQueue->id . '] ' . $oneQueue->subject . ' : ' . $allSubcribersA[$oneQueue->subscriber_id]->email . ' -> ' . _JNEWS_MESSAGE_NOT . "\r\n" . _JNEWS_MAILER_ERROR . ': ' . $mailerC->ErrorInfo . "\r\n"; } else { $log_detailed .= '[' . $oneQueue->id . '] ' . $oneQueue->subject . ' : ' . $allSubcribersA[$oneQueue->subscriber_id]->email . ' -> ' . _JNEWS_MESSAGE_SENT_SUCCESSFULLY . "\r\n"; } } else { $log_detailed .= '[' . $oneQueue->id . '] ' . $oneQueue->subject . ' : ' . $allSubcribersA[$oneQueue->subscriber_id]->email . ' -> ' . _JNEWS_MESSAGE_SENT_SUCCESSFULLY . "\r\n"; } } //Screen message for manual sending if ($manualSend) { if ($emailSentStatus) { $message = '<strong><i>' . $oneQueue->subject . '</i></strong> ' . _JNEWS_MSG_SENT_SUCCESS . ' <strong><i>' . $allSubcribersA[$oneQueue->subscriber_id]->name . ' ( ' . $allSubcribersA[$oneQueue->subscriber_id]->email . ' )</i></strong>' . "\r\n"; } else { $message = '<i>' . _JNEWS_ATTEMPTED . ' ' . $oneQueue->subject . ' to ' . $allSubcribersA[$oneQueue->subscriber_id]->name . ' ( ' . $allSubcribersA[$oneQueue->subscriber_id]->email . ' )' . ".\r\n" . _JNEWS_RESCHEDULED . "\r\n\r\n" . _JNEWS_REACHED_MAX_ATTEMPT . "</i>\r\n\r\n"; } $this->_displayDetails($message, $emailSentStatus, $counterEmail); } if ($emailSentStatus) { //succeess send $query = 'DELETE FROM `#__jnews_queue` WHERE `qid`=' . $oneQueue->qid; $this->db->setQuery($query); $this->db->query(); if ($mailerC->html) { $this->sentHTML[$oneQueue->id]++; } else { $this->sentText[$oneQueue->id]++; } //user statistics if ($GLOBALS[JNEWS . 'enable_statistics'] && $GLOBALS[JNEWS . 'statistics_per_subscriber']) { $addToStatisticsA[$oneQueue->id][$oneQueue->subscriber_id] = (int) $mailerC->html; } $this->sentSuccess++; $this->recurringError = 0; $queueSuccessfullySent[] = $oneQueue->qid; //we save the successfully sent qids so that we can differentiate from the allqueue what qids that were not processed because the max execution time has been reached } else { // failed send $queueToBeAttempted[] = $oneQueue->qid; $this->sentFailed[$oneQueue->id]++; $this->recurringError++; } $time = time(); if ($this->maxExetime != 0 && $this->maxExetime <= $time) { $stillProcess = true; break; } if ($this->recurringError > 2 && $this->sentSuccess > 3) { $stillProcess = false; break; } if ($this->recurringError > 5 || connection_aborted()) { $stillProcess = false; break; } } //we close the processing of emails $mail = JFactory::getMailer(); $mailerC->close($mail); if (!empty($this->total) && $counterEmail >= $this->total) { $stillProcess = false; } //update queue with try + 1; if (!empty($queueToBeAttempted)) { $query = 'UPDATE `#__jnews_queue` SET `attempt`=`attempt`+1,`send_date`=`send_date`+`attempt`*25299+4000, `block`= 0 WHERE `qid` IN (' . jnews::implode(',', $queueToBeAttempted) . ')'; //we will also update the block to 0 so that it will be processed again $this->db->setQuery($query); $this->db->query(); } //delete the queue when the emails are sent successfully after x number of attempts if (!empty($queueToBeDelted)) { $query = 'DELETE FROM `#__jnews_queue` WHERE `qid` IN (' . jnews::implode(',', $queueToBeDelted) . ')'; $this->db->setQuery($query); $this->db->query(); } //unblock again the queue that were not sent because the timeout has been reached so that they will be processed again if (!empty($allQueuedA)) { foreach ($allQueuedA as $oneQueue) { if (!in_array($oneQueue->qid, $queueSuccessfullySent)) { $query = 'UPDATE `#__jnews_queue` SET `block` = 0 WHERE `qid` =' . $oneQueue->qid; $this->db->setQuery($query); $this->db->query(); } } } //we update and increment the statistics if ($GLOBALS[JNEWS . 'enable_statistics']) { $this->_updateStatsGlobal($allQueuedA); } if (!empty($addToStatisticsA)) { $this->_insertStats($addToStatisticsA); } //we prompt message that the mailing has been sent successfully for each batch // echo '<br><br><span style="font-weight:bold; font-style:italic; color:green;">'.$oneQueue->subject.' successfully sent to subscribers.'.'</span> '; //mailing reports $this->_writeLogs($log_detailed); if (isset($stillProcess)) { //manual sending if ($stillProcess && $manualSend) { echo '<script type="text/javascript" language="javascript">setWaitingTime();</script>'; } else { echo '<br><br><span style="font-weight:bold; font-style:italic; color:green;">' . _JNEWS_THE_MAILING . $oneQueue->subject . _JNEWS_SENT_ALL . '</span> '; // $subject = 'jNews Mailing Notification - Status: End'; // $content = 'The mailing '.$oneQueue->subject.' has been successfully sent.'; // if( version_compare(JVERSION,'1.6.0','<') ){ //j15 // $this->db->setQuery( "SELECT * FROM `#__users` WHERE `gid` = 25 ORDER BY `id` ASC LIMIT 1" ); // }else{ // $this->db->setQuery( "SELECT * FROM `#__users` AS U LEFT JOIN `#__user_usergroup_map` AS UGM ON U.id =UGM.user_id WHERE `group_id` = 8 ORDER BY `id` ASC LIMIT 1" ); // } // $admin = $this->db->loadObject(); // // JUTility::sendMail($admin->email, $admin->name, $admin->email, $subject, $content ); } if (!$stillProcess) { jNews_Queue::sendReport(); } return $stillProcess ? true : false; } else { //manual sending if ($manualSend && $maxTask < $this->total) { echo '<script type="text/javascript" language="javascript">setWaitingTime();</script>'; } else { echo '<br><br><span style="font-weight:bold; font-style:italic; color:green;">' . _JNEWS_THE_MAILING . $oneQueue->subject . _JNEWS_SENT_ALL . '</span> '; // $subject = 'jNews Mailing Notification - Status: End'; // $content = 'The mailing '.$oneQueue->subject.' has been successfully sent.'; // if( version_compare(JVERSION,'1.6.0','<') ){ //j15 // $this->db->setQuery( "SELECT * FROM `#__users` WHERE `gid` = 25 ORDER BY `id` ASC LIMIT 1" ); // }else{ // $this->db->setQuery( "SELECT * FROM `#__users` AS U LEFT JOIN `#__user_usergroup_map` AS UGM ON U.id =UGM.user_id WHERE `group_id` = 8 ORDER BY `id` ASC LIMIT 1" ); // } // $admin = $this->db->loadObject(); // // JUTility::sendMail($admin->email, $admin->name, $admin->email, $subject, $content ); } if ($this->maxQueue > count($allQueuedA)) { jNews_Queue::sendReport(); } return $this->maxQueue > count($allQueuedA) ? false : true; } }