Ejemplo n.º 1
0
    /** 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;
        }
    }