<?php
/* $Id: class.mailing.php 44 2005-12-01 03:49:19Z schmalls $ */
/**
* class.mailing.php
*
* <p>Includes {@link mailing} class.</p>
*
* @package ANJEL
* @subpackage classes
* @copyright © 2004 Schmalls / Joshua Thompson / All Rights Reserved
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
* @author Schmalls / Joshua Thompson <hide@address.com>
* @version 0.6.1
* @since 0.4.3
* @link http://www.schmalls.com
*/
/**
* Ensures this file is being included by a parent file
*/
defined('_VALID_MOS') or die('Direct Access to this location is not allowed.');
/**
* Require the sef component
*/
if (!function_exists('sefRelToAbs')) {
if (file_exists($mosConfig_absolute_path . '/components/com_sef/sef.php')) {
// check for opensef
if (file_exists($mosConfig_absolute_path . '/administrator/components/com_sef/cache.config.php') && filesize($mosConfig_absolute_path . '/administrator/components/com_sef/cache.config.php') > 0) {
// if so, include the class and function file and not the sef file
require_once($mosConfig_absolute_path. '/administrator/components/com_sef/sef.class.php');
require_once($mosConfig_absolute_path. '/administrator/components/com_sef/sef.functions.php');
// get sef config
$sefConfig =& new mosSEFConfig($database, false);
// get sef site variable
if (!empty($sefConfig->use_multisite)) {
$sefSite =& mosSEFSite::lookup($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI']);
} else if (!isset($sefSite)) {
$sefSite =& mosSEFSite::getDefault();
} // end if
} else {
// set sef to off temporarily to fix problems with sef
$sef_temp = $mosConfig_sef;
$mosConfig_sef = false;
require_once($mosConfig_absolute_path . '/components/com_sef/sef.php');
// restore sef
$mosConfig_sef = $sef_temp;
} // end if
} else {
// set sef to off temporarily to fix problems with sef
$sef_temp = $mosConfig_sef;
$mosConfig_sef = false;
require_once($mosConfig_absolute_path . '/includes/sef.php');
// restore sef
$mosConfig_sef = $sef_temp;
} // end if
} // end if
/**
* Class with mailing functions
*
* <p>Class for both frontend and backend mailing functions.</p>
*
* @package ANJEL
* @author Schmalls / Joshua Thompson <hide@address.com>
* @version 0.6.1
* @since 0.4.3
*/
class mailing {
/**
* Gets layout and html information for the newsletter
*
* <p>Gets the layout and html information for a newsletter from the
* database and returns as an object.</p>
*
* @version 0.6.1
* @since 0.4.3
* @param int $listid the list to get information for
* @global class access to the database
* @return object data for newlsetter layout and html options
*/
function getListData($listid) {
global $database;
$query = 'SELECT * FROM `#__anjel_letters` WHERE `id` = ' . $listid;
$database->setQuery($query);
$database->loadObject($list_data);
$error = $database->getErrorMsg();
// quit on error
if (!empty($error)) {
echo '<p>Error (classes/class.mailing.php->getListData() line ' . __LINE__ . '): Could not get newsletter information from database. Database error: <br />' . $error . '</p>';
return false;
} else {
// check if it is empty
if(empty($list_data)) {
$list_data->id = '';
$list_data->list_name = '';
$list_data->list_desc = '';
$list_data->sendername = '';
$list_data->senderemail = '';
$list_data->bounceadres = '';
$list_data->layout = '';
$list_data->subscribemessage = '';
$list_data->unsubscribemessage = '';
$list_data->html = '';
$list_data->hidden = '';
} // end if
// check for slashes
if(get_magic_quotes_runtime()) {
$list_data->id = stripslashes($list_data->id);
$list_data->list_name = stripslashes($list_data->list_name);
$list_data->list_desc = stripslashes($list_data->list_desc);
$list_data->sendername = stripslashes($list_data->sendername);
$list_data->senderemail = stripslashes($list_data->senderemail);
$list_data->bounceadres = stripslashes($list_data->bounceadres);
$list_data->layout = stripslashes($list_data->layout);
$list_data->subscribemessage = stripslashes($list_data->subscribemessage);
$list_data->unsubscribemessage = stripslashes($list_data->unsubscribemessage);
$list_data->html = stripslashes($list_data->html);
$list_data->hidden = stripslashes($list_data->hidden);
} // end if
return $list_data;
} // end if
} // end function
/**
* Gets letter data
*
* <p>Gets the html content, subject, attachments, and text content for
* a mailing from the database and returns as an object.</p>
*
* @version 0.6.1
* @since 0.4.3
* @param int $listid the list to get information for
* @param string $senddate the senddate
* @param int &$new whether the letter is new or not
* @global class access to the database
* @return object mailing data
*/
function getLetterData($listid, $senddate, &$new) {
global $database;
$query = 'SELECT * FROM `#__anjel_mailing` WHERE `list_id` = \'' . $listid . '\' AND `send_date` = \'' . $senddate . '\'';
$database->setQuery($query);
$database->loadObject($letter);
$error = $database->getErrorMsg();
// quit on error
if (!empty($error)) {
echo '<p>Error (classes/class.mailing.php->getLetterData() line ' . __LINE__ . '): Could not get mailing information from database. Database error: <br />' . $error . '</p>';
return false;
} else {
// check if this is a new list
if(empty($letter)) {
$letter->list_id = '';
$letter->list_content = '';
$letter->list_subject = '';
$letter->attachments = '';
$letter->list_textonly = '';
$letter->send_date = '';
$letter->published = '';
$letter->visible = '';
$letter->fromname = '';
$letter->fromemail = '';
$letter->frombounce = '';
$letter->subscriber_id = '';
$new = 1;
} else {
$new = 0;
} // end if
// check for slashes
if(get_magic_quotes_runtime()) {
$letter->list_content = stripslashes($letter->list_content);
$letter->list_subject = stripslashes($letter->list_subject);
$letter->attachments = stripslashes($letter->attachments);
$letter->list_textonly = stripslashes($letter->list_textonly);
$letter->send_date = stripslashes($letter->send_date);
} // end if
if (!empty($letter->attachments)) {
$letter->attachments = explode("\n", $letter->attachments);
array_pop($letter->attachments);
} else {
$letter->attachments = array();
} // end if
return $letter;
} // end if
} // end function
/**
* Replaces tags in the mailing
*
* <p>Replaces the following:
* <ul>
* <li>[CONFIRM] = This creates a clickable link where the subscriber can confirm their subscription. This is required to make ANJEL work properly.</li>
* <li>[NAME] = This will be replaced by the name the subscriber entered, you'll be sending personalized email when using this.</li>
* <li>[SUBSCRIPTIONS] = This shows current subscriptions for the subscriber and a link to change their subscriptions.</li>
* </ul>
* </p>
*
* @version 0.6.1
* @since 0.4.3
* @param string $content the content for the mailing
* @param object $subscriber the subscriber's information
* @param int $listid the newsletter's id
* @param int $html tells whether this is an html mailing or not
* @param string $senddate the date the mailing was sent
* @global string url to main site directory
* @global array configuration information
* @global class access to the database
* @global int Itemid to help with pathway
* @return string the updated content for the mailing
*/
function replaceTags($content, $subscriber, $listid, $html, $senddate = ''){
global $mosConfig_live_site, $newsletterConfig, $database, $Itemid;
// check to see if subscriber is registered or not and change subscriptionslink accordingly
if ($subscriber->registered != 1) {
$query = 'SELECT * FROM `#__anjel_unregistered` WHERE `unregistered_id` = ' . $subscriber->id;
$database->setQuery($query);
$database->loadObject($row);
echo $database->getErrorMsg();
$subscriptionslink = anjel_sef_rel_to_abs('index.php?option=com_anjel&Itemid=' . $Itemid . '&action=unregistered&type=unregistered&userid=' . $subscriber->id . '&test=' . md5($subscriber->email));
$unsubscribelink = anjel_sef_rel_to_abs('index.php?option=com_anjel&Itemid=' . $Itemid . '&action=unregistered&type=unregistered&task=unsubscribe&userid=' . $subscriber->id . '&test=' . md5($subscriber->email));
} else {
$query = 'SELECT M.name AS name, M.email AS email, N.* FROM `#__anjel_subscribers` AS N, `#__users` AS M WHERE M.id = N.subscriber_id AND N.subscriber_id = ' . $subscriber->id;
$database->setQuery($query);
$database->loadObject($row);
echo $database->getErrorMsg();
$subscriptionslink = anjel_sef_rel_to_abs('index.php?option=com_anjel&Itemid=' . $Itemid . '&action=registered&type=registered&userid=' . $subscriber->id . '&test=' . md5($subscriber->email));
$unsubscribelink = anjel_sef_rel_to_abs('index.php?option=com_anjel&Itemid=' . $Itemid . '&action=registered&type=registered&task=unsubscribe&userid=' . $subscriber->id . '&test=' . md5($subscriber->email));
} // end if
// create unregistered confirmation link
$confirmlink = anjel_sef_rel_to_abs('index.php?option=com_anjel&Itemid=' . $Itemid. '&action=unregistered&type=unregistered&task=confirm&test=' . md5($subscriber->email) . '&userid=' . $subscriber->id);
if ($html) {
$confirmlink = '<a href="' . $confirmlink . '" target="_blank">' . _CONFIRMLINKTEKST . '</a>';
} else {
$confirmlink = _CONFIRMLINKTEKST . "\n" . $confirmlink;
} // end if
// get the letter ids for inclusion in current subscriptions text
$query = 'SELECT `list_name`, `id` FROM `#__anjel_letters` ORDER BY `id`';
$database->setQuery($query);
$letters = $database->loadObjectList();
$subscriptionstext = '';
foreach ($letters as $letter) {
$list = 'list_' . $letter->id;
if ($row->$list != 0) {
$subscriptionstext .= '[' . $letter->list_name . '] ';
} // end if
} // end foreach
// change to html or text specific versions for subscriptions text
if($html) {
$subscriptionslink = '<a href="' . $subscriptionslink . '" target="_blank">' . _CHANGESUBSCRIPTIONS . '</a>';
$unsubscribelink = '<a href="' . $unsubscribelink . '" target="_blank">' . _UNSUBSCRIBE . '</a>';
$subscriptionstext = '<p>' . _SUBSCRIPTIONS . ':<br />' . $subscriptionstext . '</p><p>' . $subscriptionslink . '<br />' . $unsubscribelink . '</p>';
} else {
$subscriptionslink = _CHANGESUBSCRIPTIONS . ' ( ' . $subscriptionslink . ' )';
$unsubscribelink = _UNSUBSCRIBE . ' ( ' . $unsubscribelink . ' )';
$subscriptionstext = "\r\n" . _SUBSCRIPTIONS . ': ' . $subscriptionstext . "\r\n\r\n" . $subscriptionslink . "\r\n" . $unsubscribelink;
} // end if
// finally do the tag replacing
$content = str_replace('[CONFIRM]', $confirmlink, $content);
$content = str_replace('[NAME]', $subscriber->name, $content);
$content = str_replace('[SUBSCRIPTIONS]', $subscriptionstext, $content);
// create images to check html read statistics
if (!empty($senddate)) {
if ($newsletterConfig['enable_statistics'] == '1') {
if ($newsletterConfig['statistics_per_subscriber'] == '1') {
//add image with subscriberid
if($html) {
// check if user is registered or unregistered
if ($subscriber->registered) {
// if registered
$content = $content . '<img src="' . $mosConfig_live_site . '/index2.php?option=com_anjel&Itemid=' . $Itemid . '&listid=' . $listid . '&action=log&senddate=' . $senddate . '&subscriber=' . $subscriber->id . '&type=registered" border="0" width="1" height="1" />';
} else {
// if unregistered
$content = $content . '<img src="' . $mosConfig_live_site . '/index2.php?option=com_anjel&Itemid=' . $Itemid . '&listid=' . $listid . '&action=log&senddate=' . $senddate . '&subscriber=' . $subscriber->id . '&type=unregistered" border="0" width="1" height="1" />';
} // end if
} // end if
} else {
//add image without subscriberid
if ($html) {
$content = $content . '<img src="' . $mosConfig_live_site . '/index2.php?option=com_anjel&Itemid=' . $Itemid . '&listid=' . $listid . '&action=log&send=' . $senddate . '" border="0" width="1" height="1" />';
} // end if
} // end if
} // end if
} // end if
return $content;
} // end function
/**
* Changes html content to text content
*
* <p>Replaces break tags with newlines, changes links to the link text
* followed by the link location in parentheses, removes the entire head
* section if it exists, removes html entities, strips the remaining html
* tags, and returns the text.</p>
*
* @version 0.6.1
* @since 0.6.1
* @param string $textonly the string to be changed from html to text
* @return string the changed string
*/
function htmlToText($textonly) {
// fix line breaks
$textonly = str_replace(array('<br>', '<br/>', '<br />', '<BR>', '<BR/>', '<BR />', '<p>', '</p>', '<P>', '</P>', '<p />', '<p/>', '<P />', '<P/>'), "\r\n", $textonly);
// fix links
$textonly = preg_replace('/<a href="([^"]*)"[^>]*>([^<]*)<\/a>/i','${2} ( ${1} )', $textonly);
// remove all <head> information
$textonly = preg_replace('/<head>.*<\/head>/i', '', $textonly);
// replace html entities (from http://us2.php.net/manual/en/function.html-entity-decode.php)
// replace numeric entities
$textonly = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $textonly);
$textonly = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $textonly);
// replace literal entities
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip($trans_tbl);
$textonly = strtr($textonly, $trans_tbl);
// strip html tags
$textonly = strip_tags($textonly);
// return text
return $textonly;
} // end function
/**
* Saves the mailing to the database
*
* <p>Appends the content item placeholders to the mailing and creates
* the attachment string and either updates or adds to the database.</p>
*
* @version 0.6.1
* @since 0.4.3
* @param string $senddate the senddate for the mailing
* @global class access to the database
* @return boolean to tell whether it was successful
*/
function save(&$senddate){
global $database;
$listid = mosGetParam($_REQUEST, 'listid', 0);
$senddate = mosGetParam($_REQUEST, 'senddate', 0);
$subject = mosGetParam($_REQUEST, 'subject', '');
$content = mosGetParam($_REQUEST, 'content', '', _MOS_ALLOWHTML);
$html = mosGetParam($_REQUEST, 'html', 0);
$alt_content = mosGetParam($_REQUEST, 'alt_content', '', _MOS_NOTRIM);
$new_list = mosGetParam($_REQUEST, 'new_list', 0);
$fromname = mosGetParam($_REQUEST, 'fromname', '');
$fromemail = mosGetParam($_REQUEST, 'fromemail', '');
$frombounce = mosGetParam($_REQUEST, 'frombounce', '');
$userid = mosGetParam($_REQUEST, 'userid', 0);
// get attachments
$attachments = mosGetParam($_REQUEST, 'attachments', 0);
$attach = '';
if($attachments != 0){
foreach ($attachments as $attachment) {
$attach .= $attachment . "\n";
} // end foreach
} // end if
// check if it is a new letter, and update the database
if($new_list != 0) {
$query = 'INSERT INTO `#__anjel_mailing` (`list_id`, `send_date`, `list_subject`, `list_content`, `list_textonly`, `attachments`, `published`, `fromname`, `fromemail`, `frombounce`, `subscriber_id`)
VALUES(' . $listid . ', NOW(), \'' . $subject . '\', \'' . $content . '\', \'' . $alt_content . '\', \'' . $attach . '\', 0, \'' . $fromname . '\', \'' . $fromemail . '\', \'' . $frombounce . '\', \'' . $userid . '\')';
$database->setQuery($query);
$database->query();
$error = $database->getErrorMsg();
// get new senddate
$query = 'SELECT `send_date` FROM `#__anjel_mailing` WHERE `published` = 0 AND `list_id` = ' . $listid . ' AND `list_content` = \'' . $content . '\'';
$database->setQuery($query);
$senddate = $database->loadResult();
$error .= $database->getErrorMsg();
} else {
$query = 'UPDATE `#__anjel_mailing` SET
`list_subject` = \'' . $subject . '\',
`list_content` = \'' . $content . '\',
`list_textonly` = \'' . $alt_content . '\',
`attachments` = \'' . $attach . '\',
`fromname` = \'' . $fromname . '\',
`fromemail` = \'' . $fromemail . '\',
`frombounce` = \'' . $frombounce . '\'
WHERE `list_id` = \'' . $listid . '\' AND `send_date` = \'' . $senddate . '\'';
$database->setQuery($query);
$database->query();
$error = $database->getErrorMsg();
} // end if
// check for error
if (!empty($error)) {
echo '<p>Error (classes/class.mailing.php->save() line ' . __LINE__ . '): Letter not saved to database. Database error: <br />' . $error . '</p>';
return false;
} else {
return true;
} // end if
} // end function
/**
* Publishes the letter
*
* <p>Saves the mailing if it is supposed to do so. Then gets the
* mailing information and subscribers from the database and then sends
* the information to the {@link send()} function. After that it
* updates the mailing to sent if it was successful.</p>
*
* @version 0.6.1
* @since 0.4.3
* @param int $listid the newsletter to work with
* @param boolean $preview tells whether this is a preview mailing
* @global class access to the database
* @global class access to subscriber functions
* @global int Itemid to help with pathway
* @uses save()
* @uses subscribers::getSubscribers()
* @uses send()
* @return boolean whether it was successful or not
*/
function publish($listid, $preview = false){
global $database, $subscribers, $Itemid;
$senddate = mosGetParam($_REQUEST, 'senddate', 0);
$donotsave = mosGetParam($_REQUEST, 'donotsave', 0);
// if not preview or not specified not to save, save mailing
if ((!$preview) && ($donotsave == 0)) {
$this->save($senddate);
} // end if
// get letter from database
$mailing = $this->getLetterData($listid, $senddate, $new);
// quit on error
if ($new == 1) {
echo '<p>Error (classes/class.mailing.php->publish() line ' . __LINE__ . '): Could not get letter from database.</p>';
return false;
} else {
// get list details
$list = $this->getListData($listid);
// if not preview get subscribers, else get preview details to send
if (!$preview) {
$receivers = $subscribers->getSubscribers($listid, "AND confirmed != 0 AND blacklist = 0");
// quit if no subscribers
if (count($receivers) == 0) {
echo '<p>Error (classes/class.mailing.php->publish() line ' . __LINE__ . '): No subscribers for this list found in the database.</p>';
return false;
} // end if
} else {
$previewemailaddress = mosGetParam($_REQUEST, 'emailaddress', '');
$previewname = mosGetParam($_REQUEST, 'name', '');
$previewhtml = mosGetParam($_REQUEST, 'html', 0);
$receivers = array('preview');
$receivers[1]->id = 0;
$receivers[1]->email = $previewemailaddress;
$receivers[1]->name = $previewname;
$receivers[1]->receive_html = $previewhtml;
} // end if
$check = $this->send($mailing->list_subject, $mailing->list_content, $mailing->list_textonly, $receivers, $mailing->fromname, $mailing->fromemail, $mailing->frombounce, $list->html, $list->layout, $mailing->attachments, $listid, $Itemid, $senddate);
// if not preview
if (!$preview) {
// if messages sent
if ($check) {
// set message as sent
$query = 'UPDATE `#__anjel_mailing` SET `published` = 1 WHERE `list_id` = ' . $listid;
$database->setQuery($query);
$database->query();
$error = $database->getErrorMsg();
// quit on error
if (!empty($error)) {
echo '<p>Error (classes/class.mailing.php->publish() line ' . __LINE__ . '): Error setting letter to published. Database error: ' . $error . '</p>';
return false;
} else {
return true;
} // end if
} else {
echo '<p>Error (classes/class.mailing.php->publish() line ' . __LINE__ . '): Error sending messages.</p>';
return false;
} // end if
} else {
return $check;
} // end if
} // end if
} // end function
/**
* Sends the mailing
*
* <p>Sets up the PHPMailer class with the correct information. Then it
* sends a message to each subscriber individually after replacing the
* tags with custom information. Then it updates the statistics
* information in the database. Also, outputs a list of the subscribers
* and whether the mailing was sent to them successfully or not. It
* also provides the email throttling options.</p>
*
* @version 0.6.1
* @since 0.4.3
* @param string $subject the mailing's subject
* @param string $content the mailing's content
* @param string $textonly the mailing's text-only content
* @param array $to subscriber information
* @param string $fromname the mailing's from name
* @param string $fromemail the mailing's from email
* @param string $frombounce the mailing's from bounce
* @param int $html tells whether this is an html mailing
* @param string $layout the mailing's layout information
* @param array $attachments the mailings attachments
* @param int $listid the newsletter to work with
* @param int $menuitem Itemid to help with pathway
* @param string $senddate the date the mailing was sent
* @global array configuration options
* @global string url to the site's main directory
* @global string filesystem path to the site's main directory
* @global class access to the database
* @global string md5 of email address
* @global string the user type
* @global int the user's id
* @global object the mambots object
* @uses PHPMailer
* @uses PHPMailer::$PluginDir
* @uses PHPMailer::SetLanguage()
* @uses PHPMailer::CharSet
* @uses PHPMailer::$From
* @uses PHPMailer::$FromName
* @uses PHPMailer::AddReplyTo()
* @uses PHPMailer::$Subject
* @uses PHPMailer::$Mailer
* @uses PHPMailer::$Sendmail
* @uses PHPMailer::IsSMTP()
* @uses PHPMailer::$Host
* @uses PHPMailer::$SMTPAuth
* @uses PHPMailer::$Password
* @uses PHPMailer::$Username
* @uses PHPMailer::AddAttachment()
* @uses PHPMailer::AddEmbeddedImage()
* @uses PHPMailer::$Body
* @uses PHPMailer::$AltBody
* @uses PHPMailer::AddAddress()
* @uses PHPMailer::ClearAddresses()
* @uses sendReport()
* @return boolean tell whether it was successful
*/
function send($subject, $content, $textonly, $to, $fromname, $fromemail, $frombounce, $html, $layout = '', $attachments = array(), $listid = 0, $menuitem = 0, $send_date = '') {
global $newsletterConfig, $mosConfig_live_site, $mosConfig_absolute_path, $database, $test, $type, $userid, $_MAMBOTS;
// Check for safe mode
if (ini_get('safe_mode')) {
// Do it the safe mode way
// no safe mode way yet
} else {
// set time limit to configured number of minutes
set_time_limit(60 * $newsletterConfig['script_timeout']);
}
// continue working after window closed
ignore_user_abort(true);
// if layout set up, replace content marker with content
if (!empty($layout)) {
$content = str_replace('[CONTENT]', $content, $layout);
} // end if
// initialize phpmailer
$mail = new PHPMailer();
// set plugin directory
$mail->PluginDir = $mosConfig_absolute_path . '/administrator/components/com_anjel/classes/';
// set language to english
$mail->SetLanguage('en', $mosConfig_absolute_path . '/components/com_anjel/languages/');
// set character encoding to Joomla defualt
$mail->CharSet = substr_replace(_ISO, '', 0, 8);
// set wordwrap
$mail->WordWrap = 200;
// set from parts
$mail->From = '' . $fromemail . '';
$mail->FromName = '' . $fromname . '';
$mail->AddReplyTo($frombounce);
$mail->Sender = '' . $fromemail . '';
// set send method
switch ($newsletterConfig['emailmethod']){
case 'mail' :
$mail->Mailer = 'mail';
break;
case 'sendmail':
$mail->Mailer = 'sendmail';
$mail->Sendmail = $newsletterConfig['sendmail_path'];
break;
case 'smtp':
$mail->Mailer = 'smtp';
$mail->IsSMTP();
$mail->Host = $newsletterConfig['smtp_host'];
// set smtp authorization if required
if((boolean)$newsletterConfig['smtp_auth_required']){
$mail->SMTPAuth = $newsletterConfig['smtp_auth_required'];
$mail->Password = $newsletterConfig['smtp_password'];
$mail->Username = $newsletterConfig['smtp_username'];
} // end if
break;
} // end switch
// add attachments
if (sizeof($attachments) > 0) {
foreach ($attachments AS $attachment) {
// check if path needs to be added
if (stristr($mosConfig_absolute_path, $attachment) === false) {
$mail->AddAttachment($mosConfig_absolute_path . '/images/stories/' . $attachment);
} else {
$mail->AddAttachment($attachment);
} // end if
} // end foreach
} // end if
// make textonly equal to html if empty
if(!(strlen($textonly) > 0)) {
$textonly = $this->htmlToText($content);
} // end if
// run "transform all" bots
$_MAMBOTS->loadBotGroup('anjel');
$bot_results = $_MAMBOTS->trigger('bot_anjel_transform_all', array(&$content, &$textonly));
// change img to inline if option is true, otherwise change to correct paths
preg_match_all('/<img([^>]*)src="([^">]+)"([^>]*)>/i', $content, $images, PREG_SET_ORDER);
foreach($images as $image) {
// get rid of ../
$image[2] = preg_replace('/(\.\.\/)+/', '/', $image[2]);
// remove the site information if it is a local image
$image[2] = str_replace($mosConfig_live_site, '', $image[2]);
// remove a / at the beginning of the path (fixes some problems)
$image[2] = preg_replace('/^\//', '', $image[2]);
// get absolute image path
$imagepath = $mosConfig_absolute_path . '/' . $image[2];
// get the image name
$filename = basename($image[2]);
$cid = explode('.', $filename);
$cid = str_replace(' ', '_', $cid[0]);
// check if images should be embedded
if(($newsletterConfig['use_embedded_images'] != 0) && (stristr($image[2], 'http://') === false)) {
$mail->AddEmbeddedImage($imagepath, $cid, $filename);
$replacement = '<img' . $image[1] . 'src="cid:' . $cid . '"' . $image[3] . '>';
} else {
if (stristr($image[2], 'http://') === false) {
// remove unneeded directory information
if (stristr($image[2], 'images/stories/') !== false) {
$image[2] = '/' . stristr($image[2], 'images/stories/');
} // end if
$replacement = '<img' . $image[1] . 'src="' . $mosConfig_live_site . $image[2] . '"' . $image[3] . '>';
} else {
$replacement = '<img' . $image[1] . 'src="' . $image[2] . '"' . $image[3] . '>';
} // end if
} // end if
$content = str_replace($image[0], $replacement, $content);
} // end foreach
// if it is not a preview, subscribe, or unsubscribe message
if(($to[0] != 'preview') && ($to[0] != 'subscribe') && ($to[0] != 'unsubscribe')){
// set starting time
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
// initialize counting variables
$html_sent = 0;
$text_sent = 0;
$size = sizeof($to);
$i = 1;
// ouput toolbar cancel button handling form
?>
<form action="index2.php" method="post" name="adminForm">
<input type="hidden" name="option" value="com_anjel" />
<input type="hidden" name="act" value="mailing" />
<input type="hidden" name="task" value="" />
</form>
<?php
// create counter
echo '
<form action="#" name="counterForm">
' . _SENDINGEMAIL . ': <input type="text" name="teller" value="0" style="border: 0px solid white; font-family: Arial, Helvetica, sans-serif; font-size: 11px;" size="1" /> of ' . $size . '
</form>';
// add subscriptions placeholder to content
$content .= '<p>[SUBSCRIPTIONS]</p>';
$textonly .= "\r\n \r\n[SUBSCRIPTIONS]";
// close output buffers
while (@ob_end_flush());
// initialize log data
$log_detailed = '';
// send to each subscriber
$skip_subscribers = mosGetParam($_REQUEST, 'skip_subscribers', 0);
foreach ($to AS $receiver) {
// check if this subscriber should be skipped
if ($i <= $skip_subscribers) {
$i++;
continue;
} // end if
// run "transform personal" bots
$_MAMBOTS->loadBotGroup('anjel');
$bot_results = $_MAMBOTS->trigger('bot_anjel_transform_personal', array(&$content, &$textonly, $receiver, $listid, $send_date));
// if receive html, otherwise send text
if ($html && (intval($receiver->receive_html) == 1)) {
$mail->IsHTML(true);
$ashtml = 1;
$letterBody = $this->replaceTags($content, $receiver, $listid, $ashtml, $send_date);
$mail->AltBody = $this->replaceTags($textonly, $receiver, $listid, 0, $send_date);
$html_sent++;
} else {
$mail->IsHTML(false);
$mail->AltBody = '';
$ashtml = 0;
$letterBody = $this->replaceTags($textonly, $receiver, $listid, $receiver->id, 0, $send_date);
$text_sent++;
} // end if
// set body, receiver, and subject
$mail->Body = $letterBody;
$mail->AddAddress($receiver->email, $receiver->name);
$mail->Subject = str_replace('[NAME]', $receiver->name, $subject);
// output information
echo $i . ' ';
// report error or success
if (!$mail->Send()) {
echo '<strong>' . $receiver->email . '</strong> -> ' . _MESSAGENOT . '. <p>' . _MAILERERROR . ': ' . $mail->ErrorInfo . '</p>';
$log_detailed .= $receiver->email . ' -> ' . _MESSAGENOT . "\r\n" . _MAILERERROR . ': ' . $mail->ErrorInfo . "\r\n";
if($html && (intval($receiver->receive_html) == 1)){
$html_sent--;
} else{
$text_sent--;
}
} else{
echo '<strong>' . $receiver->email . '</strong> -> ' . _MESSAGESENTSUCCESSFULLY . '<br />';
$log_detailed .= $receiver->email . ' -> ' . _MESSAGESENTSUCCESSFULLY . "\r\n";
// update statistics for subscriber
if ($newsletterConfig['enable_statistics'] == '1') {
if ($newsletterConfig['statistics_per_subscriber'] == '1') {
// check if subscriber is registered or unregistered
$check = strpos($letterBody, 'type=unregistered');
if ($check === false) {
// if registered
$query = 'INSERT INTO `#__anjel_stats_detailed` (`listid`, `send_date`, `subscriber_id`, `html`) VALUES (\'' . $listid . '\', \'' . $send_date . '\', \'' . $receiver->id . '\', \'' . $ashtml . '\');';
} else {
// if unregistered
$query = 'INSERT INTO `#__anjel_stats_detailed_unregistered` (`listid`, `send_date`, `subscriber_id`, `html`) VALUES (\'' . $listid . '\', \'' . $send_date . '\', \'' . $receiver->id . '\', \'' . $ashtml . '\');';
} // end if
$database->setQuery($query);
$database->query();
} // end if
} // end if
} // end if
// remove address
$mail->ClearAddresses();
// increment number of mails sent
echo '<script type="text/javascript" language="javascript">document.counterForm.teller.value=\'' . $i . '\';</script>';
// flush
flush();
// if sent out a multiple of the configured amount of emails, take a break
if (($i % $newsletterConfig['emails_between_pauses']) == 0) {
// check if we should sleep or wait for user input
if ($newsletterConfig['wait_for_user_at_pause'] == 0) {
// if sleep, sleep
echo '--- Waiting ' . $newsletterConfig['pause_time']. ' seconds ---<br /><br />';
$log_detailed .= "\r\n" . '--- Waiting ' . $newsletterConfig['pause_time']. ' seconds ---' . "\r\n\r\n";
// flush
flush();
// sleep
sleep($newsletterConfig['pause_time']);
} else {
// if wait, wait
$log_detailed .= "\r\n" . '--- Waiting for user input to continue sending ---' . "\r\n\r\n";
?>
<form action="index3.php" method="post">
<input type="hidden" name="option" value="com_anjel" />
<input type="hidden" name="act" value="mailing" />
<input type="hidden" name="task" value="publish" />
<input type="hidden" name="listid" value="<?php echo $listid; ?>" />
<input type="hidden" name="skip_subscribers" value="<?php echo $i; ?>" />
<input type="hidden" name="fromname" value="<?php echo $fromname; ?>" />
<input type="hidden" name="fromemail" value="<?php echo $fromemail; ?>" />
<input type="hidden" name="return" value="<?php echo $frombounce; ?>" />
<input type="hidden" name="donotsave" value="1" />
<input type="hidden" name="senddate" value="<?php echo $send_date; ?>" />
<input type="submit" name="submit" value="<?php echo _CONTINUE_SENDING; ?>" />
</form>
<?php
exit;
} // end if
} // end if
$i++;
} // end foreach
// update statistics for newsletter
if($newsletterConfig['enable_statistics'] == '1'){
$query = 'INSERT INTO `#__anjel_stats_overall` (`listid`, `send_date`, `html_sent`, `text_sent`)
VALUES (\'' . $listid . '\', \'' . $send_date . '\', \'' . $html_sent . '\', \'' . $text_sent . '\');';
$database->setQuery($query);
$database->query();
} // end if
// set endtime and calculate total time
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = number_format($endtime - $starttime, 4, ',', '');
// send mailing report
if($newsletterConfig['send_data'] == 1){
$this->sendReport($fromemail, $totaltime, $html_sent, $text_sent);
} // end if
// display statistics
echo '<br /><b>' . _SENDINGTOOK . ' ' . $totaltime . ' ' . _SECONDS . '</b><br />';
$log_simple = 'Time to send: ' . $totaltime . "\r\n" .
'Number of subscribers: ' . ($text_sent + $html_sent) . "\r\n" .
'HTML format: ' . $html_sent . "\r\n" .
'Text format: ' . $text_sent . "\r\n";
$log_detailed = $log_simple . 'Details: ' . "\r\n" . $log_detailed . "\r\n";
$this->log($log_simple, $log_detailed, $fromemail);
// start output buffer to stop external error
ob_start();
return true;
} else {
// check if address was entered
if(!empty($to)){
// if html otherwise textonly
if($html && (intval($to[1]->receive_html) == 1)) {
$mail->IsHTML(true);
$ashtml = 1;
$letterBody = $this->replaceTags($content, $to[1], $listid, $ashtml, $send_date);
$mail->AltBody = $this->replaceTags($textonly, $to[1], $listid, 0, $send_date);
} else{
$mail->IsHTML(false);
$mail->AltBody = '';
$ashtml = 0;
$letterBody = $this->replaceTags($textonly, $to[1], $listid, $ashtml, $send_date);
} // end if
// add address, body, and subject
$mail->AddAddress($to[1]->email, $to[1]->name);
$mail->Body = $letterBody;
$mail->Subject = str_replace('[NAME]', $to[1]->name, $subject);
// check if mail was sent
if(!$mail->Send()){
echo _MESSAGENOT . " <p>";
echo _MAILERERROR . ": " . $mail->ErrorInfo;
return false;
} else {
return true;
} // end if
} else {
echo _NOADDRESSENTERED;
return false;
} // end if
} // end if
} // end function
/**
* Send a report to the developer
*
* <p>Sends a report of the mailing to
* {@link mailto:hide@address.com hide@address.com} along with
* server and configuration options.</p>
*
* @version 0.6.1
* @since 0.4.3
* @param string $from_email the return email address
* @param int $time the time it took to send
* @param int $html_sent the number of html mailings sent
* @param int $text_sent the number of text mailing sent
*/
function sendReport($from_email, $time, $html_sent, $text_sent) {
global $newsletterConfig;
$safemode = (ini_get("safe_mode") == 0) ? 'off' : 'on';
$numberSubscribers = $text_sent + $html_sent;
$content = 'ANJEL send mailing report of ' . date("d-m-Y H:i") . "\n\n";
$content .= "-----------------------------------\n";
$content .= "Server: \n";
$content .= "-----------------------------------\n\n";
$content .= "Software: " . $_SERVER['SERVER_SOFTWARE'] . "\n";
$content .= "PHP Version: " . phpversion() . "\n";
$content .= "Zend Version: " . zend_version() . "\n";
$content .= "Magic_quotes_gpc: " . ini_get("magic_quotes_gpc") . "\n";
$content .= "Disable_functions: " . ini_get("disable_functions") . "\n";
$content .= "Max_execution_time: " . ini_get("max_execution_time") . "\n";
$content .= "Safe_mode: " . $safemode . "\n";
$content .= "Memory_limit: " . ini_get("memory_limit") . "\n";
$content .= "\n\n";
$content .= "-----------------------------------\n";
$content .= "ANJEL configuration: \n";
$content .= "-----------------------------------\n\n";
$content .= "Send method: " . $newsletterConfig['emailmethod'] . "\n";
if($newsletterConfig['emailmethod'] == 'smtp'){
$auth = ($newsletterConfig['smtp_auth_required'] == 1) ? 'yes' : 'no';
$content .= "Authentication required: " . $auth . "\n";
}
$content .= "ANJEL Version: 0.6.1-final\n";
$content .= "\n\n";
$content .= "-----------------------------------\n";
$content .= "Mailing options: \n";
$content .= "-----------------------------------\n\n";
$content .= "Time to send: " . $time . "\n";
$content .= "Number of subscribers: " . $numberSubscribers . "\n";
$content .= "HTML format: " . $html_sent . "\n";
$content .= "Text format: " . $text_sent . "\n";
mail("hide@address.com", "ANJEL mailing report", $content, "From: " . $from_email . "");
} // end function
/**
* Logs and/or sends a report to the administrator
*
* <p>Sends a report of the mailing to the administrator of the
* newsletter if configured to do so. Also writes to the log if configured
* to do so.</p>
*
* @version 0.6.1
* @since 0.6.1
* @param string $log_simple the simple log information
* @param string $log_detailed the detailed log information
* @global array configuration options
* @global string filesystem path to the site's main directory
*/
function log($log_simple, $log_detailed, $from_email) {
global $newsletterConfig, $mosConfig_absolute_path;
// check if log should be sent to admin
if ($newsletterConfig['send_log']) {
// check if it should be a simple log
if ($newsletterConfig['send_log_simple']) {
$send = $log_simple;
} else {
$send = $log_detailed;
} // end if
mail($newsletterConfig['send_log_address'], 'ANJEL mailing report', $send, 'From: ' . $from_email . '');
} else {
// check if it should be sent on closed connection
if ($newsletterConfig['send_log_closed'] && connection_aborted()) {
// check if it should be a simple log
if ($newsletterConfig['send_log_simple']) {
$send = $log_simple;
} else {
$send = $log_detailed;
} // end if
mail($from_email, 'ANJEL mailing report', $send, 'From: ' . $from_email . '');
} // end if
} // end if
// check if log should be appended to log file
if ($newsletterConfig['save_log']) {
// check if it should be a simple log
if ($newsletterConfig['save_log_simple']) {
file_put_contents($mosConfig_absolute_path . $newsletterConfig['save_log_file'], $log_simple, FILE_APPEND);
} else {
file_put_contents($mosConfig_absolute_path . $newsletterConfig['save_log_file'], $log_detailed, FILE_APPEND);
} // end if
} // end if
} // end function
} // end class
?>