Ejemplo n.º 1
0
 public static function sendReport($subject, $message)
 {
     $report_addresses = explode(',', Config::get('report_address'));
     foreach ($report_addresses as $address) {
         phpListMailer::sendMail($address, Config::get('installation_name') . ' ' . $subject, $message);
     }
     /*TODO: enable plugins
       foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
           $plugin->sendReport(Config::get('installation_name').' '.$subject,$message);
       }*/
 }
Ejemplo n.º 2
0
 /**
  * @throws \Exception
  */
 public function startProcessing()
 {
     $this->preflightCheck();
     # lets not do this unless we do some locking first
     register_shutdown_function(array(&$this, 'processBouncesShutdown'));
     ignore_user_abort(1);
     if (Config::get('commandline', false) !== false && Config::get('commandline_force', false) !== false) {
         # force set, so kill other processes
         phpList::log()->info('Force set, killing other send processes', ['page' => 'procesbounces']);
         $this->process_id = Process::getPageLock('BounceProcessor', true);
     } else {
         $this->process_id = Process::getPageLock('BounceProcessor');
     }
     if (empty($this->process_id)) {
         return;
     }
     switch (Config::BOUNCE_PROTOCOL) {
         case 'pop':
             $this->processPop(Config::BOUNCE_MAILBOX_HOST, Config::BOUNCE_MAILBOX_USER, Config::BOUNCE_MAILBOX_PASSWORD);
             break;
         case 'mbox':
             $this->processMbox(Config::BOUNCE_MAILBOX);
             break;
         default:
             phpList::log()->critical(s('bounce_protocol not supported'), ['page' => 'processbounces']);
             return;
     }
     # now we have filled database with all available bounces
     ## reprocess the unidentified ones, as the bounce detection has improved, so it might catch more
     phpList::log()->info('reprocessing', ['page' => 'procesbounces']);
     $reparsed = $count = 0;
     $reidentified = 0;
     $result = phpList::DB()->query(sprintf('SELECT * FROM %s
             WHERE status = "unidentified bounce"', Config::getTableName('bounce')));
     $total = $result->rowCount();
     phpList::log()->info(s('%d bounces to reprocess', $total), ['page' => 'procesbounces']);
     while ($bounce = $result->fetch(\PDO::FETCH_ASSOC)) {
         $count++;
         if ($count % 25 == 0) {
             Output::cl_progress(s('%d out of %d processed', $count, $total));
         }
         $bounceBody = $this->decodeBody($bounce->header, $bounce->data);
         $subscriber = $this->findSubscriber($bounceBody);
         $campaign_id = $this->findCampaignId($bounceBody);
         if ($subscriber !== false || !empty($campaign_id)) {
             $reparsed++;
             if ($this->processBounceData($bounce['id'], $campaign_id, $subscriber->id)) {
                 $reidentified++;
             }
         }
     }
     phpList::log()->info(s('%d out of %d processed', $count, $total), ['page' => 'procesbounces']);
     if (Config::VERBOSE) {
         $this->output(s('%d bounces were re-processed and %d bounces were re-identified', $reparsed, $reidentified));
     }
     $advanced_report = '';
     if (Config::USE_ADVANCED_BOUNCEHANDLING) {
         $this->output(s('Processing bounces based on active bounce rules'));
         $bouncerules = BounceRule::getAllBounceRules();
         $matched = 0;
         $notmatched = 0;
         //$limit =  ' limit 10';
         //$limit =  ' limit 10000';
         $limit = '';
         # @@ not sure whether this one would make sense
         #  $result = Sql_Query(sprintf('select * from %s as bounce, %s as umb,%s as user where bounce.id = umb.bounce
         #    and user.id = umb.user and !user.confirmed and !user.blacklisted %s',
         #    $GLOBALS['tables']['bounce'],$GLOBALS['tables']['user_message_bounce'],$GLOBALS['tables']['user'],$limit));
         $result = phpList::DB()->query(sprintf('SELECT * FROM %s AS bounce, %s AS umb
                 WHERE bounce.id = umb.bounce %s', Config::getTableName('bounce'), Config::getTableName('user_message_bounce'), $limit));
         while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
             $alive = Process::checkLock($this->process_id);
             if ($alive) {
                 Process::keepLock($this->process_id);
             } else {
                 $this->bounceProcessError(s('Process Killed by other process'));
             }
             #    output('Subscriber '.$row['user']);
             $rule = BounceRule::matchedBounceRules($row['data'], $bouncerules);
             #    output('Action '.$rule['action']);
             #    output('Rule'.$rule['id']);
             if ($rule && is_array($rule)) {
                 if ($row['user']) {
                     $subscriber = Subscriber::getSubscriber($row['user']);
                 }
                 $report_linkroot = Config::get('admin_scheme') . '://' . Config::get('website') . Config::get('adminpages');
                 phpList::DB()->query(sprintf('UPDATE %s SET count = count + 1
                         WHERE id = %d', Config::getTableName('bounceregex'), $rule['id']));
                 phpList::DB()->query(sprintf('INSERT IGNORE INTO %s
                         (regex,bounce)
                         VALUES(%d,%d)', Config::getTableName('bounceregex_bounce'), $rule['id'], $row['bounce']));
                 switch ($rule['action']) {
                     case 'deletesubscriber':
                         phpList::log()->notice('Subscriber ' . $subscriber->getEmailAddress() . ' deleted by bounce rule ' . PageLink2('bouncerule&id=' . $rule['id'], $rule['id']));
                         $advanced_report .= 'Subscriber ' . $subscriber->getEmailAddress() . ' deleted by bounce rule ' . $rule['id'] . "\n";
                         $advanced_report .= 'Subscriber: ' . $report_linkroot . '/?page=subscriber&id=' . $subscriber->id . "\n";
                         $advanced_report .= 'Rule: ' . $report_linkroot . '/?page=bouncerule&id=' . $rule['id'] . "\n";
                         $subscriber->delete();
                         break;
                     case 'unconfirmsubscriber':
                         phpList::log()->notice('Subscriber ' . $subscriber->getEmailAddress() . ' unconfirmed by bounce rule ' . PageLink2('bouncerule&id=' . $rule['id'], $rule['id']));
                         $subscriber->confirmed = 0;
                         $subscriber->update();
                         $advanced_report .= 'Subscriber ' . $subscriber->getEmailAddress() . ' made unconfirmed by bounce rule ' . $rule['id'] . "\n";
                         $advanced_report .= 'Subscriber: ' . $report_linkroot . '/?page=subscriber&id=' . $subscriber->id . "\n";
                         $advanced_report .= 'Rule: ' . $report_linkroot . '/?page=bouncerule&id=' . $rule['id'] . "\n";
                         $subscriber->addHistory(s('Auto Unconfirmed'), s('Subscriber auto unconfirmed for') . " " . s('bounce rule') . ' ' . $rule['id'], $subscriber->id);
                         Util::addSubscriberStatistics('auto unsubscribe', 1);
                         break;
                     case 'deletesubscriberandbounce':
                         phpList::log()->notice('Subscriber ' . $row['user'] . ' deleted by bounce rule ' . PageLink2('bouncerule&id=' . $rule['id'], $rule['id']));
                         $advanced_report .= 'Subscriber ' . $subscriber->getEmailAddress() . ' deleted by bounce rule ' . $rule['id'] . "\n";
                         $advanced_report .= 'Subscriber: ' . $report_linkroot . '/?page=subscriber&id=' . $subscriber->id . "\n";
                         $advanced_report .= 'Rule: ' . $report_linkroot . '/?page=bouncerule&id=' . $rule['id'] . "\n";
                         $subscriber->delete();
                         Bounce::deleteBounce($row['bounce']);
                         break;
                     case 'unconfirmsubscriberanddeletebounce':
                         phpList::log()->notice('Subscriber ' . $subscriber->getEmailAddress() . ' unconfirmed by bounce rule ' . PageLink2('bouncerule&id=' . $rule['id'], $rule['id']));
                         $subscriber->confirmed = 0;
                         $subscriber->update();
                         $advanced_report .= 'Subscriber ' . $subscriber->getEmailAddress() . ' made unconfirmed by bounce rule ' . $rule['id'] . "\n";
                         $advanced_report .= 'Subscriber: ' . $report_linkroot . '/?page=subscriber&id=' . $subscriber->id . "\n";
                         $advanced_report .= 'Rule: ' . $report_linkroot . '/?page=bouncerule&id=' . $rule['id'] . "\n";
                         $subscriber->addHistory(s('Auto unconfirmed'), s('Subscriber auto unconfirmed for') . " " . s("bounce rule") . ' ' . $rule['id'], $subscriber->id);
                         Util::addSubscriberStatistics('auto unsubscribe', 1);
                         Bounce::deleteBounce($row['bounce']);
                         break;
                     case 'blacklistsubscriber':
                         phpList::log()->notice('Subscriber ' . $subscriber->getEmailAddress() . ' blacklisted by bounce rule ' . PageLink2('bouncerule&id=' . $rule['id'], $rule['id']));
                         $subscriber->blacklistSubscriber($subscriber->getEmailAddress(), s("Auto Blacklisted"), s("Subscriber auto blacklisted for") . " " . s("bounce rule") . ' ' . $rule['id']);
                         $advanced_report .= 'Subscriber ' . $subscriber->getEmailAddress() . ' blacklisted by bounce rule ' . $rule['id'] . "\n";
                         $advanced_report .= 'Subscriber: ' . $report_linkroot . '/?page=subscriber&id=' . $subscriber->id . "\n";
                         $advanced_report .= 'Rule: ' . $report_linkroot . '/?page=bouncerule&id=' . $rule['id'] . "\n";
                         $subscriber->addHistory(s("Auto Unsubscribed"), s("Subscriber auto unsubscribed for") . " " . s("bounce rule") . ' ' . $rule['id'], $subscriber->id);
                         Util::addSubscriberStatistics('auto blacklist', 1);
                         break;
                     case 'blacklistsubscriberanddeletebounce':
                         phpList::log()->notice('Subscriber ' . $subscriber->getEmailAddress() . ' blacklisted by bounce rule ' . PageLink2('bouncerule&id=' . $rule['id'], $rule['id']));
                         $subscriber->blacklistSubscriber($subscriber->getEmailAddress(), s("Auto Blacklisted"), s("Subscriber auto blacklisted for") . " " . s("bounce rule") . ' ' . $rule['id']);
                         $advanced_report .= 'Subscriber ' . $subscriber->getEmailAddress() . ' blacklisted by bounce rule ' . $rule['id'] . "\n";
                         $advanced_report .= 'Subscriber: ' . $report_linkroot . '/?page=subscriber&id=' . $subscriber->id . "\n";
                         $advanced_report .= 'Rule: ' . $report_linkroot . '/?page=bouncerule&id=' . $rule['id'] . "\n";
                         $subscriber->addHistory(s("Auto Unsubscribed"), s("Subscriber auto unsubscribed for") . " " . s("bounce rule") . ' ' . $rule['id'], $subscriber->id);
                         Util::addSubscriberStatistics('auto blacklist', 1);
                         Bounce::deleteBounce($row['bounce']);
                         break;
                     case 'deletebounce':
                         Bounce::deleteBounce($row['bounce']);
                         break;
                 }
                 $matched++;
             } else {
                 $notmatched++;
             }
         }
         $this->output($matched . ' ' . s('bounces processed by advanced processing'));
         $this->output($notmatched . ' ' . s('bounces were not matched by advanced processing rules'));
     }
     # have a look who should be flagged as unconfirmed
     $this->output(s("Identifying consecutive bounces"));
     # we only need subscriber who are confirmed at the moment
     $subscriberid_result = phpList::DB()->query(sprintf('SELECT DISTINCT umb.user FROM %s AS umb, %s AS u
             WHERE u.id = umb.user
             AND u.confirmed', Config::getTableName('user_message_bounce'), Config::getTableName('user', true)));
     if ($subscriberid_result->rowCount() <= 0) {
         $this->output(s("Nothing to do"));
     }
     $subscribercnt = 0;
     $unsubscribed_subscribers = "";
     while ($subscriber = $subscriberid_result->fetch(\PDO::FETCH_ASSOC)) {
         Process::keepLock($this->process_id);
         set_time_limit(600);
         $msg_req = phpList::DB()->query(sprintf('SELECT * FROM %s AS um
                 LEFT JOIN %s AS umb
                   ON (um.messageid = umb.message AND userid = user)
                 WHERE userid = %d
                   AND um.status = "sent"
                 ORDER BY entered DESC', Config::getTableName('usermessage'), Config::getTableName('user_message_bounce'), $subscriber[0]));
         /*  $cnt = 0;
             $alive = 1;$removed = 0;
             while ($alive && !$removed && $bounce = Sql_Fetch_Array($msg_req)) {
               $alive = checkLock($process_id);
               if ($alive)
                 keepLock($process_id);
               else
                 ProcessError(s("Process Killed by other process"));
               if (sprintf('%d',$bounce['bounce']) == $bounce['bounce']) {
                 $cnt++;
                 if ($cnt >= $bounce_unsubscribe_threshold) {
                   $removed = 1;
                   output(sprintf('unsubscribing %d -> %d bounces',$subscriber[0],$cnt));
                   $subscriberurl = PageLink2("user&amp;id=$subscriber[0]",$subscriber[0]);
                   logEvent(s("Subscriber")." $subscriberurl ".s("has consecutive bounces")." ($cnt) ".s("over threshold, user marked unconfirmed"));
                   $emailreq = Sql_Fetch_Row_Query("select email from {$tables['user']} where id = $subscriber[0]");
                   addSubscriberHistory($emailreq[0],s("Auto Unsubscribed"),s("Subscriber auto unsubscribed for")." $cnt ".s("consecutive bounces"));
                   Sql_Query(sprintf('update %s set confirmed = 0 where id = %d',$tables['user'],$subscriber[0]));
                   addSubscriberStatistics('auto unsubscribe',1);
                   $email_req = Sql_Fetch_Row_Query(sprintf('select email from %s where id = %d',$tables['user'],$subscriber[0]));
                   $unsubscribed_users .= $email_req[0] . " [$subscriber[0]] ($cnt)\n";
                 }
               } elseif ($bounce['bounce'] == "") {
                 $cnt = 0;
               }
             }*/
         #$alive = 1;$removed = 0; DT 051105
         $cnt = 0;
         $alive = 1;
         $removed = $msgokay = $unconfirmed = $unsubscribed = 0;
         #while ($alive && !$removed && $bounce = Sql_Fetch_Array($msg_req)) { DT 051105
         while ($alive && !$removed && !$msgokay && ($bounce = $msg_req->fetch(\PDO::FETCH_ASSOC))) {
             $alive = Process::checkLock($this->process_id);
             if ($alive) {
                 Process::keepLock($this->process_id);
             } else {
                 $this->bounceProcessError('Process Killed by other process');
             }
             if (sprintf('%d', $bounce['bounce']) == $bounce['bounce']) {
                 $cnt++;
                 if ($cnt >= Config::BOUNCE_UNSUBSCRIBE_THRESHOLD) {
                     if (!$unsubscribed) {
                         $this->output(sprintf('unsubscribing %d -> %d bounces', $subscriber[0], $cnt));
                         $subscriberurl = PageLink2("user&amp;id={$subscriber['0']}", $subscriber[0]);
                         phpList::log()->notice(s('Subscriber (url:%s) has consecutive bounces (%d) over threshold (%d), user marked unconfirmed', $subscriberurl, $cnt, Config::BOUNCE_UNSUBSCRIBE_THRESHOLD));
                         Subscriber::addHistory(s('Auto Unconfirmed'), s('Subscriber auto unconfirmed for %d consecutive bounces', $cnt), $subscriber[0]);
                         phpList::DB()->query(sprintf('UPDATE %s SET confirmed = 0
                                 WHERE id = %d', Config::getTableName('user', true), $subscriber[0]));
                         $email_req = phpList::DB()->query(sprintf('SELECT email FROM %s WHERE id = %d', Config::getTableName('user', true), $subscriber[0]));
                         $unsubscribed_subscribers .= $email_req[0] . "\t\t({$cnt})\t\t" . Config::get('scheme') . '://' . Config::get('website') . Config::get('adminpages') . '/?page=user&amp;id=' . $subscriber[0] . "\n";
                         $unsubscribed = 1;
                     }
                     if (Config::get('BLACKLIST_EMAIL_ON_BOUNCE') && $cnt >= Config::get('BLACKLIST_EMAIL_ON_BOUNCE')) {
                         $removed = 1;
                         #0012262: blacklist email when email bounces
                         phpList::log()->info(s('%d consecutive bounces, threshold reached, blacklisting subscriber', $cnt), ['page' => 'procesbounces']);
                         Subscriber::blacklistSubscriber($subscriber[0], s('%d consecutive bounces, threshold reached', $cnt));
                     }
                 }
             } elseif ($bounce['bounce'] == '') {
                 #$cnt = 0; DT 051105
                 $cnt = 0;
                 $msgokay = 1;
                 #DT 051105 - escaping loop if message received okay
             }
         }
         if ($subscribercnt % 5 == 0) {
             #    output(s("Identifying consecutive bounces"));
             phpList::log()->info(s('processed %d out of %d subscribers', $subscribercnt, $total), ['page' => 'procesbounces']);
         }
         $subscribercnt++;
     }
     #output(s("Identifying consecutive bounces"));
     $this->output("\n" . s('total of %d subscribers processed', $total) . '                            ');
     /*
     $report = '';
     
     if (phpList::log()->getReport()) {
         $report .= s('Report:')."\n" . phpList::log()->getReport() . "\n";
     }
     
     if ($advanced_report) {
         $report .= s('Report of advanced bounce processing:')."\n$advanced_report\n";
     }
     if ($unsubscribed_subscribers) {
         $report .= "\n".s('Below are subscribers who have been marked unconfirmed. The in () is the number of consecutive bounces.')."\n";
         $report .= "\n$unsubscribed_subscribers";
     } else {
         # don't send a report email, if only some bounces were downloaded, but no subscribers unsubscribed.
         $report = '';
     }
     # shutdown will take care of reporting
     #finish("info",$report);
     */
     # IMAP errors following when Notices are on are a PHP bug
     # http://bugs.php.net/bug.php?id=7207
 }
Ejemplo n.º 3
0
 /**
  * Delete expired tokens from the database
  */
 public static function deleteOldTokens()
 {
     phpList::DB()->query(sprintf('DELETE FROM %s
             WHERE date_add( date, INTERVAL %s) < CURRENT_TIMESTAMP', Config::getTableName('admin_password_request'), Config::get('password_change_timeframe')), 1);
     phpList::DB()->query(sprintf('DELETE FROM %s
             WHERE expires < CURRENT_TIMESTAMP', Config::getTableName('admintoken')), 1);
 }
Ejemplo n.º 4
0
 public static function getPageLock($page, $force = false)
 {
     $commandline = Config::get('commandline', false);
     if ($commandline && $page == 'processqueue') {
         //TODO: implement memcached_enabled config
         if (Config::get('memcached_enabled', false)) {
             ## multi-send requires a valid memcached setup
             $max = Config::get('MAX_SENDPROCESSES');
         } else {
             $max = 1;
         }
     } else {
         $max = 1;
     }
     ## allow killing other processes
     if ($force) {
         phpList::DB()->query(sprintf('DELETE FROM %s
                 WHERE page = "%s"', Config::getTableName('sendprocess'), $page));
     }
     $running_processes = self::getRunningProcesses($page);
     phpList::log()->info($running_processes['count'] . ' out of ' . $max . ' active processes', ['page' => 'process']);
     $waited = 0;
     # while ($running_res['age'] && $count >= $max) { # a process is already running
     while ($running_processes['count'] >= $max) {
         # don't check age, as it may be 0
         #   cl_output('running process: '.$running_res['age'].' '.$max);
         if ($running_processes['result']['age'] > 600) {
             # some sql queries can take quite a while
             #cl_output($running_res['id'].' is old '.$running_res['age']);
             # process has been inactive for too long, kill it
             phpList::DB()->query(sprintf('UPDATE %s SET alive = 0
                     WHERE id = %d', Config::getTableName('sendprocess'), $running_processes['result']['id']));
         } elseif ((int) $running_processes['count'] >= (int) $max) {
             phpList::log()->log(sprintf(s('A process for this page is already running and it was still alive %s seconds ago'), $running_processes['result']['age']), ['page' => 'process']);
             sleep(1);
             # to log the messages in the correct order
             if ($commandline) {
                 phpList::log()->info(s('Running commandline, quitting. We\'ll find out what to do in the next run.'), ['page' => 'process']);
                 exit;
             }
             phpList::log()->info(s('Sleeping for 20 seconds, aborting will quit'), ['page' => 'process']);
             flush();
             ignore_user_abort(0);
             sleep(20);
         }
         $waited++;
         if ($waited > 10) {
             # we have waited 10 cycles, abort and quit script
             phpList::log()->info(s('We have been waiting too long, I guess the other process is still going ok'), ['page' => 'process']);
             return false;
         }
     }
     $processIdentifier = $_SERVER['REMOTE_ADDR'];
     if ($commandline) {
         $processIdentifier = Config::get('SENDPROCESS_SERVERNAME') . ':' . getmypid();
     }
     phpList::DB()->query(sprintf('INSERT INTO %s (started, page, alive, ipaddress)
             VALUES(CURRENT_TIMESTAMP, "%s", 1, "%s")', Config::getTableName('sendprocess'), $page, $processIdentifier));
     $send_process_id = phpList::DB()->insertedId();
     ignore_user_abort(1);
     #  cl_output('Got pagelock '.$send_process_id );
     return $send_process_id;
 }
Ejemplo n.º 5
0
 /**
  * Load campaign in memory cache
  * @param Campaign $campaign
  * @param bool $forwardContent
  * @return bool
  */
 public static function precacheCampaign($campaign, $forwardContent = false)
 {
     $domain = Config::get('domain');
     /**
      * @var Campaign $cached_campaign
      */
     $cached_campaign =& Cache::getCachedCampaign($campaign);
     ## the reply to is actually not in use
     if (preg_match('/([^ ]+@[^ ]+)/', $campaign->replyto, $regs)) {
         # if there is an email in the from, rewrite it as "name <email>"
         $campaign->replyto = str_replace($regs[0], '', $campaign->replyto);
         $cached_campaign->replytoemail = $regs[0];
         # if the email has < and > take them out here
         $cached_campaign->replytoemail = str_replace(array('<', '>'), '', $cached_campaign->replytoemail);
         //$cached->replytoemail = str_replace('>', '', $cached->replytoemail);
         # make sure there are no quotes around the name
         $cached_campaign->replytoname = str_replace('"', '', ltrim(rtrim($campaign->replyto)));
     } elseif (strpos($campaign->replyto, ' ')) {
         # if there is a space, we need to add the email
         $cached_campaign->replytoname = $campaign->replyto;
         $cached_campaign->replytoemail = "listmaster@{$domain}";
     } else {
         if (!empty($campaign->replyto)) {
             $cached_campaign->replytoemail = "{$campaign->replyto}@{$domain}";
             ## makes more sense not to add the domain to the word, but the help says it does
             ## so let's keep it for now
             $cached_campaign->replytoname = "{$campaign->replyto}@{$domain}";
         }
     }
     //$cached_campaign->fromname = $campaign->fromname;
     //$cached_campaign->fromemail = $campaign->fromemail;
     $cached_campaign->to = $campaign->tofield;
     #0013076: different content when forwarding 'to a friend'
     $cached_campaign->subject = $forwardContent ? stripslashes($campaign->forwardsubject) : $campaign->subject;
     #0013076: different content when forwarding 'to a friend'
     $cached_campaign->content = $forwardContent ? stripslashes($campaign->forwardcampaign) : $campaign->campaign;
     if (Config::USE_MANUAL_TEXT_PART && !$forwardContent) {
         $cached_campaign->textcontent = $campaign->textcampaign;
     } else {
         $cached_campaign->textcontent = '';
     }
     #var_dump($cached);exit;
     #0013076: different content when forwarding 'to a friend'
     $cached_campaign->footer = $forwardContent ? stripslashes($campaign->forwardfooter) : $campaign->footer;
     if (strip_tags($cached_campaign->footer) != $cached_campaign->footer) {
         $cached_campaign->textfooter = String::HTML2Text($cached_campaign->footer);
         $cached_campaign->htmlfooter = $cached_campaign->footer;
     } else {
         $cached_campaign->textfooter = $cached_campaign->footer;
         $cached_campaign->htmlfooter = PrepareCampaign::parseText($cached_campaign->footer);
     }
     $cached_campaign->htmlformatted = strip_tags($cached_campaign->content) != $cached_campaign->content;
     //$cached_campaign->sendformat = $campaign->sendformat;
     ## @@ put this here, so it can become editable per email sent out at a later stage
     $cached_campaign->html_charset = 'UTF-8';
     #Config::get('html_charset');
     ## @@ need to check on validity of charset
     /*if (!$cached_campaign->html_charset) {
           $cached_campaign->html_charset = 'UTF-8'; #'iso-8859-1';
       }*/
     $cached_campaign->text_charset = 'UTF-8';
     #Config::get('text_charset');
     /*if (!$cached_campaign->text_charset) {
           $cached_campaign->text_charset = 'UTF-8'; #'iso-8859-1';
       }*/
     ## if we are sending a URL that contains subscriber attributes, we cannot pre-parse the campaign here
     ## but that has quite some impact on speed. So check if that's the case and apply
     $cached_campaign->subscriberspecific_url = preg_match('/\\[.+\\]/', $campaign->sendurl);
     if (!$cached_campaign->subscriberspecific_url) {
         ## Fetch external content here, because URL does not contain placeholders
         if (Config::get('canFetchUrl') && preg_match('/\\[URL:([^\\s]+)\\]/i', $cached_campaign->content, $regs)) {
             $remote_content = Util::fetchUrl($regs[1]);
             #  $remote_content = fetchUrl($campaign['sendurl'],array());
             # @@ don't use this
             #      $remote_content = includeStyles($remote_content);
             if ($remote_content) {
                 $cached_campaign->content = str_replace($regs[0], $remote_content, $cached_campaign->content);
                 #  $cached[$campaign_id]['content'] = $remote_content;
                 $cached_campaign->htmlformatted = strip_tags($remote_content) != $remote_content;
             } else {
                 #print Error(s('unable to fetch web page for sending'));
                 phpList::log()->notice("Error fetching URL: " . $campaign->sendurl . ' cannot proceed');
                 return false;
             }
         }
         if (Config::VERBOSE && Config::get('getspeedstats', false) !== false) {
             phpList::log()->debug('fetch URL end', ['page' => 'preparecampaign']);
         }
         /*
         print $campaign->sendurl;
         print $remote_content;exit;
         */
     }
     // end if not subscriberspecific url
     /*if ($cached_campaign->htmlformatted) {
           #   $cached->content = String::compressContent($cached->content);
       }*/
     //$cached_campaign->google_track = $campaign->google_track;
     /*
         else {
     print $campaign->sendurl;
     exit;
     }
     */
     if (Config::VERBOSE && Config::get('getspeedstats', false) !== false) {
         phpList::log()->debug('parse config start', ['page' => 'preparecampaign']);
     }
     /*
              * this is not a good idea, as it'll replace eg "unsubscribeurl" with a general one instead of personalised
              *   if (is_array($GLOBALS['default_config'])) {
       foreach($GLOBALS['default_config'] as $key => $val) {
         if (is_array($val)) {
           $cached[$campaign_id]['content'] = str_ireplace("[$key]",Config::get($key),$cached[$campaign_id]['content']);
           $cached->textcontent = str_ireplace("[$key]",Config::get($key),$cached->textcontent);
           $cached->textfooter = str_ireplace("[$key]",Config::get($key),$cached[$campaign_id]['textfooter']);
           $cached->htmlfooter = str_ireplace("[$key]",Config::get($key),$cached[$campaign_id]['htmlfooter']);
         }
       }
     }
     */
     if (Config::VERBOSE && Config::get('getspeedstats', false) !== false) {
         phpList::log()->debug('parse config end', ['page' => 'preparecampaign']);
     }
     /*TODO: figure out what this does
       foreach ($campaign as $key => $val) {
           if (!is_array($val)) {
               $cached_campaign->content = str_ireplace("[$key]", $val, $cached_campaign->content);
               $cached_campaign->textcontent = str_ireplace("[$key]", $val, $cached_campaign->textcontent);
               $cached_campaign->textfooter = str_ireplace("[$key]", $val, $cached_campaign->textfooter);
               $cached_campaign->htmlfooter = str_ireplace("[$key]", $val, $cached_campaign->htmlfooter);
           }
       }*/
     if (preg_match("/##LISTOWNER=(.*)/", $cached_campaign->content, $regs)) {
         $cached_campaign->listowner = $regs[1];
         $cached_campaign->content = str_replace($regs[0], '', $cached_campaign->content);
     } else {
         $cached_campaign->listowner = 0;
     }
     if (!empty($cached_campaign->listowner)) {
         $att_result = phpList::DB()->query(sprintf('SELECT name,value FROM %s AS aa, %s AS a_a
             WHERE aa.id = a_a.adminattributeid AND aa.adminid = %d', Config::getTableName('adminattribute'), Config::getTableName('admin_attribute'), $cached_campaign->listowner));
         while ($att = $att_result->fetch(\PDO::FETCH_ASSOC)) {
             $cached_campaign->content = preg_replace('#\\[LISTOWNER.' . strtoupper(preg_quote($att['name'])) . '\\]#', $att['value'], $cached_campaign->content);
         }
     }
     $baseurl = Config::get('website');
     if (Config::UPLOADIMAGES_DIR != null) {
         ## escape subdirectories, otherwise this renders empty
         $dir = str_replace('/', '\\/', Config::UPLOADIMAGES_DIR);
         $cached_campaign->content = preg_replace('/<img(.*)src="\\/' . $dir . '(.*)>/iU', '<img\\1src="' . Config::get('public_scheme') . '://' . $baseurl . '/' . Config::UPLOADIMAGES_DIR . '\\2>', $cached_campaign->content);
     }
     //if (defined('FCKIMAGES_DIR') && FCKIMAGES_DIR) {
     //$cached[$campaign_id]['content'] = preg_replace('/<img(.*)src="\/lists\/'.FCKIMAGES_DIR.'(.*)>/iU','<img\\1src="'.$GLOBALS['public_scheme'].'://'.$baseurl.'/lists/'.FCKIMAGES_DIR.'\\2>',$cached[$campaign_id]['content']);
     //}
     return true;
 }
Ejemplo n.º 6
0
 /**
  * Shutdown function for execution on shutdown
  * @link http://php.net/manual/en/function.register-shutdown-function.php
  */
 public function shutdown()
 {
     #  phpList::log()->debug( "Script status: ".connection_status(), ['page' => 'porcessqueue']); # with PHP 4.2.1 buggy. http://bugs.php.net/bug.php?id=17774
     phpList::log()->debug(s('Script stage') . ': ' . $this->script_stage, ['page' => 'porcessqueue']);
     $some = $this->processed;
     #$this->sent;# || $this->invalid || $this->notsent;
     if (!$some) {
         phpList::log()->debug(s('Finished, Nothing to do'), ['page' => 'porcessqueue']);
         $this->nothingtodo = 1;
     }
     $totaltime = Timer::get('process_queue')->elapsed(true);
     if ($totaltime > 0) {
         $msgperhour = 3600 / $totaltime * $this->sent;
     } else {
         $msgperhour = s('Calculating');
     }
     if ($this->sent) {
         phpList::log()->debug(sprintf('%d %s %01.2f %s (%d %s)', $this->sent, s('campaigns sent in'), $totaltime, s('seconds'), $msgperhour, s('msgs/hr')), ['page' => 'processqueue']);
     }
     if ($this->invalid > 0) {
         phpList::log()->debug(s('%d invalid email addresses', $this->invalid), ['page' => 'porcessqueue']);
     }
     if ($this->failed_sent > 0) {
         phpList::log()->debug(s('%d failed (will retry later)', $this->failed_sent), ['page' => 'porcessqueue']);
         foreach ($this->counters as $label => $value) {
             #  phpList::log()->debug(sprintf('%d %s',$value,s($label)),1,'progress', ['page' => 'porcessqueue']);
             phpList::log()->info(sprintf('%d %s', $value, s($label)), ['page' => 'processqueue']);
         }
     }
     if ($this->unconfirmed > 0) {
         phpList::log()->debug(sprintf(s('%d emails unconfirmed (not sent)'), $this->unconfirmed), ['page' => 'porcessqueue']);
     }
     /*
      * TODO: enable plugins
     foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
         $plugin->processSendStats($this->sent,$this->invalid,$this->failed_sent,$this->unconfirmed,$this->counters);
     }
     */
     Cache::flushClickTrackCache();
     Process::releaseLock($this->send_process_id);
     //finish("info",$report,$this->script_stage);
     //function finish ($flag,$campaign,$this->script_stage) {
     $subject = s('Maillist Processing info');
     if (!$this->nothingtodo) {
         phpList::log()->info(s('Finished this run'), ['page' => 'progress']);
         phpList::log()->info(s('%s of %s done', $this->sent, $this->counters['total_subscribers_for_campaign ' . $this->current_campaign->id]), ['page' => 'progress']);
     }
     //TODO:enable plugins
     /*
     if (!Config::TEST && !$this->nothingtodo && Config::get(('END_QUEUE_PROCESSING_REPORT'))) {
         foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
             $plugin->sendReport($subject,$campaign);
         }
     }
     */
     if ($this->script_stage < 5 && !$this->nothingtodo) {
         phpList::log()->info(s('Warning: script never reached stage 5') . "\n" . s('This may be caused by a too slow or too busy server') . " \n");
         //TODO: remove globals
     } elseif ($this->script_stage == 5 && (!$this->nothingtodo || isset($GLOBALS['wait']))) {
         # if the script timed out in stage 5, reload the page to continue with the rest
         $this->reload++;
         if (!Config::get('commandline') && $this->num_per_batch && $this->batch_period) {
             if ($this->sent + 10 < $this->original_num_per_batch) {
                 phpList::log()->debug(s('Less than batch size were sent, so reloading imminently'), ['page' => 'porcessqueue']);
                 $delaytime = 10;
             } else {
                 // TODO: we should actually want batch period minus time already spent.
                 // might be nice to calculate that at some point
                 phpList::log()->info(sprintf(s('Waiting for %d seconds before reloading'), $this->batch_period), ['page' => 'processqueue']);
                 $delaytime = $this->batch_period;
             }
             sleep($delaytime);
             /*Output::customPrintf(
                   '<script type="text/javascript">
                      document.location = "./?page=pageaction&action=processqueue&ajaxed=true&reload=%d&lastsent=%d&lastskipped=%d";
                   </script>',
                   $this->reload,
                   $this->sent,
                   $this->notsent
               );*/
         } else {
             /*Output::customPrintf(
                   '<script type="text/javascript">
                      document.location = "./?page=pageaction&action=processqueue&ajaxed=true&reload=%d&lastsent=%d&lastskipped=%d";
                   </script>',
                   $this->reload,
                   $this->sent,
                   $this->notsent
               );*/
         }
     } elseif ($this->script_stage == 6 || $this->nothingtodo) {
         /*
                      * TODO: enable plugins
                     foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
                         $plugin->campaignQueueFinished();
                     }*/
         phpList::log()->debug(s('Finished, All done'), 0, ['page' => 'porcessqueue']);
     } else {
         phpList::log()->debug(s('Script finished, but not all campaigns have been sent yet.'), ['page' => 'porcessqueue']);
     }
     if (!Config::get('commandline') && empty($_GET['ajaxed'])) {
         include_once "footer.inc";
     } elseif (Config::get('commandline')) {
         @ob_end_clean();
     }
     exit;
 }