public function runtest() { $this->userdata = Sql_Fetch_Assoc_Query(sprintf('select * from %s where email = "%s"', $GLOBALS['tables']['user'], $GLOBALS['developer_email'])); if (!$this->userdata['id']) { Sql_Query(sprintf('insert into %s (email) values("%s")', $GLOBALS['tables']['user'], $GLOBALS['developer_email'])); print 'Bounce user created: ' . $GLOBALS['developer_email'] . '<br/>'; } $GLOBALS['message_envelope'] = $GLOBALS['developer_email']; return 1; }
function saveUserAttribute($userid, $attid, $data) { global $usertable_prefix, $table_prefix, $tables; # workaround for integration webbler/phplist if (!isset($usertable_prefix)) { $usertable_prefix = ''; } if (!isset($table_prefix)) { $table_prefix = 'phplist_'; } if (!empty($tables["attribute"])) { $att_table = $usertable_prefix . $tables["attribute"]; $user_att_table = $usertable_prefix . $tables["user_attribute"]; } else { $att_table = $usertable_prefix . "attribute"; $user_att_table = $usertable_prefix . "user_attribute"; } if (!is_array($data)) { $tmp = $data; $data = Sql_Fetch_Assoc_Query(sprintf('select * from %s where id = %d', $att_table, $attid)); $data['value'] = $tmp; $data['displayvalue'] = $tmp; } # dbg($data,'$data to store for '.$userid.' '.$attid); if ($data["nodbsave"]) { # dbg($attid, "Not saving, nodbsave"); return; } if ($attid == "emailcheck" || $attid == "passwordcheck") { # dbg($attid, "Not saving, emailcheck/passwordcheck"); return; } if (!$data["type"]) { $data["type"] = "textline"; } if ($data["type"] == "static" || $data["type"] == "password" || $data['type'] == 'htmlpref') { if (!empty($GLOBALS['config']['dontsave_userpassword']) && $data['type'] == 'password') { $data["value"] = 'not authoritative'; } Sql_Query(sprintf('update user set %s = "%s" where id = %d', $attid, $data["value"], $userid)); dbg('Saving', $data['value'], DBG_TRACE); if ($data["type"] == "password") { Sql_Query(sprintf('update user set passwordchanged = now(),password="******" where id = %d', hash('sha256', $data['value']), $userid)); } return 1; } $attributetype = $data['type']; $attid_req = Sql_Fetch_Row_Query(sprintf(' select id,type,tablename from %s where id = %d', $att_table, $attid)); if (!$attid_req[0]) { $attid_req = Sql_Fetch_Row_Query(sprintf(' select id,type,tablename from %s where name = "%s"', $att_table, $data["name"])); if (!$attid_req[0]) { if (!empty($data["name"]) && $GLOBALS["config"]["autocreate_attributes"]) { # Dbg("Creating new Attribute: ".$data["name"]); sendError("creating new attribute " . $data["name"]); $atttable = getNewAttributeTablename($data["name"]); Sql_Query(sprintf('insert into %s (name,type,tablename) values("%s","%s","%s")', $att_table, $data["name"], $data["type"], $atttable)); $attid = Sql_Insert_Id(); } else { # dbg("Not creating new Attribute: ".$data["name"]); # sendError("Not creating new attribute ".$data["name"]); } } else { $attid = $attid_req[0]; if (empty($attributetype)) { $attributetype = $attid_req[1]; } $atttable = $attid_req[2]; } } else { $attid = $attid_req[0]; if (empty($attributetype)) { $attributetype = $attid_req[1]; } $atttable = $attid_req[2]; } if (!$atttable && !empty($data['name'])) { $atttable = getNewAttributeTablename($data["name"]); # fix attribute without tablename Sql_Query(sprintf('update %s set tablename ="%s" where id = %d', $att_table, $atttable, $attid)); # sendError("Attribute without Tablename $attid"); } switch ($attributetype) { case "static": case "password": # dbg('SAVING STATIC OR PASSWORD'); if (!empty($GLOBALS['config']['dontsave_userpassword']) && $data['type'] == 'password') { $data["value"] = 'not authoritative'; } Sql_Query(sprintf('update user set %s = "%s" where id = %d', $attid, $data["value"], $userid)); break; case "select": $curval = Sql_Fetch_Row_Query(sprintf('select id from ' . $table_prefix . 'listattr_%s where name = "%s"', $atttable, $data["displayvalue"]), 1); if (!$curval[0] && $data['displayvalue'] && $data['displayvalue'] != '') { Sql_Query(sprintf('insert into ' . $table_prefix . 'listattr_%s (name) values("%s")', $atttable, $data["displayvalue"])); sendError("Added " . $data["displayvalue"] . " to {$atttable}"); $valid = Sql_Insert_id(); } else { $valid = $curval[0]; } Sql_Query(sprintf('replace into %s (userid,attributeid,value) values(%d,%d,"%s")', $user_att_table, $userid, $attid, $valid)); break; case 'avatar': if (is_array($_FILES)) { ## only avatars are files, for now if (!defined('MAX_AVATAR_SIZE')) { define('MAX_AVATAR_SIZE', 100000); } $formfield = 'attribute' . $attid . '_file'; ## the name of the fileupload element if (!empty($_FILES[$formfield]['name']) && !empty($_FILES[$formfield]['tmp_name'])) { $tmpnam = $_FILES[$formfield]['tmp_name']; move_uploaded_file($tmpnam, '/tmp/avatar' . $userid . '.jpg'); $size = filesize('/tmp/avatar' . $userid . '.jpg'); # dbg('New size: '.$size); if ($size < MAX_AVATAR_SIZE) { $avatar = file_get_contents('/tmp/avatar' . $userid . '.jpg'); Sql_Query(sprintf('replace into %s (userid,attributeid,value) values(%d,%d,"%s")', $user_att_table, $userid, $attid, base64_encode($avatar))); unlink('/tmp/avatar' . $userid . '.jpg'); } } } break; default: Sql_Query(sprintf('replace into %s (userid,attributeid,value) values(%d,%d,"%s")', $user_att_table, $userid, $attid, $data["value"])); break; } return 1; }
<?php verifyCsrfGetToken(); $access = accessLevel('export'); $list = $_SESSION['export']['list']; switch ($access) { case 'owner': if ($list) { $check = Sql_Fetch_Assoc_Query(sprintf('select id from %s where owner = %d and id = %d', $GLOBALS['tables']['list'], $_SESSION['logindetails']['id'], $list)); if (empty($check['id'])) { print Error(s('That is not your list')); return; } } $querytables = $GLOBALS['tables']['list'] . ' list INNER JOIN ' . $GLOBALS['tables']['listuser'] . ' listuser ON listuser.listid = list.id' . ' INNER JOIN ' . $GLOBALS['tables']['user'] . ' user ON listuser.userid = user.id'; $subselect = ' and list.owner = ' . $_SESSION['logindetails']['id']; $listselect_and = ' and owner = ' . $_SESSION['logindetails']['id']; break; case 'all': if ($list) { $querytables = $GLOBALS['tables']['user'] . ' user' . ' INNER JOIN ' . $GLOBALS['tables']['listuser'] . ' listuser ON user.id = listuser.userid'; $subselect = ''; } else { $querytables = $GLOBALS['tables']['user'] . ' user'; $subselect = ''; } $listselect_and = ''; break; case 'none': default: $querytables = $GLOBALS['tables']['user'] . ' user';
function confirmPage($id) { global $tables, $envelope; if (!$_GET['uid']) { FileNotFound(); } $req = Sql_Query(sprintf('select * from %s where uniqid = "%s"', $tables['user'], sql_escape($_GET['uid']))); $userdata = Sql_Fetch_Array($req); if ($userdata['id']) { $html = '<ul>'; $lists = ''; $currently = Sql_Fetch_Assoc_Query("select confirmed from {$tables['user']} where id = " . $userdata['id']); $blacklisted = isBlackListed($userdata['email']); foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { $plugin->subscriberConfirmation($id, $userdata); } Sql_Query("update {$tables['user']} set confirmed = 1,blacklisted = 0, optedin = 1 where id = " . $userdata['id']); $subscriptions = array(); $req = Sql_Query(sprintf('select list.id,name,description from %s list, %s listuser where listuser.userid = %d and listuser.listid = list.id and list.active', $tables['list'], $tables['listuser'], $userdata['id'])); if (!Sql_Affected_Rows()) { $lists = "\n * " . $GLOBALS['strNoLists']; $html .= '<li>' . $GLOBALS['strNoLists'] . '</li>'; } while ($row = Sql_fetch_array($req)) { array_push($subscriptions, $row['id']); $lists .= "\n *" . stripslashes($row['name']); $html .= '<li class="list">' . stripslashes($row['name']) . '<div class="listdescription">' . stripslashes($row['description']) . '</div></li>'; } $html .= '</ul>'; if ($blacklisted) { unBlackList($userdata['id']); addUserHistory($userdata['email'], 'Confirmation', s('Subscriber removed from Blacklist for manual confirmation of subscription')); } if (empty($_SESSION['subscriberConfirmed'])) { $_SESSION['subscriberConfirmed'] = array(); } ## 17513 - don't process confirmation if the subscriber is already confirmed if (empty($currently['confirmed']) && empty($_SESSION['subscriberConfirmed'][$userdata['email']])) { addUserHistory($userdata['email'], 'Confirmation', "Lists: {$lists}"); $confirmationmessage = str_ireplace('[LISTS]', $lists, getUserConfig("confirmationmessage:{$id}", $userdata['id'])); if (!TEST) { sendMail($userdata['email'], getConfig("confirmationsubject:{$id}"), $confirmationmessage, system_messageheaders(), $envelope); $adminmessage = $userdata['email'] . ' has confirmed their subscription'; if ($blacklisted) { $adminmessage .= "\n\n" . s('Subscriber has been removed from blacklist'); } sendAdminCopy('List confirmation', $adminmessage, $subscriptions); addSubscriberStatistics('confirmation', 1); } } else { $html = $GLOBALS['strAlreadyConfirmed']; } $_SESSION['subscriberConfirmed'][$userdata['email']] = time(); $info = $GLOBALS['strConfirmInfo']; } else { logEvent('Request for confirmation for invalid user ID: ' . substr($_GET['uid'], 0, 150)); $html = 'Error: ' . $GLOBALS['strUserNotFound']; $info = $GLOBALS['strConfirmFailInfo']; } $res = '<title>' . $GLOBALS['strConfirmTitle'] . '</title>'; $res .= $GLOBALS['pagedata']['header']; $res .= '<h3>' . $info . '</h3>'; $res .= $html; $res .= '<p>' . $GLOBALS['PoweredBy'] . '</p>'; $res .= $GLOBALS['pagedata']['footer']; return $res; }
if ($num_messages == 1) { processQueueOutput(s('One campaign to process.')); } else { processQueueOutput(s('%d campaigns to process.', $num_messages)); } } clearPageCache(); if (!$GLOBALS['commandline'] && empty($reload)) { processQueueOutput(s('Please leave this window open.') . ' ' . s('phpList will process your queue until all messages have been sent.') . ' ' . s('This may take a while')); if (SEND_QUEUE_PROCESSING_REPORT) { processQueueOutput(s('Report of processing will be sent by email')); } } } else { ## check for a future embargo, to be able to report when it expires. $future = Sql_Fetch_Assoc_Query('select unix_timestamp(embargo) - unix_timestamp(now()) as waittime ' . " from {$tables['message']}" . " where status not in ('draft', 'sent', 'prepared', 'suspended')" . ' and embargo > now()' . ' order by embargo asc limit 1'); $counters['status'] = 'embargo'; $counters['delaysend'] = $future['waittime']; } $script_stage = 2; # we know the messages to process #include_once "footer.inc"; if (empty($counters['num_per_batch'])) { $counters['num_per_batch'] = 10000000; } while ($message = Sql_fetch_array($messages)) { ++$counters['campaign']; $throttlecount = 0; $messageid = $message['id']; $counters['sent_users_for_message ' . $messageid] = 0; $counters['total_users_for_message ' . $messageid] = 0;
function createCachedLogoImage($size) { $logoImageId = getConfig('organisation_logo'); if (empty($logoImageId)) { return false; } $imgData = Sql_Fetch_Assoc_Query(sprintf('select data from %s where template = 0 and filename = "ORGANISATIONLOGO%d.png"', $GLOBALS['tables']['templateimage'], $size)); if (!empty($imgData['data'])) { return true; } $imgData = Sql_Fetch_Assoc_Query(sprintf('select data from %s where id = %d and template = 0', $GLOBALS['tables']['templateimage'], $logoImageId)); $imageContent = base64_decode($imgData['data']); if (empty($imageContent)) { ## fall back to a single pixel, so that there are no broken images $imageContent = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABGdBTUEAALGPC/xhBQAAAAZQTFRF////AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH0gQCEx05cqKA8gAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII='); } if (function_exists('getimagesizefromstring')) { $imgSize = getimagesizefromstring($imageContent); $sizeW = $imgSize[0]; $sizeH = $imgSize[1]; if ($sizeH > $sizeW) { $sizefactor = (double) ($size / $sizeH); } else { $sizefactor = (double) ($size / $sizeW); } $newwidth = (int) ($sizeW * $sizefactor); $newheight = (int) ($sizeH * $sizefactor); } else { $sizefactor = 1; } if ($sizefactor < 1) { $original = imagecreatefromstring($imageContent); $resized = imagecreatetruecolor($newwidth, $newheight); ## creates a black image (why would you want that....) imagesavealpha($resized, true); $transparent = imagecolorallocatealpha($resized, 255, 255, 255, 127); ## white. All the methods to make it transparent didn't work for me @@TODO really make transparent imagefill($resized, 0, 0, $transparent); if (imagecopyresized($resized, $original, 0, 0, 0, 0, $newwidth, $newheight, $sizeW, $sizeH)) { Sql_Query(sprintf('delete from %s where template = 0 and filename = "ORGANISATIONLOGO%d.png"', $GLOBALS['tables']['templateimage'], $size)); ## rather convoluted way to get the image contents $buffer = ob_get_contents(); ob_end_clean(); ob_start(); imagepng($resized); $imageContent = ob_get_contents(); ob_end_clean(); print $buffer; } } # else copy original Sql_Query(sprintf('insert into %s (template,filename,mimetype,data,width,height) values(0,"ORGANISATIONLOGO%d.png","%s","%s",%d,%d)', $GLOBALS['tables']['templateimage'], $size, $imgSize['mime'], base64_encode($imageContent), $newwidth, $newheight)); return true; }
function loadMessageData($msgid) { $default = array('from' => getConfig('message_from_address'), 'google_track' => getConfig('always_add_googletracking')); if (empty($default['from'])) { $default['from'] = getConfig('admin_address'); } if (!isset($GLOBALS['MD']) || !is_array($GLOBALS['MD'])) { $GLOBALS['MD'] = array(); } if (isset($GLOBALS['MD'][$msgid])) { return $GLOBALS['MD'][$msgid]; } ## when loading an old message that hasn't got data stored in message data, load it from the message table $prevMsgData = Sql_Fetch_Assoc_Query(sprintf('select * from %s where id = %d', $GLOBALS['tables']['message'], $msgid)); $finishSending = time() + DEFAULT_MESSAGEAGE; $messagedata = array('template' => getConfig("defaultmessagetemplate"), 'sendformat' => 'HTML', 'message' => '', 'forwardmessage' => '', 'textmessage' => '', 'rsstemplate' => '', 'embargo' => array('year' => date('Y'), 'month' => date('m'), 'day' => date('d'), 'hour' => date('H'), 'minute' => date('i')), 'repeatinterval' => 0, 'repeatuntil' => array('year' => date('Y'), 'month' => date('m'), 'day' => date('d'), 'hour' => date('H'), 'minute' => date('i')), 'requeueinterval' => 0, 'requeueuntil' => array('year' => date('Y'), 'month' => date('m'), 'day' => date('d'), 'hour' => date('H'), 'minute' => date('i')), 'finishsending' => array('year' => date('Y', $finishSending), 'month' => date('m', $finishSending), 'day' => date('d', $finishSending), 'hour' => date('H', $finishSending), 'minute' => date('i', $finishSending)), 'fromfield' => '', 'subject' => '', 'forwardsubject' => '', 'footer' => getConfig("messagefooter"), 'forwardfooter' => getConfig("forwardfooter"), 'status' => '', 'tofield' => '', 'replyto' => '', 'targetlist' => '', 'criteria_match' => '', 'sendurl' => '', 'sendmethod' => 'inputhere', 'testtarget' => '', 'notify_start' => getConfig("notifystart_default"), 'notify_end' => getConfig("notifyend_default"), 'google_track' => $default['google_track'] == 'true' || $default['google_track'] === true || $default['google_track'] == '1', 'excludelist' => array()); if (is_array($prevMsgData)) { foreach ($prevMsgData as $key => $val) { $messagedata[$key] = $val; } } $msgdata_req = Sql_Query(sprintf('select * from %s where id = %d', $GLOBALS['tables']['messagedata'], $msgid)); while ($row = Sql_Fetch_Assoc($msgdata_req)) { if (strpos($row['data'], 'SER:') === 0) { $data = stripSlashesArray(unserialize(substr($row['data'], 4))); } else { $data = stripslashes($row['data']); } if (!in_array($row['name'], array('astext', 'ashtml', 'astextandhtml', 'aspdf', 'astextandpdf'))) { ## don't overwrite counters in the message table from the data table $messagedata[stripslashes($row['name'])] = $data; } } foreach (array('embargo', 'repeatuntil', 'requeueuntil') as $datefield) { if (!is_array($messagedata[$datefield])) { $messagedata[$datefield] = array('year' => date('Y'), 'month' => date('m'), 'day' => date('d'), 'hour' => date('H'), 'minute' => date('i')); } } // Load lists that were targetted with message... $result = Sql_Query(sprintf('select list.name,list.id from ' . $GLOBALS['tables']['listmessage'] . ' listmessage,' . $GLOBALS['tables']['list'] . ' list where listmessage.messageid = %d and listmessage.listid = list.id', $msgid)); while ($lst = Sql_fetch_array($result)) { $messagedata["targetlist"][$lst["id"]] = 1; } ## backwards, check that the content has a url and use it to fill the sendurl if (empty($messagedata['sendurl'])) { ## can't do "ungreedy matching, in case the URL has placeholders, but this can potentially ## throw problems if (preg_match('/\\[URL:(.*)\\]/i', $messagedata['message'], $regs)) { $messagedata['sendurl'] = $regs[1]; } } if (empty($messagedata['sendurl']) && !empty($messagedata['message'])) { # if there's a message and no url, make sure to show the editor, and not the URL input $messagedata['sendmethod'] = 'inputhere'; } ### parse the from field into it's components - email and name if (preg_match("/([^ ]+@[^ ]+)/", $messagedata["fromfield"], $regs)) { # if there is an email in the from, rewrite it as "name <email>" $messagedata["fromname"] = str_replace($regs[0], "", $messagedata["fromfield"]); $messagedata["fromemail"] = $regs[0]; # if the email has < and > take them out here $messagedata["fromemail"] = str_replace("<", "", $messagedata["fromemail"]); $messagedata["fromemail"] = str_replace(">", "", $messagedata["fromemail"]); # make sure there are no quotes around the name $messagedata["fromname"] = str_replace('"', "", ltrim(rtrim($messagedata["fromname"]))); } elseif (strpos($messagedata["fromfield"], " ")) { # if there is a space, we need to add the email $messagedata["fromname"] = $messagedata["fromfield"]; # $cached[$messageid]["fromemail"] = "listmaster@$domain"; $messagedata["fromemail"] = $default['from']; } else { $messagedata["fromemail"] = $default['from']; $messagedata["fromname"] = $messagedata["fromfield"]; } $messagedata["fromname"] = trim($messagedata["fromname"]); # erase double spacing while (strpos($messagedata["fromname"], " ")) { $messagedata["fromname"] = str_replace(" ", " ", $messagedata["fromname"]); } ## if the name ends up being empty, copy the email if (empty($messagedata["fromname"])) { $messagedata["fromname"] = $messagedata["fromemail"]; } if (!empty($messagedata['targetlist']['unselect'])) { unset($messagedata['targetlist']['unselect']); } if (!empty($messagedata['excludelist']['unselect'])) { unset($messagedata['excludelist']['unselect']); } $GLOBALS['MD'][$msgid] = $messagedata; # var_dump($messagedata); return $messagedata; }
function sendEmail($messageid, $email, $hash, $htmlpref = 0, $rssitems = array(), $forwardedby = array()) { $getspeedstats = VERBOSE && !empty($GLOBALS['getspeedstats']) && isset($GLOBALS['processqueue_timer']); $sqlCountStart = $GLOBALS['pagestats']['number_of_queries']; $isTestMail = isset($_GET['page']) && $_GET['page'] == 'send'; ## for testing concurrency, put in a delay to check if multiple send processes cause duplicates #usleep(rand(0,10) * 1000000); global $strThisLink, $strUnsubscribe, $PoweredByImage, $PoweredByText, $cached, $website, $counters; if ($email == '') { return 0; } if ($getspeedstats) { output('sendEmail start ' . $GLOBALS['processqueue_timer']->interval(1)); } #0013076: different content when forwarding 'to a friend' if (FORWARD_ALTERNATIVE_CONTENT) { $forwardContent = count($forwardedby) > 0; } else { $forwardContent = 0; } if (empty($cached[$messageid])) { if (!precacheMessage($messageid, $forwardContent)) { unset($cached[$messageid]); logEvent('Error loading message ' . $messageid . ' in cache'); return 0; } } else { # dbg("Using cached {$cached[$messageid]["fromemail"]}"); if (VERBOSE) { output('Using cached message'); } } if (VERBOSE) { output(s('Sending message %d with subject %s to %s', $messageid, $cached[$messageid]['subject'], $email)); } ## at this stage we don't know whether the content is HTML or text, it's just content $content = $cached[$messageid]['content']; if (VERBOSE && $getspeedstats) { output('Load user start'); } $userdata = array(); $user_att_values = array(); #0011857: forward to friend, retain attributes if ($hash == 'forwarded' && defined('KEEPFORWARDERATTRIBUTES') && KEEPFORWARDERATTRIBUTES) { $user_att_values = getUserAttributeValues($forwardedby['email']); } elseif ($hash != 'forwarded') { $user_att_values = getUserAttributeValues($email); } if (!is_array($user_att_values)) { $user_att_values = array(); } foreach ($user_att_values as $key => $val) { $newkey = cleanAttributeName($key); ## in the help, we only list attributes with "strlen <= 30" unset($user_att_values[$key]); if (strlen($key) <= 30) { $user_att_values[$newkey] = $val; } } # print '<pre>';var_dump($user_att_values);print '</pre>';exit; $query = sprintf('select * from %s where email = "%s"', $GLOBALS['tables']['user'], sql_escape($email)); $userdata = Sql_Fetch_Assoc_Query($query); if (empty($userdata['id'])) { $userdata = array(); } #var_dump($userdata); if (stripos($content, '[LISTS]') !== false) { $listsarr = array(); $req = Sql_Query(sprintf('select list.name,list.active from %s as list,%s as listuser where list.id = listuser.listid and listuser.userid = %d', $GLOBALS['tables']['list'], $GLOBALS['tables']['listuser'], $userdata['id'])); while ($row = Sql_Fetch_Assoc($req)) { if ($row['active'] || PREFERENCEPAGE_SHOW_PRIVATE_LISTS) { array_push($listsarr, stripslashes($row['name'])); } } if (!empty($listsarr)) { $html['lists'] = implode('<br/>', $listsarr); $text['lists'] = implode("\n", $listsarr); } else { $html['lists'] = $GLOBALS['strNoListsFound']; $text['lists'] = $GLOBALS['strNoListsFound']; } unset($listsarr); } if (VERBOSE && $getspeedstats) { output('Load user end'); } if ($cached[$messageid]['userspecific_url']) { if (VERBOSE && $getspeedstats) { output('fetch personal URL start'); } ## Fetch external content, only if the URL has placeholders if ($GLOBALS['can_fetchUrl'] && preg_match("/\\[URL:([^\\s]+)\\]/i", $content, $regs)) { while (isset($regs[1]) && strlen($regs[1])) { $url = $regs[1]; if (!preg_match('/^http/i', $url)) { $url = 'http://' . $url; } $remote_content = fetchUrl($url, $userdata); # @@ don't use this # $remote_content = includeStyles($remote_content); if ($remote_content) { ## @TODO, work out a nice way to do this: ##17197 ## collecting different remote URLS only works if they do not have html and body tags. ## but if we strip them here, that might affect specially crafted ones, eg <body class="xx"> if (0) { $remote_content = preg_replace('/<html[^>]*>/', '', $remote_content); $remote_content = preg_replace('/<body[^>]*>/', '', $remote_content); $remote_content = preg_replace('/<\\/html[^>]*>/', '', $remote_content); $remote_content = preg_replace('/<\\/body[^>]*>/', '', $remote_content); } $content = str_replace($regs[0], '<!--' . $url . '-->' . $remote_content, $content); $cached[$messageid]['htmlformatted'] = strip_tags($content) != $content; } else { logEvent("Error fetching URL: {$regs['1']} to send to {$email}"); return 0; } preg_match("/\\[URL:([^\\s]+)\\]/i", $content, $regs); } } if (VERBOSE && $getspeedstats) { output('fetch personal URL end'); } } if (VERBOSE && $getspeedstats) { output('define placeholders start'); } $url = getConfig('unsubscribeurl'); ## https://mantis.phplist.com/view.php?id=16680 -> the "sep" should be & for the text links $sep = strpos($url, '?') === false ? '?' : '&'; $html['unsubscribe'] = sprintf('<a href="%s%suid=%s">%s</a>', $url, htmlspecialchars($sep), $hash, $strUnsubscribe); $text['unsubscribe'] = sprintf('%s%suid=%s', $url, $sep, $hash); $text['jumpoff'] = sprintf('%s%suid=%s&jo=1', $url, $sep, $hash); $html['unsubscribeurl'] = sprintf('%s%suid=%s', $url, htmlspecialchars($sep), $hash); $text['unsubscribeurl'] = sprintf('%s%suid=%s', $url, $sep, $hash); $text['jumpoffurl'] = sprintf('%s%suid=%s&jo=1', $url, $sep, $hash); #0013076: Blacklisting posibility for unknown users $url = getConfig('blacklisturl'); $sep = strpos($url, '?') === false ? '?' : '&'; $html['blacklist'] = sprintf('<a href="%s%semail=%s">%s</a>', $url, htmlspecialchars($sep), $email, $strUnsubscribe); $text['blacklist'] = sprintf('%s%semail=%s', $url, $sep, $email); $html['blacklisturl'] = sprintf('%s%semail=%s', $url, htmlspecialchars($sep), $email); $text['blacklisturl'] = sprintf('%s%semail=%s', $url, $sep, $email); #0013076: Problem found during testing: message part must be parsed correctly as well. if (count($forwardedby) && isset($forwardedby['email'])) { $html['unsubscribe'] = $html['blacklist']; $text['unsubscribe'] = $text['blacklist']; $html['forwardedby'] = $forwardedby['email']; $text['forwardedby'] = $forwardedby['email']; } $url = getConfig('subscribeurl'); $sep = strpos($url, '?') === false ? '?' : '&'; $html['subscribe'] = sprintf('<a href="%s">%s</a>', $url, $strThisLink); $text['subscribe'] = sprintf('%s', $url); $html['subscribeurl'] = sprintf('%s', $url); $text['subscribeurl'] = sprintf('%s', $url); $url = getConfig('forwardurl'); $sep = strpos($url, '?') === false ? '?' : '&'; $html['forward'] = sprintf('<a href="%s%suid=%s&mid=%d">%s</a>', $url, htmlspecialchars($sep), $hash, $messageid, $strThisLink); $text['forward'] = sprintf('%s%suid=%s&mid=%d', $url, $sep, $hash, $messageid); $html['forwardurl'] = sprintf('%s%suid=%s&mid=%d', $url, htmlspecialchars($sep), $hash, $messageid); $text['forwardurl'] = $text['forward']; $html['messageid'] = sprintf('%d', $messageid); $text['messageid'] = sprintf('%d', $messageid); $url = getConfig('forwardurl'); # make sure there are no newlines, otherwise they get turned into <br/>s $html['forwardform'] = ''; #sprintf('<form method="get" action="%s" name="forwardform" class="forwardform"><input type="hidden" name="uid" value="%s" /><input type="hidden" name="mid" value="%d" /><input type="hidden" name="p" value="forward" /><input type=text name="email" value="" class="forwardinput" /><input name="Send" type="submit" value="%s" class="forwardsubmit"/></form>',$url,$hash,$messageid,$GLOBALS['strForward']); $text['signature'] = "\n\n-- powered by phpList, www.phplist.com --\n\n"; $url = getConfig('preferencesurl'); $sep = strpos($url, '?') === false ? '?' : '&'; $html['preferences'] = sprintf('<a href="%s%suid=%s">%s</a>', $url, htmlspecialchars($sep), $hash, $strThisLink); $text['preferences'] = sprintf('%s%suid=%s', $url, $sep, $hash); $html['preferencesurl'] = sprintf('%s%suid=%s', $url, htmlspecialchars($sep), $hash); $text['preferencesurl'] = sprintf('%s%suid=%s', $url, $sep, $hash); $url = getConfig('confirmationurl'); $sep = strpos($url, '?') === false ? '?' : '&'; $html['confirmationurl'] = sprintf('%s%suid=%s', $url, htmlspecialchars($sep), $hash); $text['confirmationurl'] = sprintf('%s%suid=%s', $url, $sep, $hash); #historical, not sure it's still used $html['userid'] = $hash; $text['userid'] = $hash; $html['website'] = $GLOBALS['website']; # Your website's address, e.g. www.yourdomain.com $text['website'] = $GLOBALS['website']; $html['domain'] = $GLOBALS['domain']; # Your domain, e.g. yourdomain.com $text['domain'] = $GLOBALS['domain']; if ($hash != 'forwarded') { $text['footer'] = $cached[$messageid]['textfooter']; $html['footer'] = $cached[$messageid]['htmlfooter']; } else { #0013076: different content when forwarding 'to a friend' if (FORWARD_ALTERNATIVE_CONTENT) { $text['footer'] = stripslashes($messagedata['forwardfooter']); } else { $text['footer'] = getConfig('forwardfooter'); } $html['footer'] = $text['footer']; } /* We request you retain the signature below in your emails including the links. This not only gives respect to the large amount of time given freely by the developers but also helps build interest, traffic and use of phpList, which is beneficial to it's future development. You can configure how the credits are added to your pages and emails in your config file. Michiel Dethmers, phpList Ltd 2003 - 2013 */ if (!EMAILTEXTCREDITS) { $html['signature'] = $PoweredByImage; #'<div align="center" id="signature"><a href="http://www.phplist.com"><img src="powerphplist.png" width=88 height=31 title="Powered by PHPlist" alt="Powered by PHPlist" border="0" /></a></div>'; # oops, accidentally became spyware, never intended that, so take it out again :-) $html['signature'] = preg_replace('/src=".*power-phplist.png"/', 'src="powerphplist.png"', $html['signature']); } else { $html['signature'] = $PoweredByText; } # $content = $cached[$messageid]["htmlcontent"]; if (VERBOSE && $getspeedstats) { output('define placeholders end'); } ## Fill text and html versions depending on given versions. if (VERBOSE && $getspeedstats) { output('parse text to html or html to text start'); } if ($cached[$messageid]['htmlformatted']) { if (empty($cached[$messageid]['textcontent'])) { $textcontent = HTML2Text($content); } else { $textcontent = $cached[$messageid]['textcontent']; } $htmlcontent = $content; } else { if (empty($cached[$messageid]['textcontent'])) { $textcontent = $content; } else { $textcontent = $cached[$messageid]['textcontent']; } $htmlcontent = parseText($content); } if (VERBOSE && $getspeedstats) { output('parse text to html or html to text end'); } $defaultstyle = getConfig('html_email_style'); $adddefaultstyle = 0; if (VERBOSE && $getspeedstats) { output('merge into template start'); } if ($cached[$messageid]['template']) { # template used $htmlmessage = str_replace('[CONTENT]', $htmlcontent, $cached[$messageid]['template']); } else { # no template used $htmlmessage = $htmlcontent; $adddefaultstyle = 1; } $textmessage = $textcontent; if (VERBOSE && $getspeedstats) { output('merge into template end'); } ## Parse placeholders if (VERBOSE && $getspeedstats) { output('parse placeholders start'); } /* var_dump($html); var_dump($userdata); var_dump($user_att_values); exit; */ # print htmlspecialchars($htmlmessage);exit; ### @@@TODO don't use forward and forward form in a forwarded message as it'll fail if (strpos($htmlmessage, '[FOOTER]') !== false) { $htmlmessage = str_ireplace('[FOOTER]', $html['footer'], $htmlmessage); } elseif ($html['footer']) { $htmlmessage = addHTMLFooter($htmlmessage, '<br />' . $html['footer']); } if (strpos($htmlmessage, '[SIGNATURE]') !== false) { $htmlmessage = str_ireplace('[SIGNATURE]', $html['signature'], $htmlmessage); } else { # BUGFIX 0015303, 2/2 // $htmlmessage .= '<br />'.$html["signature"]; $htmlmessage = addHTMLFooter($htmlmessage, ' ' . $html['signature']); } # END BUGFIX 0015303, 2/2 if (strpos($textmessage, '[FOOTER]')) { $textmessage = str_ireplace('[FOOTER]', $text['footer'], $textmessage); } else { $textmessage .= "\n\n" . $text['footer']; } if (strpos($textmessage, '[SIGNATURE]')) { $textmessage = str_ireplace('[SIGNATURE]', $text['signature'], $textmessage); } else { $textmessage .= "\n" . $text['signature']; } ### addition to handle [FORWARDURL:Message ID:Link Text] (link text optional) while (preg_match('/\\[FORWARD:([^\\]]+)\\]/Uxm', $htmlmessage, $regs)) { $newforward = $regs[1]; $matchtext = $regs[0]; if (strpos($newforward, ':')) { ## using FORWARDURL:messageid:linktext list($forwardmessage, $forwardtext) = explode(':', $newforward); } else { $forwardmessage = sprintf('%d', $newforward); $forwardtext = 'this link'; } if (!empty($forwardmessage)) { $url = getConfig('forwardurl'); $sep = strpos($url, '?') === false ? '?' : '&'; $forwardurl = sprintf('%s%suid=%s&mid=%d', $url, $sep, $hash, $forwardmessage); $htmlmessage = str_replace($matchtext, '<a href="' . htmlspecialchars($forwardurl) . '">' . $forwardtext . '</a>', $htmlmessage); } else { ## make sure to remove the match, otherwise, it'll be an eternal loop $htmlmessage = str_replace($matchtext, '', $htmlmessage); } } ## the text message has to be parsed seperately, because the line might wrap if the text for the link is long, so the match text is different while (preg_match('/\\[FORWARD:([^\\]]+)\\]/Uxm', $textmessage, $regs)) { $newforward = $regs[1]; $matchtext = $regs[0]; if (strpos($newforward, ':')) { ## using FORWARDURL:messageid:linktext list($forwardmessage, $forwardtext) = explode(':', $newforward); } else { $forwardmessage = sprintf('%d', $newforward); $forwardtext = 'this link'; } if (!empty($forwardmessage)) { $url = getConfig('forwardurl'); $sep = strpos($url, '?') === false ? '?' : '&'; $forwardurl = sprintf('%s%suid=%s&mid=%d', $url, $sep, $hash, $forwardmessage); $textmessage = str_replace($matchtext, $forwardtext . ' ' . $forwardurl, $textmessage); } else { ## make sure to remove the match, otherwise, it'll be an eternal loop $textmessage = str_replace($matchtext, '', $textmessage); } } # $req = Sql_Query(sprintf('select filename,data from %s where template = %d', # $GLOBALS["tables"]["templateimage"],$cached[$messageid]["templateid"])); if (ALWAYS_ADD_USERTRACK) { if (stripos($htmlmessage, '</body>')) { $htmlmessage = str_replace('</body>', '<img src="' . $GLOBALS['public_scheme'] . '://' . $website . $GLOBALS['pageroot'] . '/ut.php?u=' . $hash . '&m=' . $messageid . '" width="1" height="1" border="0" alt="" /></body>', $htmlmessage); } else { $htmlmessage .= '<img src="' . $GLOBALS['public_scheme'] . '://' . $website . $GLOBALS['pageroot'] . '/ut.php?u=' . $hash . '&m=' . $messageid . '" width="1" height="1" border="0" alt="" />'; } } else { ## can't use str_replace or str_ireplace, because those replace all, and we only want to replace one $htmlmessage = preg_replace('/\\[USERTRACK\\]/i', '<img src="' . $GLOBALS['public_scheme'] . '://' . $website . $GLOBALS['pageroot'] . '/ut.php?u=' . $hash . '&m=' . $messageid . '" width="1" height="1" border="0" alt="" />', $htmlmessage, 1); } # make sure to only include usertrack once, otherwise the stats would go silly $htmlmessage = str_ireplace('[USERTRACK]', '', $htmlmessage); $textmessage = str_ireplace('[USERTRACK]', '', $textmessage); $html['subject'] = $cached[$messageid]['subject']; $text['subject'] = $cached[$messageid]['subject']; $htmlmessage = parsePlaceHolders($htmlmessage, $html); $textmessage = parsePlaceHolders($textmessage, $text); if (VERBOSE && $getspeedstats) { output('parse placeholders end'); } if (VERBOSE && $getspeedstats) { output('parse userdata start'); } $htmlmessage = parsePlaceHolders($htmlmessage, $userdata); $textmessage = parsePlaceHolders($textmessage, $userdata); //CUT 2 $destinationemail = ''; if (is_array($user_att_values)) { // CUT 3 $htmlmessage = parsePlaceHolders($htmlmessage, $user_att_values); $textmessage = parsePlaceHolders($textmessage, $user_att_values); } if (VERBOSE && $getspeedstats) { output('parse userdata end'); } if (!$destinationemail) { $destinationemail = $email; } # this should move into a plugin if (strpos($destinationemail, '@') === false && isset($GLOBALS['expand_unqualifiedemail'])) { $destinationemail .= $GLOBALS['expand_unqualifiedemail']; } if (VERBOSE && $getspeedstats) { output('pass to plugins for destination email start'); } foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { # print "Checking Destination for ".$plugin->name."<br/>"; $destinationemail = $plugin->setFinalDestinationEmail($messageid, $user_att_values, $destinationemail); } if (VERBOSE && $getspeedstats) { output('pass to plugins for destination email end'); } foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { $textmessage = $plugin->parseOutgoingTextMessage($messageid, $textmessage, $destinationemail, $userdata); $htmlmessage = $plugin->parseOutgoingHTMLMessage($messageid, $htmlmessage, $destinationemail, $userdata); } ## click tracking # for now we won't click track forwards, as they are not necessarily users, so everything would fail if (VERBOSE && $getspeedstats) { output('click track start'); } if (CLICKTRACK && $hash != 'forwarded' && !empty($userdata['id'])) { $urlbase = ''; # let's leave this for now /* if (preg_match('/<base href="(.*)"([^>]*)>/Umis',$htmlmessage,$regs)) { $urlbase = $regs[1]; } else { $urlbase = ''; } # print "URLBASE: $urlbase<br/>"; */ # convert html message # preg_match_all('/<a href="?([^> "]*)"?([^>]*)>(.*)<\/a>/Umis',$htmlmessage,$links); preg_match_all('/<a (.*)href=["\'](.*)["\']([^>]*)>(.*)<\\/a>/Umis', $htmlmessage, $links); # to process the Yahoo webpage with base href and link like <a href=link> we'd need this one # preg_match_all('/<a href=([^> ]*)([^>]*)>(.*)<\/a>/Umis',$htmlmessage,$links); $clicktrack_root = sprintf('%s://%s/lt.php', $GLOBALS['public_scheme'], $website . $GLOBALS['pageroot']); for ($i = 0; $i < count($links[2]); ++$i) { $link = cleanUrl($links[2][$i]); $link = str_replace('"', '', $link); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } $linkid = 0; $linktext = $links[4][$i]; ## if the link is text containing a "protocol" eg http:// then do not track it, otherwise ## it will look like Phishing ## it's ok when the link is an image $linktext = strip_tags($linktext); $looksLikePhishing = stripos($linktext, 'https://') !== false || stripos($linktext, 'http://') !== false; if (!$looksLikePhishing && (preg_match('/^http|ftp/i', $link) || preg_match('/^http|ftp/i', $urlbase)) && !strpos($link, $clicktrack_root)) { # take off personal uids $url = cleanUrl($link, array('PHPSESSID', 'uid')); # $url = preg_replace('/&uid=[^\s&]+/','',$link); # if (!strpos('http:',$link)) { # $link = $urlbase . $link; # } $linkid = clickTrackLinkId($messageid, $userdata['id'], $url, $link); $masked = "H|{$linkid}|{$messageid}|" . $userdata['id'] ^ XORmask; $masked = base64_encode($masked); ## 15254- the encoding adds one or two extraneous = signs, take them off $masked = preg_replace('/=$/', '', $masked); $masked = preg_replace('/=$/', '', $masked); $masked = urlencode($masked); if (!CLICKTRACK_LINKMAP) { $newlink = sprintf('<a %shref="%s://%s/lt.php?id=%s" %s>%s</a>', $links[1][$i], $GLOBALS['public_scheme'], $website . $GLOBALS['pageroot'], $masked, $links[3][$i], $links[4][$i]); } else { $newlink = sprintf('<a %shref="%s://%s%s" %s>%s</a>', $links[1][$i], $GLOBALS['public_scheme'], $website . CLICKTRACK_LINKMAP, $masked, $links[3][$i], $links[4][$i]); } $htmlmessage = str_replace($links[0][$i], $newlink, $htmlmessage); } } # convert Text message # first find occurances of our top domain, to avoid replacing them later # hmm, this is no point, it's not just *our* topdomain, but any if (0) { preg_match_all('#(https?://' . $GLOBALS['website'] . '/?)\\s+#mis', $textmessage, $links); # preg_match_all('#(https?://[a-z0-9\./\#\?&:@=%\-]+)#ims',$textmessage,$links); # preg_match_all('!(https?:\/\/www\.[a-zA-Z0-9\.\/#~\?+=&%@-_]+)!mis',$textmessage,$links); for ($i = 0; $i < count($links[1]); ++$i) { # not entirely sure why strtolower was used, but it seems to break things http://mantis.phplist.com/view.php?id=4406 # $link = strtolower(cleanUrl($links[1][$i])); $link = cleanUrl($links[1][$i]); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } $linkid = 0; if (preg_match('/^http|ftp/i', $link) && !strpos($link, $clicktrack_root)) { $url = cleanUrl($link, array('PHPSESSID', 'uid')); $req = Sql_Query(sprintf('insert ignore into %s (messageid,userid,url,forward) values(%d,%d,"%s","%s")', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $url, $link)); $req = Sql_Fetch_Row_Query(sprintf('select linkid from %s where messageid = %s and userid = %d and forward = "%s" ', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $link)); $linkid = $req[0]; $masked = "T|{$linkid}|{$messageid}|" . $userdata['id'] ^ XORmask; $masked = urlencode(base64_encode($masked)); $newlink = sprintf('%s://%s/lt.php?id=%s', $GLOBALS['public_scheme'], $website . $GLOBALS['pageroot'], $masked); $textmessage = str_replace($links[0][$i], '<' . $newlink . '>', $textmessage); } } } #now find the rest # @@@ needs to expand to find complete urls like: #http://user:password@www.web-site.com:1234/document.php?parameter=something&otherpar=somethingelse#anchor # or secure #https://user:password@www.website.com:2345/document.php?parameter=something%20&otherpar=somethingelse#anchor preg_match_all('#(https?://[^\\s\\>\\}\\,]+)#mis', $textmessage, $links); # preg_match_all('#(https?://[a-z0-9\./\#\?&:@=%\-]+)#ims',$textmessage,$links); # preg_match_all('!(https?:\/\/www\.[a-zA-Z0-9\.\/#~\?+=&%@-_]+)!mis',$textmessage,$links); ## sort the results in reverse order, so that they are replaced correctly rsort($links[1]); $newlinks = array(); for ($i = 0; $i < count($links[1]); ++$i) { $link = cleanUrl($links[1][$i]); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } $linkid = 0; if (preg_match('/^http|ftp/i', $link)) { # && !strpos($link,$clicktrack_root)) { $url = cleanUrl($link, array('PHPSESSID', 'uid')); $linkid = clickTrackLinkId($messageid, $userdata['id'], $url, $link); $masked = "T|{$linkid}|{$messageid}|" . $userdata['id'] ^ XORmask; $masked = base64_encode($masked); ## 15254- the encoding adds one or two extraneous = signs, take them off $masked = preg_replace('/=$/', '', $masked); $masked = preg_replace('/=$/', '', $masked); $masked = urlencode($masked); if (!CLICKTRACK_LINKMAP) { $newlinks[$linkid] = sprintf('%s://%s/lt.php?id=%s', $GLOBALS['public_scheme'], $website . $GLOBALS['pageroot'], $masked); } else { $newlinks[$linkid] = sprintf('%s://%s%s', $GLOBALS['public_scheme'], $website . CLICKTRACK_LINKMAP, $masked); } # print $links[0][$i] .' -> '.$newlink.'<br/>'; $textmessage = str_replace($links[1][$i], '[%%%' . $linkid . '%%%]', $textmessage); } } foreach ($newlinks as $linkid => $newlink) { $textmessage = str_replace('[%%%' . $linkid . '%%%]', $newlink, $textmessage); } } if (VERBOSE && $getspeedstats) { output('click track end'); } ## if we're not tracking clicks, we should add Google tracking here ## otherwise, we can add it when redirecting on the click if (!CLICKTRACK && !empty($cached[$messageid]['google_track'])) { preg_match_all('/<a (.*)href=["\'](.*)["\']([^>]*)>(.*)<\\/a>/Umis', $htmlmessage, $links); for ($i = 0; $i < count($links[2]); ++$i) { $link = cleanUrl($links[2][$i]); $link = str_replace('"', '', $link); ## http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=55578 $trackingcode = 'utm_source=phplist' . $messageid . '&utm_medium=email&utm_content=HTML&utm_campaign=' . urlencode($cached[$messageid]['subject']); ## take off existing tracking code, if found if (strpos($link, 'utm_medium') !== false) { $link = preg_replace('/utm_(\\w+)\\=[^&]+&/U', '', $link); } ## 16894 make sure to keep the fragment value at the end of the URL if (strpos($link, '#')) { list($tmplink, $fragment) = explode('#', $link); $link = $tmplink; unset($tmplink); $fragment = '#' . $fragment; } else { $fragment = ''; } if (strpos($link, '?')) { $newurl = $link . '&' . $trackingcode . $fragment; } else { $newurl = $link . '?' . $trackingcode . $fragment; } # print $link. ' '.$newurl.' <br/>'; $newlink = sprintf('<a %shref="%s" %s>%s</a>', $links[1][$i], $newurl, $links[3][$i], $links[4][$i]); $htmlmessage = str_replace($links[0][$i], $newlink, $htmlmessage); } preg_match_all('#(https?://[^\\s\\>\\}\\,]+)#mis', $textmessage, $links); rsort($links[1]); $newlinks = array(); for ($i = 0; $i < count($links[1]); ++$i) { $link = cleanUrl($links[1][$i]); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } if (preg_match('/^http|ftp/i', $link)) { # && !strpos($link,$clicktrack_root)) { $url = cleanUrl($link, array('PHPSESSID', 'uid')); //@alpha1: maybe source should be message id? $trackingcode = 'utm_source=phplist' . $messageid . '&utm_medium=email&utm_content=text&utm_campaign=' . urlencode($cached[$messageid]['subject']); ## take off existing tracking code, if found if (strpos($link, 'utm_medium') !== false) { $link = preg_replace('/utm_(\\w+)\\=[^&]+/', '', $link); } ## 16894 make sure to keep the fragment value at the end of the URL if (strpos($link, '#')) { list($tmplink, $fragment) = explode('#', $link); $link = $tmplink; unset($tmplink); $fragment = '#' . $fragment; } else { $fragment = ''; } if (strpos($link, '?')) { $newurl = $link . '&' . $trackingcode . $fragment; } else { $newurl = $link . '?' . $trackingcode . $fragment; } $newlinks[$i] = $newurl; $textmessage = str_replace($links[1][$i], '[%%%' . $i . '%%%]', $textmessage); } } foreach ($newlinks as $linkid => $newlink) { $textmessage = str_replace('[%%%' . $linkid . '%%%]', $newlink, $textmessage); } unset($newlinks); } # print htmlspecialchars($htmlmessage);exit; #0011996: forward to friend - personal message if (FORWARD_PERSONAL_NOTE_SIZE && $hash == 'forwarded' && !empty($forwardedby['personalNote'])) { $htmlmessage = nl2br($forwardedby['personalNote']) . '<br/>' . $htmlmessage; $textmessage = $forwardedby['personalNote'] . "\n" . $textmessage; } if (VERBOSE && $getspeedstats) { output('cleanup start'); } ## allow fallback to default value for the ones that do not have a value ## delimiter is %% to avoid interfering with markup preg_match_all('/\\[.*\\%\\%([^\\]]+)\\]/Ui', $htmlmessage, $matches); for ($i = 0; $i < count($matches[0]); ++$i) { $htmlmessage = str_ireplace($matches[0][$i], $matches[1][$i], $htmlmessage); } preg_match_all('/\\[.*\\%\\%([^\\]]+)\\]/Ui', $textmessage, $matches); for ($i = 0; $i < count($matches[0]); ++$i) { $textmessage = str_ireplace($matches[0][$i], $matches[1][$i], $textmessage); } ## remove any remaining placeholders ## 16671 - do not do this, as it'll remove conditional CSS and other stuff ## that we'd like to keep //$htmlmessage = preg_replace("/\[[A-Z\. ]+\]/i","",$htmlmessage); //$textmessage = preg_replace("/\[[A-Z\. ]+\]/i","",$textmessage); # print htmlspecialchars($htmlmessage);exit; # check that the HTML message as proper <head> </head> and <body> </body> tags # some readers fail when it doesn't if (!preg_match('#<body.*</body>#ims', $htmlmessage)) { $htmlmessage = '<body>' . $htmlmessage . '</body>'; } if (!preg_match('#<head.*</head>#ims', $htmlmessage)) { if (!$adddefaultstyle) { $defaultstyle = ''; } $htmlmessage = '<head> <meta content="text/html;charset=' . $cached[$messageid]['html_charset'] . '" http-equiv="Content-Type"> <title></title>' . $defaultstyle . '</head>' . $htmlmessage; } if (!preg_match('#<html.*</html>#ims', $htmlmessage)) { $htmlmessage = '<html>' . $htmlmessage . '</html>'; } ## remove trailing code after </html> $htmlmessage = preg_replace('#</html>.*#msi', '</html>', $htmlmessage); ## the editor sometimes places <p> and </p> around the URL $htmlmessage = str_ireplace('<p><!DOCTYPE', '<!DOCTYPE', $htmlmessage); $htmlmessage = str_ireplace('</html></p>', '</html>', $htmlmessage); if (VERBOSE && $getspeedstats) { output('cleanup end'); } # $htmlmessage = compressContent($htmlmessage); # print htmlspecialchars($htmlmessage);exit; if ($getspeedstats) { output('build Start ' . $GLOBALS['processqueue_timer']->interval(1)); } # build the email $mail = new PHPlistMailer($messageid, $destinationemail); if ($isTestMail) { $mail->SMTPDebug = PHPMAILER_SMTP_DEBUG; $mail->Debugoutput = 'html'; } if ($forwardedby) { $mail->add_timestamp(); } $mail->addCustomHeader('List-Help: <' . $text['preferences'] . '>'); $mail->addCustomHeader('List-Unsubscribe: <' . $text['jumpoffurl'] . '>'); $mail->addCustomHeader('List-Subscribe: <' . getConfig('subscribeurl') . '>'); $mail->addCustomHeader('List-Owner: <mailto:' . getConfig('admin_address') . '>'); list($dummy, $domaincheck) = explode('@', $destinationemail); $text_domains = explode("\n", trim(getConfig('alwayssendtextto'))); if (in_array($domaincheck, $text_domains)) { $htmlpref = 0; if (VERBOSE) { output($GLOBALS['I18N']->get('sendingtextonlyto') . " {$domaincheck}"); } } foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { $plugin_attachments = $plugin->getMessageAttachment($messageid, $mail->Body); if (!empty($plugin_attachments[0]['content'])) { foreach ($plugins_attachments as $plugin_attachment) { $mail->add_attachment($plugin_attachment['content'], basename($plugin_attachment['filename']), $plugin_attachment['mimetype']); } } } # so what do we actually send? switch ($cached[$messageid]['sendformat']) { case 'PDF': # send a PDF file to users who want html and text to everyone else if ($htmlpref) { if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set aspdf = aspdf + 1 where id = {$messageid}"); } $pdffile = createPdf($textmessage); if (is_file($pdffile) && filesize($pdffile)) { $fp = fopen($pdffile, 'r'); if ($fp) { $contents = fread($fp, filesize($pdffile)); fclose($fp); unlink($pdffile); $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <embed src="message.pdf" width="450" height="450" href="message.pdf"></embed> </body> </html>'; # $mail->add_html($html,$textmessage); # $mail->add_text($textmessage); $mail->add_attachment($contents, 'message.pdf', 'application/pdf'); } } if (!addAttachments($messageid, $mail, 'HTML')) { return 0; } } else { if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set astext = astext + 1 where id = {$messageid}"); } $mail->add_text($textmessage); if (!addAttachments($messageid, $mail, 'text')) { return 0; } } break; case 'text and PDF': # send a PDF file to users who want html and text to everyone else if ($htmlpref) { if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set astextandpdf = astextandpdf + 1 where id = {$messageid}"); } $pdffile = createPdf($textmessage); if (is_file($pdffile) && filesize($pdffile)) { $fp = fopen($pdffile, 'r'); if ($fp) { $contents = fread($fp, filesize($pdffile)); fclose($fp); unlink($pdffile); $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <embed src="message.pdf" width="450" height="450" href="message.pdf"></embed> </body> </html>'; # $mail->add_html($html,$textmessage); $mail->add_text($textmessage); $mail->add_attachment($contents, 'message.pdf', 'application/pdf'); } } if (!addAttachments($messageid, $mail, 'HTML')) { return 0; } } else { if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set astext = astext + 1 where id = {$messageid}"); } $mail->add_text($textmessage); if (!addAttachments($messageid, $mail, 'text')) { return 0; } } break; case 'text': # send as text if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set astext = astext + 1 where id = {$messageid}"); } $mail->add_text($textmessage); if (!addAttachments($messageid, $mail, 'text')) { return 0; } break; case 'both': case 'text and HTML': case 'HTML': default: $handled_by_plugin = 0; if (!empty($GLOBALS['pluginsendformats'][$cached[$messageid]['sendformat']])) { # possibly handled by plugin $pl = $GLOBALS['plugins'][$GLOBALS['pluginsendformats'][$cached[$messageid]['sendformat']]]; if (is_object($pl) && method_exists($pl, 'parseFinalMessage')) { $handled_by_plugin = $pl->parseFinalMessage($cached[$messageid]['sendformat'], $htmlmessage, $textmessage, $mail, $messageid); } } if (!$handled_by_plugin) { # send one big file to users who want html and text to everyone else if ($htmlpref) { if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set astextandhtml = astextandhtml + 1 where id = {$messageid}"); } # dbg("Adding HTML ".$cached[$messageid]["templateid"]); if (WORDWRAP_HTML) { ## wrap it: http://mantis.phplist.com/view.php?id=15528 ## some reports say, this fixes things and others say it breaks things https://mantis.phplist.com/view.php?id=15617 ## so for now, only switch on if requested. ## it probably has to do with the MTA used $htmlmessage = wordwrap($htmlmessage, WORDWRAP_HTML, "\r\n"); } $mail->add_html($htmlmessage, $textmessage, $cached[$messageid]['templateid']); if (!addAttachments($messageid, $mail, 'HTML')) { return 0; } } else { if (!$isTestMail) { Sql_Query("update {$GLOBALS['tables']['message']} set astext = astext + 1 where id = {$messageid}"); } $mail->add_text($textmessage); # $mail->setText($textmessage); # $mail->Encoding = TEXTEMAIL_ENCODING; if (!addAttachments($messageid, $mail, 'text')) { return 0; } } } break; } # print htmlspecialchars($htmlmessage);exit; if (!TEST) { if ($hash != 'forwarded' || !count($forwardedby)) { $fromname = $cached[$messageid]['fromname']; $fromemail = $cached[$messageid]['fromemail']; $subject = $cached[$messageid]['subject']; } else { $fromname = ''; $fromemail = $forwardedby['email']; $subject = $GLOBALS['strFwd'] . ': ' . $cached[$messageid]['subject']; } if (!empty($cached[$messageid]['replytoemail'])) { $mail->AddReplyTo($cached[$messageid]['replytoemail'], $cached[$messageid]['replytoname']); } if ($getspeedstats) { output('build End ' . $GLOBALS['processqueue_timer']->interval(1)); } if ($getspeedstats) { output('send Start ' . $GLOBALS['processqueue_timer']->interval(1)); } if (!empty($GLOBALS['developer_email'])) { $destinationemail = $GLOBALS['developer_email']; } $sendOK = false; if (!$mail->compatSend('', $destinationemail, $fromname, $fromemail, $subject)) { foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { $plugin->processSendFailed($messageid, $userdata, $isTestMail); } output(sprintf(s('Error sending message %d (%d/%d) to %s (%s) '), $messageid, $counters['batch_count'], $counters['batch_total'], $email, $destinationemail), 0); } else { $sendOK = true; foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { $plugin->processSendSuccess($messageid, $userdata, $isTestMail); } } if ($getspeedstats) { output('send End ' . $GLOBALS['processqueue_timer']->interval(1)); } if (!empty($mail->mailsize)) { $sizename = $htmlpref ? 'htmlsize' : 'textsize'; if (empty($cached[$messageid][$sizename])) { setMessageData($messageid, $sizename, $mail->mailsize); $cached[$messageid][$sizename] = $mail->mailsize; if (isset($cached[$messageid]['htmlsize'])) { output(sprintf(s('Size of HTML email: %s ', formatBytes($cached[$messageid]['htmlsize']))), 0, 'progress'); } if (isset($cached[$messageid]['textsize'])) { output(sprintf(s('Size of Text email: %s ', formatBytes($cached[$messageid]['textsize']))), 0, 'progress'); } } } if (defined('MAX_MAILSIZE') && isset($cached[$messageid]['htmlsize']) && $cached[$messageid]['htmlsize'] > MAX_MAILSIZE) { logEvent(s('Message too large (%s is over %s), suspending', $cached[$messageid]['htmlsize'], MAX_MAILSIZE)); if ($isTestMail) { $_SESSION['action_result'] = s('Warning: the final message exceeds the sending limit, this campaign will fail sending. Reduce the size by removing attachments or images'); } else { Sql_Query(sprintf('update %s set status = "suspended" where id = %d', $GLOBALS['tables']['message'], $messageid)); logEvent(s('Campaign %d suspended. Message too large', $messageid)); foreach ($GLOBALS['plugins'] as $pluginname => $plugin) { $plugin->processError(s('Campaign %d suspended, message too large', $messageid)); } } } $sqlCount = $GLOBALS['pagestats']['number_of_queries'] - $sqlCountStart; if ($getspeedstats) { output('It took ' . $sqlCount . ' queries to send this message'); } return $sendOK; } return 0; }
function sendEmail($messageid, $email, $hash, $htmlpref = 0, $rssitems = array(), $forwardedby = array()) { global $strThisLink, $PoweredByImage, $PoweredByText, $cached, $website; if ($email == "") { return 0; } #0013076: different content when forwarding 'to a friend' if (FORWARD_ALTERNATIVE_CONTENT) { $forwardContent = sizeof($forwardedby) > 0; $messagedata = loadMessageData($messageid); } else { $forwardContent = 0; } if (empty($cached[$messageid])) { $domain = getConfig("domain"); $message = Sql_query("select * from {$GLOBALS["tables"]["message"]} where id = {$messageid}"); $cached[$messageid] = array(); $message = Sql_fetch_array($message); if (ereg("([^ ]+@[^ ]+)", $message["fromfield"], $regs)) { # if there is an email in the from, rewrite it as "name <email>" $message["fromfield"] = ereg_replace($regs[0], "", $message["fromfield"]); $cached[$messageid]["fromemail"] = $regs[0]; # if the email has < and > take them out here $cached[$messageid]["fromemail"] = ereg_replace("<", "", $cached[$messageid]["fromemail"]); $cached[$messageid]["fromemail"] = ereg_replace(">", "", $cached[$messageid]["fromemail"]); # make sure there are no quotes around the name $cached[$messageid]["fromname"] = ereg_replace('"', "", ltrim(rtrim($message["fromfield"]))); } elseif (ereg(" ", $message["fromfield"], $regs)) { # if there is a space, we need to add the email $cached[$messageid]["fromname"] = $message["fromfield"]; $cached[$messageid]["fromemail"] = "listmaster@{$domain}"; } else { $cached[$messageid]["fromemail"] = $message["fromfield"] . "@{$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[$messageid]["fromname"] = $message["fromfield"] . "@{$domain}"; } # erase double spacing while (ereg(" ", $cached[$messageid]["fromname"])) { $cached[$messageid]["fromname"] = eregi_replace(" ", " ", $cached[$messageid]["fromname"]); } ## this has weird effects when used with only one word, so take it out for now # $cached[$messageid]["fromname"] = eregi_replace("@","",$cached[$messageid]["fromname"]); $cached[$messageid]["fromname"] = trim($cached[$messageid]["fromname"]); $cached[$messageid]["to"] = $message["tofield"]; #0013076: different content when forwarding 'to a friend' $cached[$messageid]["subject"] = $forwardContent ? stripslashes($messagedata["forwardsubject"]) : $message["subject"]; $cached[$messageid]["replyto"] = $message["replyto"]; #0013076: different content when forwarding 'to a friend' $cached[$messageid]["content"] = $forwardContent ? stripslashes($messagedata["forwardmessage"]) : $message["message"]; if (USE_MANUAL_TEXT_PART && !$forwardContent) { $cached[$messageid]["textcontent"] = $message["textmessage"]; } else { $cached[$messageid]["textcontent"] = ''; } #0013076: different content when forwarding 'to a friend' $cached[$messageid]["footer"] = $forwardContent ? stripslashes($messagedata["forwardfooter"]) : $message["footer"]; $cached[$messageid]["htmlformatted"] = $message["htmlformatted"]; $cached[$messageid]["sendformat"] = $message["sendformat"]; if ($message["template"]) { $req = Sql_Fetch_Row_Query("select template from {$GLOBALS["tables"]["template"]} where id = {$message["template"]}"); $cached[$messageid]["template"] = stripslashes($req[0]); $cached[$messageid]["templateid"] = $message["template"]; # dbg("TEMPLATE: ".$req[0]); } else { $cached[$messageid]["template"] = ''; $cached[$messageid]["templateid"] = 0; } ## @@ put this here, so it can become editable per email sent out at a later stage $cached[$messageid]["html_charset"] = getConfig("html_charset"); ## @@ need to check on validity of charset if (!$cached[$messageid]["html_charset"]) { $cached[$messageid]["html_charset"] = 'iso-8859-1'; } $cached[$messageid]["text_charset"] = getConfig("text_charset"); if (!$cached[$messageid]["text_charset"]) { $cached[$messageid]["text_charset"] = 'iso-8859-1'; } } # else # dbg("Using cached {$cached[$messageid]["fromemail"]}"); if (VERBOSE) { output($GLOBALS['I18N']->get('sendingmessage') . ' ' . $messageid . ' ' . $GLOBALS['I18N']->get('withsubject') . ' ' . $cached[$messageid]["subject"] . ' ' . $GLOBALS['I18N']->get('to') . ' ' . $email); } # erase any placeholders that were not found # $msg = ereg_replace("\[[A-Z ]+\]","",$msg); #0011857: forward to friend, retain attributes if ($hash == 'forwarded' && defined('KEEPFORWARDERATTRIBUTES') && KEEPFORWARDERATTRIBUTES) { $user_att_values = getUserAttributeValues($forwardedby['email']); } else { $user_att_values = getUserAttributeValues($email); } $userdata = Sql_Fetch_Assoc_Query(sprintf('select * from %s where email = "%s"', $GLOBALS["tables"]["user"], $email)); $url = getConfig("unsubscribeurl"); $sep = ereg('\\?', $url) ? '&' : '?'; $html["unsubscribe"] = sprintf('<a href="%s%suid=%s">%s</a>', $url, $sep, $hash, $strThisLink); $text["unsubscribe"] = sprintf('%s%suid=%s', $url, $sep, $hash); $html["unsubscribeurl"] = sprintf('%s%suid=%s', $url, $sep, $hash); $text["unsubscribeurl"] = sprintf('%s%suid=%s', $url, $sep, $hash); #0013076: Blacklisting posibility for unknown users $url = getConfig("blacklisturl"); $sep = ereg('\\?', $url) ? '&' : '?'; $html["blacklist"] = sprintf('<a href="%s%semail=%s">%s</a>', $url, $sep, $email, $strThisLink); $text["blacklist"] = sprintf('%s%semail=%s', $url, $sep, $email); $html["blacklisturl"] = sprintf('%s%semail=%s', $url, $sep, $email); $text["blacklisturl"] = sprintf('%s%semail=%s', $url, $sep, $email); #0013076: Problem found during testing: mesage part must be parsed correctly as well. if ($forwardContent) { $html["unsubscribe"] = $html["blacklist"]; $text["unsubscribe"] = $text["blacklist"]; } $url = getConfig("subscribeurl"); $sep = ereg('\\?', $url) ? '&' : '?'; $html["subscribe"] = sprintf('<a href="%s">%s</a>', $url, $strThisLink); $text["subscribe"] = sprintf('%s', $url); $html["subscribeurl"] = sprintf('%s', $url); $text["subscribeurl"] = sprintf('%s', $url); #?mid=1&id=1&uid=a9f35f130593a3d6b89cfe5cfb32a0d8&p=forward&email=michiel%40tincan.co.uk& $url = getConfig("forwardurl"); $sep = ereg('\\?', $url) ? '&' : '?'; $html["forward"] = sprintf('<a href="%s%suid=%s&mid=%d">%s</a>', $url, $sep, $hash, $messageid, $strThisLink); $text["forward"] = sprintf('%s%suid=%s&mid=%d', $url, $sep, $hash, $messageid); $html["forwardurl"] = sprintf('%s%suid=%s&mid=%d', $url, $sep, $hash, $messageid); $text["forwardurl"] = $text["forward"]; $url = getConfig("forwardurl"); # make sure there are no newlines, otherwise they get turned into <br/>s $html["forwardform"] = sprintf('<form method="get" action="%s" name="forwardform" class="forwardform"><input type=hidden name="uid" value="%s" /><input type=hidden name="mid" value="%d" /><input type=hidden name="p" value="forward" /><input type=text name="email" value="" class="forwardinput" /><input name="Send" type="submit" value="%s" class="forwardsubmit"/></form>', $url, $hash, $messageid, $GLOBALS['strForward']); $text["signature"] = "\n\n--\nPowered by PHPlist, www.phplist.com --\n\n"; $url = getConfig("preferencesurl"); $sep = ereg('\\?', $url) ? '&' : '?'; $html["preferences"] = sprintf('<a href="%s%suid=%s">%s</a>', $url, $sep, $hash, $strThisLink); $text["preferences"] = sprintf('%s%suid=%s', $url, $sep, $hash); $html["preferencesurl"] = sprintf('%s%suid=%s', $url, $sep, $hash); $text["preferencesurl"] = sprintf('%s%suid=%s', $url, $sep, $hash); /* We request you retain the signature below in your emails including the links. This not only gives respect to the large amount of time given freely by the developers but also helps build interest, traffic and use of PHPlist, which is beneficial to it's future development. You can configure how the credits are added to your pages and emails in your config file. Michiel Dethmers, Tincan Ltd 2003, 2004, 2005, 2006 */ if (!EMAILTEXTCREDITS) { $html["signature"] = $PoweredByImage; #'<div align="center" id="signature"><a href="http://www.phplist.com"><img src="powerphplist.png" width=88 height=31 title="Powered by PHPlist" alt="Powered by PHPlist" border="0"></a></div>'; # oops, accidentally became spyware, never intended that, so take it out again :-) $html["signature"] = preg_replace('/src=".*power-phplist.png"/', 'src="powerphplist.png"', $html["signature"]); } else { $html["signature"] = $PoweredByText; } $content = $cached[$messageid]["content"]; if (preg_match("/##LISTOWNER=(.*)/", $content, $regs)) { $listowner = $regs[1]; $content = ereg_replace($regs[0], "", $content); } else { $listowner = 0; } ## Fetch external content if ($GLOBALS["has_pear_http_request"] && preg_match("/\\[URL:([^\\s]+)\\]/i", $content, $regs)) { while (isset($regs[1]) && strlen($regs[1])) { $url = $regs[1]; if (!preg_match('/^http/i', $url)) { $url = 'http://' . $url; } $remote_content = fetchUrl($url, $userdata); if ($remote_content) { $content = eregi_replace(preg_quote($regs[0]), $remote_content, $content); $cached[$messageid]["htmlformatted"] = strip_tags($content) != $content; } else { logEvent("Error fetching URL: {$regs['1']} to send to {$email}"); return 0; } preg_match("/\\[URL:([^\\s]+)\\]/i", $content, $regs); } } #~Bas 0008857 // @@ Switched off for now, needs rigid testing, or config setting // $content = mailto2href($content); // $content = encodeLinks($content); ## Fill text and html versions depending on given versions. if ($cached[$messageid]["htmlformatted"]) { if (!$cached[$messageid]["textcontent"]) { $textcontent = stripHTML($content); } else { $textcontent = $cached[$messageid]["textcontent"]; } $htmlcontent = $content; } else { # $textcontent = $content; if (!$cached[$messageid]["textcontent"]) { $textcontent = $content; } else { $textcontent = $cached[$messageid]["textcontent"]; } $htmlcontent = parseText($content); } $defaultstyle = getConfig("html_email_style"); $adddefaultstyle = 0; if ($cached[$messageid]["template"]) { # template used $htmlmessage = eregi_replace("\\[CONTENT\\]", $htmlcontent, $cached[$messageid]["template"]); } else { # no template used $htmlmessage = $htmlcontent; $adddefaultstyle = 1; } $textmessage = $textcontent; ## Parse placeholders #0013076: Blacklisting posibility for unknown users foreach (array("forwardform", "subscribe", "preferences", "unsubscribe", "signature", 'blacklist') as $item) { if (eregi('\\[' . $item . '\\]', $htmlmessage, $regs)) { $htmlmessage = eregi_replace('\\[' . $item . '\\]', $html[$item], $htmlmessage); // unset($html[$item]); //ASK: Why was this done? It breaks placeholders in the footer } if (eregi('\\[' . $item . '\\]', $textmessage, $regs)) { $textmessage = eregi_replace('\\[' . $item . '\\]', $text[$item], $textmessage); // unset($text[$item]); } } #0013076: Blacklisting posibility for unknown users foreach (array("forward", "forwardurl", "subscribeurl", "preferencesurl", "unsubscribeurl", 'blacklisturl') as $item) { if (eregi('\\[' . $item . '\\]', $htmlmessage, $regs)) { $htmlmessage = eregi_replace('\\[' . $item . '\\]', $html[$item], $htmlmessage); } if (eregi('\\[' . $item . '\\]', $textmessage, $regs)) { $textmessage = eregi_replace('\\[' . $item . '\\]', $text[$item], $textmessage); } } if ($hash != 'forwarded') { $text['footer'] = $cached[$messageid]["footer"]; $html['footer'] = $cached[$messageid]["footer"]; } else { #0013076: different content when forwarding 'to a friend' if (FORWARD_ALTERNATIVE_CONTENT) { $text['footer'] = stripslashes($messagedata["forwardfooter"]); } else { $text['footer'] = getConfig('forwardfooter'); } $html['footer'] = $text['footer']; } $text["footer"] = eregi_replace("\\[SUBSCRIBE\\]", $text["subscribe"], $text['footer']); $html["footer"] = eregi_replace("\\[SUBSCRIBE\\]", $html["subscribe"], $html['footer']); $text["footer"] = eregi_replace("\\[PREFERENCES\\]", $text["preferences"], $text["footer"]); $html["footer"] = eregi_replace("\\[PREFERENCES\\]", $html["preferences"], $html["footer"]); $text["footer"] = eregi_replace("\\[FORWARD\\]", $text["forward"], $text["footer"]); $html["footer"] = eregi_replace("\\[FORWARD\\]", $html["forward"], $html["footer"]); $html["footer"] = eregi_replace("\\[FORWARDFORM\\]", $html["forwardform"], $html["footer"]); if (sizeof($forwardedby) && isset($forwardedby['email'])) { $htmlmessage = eregi_replace("\\[FORWARDEDBY]", $forwardedby["email"], $htmlmessage); $textmessage = eregi_replace("\\[FORWARDEDBY]", $forwardedby["email"], $textmessage); $html["footer"] = eregi_replace("\\[FORWARDEDBY]", $forwardedby["email"], $html["footer"]); $text["footer"] = eregi_replace("\\[FORWARDEDBY]", $forwardedby["email"], $text["footer"]); $text["footer"] = eregi_replace("\\[BLACKLIST\\]", $text["blacklist"], $text['footer']); $html["footer"] = eregi_replace("\\[BLACKLIST\\]", $html["blacklist"], $html['footer']); $text["footer"] = eregi_replace("\\[UNSUBSCRIBE\\]", $text["blacklist"], $text['footer']); $html["footer"] = eregi_replace("\\[UNSUBSCRIBE\\]", $html["blacklist"], $html['footer']); } else { $text["footer"] = eregi_replace("\\[UNSUBSCRIBE\\]", $text["unsubscribe"], $text['footer']); $html["footer"] = eregi_replace("\\[UNSUBSCRIBE\\]", $html["unsubscribe"], $html['footer']); } $html["footer"] = '<div class="emailfooter">' . nl2br($html["footer"]) . '</div>'; if (eregi("\\[FOOTER\\]", $htmlmessage)) { $htmlmessage = eregi_replace("\\[FOOTER\\]", $html["footer"], $htmlmessage); } elseif ($html["footer"]) { $htmlmessage = addHTMLFooter($htmlmessage, '<br /><br />' . $html["footer"]); } if (eregi("\\[SIGNATURE\\]", $htmlmessage)) { $htmlmessage = eregi_replace("\\[SIGNATURE\\]", $html["signature"], $htmlmessage); } elseif ($html["signature"]) { $htmlmessage .= '<br />' . $html["signature"]; } if (eregi("\\[FOOTER\\]", $textmessage)) { $textmessage = eregi_replace("\\[FOOTER\\]", $text["footer"], $textmessage); } else { $textmessage .= "\n\n" . $text["footer"]; } if (eregi("\\[SIGNATURE\\]", $textmessage)) { $textmessage = eregi_replace("\\[SIGNATURE\\]", $text["signature"], $textmessage); } else { $textmessage .= "\n" . $text["signature"]; } # $req = Sql_Query(sprintf('select filename,data from %s where template = %d', # $GLOBALS["tables"]["templateimage"],$cached[$messageid]["templateid"])); $htmlmessage = eregi_replace("\\[USERID\\]", $hash, $htmlmessage); $textmessage = eregi_replace("\\[USERID\\]", $hash, $textmessage); $htmlmessage = preg_replace("/\\[USERTRACK\\]/i", '<img src="' . $GLOBALS['scheme'] . '://' . $website . $GLOBALS["pageroot"] . '/ut.php?u=' . $hash . '&m=' . $messageid . '" width="1" height="1" border="0">', $htmlmessage, 1); $htmlmessage = eregi_replace("\\[USERTRACK\\]", '', $htmlmessage); if ($listowner) { $att_req = Sql_Query("select name,value from {$GLOBALS["tables"]["adminattribute"]},{$GLOBALS["tables"]["admin_attribute"]} where {$GLOBALS["tables"]["adminattribute"]}.id = {$GLOBALS["tables"]["admin_attribute"]}.adminattributeid and {$GLOBALS["tables"]["admin_attribute"]}.adminid = {$listowner}"); while ($att = Sql_Fetch_Array($att_req)) { $htmlmessage = preg_replace("#\\[LISTOWNER." . strtoupper(preg_quote($att["name"])) . "\\]#", $att["value"], $htmlmessage); } } if (is_array($GLOBALS["default_config"])) { foreach ($GLOBALS["default_config"] as $key => $val) { if (is_array($val)) { $htmlmessage = eregi_replace("\\[{$key}\\]", getConfig($key), $htmlmessage); $textmessage = eregi_replace("\\[{$key}\\]", getConfig($key), $textmessage); } } } ## RSS if (ENABLE_RSS && sizeof($rssitems)) { $rssentries = array(); $request = join(",", $rssitems); $texttemplate = getConfig("rsstexttemplate"); $htmltemplate = getConfig("rsshtmltemplate"); $textseparatortemplate = getConfig("rsstextseparatortemplate"); $htmlseparatortemplate = getConfig("rsshtmlseparatortemplate"); $req = Sql_Query("select * from {$GLOBALS["tables"]["rssitem"]} where id in ({$request}) order by list,added"); $curlist = ""; while ($row = Sql_Fetch_array($req)) { if ($curlist != $row["list"]) { $row["listname"] = ListName($row["list"]); $curlist = $row["list"]; $rssentries["text"] .= parseRSSTemplate($textseparatortemplate, $row); $rssentries["html"] .= parseRSSTemplate($htmlseparatortemplate, $row); } $data_req = Sql_Query("select * from {$GLOBALS["tables"]["rssitem_data"]} where itemid = {$row["id"]}"); while ($data = Sql_Fetch_Array($data_req)) { $row[$data["tag"]] = $data["data"]; } $rssentries["text"] .= stripHTML(parseRSSTemplate($texttemplate, $row)); $rssentries["html"] .= parseRSSTemplate($htmltemplate, $row); } $htmlmessage = eregi_replace("\\[RSS\\]", $rssentries["html"], $htmlmessage); $textmessage = eregi_replace("\\[RSS\\]", $rssentries["text"], $textmessage); } if (is_array($userdata)) { foreach ($userdata as $name => $value) { if (eregi("\\[" . $name . "\\]", $htmlmessage, $regs)) { $htmlmessage = eregi_replace("\\[" . $name . "\\]", $value, $htmlmessage); } if (eregi("\\[" . $name . "\\]", $textmessage, $regs)) { $textmessage = eregi_replace("\\[" . $name . "\\]", $value, $textmessage); } } } $destinationemail = ''; if (is_array($user_att_values)) { foreach ($user_att_values as $att_name => $att_value) { if (eregi("\\[" . $att_name . "\\]", $htmlmessage, $regs)) { # the value may be a multiline textarea field $htmlatt_value = str_replace("\n", "<br/>\n", $att_value); $htmlmessage = eregi_replace("\\[" . $att_name . "\\]", $htmlatt_value, $htmlmessage); } if (eregi("\\[" . $att_name . "\\]", $textmessage, $regs)) { $textmessage = eregi_replace("\\[" . $att_name . "\\]", $att_value, $textmessage); } # @@@ undocumented, use alternate field for real email to send to if (isset($GLOBALS["alternate_email"]) && strtolower($att_name) == strtolower($GLOBALS["alternate_email"])) { $destinationemail = $att_value; } } } if (!$destinationemail) { $destinationemail = $email; } if (!ereg('@', $destinationemail) && isset($GLOBALS["expand_unqualifiedemail"])) { $destinationemail .= $GLOBALS["expand_unqualifiedemail"]; } if (eregi("\\[LISTS\\]", $htmlmessage)) { $lists = ""; $listsarr = array(); $req = Sql_Query(sprintf('select list.name from %s as list,%s as listuser where list.id = listuser.listid and listuser.userid = %d', $GLOBALS["tables"]["list"], $GLOBALS["tables"]["listuser"], $user_system_values["id"])); while ($row = Sql_Fetch_Row($req)) { array_push($listsarr, $row[0]); } $lists_html = join('<br/>', $listsarr); $lists_text = join("\n", $listsarr); $htmlmessage = ereg_replace("\\[LISTS\\]", $lists_html, $htmlmessage); $textmessage = ereg_replace("\\[LISTS\\]", $lists_text, $textmessage); } ## click tracking # for now we won't click track forwards, as they are not necessarily users, so everything would fail if (CLICKTRACK && $hash != 'forwarded') { $urlbase = ''; # let's leave this for now /* if (preg_match('/<base href="(.*)"([^>]*)>/Umis',$htmlmessage,$regs)) { $urlbase = $regs[1]; } else { $urlbase = ''; } # print "URLBASE: $urlbase<br/>"; */ # convert html message # preg_match_all('/<a href="?([^> "]*)"?([^>]*)>(.*)<\/a>/Umis',$htmlmessage,$links); preg_match_all('/<a(.*)href=["\'](.*)["\']([^>]*)>(.*)<\\/a>/Umis', $htmlmessage, $links); # to process the Yahoo webpage with base href and link like <a href=link> we'd need this one # preg_match_all('/<a href=([^> ]*)([^>]*)>(.*)<\/a>/Umis',$htmlmessage,$links); $clicktrack_root = sprintf('%s://%s/lt.php', $GLOBALS["scheme"], $website . $GLOBALS["pageroot"]); for ($i = 0; $i < count($links[2]); $i++) { $link = cleanUrl($links[2][$i]); $link = str_replace('"', '', $link); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } $linkid = 0; # print "LINK: $link<br/>"; if ((preg_match('/^http|ftp/', $link) || preg_match('/^http|ftp/', $urlbase)) && $link != 'http://www.phplist.com' && !strpos($link, $clicktrack_root)) { # take off personal uids $url = cleanUrl($link, array('PHPSESSID', 'uid')); # $url = preg_replace('/&uid=[^\s&]+/','',$link); # if (!strpos('http:',$link)) { # $link = $urlbase . $link; # } $req = Sql_Query(sprintf('insert ignore into %s (messageid,userid,url,forward) values(%d,%d,"%s","%s")', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $url, addslashes($link))); $req = Sql_Fetch_Row_Query(sprintf('select linkid from %s where messageid = %s and userid = %d and forward = "%s" ', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $link)); $linkid = $req[0]; $masked = "H|{$linkid}|{$messageid}|" . $userdata['id'] ^ XORmask; $masked = urlencode(base64_encode($masked)); $newlink = sprintf('<a%shref="%s://%s/lt.php?id=%s" %s>%s</a>', $links[1][$i], $GLOBALS["scheme"], $website . $GLOBALS["pageroot"], $masked, $links[3][$i], $links[4][$i]); $htmlmessage = str_replace($links[0][$i], $newlink, $htmlmessage); } } # convert Text message # first find occurances of our top domain, to avoid replacing them later # hmm, this is no point, it's not just *our* topdomain, but any if (0) { preg_match_all('#(https?://' . $GLOBALS['website'] . '/?)\\s+#mis', $textmessage, $links); # preg_match_all('#(https?://[a-z0-9\./\#\?&:@=%\-]+)#ims',$textmessage,$links); # preg_match_all('!(https?:\/\/www\.[a-zA-Z0-9\.\/#~\?+=&%@-_]+)!mis',$textmessage,$links); for ($i = 0; $i < count($links[1]); $i++) { # not entirely sure why strtolower was used, but it seems to break things http://mantis.tincan.co.uk/view.php?id=4406 # $link = strtolower(cleanUrl($links[1][$i])); $link = cleanUrl($links[1][$i]); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } $linkid = 0; if (preg_match('/^http|ftp/', $link) && $link != 'http://www.phplist.com' && !strpos($link, $clicktrack_root)) { $url = cleanUrl($link, array('PHPSESSID', 'uid')); $req = Sql_Query(sprintf('insert ignore into %s (messageid,userid,url,forward) values(%d,%d,"%s","%s")', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $url, $link)); $req = Sql_Fetch_Row_Query(sprintf('select linkid from %s where messageid = %s and userid = %d and forward = "%s" ', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $link)); $linkid = $req[0]; $masked = "T|{$linkid}|{$messageid}|" . $userdata['id'] ^ XORmask; $masked = urlencode(base64_encode($masked)); $newlink = sprintf('%s://%s/lt.php?id=%s', $GLOBALS["scheme"], $website . $GLOBALS["pageroot"], $masked); $textmessage = str_replace($links[0][$i], '<' . $newlink . '>', $textmessage); } } } #now find the rest # @@@ needs to expand to find complete urls like: #http://user:password@www.web-site.com:1234/document.php?parameter=something&otherpar=somethingelse#anchor # or secure #https://user:password@www.website.com:2345/document.php?parameter=something%20&otherpar=somethingelse#anchor preg_match_all('#(https?://[^\\s\\>\\}\\,]+)#mis', $textmessage, $links); # preg_match_all('#(https?://[a-z0-9\./\#\?&:@=%\-]+)#ims',$textmessage,$links); # preg_match_all('!(https?:\/\/www\.[a-zA-Z0-9\.\/#~\?+=&%@-_]+)!mis',$textmessage,$links); ## sort the results in reverse order, so that they are replaced correctly rsort($links[1]); $newlinks = array(); for ($i = 0; $i < count($links[1]); $i++) { $link = cleanUrl($links[1][$i]); if (preg_match('/\\.$/', $link)) { $link = substr($link, 0, -1); } $linkid = 0; if (preg_match('/^http|ftp/', $link) && $link != 'http://www.phplist.com') { # && !strpos($link,$clicktrack_root)) { $url = cleanUrl($link, array('PHPSESSID', 'uid')); $req = Sql_Query(sprintf('insert ignore into %s (messageid,userid,url,forward) values(%d,%d,"%s","%s")', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $url, $link)); $req = Sql_Fetch_Row_Query(sprintf('select linkid from %s where messageid = %s and userid = %d and forward = "%s" ', $GLOBALS['tables']['linktrack'], $messageid, $userdata['id'], $link)); $linkid = $req[0]; $masked = "T|{$linkid}|{$messageid}|" . $userdata['id'] ^ XORmask; $masked = urlencode(base64_encode($masked)); $newlinks[$linkid] = sprintf('%s://%s/lt.php?id=%s', $GLOBALS["scheme"], $website . $GLOBALS["pageroot"], $masked); # print $links[0][$i] .' -> '.$newlink.'<br/>'; $textmessage = str_replace($links[1][$i], '[%%%' . $linkid . '%%%]', $textmessage); } } foreach ($newlinks as $linkid => $newlink) { $textmessage = str_replace('[%%%' . $linkid . '%%%]', $newlink, $textmessage); } } # if (eregi("\\[LISTS\\]", $htmlmessage)) { $lists = ""; $listsarr = array(); $req = Sql_Query(sprintf('select list.name from %s as list,%s as listuser where list.id = listuser.listid and listuser.userid = %d', $tables["list"], $tables["listuser"], $user_system_values["id"])); while ($row = Sql_Fetch_Row($req)) { array_push($listsarr, $row[0]); } $lists_html = join('<br/>', $listsarr); $lists_text = join("\n", $listsarr); $htmlmessage = ereg_replace("\\[LISTS\\]", $lists_html, $htmlmessage); $textmessage = ereg_replace("\\[LISTS\\]", $lists_text, $textmessage); } #0011996: forward to friend - personal message if (FORWARD_PERSONAL_NOTE_SIZE && ($hash = 'forwarded' && !empty($forwardedby['personalNote']))) { $htmlmessage = nl2br($forwardedby['personalNote']) . '<br/>' . $htmlmessage; $textmessage = $forwardedby['personalNote'] . "\n" . $textmessage; } ## remove any existing placeholders $htmlmessage = eregi_replace("\\[[A-Z\\. ]+\\]", "", $htmlmessage); $textmessage = eregi_replace("\\[[A-Z\\. ]+\\]", "", $textmessage); ## check that the HTML message as proper <head> </head> and <body> </body> tags # some readers fail when it doesn't if (!preg_match("#<body.*</body>#ims", $htmlmessage)) { $htmlmessage = '<body>' . $htmlmessage . '</body>'; } if (!preg_match("#<head>.*</head>#ims", $htmlmessage)) { if (!$adddefaultstyle) { $defaultstyle = ""; } $htmlmessage = '<head> <meta content="text/html;charset=' . $cached[$messageid]["html_charset"] . '" http-equiv="Content-Type"> <title></title>' . $defaultstyle . '</head>' . $htmlmessage; } if (!preg_match("#<html>.*</html>#ims", $htmlmessage)) { $htmlmessage = '<html>' . $htmlmessage . '</html>'; } # particularly Outlook seems to have trouble if it is not \r\n # reports have come that instead this creates lots of trouble # this is now done in the global sendMail function, so it is not # necessary here # if (USE_CARRIAGE_RETURNS) { # $htmlmessage = preg_replace("/\r?\n/", "\r\n", $htmlmessage); # $textmessage = preg_replace("/\r?\n/", "\r\n", $textmessage); # } ## build the email if (!PHPMAILER) { $mail = new html_mime_mail(array('X-Mailer: PHPlist v' . VERSION, "X-MessageId: {$messageid}", "X-ListMember: {$email}", "Precedence: bulk", "List-Help: <" . $text["preferences"] . ">", "List-Unsubscribe: <" . $text["unsubscribe"] . ">", "List-Subscribe: <" . getConfig("subscribeurl") . ">", "List-Owner: <mailto:" . getConfig("admin_address") . ">")); } else { $mail = new PHPlistMailer($messageid, $destinationemail); if ($forwardedby) { $mail->add_timestamp(); } #$mail->IsSMTP(); } list($dummy, $domaincheck) = split('@', $destinationemail); $text_domains = explode("\n", trim(getConfig("alwayssendtextto"))); if (in_array($domaincheck, $text_domains)) { $htmlpref = 0; if (VERBOSE) { output($GLOBALS['I18N']->get('sendingtextonlyto') . " {$domaincheck}"); } } list($dummy, $domaincheck) = split('@', $email); $text_domains = explode("\n", trim(getConfig("alwayssendtextto"))); if (in_array($domaincheck, $text_domains)) { $htmlpref = 0; if (VERBOSE) { output("Sending text only to {$domaincheck}"); } } # so what do we actually send? switch ($cached[$messageid]["sendformat"]) { case "HTML": // # send html to users who want it and text to everyone else // if ($htmlpref) { // Sql_Query("update {$GLOBALS["tables"]["message"]} set ashtml = ashtml + 1 where id = $messageid"); // if (ENABLE_RSS && sizeof($rssitems)) // updateRSSStats($rssitems,"ashtml"); // # dbg("Adding HTML ".$cached[$messageid]["templateid"]); // $mail->add_html($htmlmessage,"",$cached[$messageid]["templateid"]); // addAttachments($messageid,$mail,"HTML"); // } else { // Sql_Query("update {$GLOBALS["tables"]["message"]} set astext = astext + 1 where id = $messageid"); // if (ENABLE_RSS && sizeof($rssitems)) // updateRSSStats($rssitems,"astext"); // $mail->add_text($textmessage); // addAttachments($messageid,$mail,"text"); // } // break; // # send html to users who want it and text to everyone else // if ($htmlpref) { // Sql_Query("update {$GLOBALS["tables"]["message"]} set ashtml = ashtml + 1 where id = $messageid"); // if (ENABLE_RSS && sizeof($rssitems)) // updateRSSStats($rssitems,"ashtml"); // # dbg("Adding HTML ".$cached[$messageid]["templateid"]); // $mail->add_html($htmlmessage,"",$cached[$messageid]["templateid"]); // addAttachments($messageid,$mail,"HTML"); // } else { // Sql_Query("update {$GLOBALS["tables"]["message"]} set astext = astext + 1 where id = $messageid"); // if (ENABLE_RSS && sizeof($rssitems)) // updateRSSStats($rssitems,"astext"); // $mail->add_text($textmessage); // addAttachments($messageid,$mail,"text"); // } // break; case "both": case "text and HTML": # send one big file to users who want html and text to everyone else if ($htmlpref) { Sql_Query("update {$GLOBALS["tables"]["message"]} set ashtml = ashtml + 1 where id = {$messageid}"); if (ENABLE_RSS && sizeof($rssitems)) { updateRSSStats($rssitems, "ashtml"); } # dbg("Adding HTML ".$cached[$messageid]["templateid"]); $mail->add_html($htmlmessage, $textmessage, $cached[$messageid]["templateid"]); addAttachments($messageid, $mail, "HTML"); } else { Sql_Query("update {$GLOBALS["tables"]["message"]} set astext = astext + 1 where id = {$messageid}"); if (ENABLE_RSS && sizeof($rssitems)) { updateRSSStats($rssitems, "astext"); } $mail->add_text($textmessage); addAttachments($messageid, $mail, "text"); } break; case "PDF": # send a PDF file to users who want html and text to everyone else if (ENABLE_RSS && sizeof($rssitems)) { updateRSSStats($rssitems, "astext"); } if ($htmlpref) { Sql_Query("update {$GLOBALS["tables"]["message"]} set aspdf = aspdf + 1 where id = {$messageid}"); $pdffile = createPdf($textmessage); if (is_file($pdffile) && filesize($pdffile)) { $fp = fopen($pdffile, "r"); if ($fp) { $contents = fread($fp, filesize($pdffile)); fclose($fp); unlink($pdffile); $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <embed src="message.pdf" width="450" height="450" href="message.pdf"></embed> </body> </html>'; # $mail->add_html($html,$textmessage); # $mail->add_text($textmessage); $mail->add_attachment($contents, "message.pdf", "application/pdf"); } } addAttachments($messageid, $mail, "HTML"); } else { Sql_Query("update {$GLOBALS["tables"]["message"]} set astext = astext + 1 where id = {$messageid}"); $mail->add_text($textmessage); addAttachments($messageid, $mail, "text"); } break; case "text and PDF": if (ENABLE_RSS && sizeof($rssitems)) { updateRSSStats($rssitems, "astext"); } # send a PDF file to users who want html and text to everyone else if ($htmlpref) { Sql_Query("update {$GLOBALS["tables"]["message"]} set astextandpdf = astextandpdf + 1 where id = {$messageid}"); $pdffile = createPdf($textmessage); if (is_file($pdffile) && filesize($pdffile)) { $fp = fopen($pdffile, "r"); if ($fp) { $contents = fread($fp, filesize($pdffile)); fclose($fp); unlink($pdffile); $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title></title> </head> <body> <embed src="message.pdf" width="450" height="450" href="message.pdf"></embed> </body> </html>'; # $mail->add_html($html,$textmessage); $mail->add_text($textmessage); $mail->add_attachment($contents, "message.pdf", "application/pdf"); } } addAttachments($messageid, $mail, "HTML"); } else { Sql_Query("update {$GLOBALS["tables"]["message"]} set astext = astext + 1 where id = {$messageid}"); $mail->add_text($textmessage); addAttachments($messageid, $mail, "text"); } break; case "text": default: # send as text if (ENABLE_RSS && sizeof($rssitems)) { updateRSSStats($rssitems, "astext"); } Sql_Query("update {$GLOBALS["tables"]["message"]} set astext = astext + 1 where id = {$messageid}"); $mail->add_text($textmessage); addAttachments($messageid, $mail, "text"); break; } $mail->build_message(array("html_charset" => $cached[$messageid]["html_charset"], "html_encoding" => HTMLEMAIL_ENCODING, "text_charset" => $cached[$messageid]["text_charset"], "text_encoding" => TEXTEMAIL_ENCODING)); if (!TEST) { if ($hash != 'forwarded' || !sizeof($forwardedby)) { $fromname = $cached[$messageid]["fromname"]; $fromemail = $cached[$messageid]["fromemail"]; $subject = $cached[$messageid]["subject"]; } else { $fromname = ''; $fromemail = $forwardedby['email']; $subject = $GLOBALS['strFwd'] . ': ' . $cached[$messageid]["subject"]; } if (!$mail->send("", $destinationemail, $fromname, $fromemail, $subject)) { logEvent("Error sending message {$messageid} to {$email} ({$destinationemail})"); return 0; } else { return 1; } } return 0; }
$userid = $req[1]; $userpassword = $req[2]; $emailcheck = $req[3]; */ } } if (isset($_REQUEST['id']) && $_REQUEST["id"]) { $id = sprintf('%d', $_REQUEST["id"]); } # make sure the subscribe page still exists $req = Sql_fetch_row_query(sprintf('select id from %s where id = %d', $tables["subscribepage"], $id)); $id = $req[0]; $msg = ""; if (!empty($_POST["sendpersonallocation"])) { if (isset($_POST['email']) && $_POST["email"]) { $uid = Sql_Fetch_Assoc_Query(sprintf('select uniqid,email,id,blacklisted from %s where email = "%s"', $tables["user"], sql_escape($_POST["email"]))); if ($uid['blacklisted']) { $msg .= $GLOBALS["strYouAreBlacklisted"]; } elseif ($uid['uniqid']) { sendMail($uid['email'], getConfig("personallocation_subject"), getUserConfig("personallocation_message", $uid['id']), system_messageheaders(), $GLOBALS["envelope"]); $msg = $GLOBALS["strPersonalLocationSent"]; addSubscriberStatistics('personal location sent', 1); } else { $msg = $GLOBALS["strUserNotFound"]; } } } if (isset($_GET['p']) && $_GET["p"] == "subscribe") { $_SESSION["userloggedin"] = 0; $_SESSION["userdata"] = array(); }
<?php require_once dirname(__FILE__) . '/accesscheck.php'; @ob_end_clean(); $id = sprintf('%d', $_GET['id']); if (!$id) { return ''; } $message = Sql_Fetch_Assoc_Query(sprintf('select * from %s where id = %d', $GLOBALS['tables']['message'], $id)); $messagedata = loadMessageData($id); if ($message['status'] != 'inprocess') { $html = $message['status']; $html .= '<br/>' . PageLink2('messages', $GLOBALS['I18N']->get('requeue'), 'resend=' . $message['id']); } else { $active = time() - $messagedata['last msg sent']; if ($active > 60) { $html = $GLOBALS['I18N']->get('Stalled'); } else { $totalsent = $messagedata['astext'] + $messagedata['ashtml'] + $messagedata['astextandhtml'] + $messagedata['aspdf'] + $messagedata['astextandpdf']; $html = $GLOBALS['I18N']->get($message['status']) . '<br/>' . $messagedata['to process'] . ' ' . $GLOBALS['I18N']->get('still to process') . '<br/>' . $GLOBALS['I18N']->get('ETA') . ': ' . $messagedata['ETA'] . '<br/>' . $GLOBALS['I18N']->get('sent') . ': ' . $totalsent . '<br/>' . $GLOBALS['I18N']->get('Processing') . ' ' . sprintf('%d', $messagedata['msg/hr']) . ' ' . $GLOBALS['I18N']->get('msgs/hr'); } } print $html; exit;
$element = shortenTextDisplay($row['url']); $ls->addElement($element, PageUrl2('uclicks&id=' . $row['forwardid'])); $ls->setClass($element, 'row1'); $ls->addColumn($element, $GLOBALS['I18N']->get('message'), PageLink2('mclicks&id=' . $row['messageid'], ' ' . $row['messageid'])); } # $element = sprintf('<a href="%s" target="_blank" class="url" title="%s">%s</a>',$row['url'],$row['url'],substr(str_replace('http://','',$row['url']),0,50)); # $total = Sql_Verbose_Query(sprintf('select count(*) as total from %s where messageid = %d and url = "%s"', # $GLOBALS['tables']['linktrack'],$id,$row['url'])); # $totalsent = Sql_Fetch_Array_Query(sprintf('select count(*) as total from %s where url = "%s"', # $GLOBALS['tables']['linktrack'],$urldata['url'])); $ls_userid = ''; if (!$userid) { $ls_userid = '<span class="viewusers"><a class="button" href="' . PageUrl2('userclicks&userid=' . $row['userid']) . '" title="' . $GLOBALS['I18N']->get('view user') . '"></a></span>'; } if (!empty($row['userid'])) { $userStatus = Sql_Fetch_Assoc_Query(sprintf('select blacklisted,confirmed from %s where id = %d', $GLOBALS['tables']['user'], $row['userid'])); $ls->addColumn($element, s('Status'), $userStatus['confirmed'] && empty($userStatus['blacklisted']) ? $GLOBALS['img_tick'] : $GLOBALS['img_cross']); } $ls->addColumn($element, $GLOBALS['I18N']->get('firstclick'), formatDateTime($row['firstclick'], 1)); $ls->addColumn($element, $GLOBALS['I18N']->get('latestclick'), $row['latestclick']); $ls->addColumn($element, $GLOBALS['I18N']->get('clicks'), $row['clicked'] . $ls_userid); if (!empty($row['htmlclicked']) && !empty($row['textclicked'])) { $ls->addRow($element, '<div class="content listingsmall fright gray">' . $GLOBALS['I18N']->get('HTML') . ': ' . $row['htmlclicked'] . '</div>' . '<div class="content listingsmall fright gray">' . $GLOBALS['I18N']->get('text') . ': ' . $row['textclicked'] . '</div>', ''); } # $ls->addColumn($element,$GLOBALS['I18N']->get('sent'),$total['total']); # $perc = sprintf('%0.2f',($row['numclicks'] / $totalsent['total'] * 100)); # $ls->addColumn($element,$GLOBALS['I18N']->get('clickrate'),$perc.'%'); $summary['totalclicks'] += $row['clicked']; } } ## adding a total doesn't make sense if we're not listing everything, it'll only do the total of the page
<?php $id = sprintf('%d', $_GET['id']); if (!$id) { return ''; } $message = Sql_Fetch_Assoc_Query(sprintf('select *,unix_timestamp(embargo) - unix_timestamp(now()) as secstowait from %s where id = %d', $GLOBALS['tables']['message'], $id)); $messagedata = loadMessageData($id); $pqchoice = getConfig('pqchoice'); $totalsent = $messagedata['astext'] + $messagedata['ashtml'] + $messagedata['astextandhtml'] + $messagedata['aspdf'] + $messagedata['astextandpdf'] + $messagedata['sentastest']; $num_users = 0; if (isset($messagedata['to process'])) { $num_users = $messagedata['to process']; } $sent = $totaltime = $sampletime = $samplesent = 0; if (!isset($messagedata['sampletime'])) { ## take a "sample" of the send speed, to calculate msg/hr $sampletime = time(); $samplesent = $totalsent; setMessageData($id, 'sampletime', $sampletime); setMessageData($id, 'samplesent', $samplesent); } else { $totaltime = time() - $messagedata['sampletime']; $sent = $totalsent - $messagedata['samplesent']; if ($totaltime > MESSAGE_SENDSTATUS_SAMPLETIME) { ## refresh speed sampling setMessageData($id, 'sampletime', time()); setMessageData($id, 'samplesent', $totalsent); } } if ($sent > 0 && $totaltime > 0) {
function campaignTitle($id) { $campaignTitle = Sql_Fetch_Assoc_Query(sprintf('select data as title from %s where name = "subject" and id = %d', $GLOBALS['tables']['messagedata'], $id)); if (empty($campaignTitle['title'])) { $campaignTitle = Sql_Fetch_Assoc_Query(sprintf('select subject as title from %s where id = %d', $GLOBALS['tables']['message'], $id)); } if (empty($campaignTitle['title'])) { $campaignTitle['title'] = $id; } return stripslashes($campaignTitle['title']); }