PageRenderTime 54ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/public_html/lists/admin/class.phplistmailer.php

https://github.com/samtuke/phplist
PHP | 628 lines | 435 code | 62 blank | 131 comment | 105 complexity | 9c92f60b802989c2684a5a9644799a49 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. require_once dirname(__FILE__).'/accesscheck.php';
  3. if (defined('PHPMAILER_PATH')) {
  4. #require_once '/usr/share/php/libphp-phpmailer/class.phpmailer.php';
  5. require_once PHPMAILER_PATH;
  6. }
  7. if (!class_exists('PHPmailer')) {
  8. //https://github.com/Synchro/PHPMailer/tags
  9. require_once dirname(__FILE__).'/PHPMailer-5.2.5/class.phpmailer.php';
  10. }
  11. class PHPlistMailer extends PHPMailer {
  12. public $WordWrap = 75;
  13. public $encoding = 'base64';
  14. public $messageid = 0;
  15. public $destionationemail = '';
  16. public $estimatedsize = 0;
  17. public $mailsize = 0;
  18. private $inBlast = false;
  19. public $image_types = array(
  20. 'gif' => 'image/gif',
  21. 'jpg' => 'image/jpeg',
  22. 'jpeg' => 'image/jpeg',
  23. 'jpe' => 'image/jpeg',
  24. 'bmp' => 'image/bmp',
  25. 'png' => 'image/png',
  26. 'tif' => 'image/tiff',
  27. 'tiff' => 'image/tiff',
  28. 'swf' => 'application/x-shockwave-flash'
  29. );
  30. public $LE = "\n";
  31. public $Hello = '';
  32. public $timeStamp = '';
  33. public $TextEncoding = '7bit';
  34. function PHPlistMailer($messageid,$email,$inBlast = true,$exceptions = false) {
  35. parent::__construct($exceptions);
  36. parent::SetLanguage('en', dirname(__FILE__) . '/phpmailer/language/');
  37. $this->addCustomHeader("X-phpList-version: ".VERSION);
  38. $this->addCustomHeader("X-MessageID: $messageid");
  39. $this->addCustomHeader("X-ListMember: $email");
  40. ## amazon SES doesn't like this
  41. /*
  42. * http://mantis.phplist.com/view.php?id=15562
  43. * Interesting, https://mantis.phplist.com/view.php?id=16688
  44. * says Gmail wants it. Everyone's confused.
  45. *
  46. * Also, are we "Precedence: bulk, or Precedence: list"
  47. *
  48. * I guess this should become configurable, to leave the choice up to the installation,
  49. * but what would be our default?
  50. *
  51. if (!USE_AMAZONSES) {
  52. # $this->addCustomHeader("Precedence: bulk");
  53. }
  54. *
  55. * ok, decided:
  56. */
  57. if (!USE_AMAZONSES && USE_PRECEDENCE_HEADER) {
  58. $this->addCustomHeader("Precedence: bulk");
  59. }
  60. $newwrap = getConfig("wordwrap");
  61. if ($newwrap) {
  62. $this->WordWrap = $newwrap;
  63. }
  64. if (defined('SMTP_TIMEOUT')) {
  65. $this->Timeout = sprintf('%d',SMTP_TIMEOUT);
  66. }
  67. $this->destinationemail = $email;
  68. $this->SingleTo = false;
  69. $this->CharSet = 'UTF-8';# getConfig("html_charset");
  70. $this->inBlast = $inBlast;
  71. ### hmm, would be good to sort this out differently, but it'll work for now
  72. ## don't send test message using the blast server
  73. if (isset($_GET['page']) && $_GET['page'] == 'send') {
  74. $this->inBlast = false;
  75. }
  76. if ($this->inBlast && defined('PHPMAILERBLASTHOST') && defined('PHPMAILERBLASTPORT') && PHPMAILERBLASTHOST != '') {
  77. $this->Helo = getConfig("website");
  78. $this->Host = PHPMAILERBLASTHOST;
  79. $this->Port = PHPMAILERBLASTPORT;
  80. // check if we've a SERVER_NAME, if not we're on CLI and need to set Hostname
  81. // as we want the Message-ID to not contain localhost.localdomain
  82. if (!empty($_SERVER['SERVER_NAME'])) {
  83. $this->Hostname = getConfig("domain");
  84. }
  85. if ( isset($GLOBALS['phpmailer_smtpuser']) && $GLOBALS['phpmailer_smtpuser'] != ''
  86. && isset($GLOBALS['phpmailer_smtppassword']) && $GLOBALS['phpmailer_smtppassword']) {
  87. $this->Username = $GLOBALS['phpmailer_smtpuser'];
  88. $this->Password = $GLOBALS['phpmailer_smtppassword'];
  89. $this->SMTPAuth = true;
  90. }
  91. $this->Mailer = "smtp";
  92. } elseif (!$this->inBlast && defined('PHPMAILERTESTHOST') && PHPMAILERTESTHOST != '') {
  93. if (defined('PHPMAILERPORT')) {
  94. $this->Port = PHPMAILERPORT;
  95. }
  96. //logEvent('Sending email via '.PHPMAILERHOST);
  97. $this->Helo = getConfig("website");
  98. $this->Host = PHPMAILERTESTHOST;
  99. // check if we've a SERVER_NAME, if not we're on CLI and need to set Hostname
  100. // as we want the Message-ID to not contain localhost.localdomain
  101. if (!empty($_SERVER['SERVER_NAME'])) {
  102. $this->Hostname = getConfig("domain");
  103. }
  104. if ( isset($GLOBALS['phpmailer_smtpuser']) && $GLOBALS['phpmailer_smtpuser'] != ''
  105. && isset($GLOBALS['phpmailer_smtppassword']) && $GLOBALS['phpmailer_smtppassword']) {
  106. $this->Username = $GLOBALS['phpmailer_smtpuser'];
  107. $this->Password = $GLOBALS['phpmailer_smtppassword'];
  108. $this->SMTPAuth = true;
  109. }
  110. $this->Mailer = "smtp";
  111. } elseif (defined('PHPMAILERHOST') && PHPMAILERHOST != '') {
  112. if (defined('PHPMAILERPORT')) {
  113. $this->Port = PHPMAILERPORT;
  114. }
  115. //logEvent('Sending email via '.PHPMAILERHOST);
  116. $this->Helo = getConfig("website");
  117. $this->Host = PHPMAILERHOST;
  118. // check if we've a SERVER_NAME, if not we're on CLI and need to set Hostname
  119. // as we want the Message-ID to not contain localhost.localdomain
  120. if (!empty($_SERVER['SERVER_NAME'])) {
  121. $this->Hostname = getConfig("domain");
  122. }
  123. if ( isset($GLOBALS['phpmailer_smtpuser']) && $GLOBALS['phpmailer_smtpuser'] != ''
  124. && isset($GLOBALS['phpmailer_smtppassword']) && $GLOBALS['phpmailer_smtppassword']) {
  125. $this->Username = $GLOBALS['phpmailer_smtpuser'];
  126. $this->Password = $GLOBALS['phpmailer_smtppassword'];
  127. $this->SMTPAuth = true;
  128. }
  129. $this->Mailer = "smtp";
  130. } else {
  131. $this->isMail();
  132. }
  133. if (defined('PHPMAILER_SECURE') && PHPMAILER_SECURE) {
  134. $this->SMTPSecure = PHPMAILER_SECURE;
  135. }
  136. if ($GLOBALS["message_envelope"]) {
  137. $this->Sender = $GLOBALS["message_envelope"];
  138. $this->addCustomHeader("Bounces-To: ".$GLOBALS["message_envelope"]);
  139. ## one to work on at a later stage
  140. # $this->addCustomHeader("Return-Receipt-To: ".$GLOBALS["message_envelope"]);
  141. }
  142. ## when the email is generated from a webpage (quite possible :-) add a "received line" to identify the origin
  143. if (!empty($_SERVER['REMOTE_ADDR'])) {
  144. $this->add_timestamp();
  145. }
  146. $this->messageid = $messageid;
  147. }
  148. function add_html($html,$text = '',$templateid = 0) {
  149. $this->Body = $html;
  150. $this->IsHTML(true);
  151. if ($text) {
  152. $this->add_text($text);
  153. }
  154. $this->Encoding = HTMLEMAIL_ENCODING;
  155. $this->find_html_images($templateid);
  156. }
  157. function add_timestamp()
  158. {
  159. #0013076:
  160. # Add a line like Received: from [10.1.2.3] by website.example.com with HTTP; 01 Jan 2003 12:34:56 -0000
  161. # more info: http://www.spamcop.net/fom-serve/cache/369.html
  162. $ip_address = $_SERVER['REMOTE_ADDR'];
  163. if ( !empty($_SERVER['REMOTE_HOST']) ) {
  164. $ip_domain = $_SERVER['REMOTE_HOST'];
  165. } else {
  166. $ip_domain = gethostbyaddr($ip_address);
  167. }
  168. $hostname = $_SERVER["HTTP_HOST"];
  169. $request_time = date('r',$_SERVER['REQUEST_TIME']);
  170. $sTimeStamp = "from $ip_domain [$ip_address] by $hostname with HTTP; $request_time";
  171. $this->addTimeStamp($sTimeStamp);
  172. }
  173. function AddTimeStamp($sTimeStamp) {
  174. $this->timeStamp = $sTimeStamp;
  175. }
  176. function add_text($text) {
  177. $this->TextEncoding = TEXTEMAIL_ENCODING;
  178. if (!$this->Body) {
  179. $this->IsHTML(false);
  180. $this->Body = html_entity_decode($text ,ENT_QUOTES, 'UTF-8' ); #$text;
  181. } else {
  182. $this->AltBody = html_entity_decode($text ,ENT_QUOTES, 'UTF-8' );#$text;
  183. }
  184. }
  185. function append_text($text) {
  186. if ($this->AltBody) {
  187. $this->AltBody .= html_entity_decode($text ,ENT_QUOTES, 'UTF-8' );#$text;
  188. } else {
  189. $this->Body .= html_entity_decode($text."\n" ,ENT_QUOTES, 'UTF-8' );#$text;
  190. }
  191. }
  192. function build_message() {
  193. }
  194. function CreateHeader() {
  195. $parentheader = parent::CreateHeader();
  196. if (!empty($this->timeStamp)) {
  197. $header = 'Received: '.$this->timeStamp.$this->LE.$parentheader;
  198. } else {
  199. $header = $parentheader;
  200. }
  201. return $header;
  202. }
  203. function CreateBody() {
  204. $body = parent::CreateBody();
  205. /*
  206. if ($this->ContentType != 'text/plain') {
  207. foreach ($GLOBALS['plugins'] as $plugin) {
  208. $plreturn = $plugin->mimeWrap($this->messageid,$body,$this->header,$this->ContentTypeHeader,$this->destinationemail);
  209. if (is_array($plreturn) && sizeof($plreturn) == 3) {
  210. $this->header = $plreturn[0];
  211. $body = $plreturn[1];
  212. $this->ContentTypeHeader = $plreturn[2];
  213. }
  214. }
  215. }
  216. */
  217. return $body;
  218. }
  219. function compatSend($to_name = "", $to_addr, $from_name, $from_addr, $subject = '', $headers = '',$envelope = '') {
  220. if (!empty($from_addr) && method_exists($this,'SetFrom')) {
  221. $this->SetFrom($from_addr, $from_name);
  222. } else {
  223. $this->From = $from_addr;
  224. $this->FromName = $from_name;
  225. }
  226. if (!empty($GLOBALS["developer_email"])) {
  227. # make sure we are not sending out emails to real users
  228. # when developing
  229. $this->AddAddress($GLOBALS["developer_email"]);
  230. if ($GLOBALS["developer_email"] != $to_addr) {
  231. $this->Body = 'X-Originally to: '.$to_addr."\n\n".$this->Body;
  232. }
  233. } else {
  234. $this->AddAddress($to_addr);
  235. }
  236. $this->Subject = $subject;
  237. if ($this->Body) {
  238. ## allow plugins to add header lines
  239. foreach ($GLOBALS['plugins'] as $pluginname => $plugin) {
  240. # print "Checking Destination for ".$plugin->name."<br/>";
  241. $pluginHeaders = $plugin->messageHeaders($this);
  242. if ($pluginHeaders && sizeof($pluginHeaders)) {
  243. foreach ($pluginHeaders as $headerItem => $headerValue) {
  244. ## @@TODO, do we need to sanitise them?
  245. $this->addCustomHeader($headerItem.': '.$headerValue);
  246. }
  247. }
  248. }
  249. if(!parent::Send()) {
  250. logEvent(s('Error sending email to %s',$to_addr).' '.$this->ErrorInfo);
  251. return 0;
  252. }#
  253. } else {
  254. logEvent(s('Error, empty message-body sending email to %s',$to_addr));
  255. return 0;
  256. }
  257. return 1;
  258. }
  259. function Send() {
  260. if(!parent::Send()) {
  261. logEvent("Error sending email to ".$to_addr);
  262. return 0;
  263. }
  264. return 1;
  265. }
  266. function add_attachment($contents,$filename,$mimetype) {
  267. ## phpmailer 2.x
  268. if (method_exists($this,'AddStringAttachment')) {
  269. $this->AddStringAttachment($contents,$filename,'base64', $mimetype);
  270. } else {
  271. ## old phpmailer
  272. // Append to $attachment array
  273. $cur = count($this->attachment);
  274. $this->attachment[$cur][0] = base64_encode($contents);
  275. $this->attachment[$cur][1] = $filename;
  276. $this->attachment[$cur][2] = $filename;
  277. $this->attachment[$cur][3] = $this->encoding;
  278. $this->attachment[$cur][4] = $mimetype;
  279. $this->attachment[$cur][5] = false; // isStringAttachment
  280. $this->attachment[$cur][6] = "attachment";
  281. $this->attachment[$cur][7] = 0;
  282. }
  283. }
  284. function find_html_images($templateid) {
  285. #if (!$templateid) return;
  286. ## no template can be templateid 0, find the powered by image
  287. $templateid = sprintf('%d',$templateid);
  288. // Build the list of image extensions
  289. while(list($key,) = each($this->image_types)) {
  290. $extensions[] = $key;
  291. }
  292. $html_images = array();
  293. $filesystem_images = array();
  294. preg_match_all('/"([^"]+\.('.implode('|', $extensions).'))"/Ui', $this->Body, $images);
  295. for($i=0; $i<count($images[1]); $i++) {
  296. if($this->image_exists($templateid,$images[1][$i])){
  297. $html_images[] = $images[1][$i];
  298. $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
  299. }
  300. ## addition for filesystem images
  301. if (EMBEDUPLOADIMAGES) {
  302. if($this->filesystem_image_exists($images[1][$i])){
  303. $filesystem_images[] = $images[1][$i];
  304. $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
  305. }
  306. }
  307. ## end addition
  308. }
  309. if(!empty($html_images)){
  310. // If duplicate images are embedded, they may show up as attachments, so remove them.
  311. $html_images = array_unique($html_images);
  312. sort($html_images);
  313. for($i=0; $i<count($html_images); $i++){
  314. if($image = $this->get_template_image($templateid,$html_images[$i])){
  315. $content_type = $this->image_types[strtolower(substr($html_images[$i], strrpos($html_images[$i], '.') + 1))];
  316. $cid = $this->add_html_image($image, basename($html_images[$i]), $content_type);
  317. if (!empty($cid)) {
  318. $this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);
  319. }
  320. }
  321. }
  322. }
  323. ## addition for filesystem images
  324. if(!empty($filesystem_images)){
  325. // If duplicate images are embedded, they may show up as attachments, so remove them.
  326. $filesystem_images = array_unique($filesystem_images);
  327. sort($filesystem_images);
  328. for($i=0; $i<count($filesystem_images); $i++){
  329. if($image = $this->get_filesystem_image($filesystem_images[$i])){
  330. $content_type = $this->image_types[strtolower(substr($filesystem_images[$i], strrpos($filesystem_images[$i], '.') + 1))];
  331. $cid = $this->add_html_image($image, basename($filesystem_images[$i]), $content_type);
  332. if (!empty($cid)) {
  333. $this->Body = str_replace(basename($filesystem_images[$i]), "cid:$cid", $this->Body);#@@@
  334. }
  335. }
  336. }
  337. }
  338. ## end addition
  339. }
  340. function add_html_image($contents, $name = '', $content_type='application/octet-stream') {
  341. ## in phpMailer 2 and up we cannot use AddStringAttachment, because that doesn't use a cid
  342. ## we can't write to "attachment" either, because it's private
  343. /* one way to do it, is using a temporary file, but that'll have
  344. * quite an effect on performance and also isn't backward compatible,
  345. * because EncodeFile would need to be reverted to the default
  346. file_put_contents('/tmp/'.$name,base64_decode($contents));
  347. $cid = md5(uniqid(time()));
  348. $this->AddEmbeddedImage('/tmp/'.$name, $cid, $name,'base64', $content_type);
  349. */
  350. /* So, for now the only way to get this working in phpMailer 2 or up is to make
  351. * the attachment array public or add the AddEmbeddedImageString method
  352. * we need to add instructions how to patch phpMailer for that.
  353. * find out here whether it's been done and give an error if not
  354. *
  355. * it's been added to phpMailer 5.2.2
  356. * http://code.google.com/a/apache-extras.org/p/phpmailer/issues/detail?id=119
  357. *
  358. *
  359. */
  360. /* @@TODO additional optimisation:
  361. *
  362. * - we store the image base64 encoded
  363. * - then we decode it to pass it back to phpMailer
  364. * - when then encodes it again
  365. * - best would be to take out a step in there, but that would require more modifications
  366. * to phpMailer
  367. */
  368. $cid = md5(uniqid(time()));
  369. if (method_exists($this,'AddEmbeddedImageString')) {
  370. $this->AddEmbeddedImageString(base64_decode($contents), $cid, $name, $this->encoding, $content_type);
  371. } elseif (method_exists($this,'AddStringEmbeddedImage')) {
  372. ## PHPMailer 5.2.5 and up renamed the method
  373. ## https://github.com/Synchro/PHPMailer/issues/42#issuecomment-16217354
  374. $this->AddStringEmbeddedImage(base64_decode($contents), $cid, $name, $this->encoding, $content_type);
  375. } elseif (isset($this->attachment) && is_array($this->attachment)) {
  376. // Append to $attachment array
  377. $cur = count($this->attachment);
  378. $this->attachment[$cur][0] = base64_decode($contents);
  379. $this->attachment[$cur][1] = '';#$filename;
  380. $this->attachment[$cur][2] = $name;
  381. $this->attachment[$cur][3] = 'base64';
  382. $this->attachment[$cur][4] = $content_type;
  383. $this->attachment[$cur][5] = true; // isStringAttachment
  384. $this->attachment[$cur][6] = "inline";
  385. $this->attachment[$cur][7] = $cid;
  386. } else {
  387. logEvent("phpMailer needs patching to be able to use inline images from templates");
  388. print Error("phpMailer needs patching to be able to use inline images from templates");
  389. return;
  390. }
  391. return $cid;
  392. }
  393. ## addition for filesystem images
  394. function filesystem_image_exists($filename) {
  395. ## find the image referenced and see if it's on the server
  396. $imageroot = getConfig('uploadimageroot');
  397. # cl_output('filesystem_image_exists '.$docroot.' '.$filename);
  398. $elements = parse_url($filename);
  399. $localfile = basename($elements['path']);
  400. $localfile = urldecode($localfile);
  401. # cl_output('CHECK'.$localfile);
  402. if (defined('UPLOADIMAGES_DIR')) {
  403. # print $_SERVER['DOCUMENT_ROOT'].$localfile;
  404. return
  405. is_file($_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/image/'.$localfile)
  406. || is_file($_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/'.$localfile)
  407. ## commandline
  408. || is_file($imageroot.'/'.$localfile);
  409. } else
  410. return
  411. is_file($_SERVER['DOCUMENT_ROOT'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR.'/image/'.$localfile)
  412. || is_file($_SERVER['DOCUMENT_ROOT'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR.'/'.$localfile)
  413. ## commandline
  414. || is_file('../'.FCKIMAGES_DIR.'/image/'.$localfile)
  415. || is_file('../'.FCKIMAGES_DIR.'/'.$localfile);
  416. }
  417. function get_filesystem_image($filename) {
  418. ## get the image contents
  419. $localfile = basename(urldecode($filename));
  420. # cl_output('get file system image'.$filename.' '.$localfile);
  421. if (defined('UPLOADIMAGES_DIR')) {
  422. # print 'UPLOAD';
  423. $imageroot = getConfig('uploadimageroot');
  424. if (is_file($imageroot.$localfile)) {
  425. return base64_encode( file_get_contents($imageroot.$localfile));
  426. } else {
  427. if (is_file($_SERVER['DOCUMENT_ROOT'].$localfile)) {
  428. ## save the document root to be able to retrieve the file later from commandline
  429. SaveConfig("uploadimageroot",$_SERVER['DOCUMENT_ROOT'],0,1);
  430. return base64_encode( file_get_contents($_SERVER['DOCUMENT_ROOT'].$localfile));
  431. } elseif (is_file($_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/image/'.$localfile)) {
  432. SaveConfig("uploadimageroot",$_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/image/',0,1);
  433. return base64_encode( file_get_contents($_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/image/'.$localfile));
  434. } elseif (is_file($_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/'.$localfile)) {
  435. SaveConfig("uploadimageroot",$_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/',0,1);
  436. return base64_encode( file_get_contents($_SERVER['DOCUMENT_ROOT'].'/'.UPLOADIMAGES_DIR.'/'.$localfile));
  437. }
  438. }
  439. } elseif (is_file($_SERVER['DOCUMENT_ROOT'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR.'/'.$localfile)) {
  440. $elements = parse_url($filename);
  441. $localfile = basename($elements['path']);
  442. return base64_encode( file_get_contents($_SERVER['DOCUMENT_ROOT'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR.'/'.$localfile));
  443. } elseif (is_file($_SERVER['DOCUMENT_ROOT'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR.'/image/'.$localfile)) {
  444. return base64_encode( file_get_contents($_SERVER['DOCUMENT_ROOT'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR.'/image/'.$localfile));
  445. } elseif (is_file('../'.FCKIMAGES_DIR.'/'.$localfile)) { ## commandline
  446. return base64_encode( file_get_contents('../'.FCKIMAGES_DIR.'/'.$localfile));
  447. } elseif (is_file('../'.FCKIMAGES_DIR.'/image/'.$localfile)) {
  448. return base64_encode( file_get_contents('../'.FCKIMAGES_DIR.'/image/'.$localfile));
  449. }
  450. return '';
  451. }
  452. ## end addition
  453. function image_exists($templateid,$filename) {
  454. if (basename($filename) == 'powerphplist.png') $templateid = 0;
  455. $query
  456. = ' select *'
  457. . ' from ' . $GLOBALS['tables']['templateimage']
  458. . ' where template = ?'
  459. . ' and (filename = ? or filename = ?)';
  460. $rs = Sql_Query_Params($query, array($templateid, $filename, basename($filename)));
  461. return Sql_Num_Rows($rs);
  462. }
  463. function get_template_image($templateid,$filename){
  464. if (basename($filename) == 'powerphplist.png') $templateid = 0;
  465. $query
  466. = ' select data'
  467. . ' from ' . $GLOBALS['tables']['templateimage']
  468. . ' where template = ?'
  469. . ' and (filename = ? or filename= ?)';
  470. $rs = Sql_Query_Params($query, array($templateid, $filename, basename($filename)));
  471. $req = Sql_Fetch_Row($rs);
  472. return $req[0];
  473. }
  474. function EncodeFile ($path, $encoding = "base64") {
  475. # as we already encoded the contents in $path, return $path
  476. return chunk_split($path, 76, $this->LE);
  477. }
  478. function AmazonSESSend($messageheader,$messagebody) {
  479. $messageheader = preg_replace('/'.$this->LE.'$/','',$messageheader);
  480. $messageheader .= $this->LE."Subject: ".$this->EncodeHeader($this->Subject).$this->LE;
  481. #print nl2br(htmlspecialchars($messageheader)); exit;
  482. $date = date('r');
  483. $aws_signature = base64_encode(hash_hmac('sha256',$date,AWS_SECRETKEY,true));
  484. $requestheader = array(
  485. 'Host: email.us-east-1.amazonaws.com',
  486. 'Content-Type: application/x-www-form-urlencoded',
  487. 'Date: '. $date,
  488. 'X-Amzn-Authorization: AWS3-HTTPS AWSAccessKeyId='.AWS_ACCESSKEYID.',Algorithm=HMACSHA256,Signature='.$aws_signature,
  489. );
  490. /*
  491. * using the SendEmail call
  492. $requestdata = array(
  493. 'Action' => 'SendEmail',
  494. 'Source' => $this->Sender,
  495. 'Destination.ToAddresses.member.1' => $this->destinationemail,
  496. 'Message.Subject.Data' => $this->Subject,
  497. 'Message.Body.Text.Data' => $messagebody,
  498. );
  499. */
  500. # print '<hr/>Rawmessage '.nl2br(htmlspecialchars($messageheader. $this->LE. $this->LE.$messagebody));
  501. $rawmessage = base64_encode($messageheader. $this->LE.$this->LE.$messagebody);
  502. # $rawmessage = str_replace('=','',$rawmessage);
  503. $requestdata = array(
  504. 'Action' => 'SendRawEmail',
  505. 'Destinations.member.1' => $this->destinationemail,
  506. 'RawMessage.Data' => $rawmessage,
  507. );
  508. $header = '';
  509. foreach ($requestheader as $param) {
  510. $header .= $param.$this->LE;
  511. }
  512. $curl = curl_init();
  513. curl_setopt($curl, CURLOPT_URL, AWS_POSTURL);
  514. curl_setopt($curl, CURLOPT_TIMEOUT, 30);
  515. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  516. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  517. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  518. curl_setopt($curl, CURLOPT_HTTPHEADER,$requestheader);
  519. # print('<br/>Sending header '.htmlspecialchars($header).'<hr/>');
  520. curl_setopt($curl, CURLOPT_HEADER, 1);
  521. curl_setopt($curl, CURLOPT_DNS_USE_GLOBAL_CACHE, TRUE);
  522. curl_setopt($curl, CURLOPT_USERAGENT,NAME." (phpList version ".VERSION.", http://www.phplist.com/)");
  523. curl_setopt($curl, CURLOPT_POST, 1);
  524. ## this generates multipart/form-data, and that crashes the API, so don't use
  525. # curl_setopt($curl, CURLOPT_POSTFIELDS, $parameters);
  526. $data = '';
  527. foreach ($requestdata as $param => $value) {
  528. $data .= $param.'='.urlencode($value).'&';
  529. }
  530. $data = substr($data,0,-1);
  531. # print('Sending data '.htmlspecialchars($data).'<hr/>');
  532. curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  533. $res = curl_exec($curl);
  534. $status = curl_getinfo($curl,CURLINFO_HTTP_CODE);
  535. # print('Curl status '.$status);
  536. if ($status != 200) {
  537. $error = curl_error($curl);
  538. logEvent('Amazon SES status '.$status.' '.strip_tags($res).' '.$error);
  539. }
  540. curl_close($curl);
  541. # print('Got remote admin response '.htmlspecialchars($res).'<br/>');
  542. return $status == 200;
  543. }
  544. function MailSend($header, $body) {
  545. $this->mailsize = strlen($header.$body);
  546. ## use Amazon, if set up, @@TODO redo with latest PHPMailer
  547. ## https://github.com/PHPMailer/PHPMailer/commit/57b183bf6a203cb69231bc3a235a00905feff75b
  548. if (USE_AMAZONSES) {
  549. $header .= "To: ".$this->destinationemail.$this->LE;
  550. return $this->AmazonSESSend($header,$body);
  551. }
  552. ## we don't really use multiple to's so pass that on to phpmailer, if there are any
  553. if (!$this->SingleTo || !USE_LOCAL_SPOOL) {
  554. return parent::MailSend($header,$body);
  555. }
  556. if (!is_dir(USE_LOCAL_SPOOL) || !is_writable(USE_LOCAL_SPOOL)) {
  557. ## if local spool is not set, send the normal way
  558. return parent::MailSend($header,$body);
  559. }
  560. $fname = tempnam(USE_LOCAL_SPOOL,'msg');
  561. file_put_contents($fname,$header."\n".$body);
  562. file_put_contents($fname.'.S',$this->Sender);
  563. return true;
  564. }
  565. }