ses.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. <?php
  2. /**
  3. *
  4. * Copyright (c) 2011, Dan Myers.
  5. * Parts copyright (c) 2008, Donovan Schonknecht.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. * - Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. * POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * This is a modified BSD license (the third clause has been removed).
  30. * The BSD license may be found here:
  31. * http://www.opensource.org/licenses/bsd-license.php
  32. *
  33. * Amazon Simple Email Service is a trademark of Amazon.com, Inc. or its affiliates.
  34. *
  35. * SimpleEmailService is based on Donovan Schonknecht's Amazon S3 PHP class, found here:
  36. * http://undesigned.org.za/2007/10/22/amazon-s3-php-class
  37. *
  38. */
  39. /**
  40. * Amazon SimpleEmailService PHP class
  41. *
  42. * @link http://sourceforge.net/projects/php-aws-ses/
  43. * version 0.8.2
  44. *
  45. */
  46. class SimpleEmailService
  47. {
  48. protected $__accessKey; // AWS Access key
  49. protected $__secretKey; // AWS Secret key
  50. protected $__host;
  51. public function getAccessKey() { return $this->__accessKey; }
  52. public function getSecretKey() { return $this->__secretKey; }
  53. public function getHost() { return $this->__host; }
  54. protected $__verifyHost = 1;
  55. protected $__verifyPeer = 1;
  56. // verifyHost and verifyPeer determine whether curl verifies ssl certificates.
  57. // It may be necessary to disable these checks on certain systems.
  58. // These only have an effect if SSL is enabled.
  59. public function verifyHost() { return $this->__verifyHost; }
  60. public function enableVerifyHost($enable = true) { $this->__verifyHost = $enable; }
  61. public function verifyPeer() { return $this->__verifyPeer; }
  62. public function enableVerifyPeer($enable = true) { $this->__verifyPeer = $enable; }
  63. /**
  64. * Constructor
  65. *
  66. * @param string $accessKey Access key
  67. * @param string $secretKey Secret key
  68. * @return void
  69. */
  70. public function __construct($accessKey = null, $secretKey = null, $host = 'email.us-east-1.amazonaws.com') {
  71. if ($accessKey !== null && $secretKey !== null) {
  72. $this->setAuth($accessKey, $secretKey);
  73. }
  74. $this->__host = $host;
  75. }
  76. /**
  77. * Set AWS access key and secret key
  78. *
  79. * @param string $accessKey Access key
  80. * @param string $secretKey Secret key
  81. * @return void
  82. */
  83. public function setAuth($accessKey, $secretKey) {
  84. $this->__accessKey = $accessKey;
  85. $this->__secretKey = $secretKey;
  86. }
  87. /**
  88. * Lists the email addresses that have been verified and can be used as the 'From' address
  89. *
  90. * @return An array containing two items: a list of verified email addresses, and the request id.
  91. */
  92. public function listVerifiedEmailAddresses() {
  93. $rest = new SimpleEmailServiceRequest($this, 'GET');
  94. $rest->setParameter('Action', 'ListVerifiedEmailAddresses');
  95. $rest = $rest->getResponse();
  96. if($rest->error === false && $rest->code !== 200) {
  97. $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
  98. }
  99. if($rest->error !== false) {
  100. $this->__triggerError('listVerifiedEmailAddresses', $rest->error);
  101. return false;
  102. }
  103. $response = array();
  104. if(!isset($rest->body)) {
  105. return $response;
  106. }
  107. $addresses = array();
  108. foreach($rest->body->ListVerifiedEmailAddressesResult->VerifiedEmailAddresses->member as $address) {
  109. $addresses[] = (string)$address;
  110. }
  111. $response['Addresses'] = $addresses;
  112. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  113. return $response;
  114. }
  115. /**
  116. * Requests verification of the provided email address, so it can be used
  117. * as the 'From' address when sending emails through SimpleEmailService.
  118. *
  119. * After submitting this request, you should receive a verification email
  120. * from Amazon at the specified address containing instructions to follow.
  121. *
  122. * @param string email The email address to get verified
  123. * @return The request id for this request.
  124. */
  125. public function verifyEmailAddress($email) {
  126. $rest = new SimpleEmailServiceRequest($this, 'POST');
  127. $rest->setParameter('Action', 'VerifyEmailAddress');
  128. $rest->setParameter('EmailAddress', $email);
  129. $rest = $rest->getResponse();
  130. if($rest->error === false && $rest->code !== 200) {
  131. $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
  132. }
  133. if($rest->error !== false) {
  134. $this->__triggerError('verifyEmailAddress', $rest->error);
  135. return false;
  136. }
  137. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  138. return $response;
  139. }
  140. /**
  141. * Removes the specified email address from the list of verified addresses.
  142. *
  143. * @param string email The email address to remove
  144. * @return The request id for this request.
  145. */
  146. public function deleteVerifiedEmailAddress($email) {
  147. $rest = new SimpleEmailServiceRequest($this, 'DELETE');
  148. $rest->setParameter('Action', 'DeleteVerifiedEmailAddress');
  149. $rest->setParameter('EmailAddress', $email);
  150. $rest = $rest->getResponse();
  151. if($rest->error === false && $rest->code !== 200) {
  152. $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
  153. }
  154. if($rest->error !== false) {
  155. $this->__triggerError('deleteVerifiedEmailAddress', $rest->error);
  156. return false;
  157. }
  158. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  159. return $response;
  160. }
  161. /**
  162. * Retrieves information on the current activity limits for this account.
  163. * See http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendQuota.html
  164. *
  165. * @return An array containing information on this account's activity limits.
  166. */
  167. public function getSendQuota() {
  168. $rest = new SimpleEmailServiceRequest($this, 'GET');
  169. $rest->setParameter('Action', 'GetSendQuota');
  170. $rest = $rest->getResponse();
  171. if($rest->error === false && $rest->code !== 200) {
  172. $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
  173. }
  174. if($rest->error !== false) {
  175. $this->__triggerError('getSendQuota', $rest->error);
  176. return false;
  177. }
  178. $response = array();
  179. if(!isset($rest->body)) {
  180. return $response;
  181. }
  182. $response['Max24HourSend'] = (string)$rest->body->GetSendQuotaResult->Max24HourSend;
  183. $response['MaxSendRate'] = (string)$rest->body->GetSendQuotaResult->MaxSendRate;
  184. $response['SentLast24Hours'] = (string)$rest->body->GetSendQuotaResult->SentLast24Hours;
  185. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  186. return $response;
  187. }
  188. /**
  189. * Retrieves statistics for the last two weeks of activity on this account.
  190. * See http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendStatistics.html
  191. *
  192. * @return An array of activity statistics. Each array item covers a 15-minute period.
  193. */
  194. public function getSendStatistics() {
  195. $rest = new SimpleEmailServiceRequest($this, 'GET');
  196. $rest->setParameter('Action', 'GetSendStatistics');
  197. $rest = $rest->getResponse();
  198. if($rest->error === false && $rest->code !== 200) {
  199. $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
  200. }
  201. if($rest->error !== false) {
  202. $this->__triggerError('getSendStatistics', $rest->error);
  203. return false;
  204. }
  205. $response = array();
  206. if(!isset($rest->body)) {
  207. return $response;
  208. }
  209. $datapoints = array();
  210. foreach($rest->body->GetSendStatisticsResult->SendDataPoints->member as $datapoint) {
  211. $p = array();
  212. $p['Bounces'] = (string)$datapoint->Bounces;
  213. $p['Complaints'] = (string)$datapoint->Complaints;
  214. $p['DeliveryAttempts'] = (string)$datapoint->DeliveryAttempts;
  215. $p['Rejects'] = (string)$datapoint->Rejects;
  216. $p['Timestamp'] = (string)$datapoint->Timestamp;
  217. $datapoints[] = $p;
  218. }
  219. $response['SendDataPoints'] = $datapoints;
  220. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  221. return $response;
  222. }
  223. /**
  224. * Given a SimpleEmailServiceMessage object, submits the message to the service for sending.
  225. *
  226. * @return An array containing the unique identifier for this message and a separate request id.
  227. * Returns false if the provided message is missing any required fields.
  228. */
  229. public function sendEmail($sesMessage) {
  230. if(!$sesMessage->validate()) {
  231. $this->__triggerError('sendEmail', 'Message failed validation.');
  232. return false;
  233. }
  234. $rest = new SimpleEmailServiceRequest($this, 'POST');
  235. $rest->setParameter('Action', 'SendEmail');
  236. $i = 1;
  237. foreach($sesMessage->to as $to) {
  238. $rest->setParameter('Destination.ToAddresses.member.'.$i, $to);
  239. $i++;
  240. }
  241. if(is_array($sesMessage->cc)) {
  242. $i = 1;
  243. foreach($sesMessage->cc as $cc) {
  244. $rest->setParameter('Destination.CcAddresses.member.'.$i, $cc);
  245. $i++;
  246. }
  247. }
  248. if(is_array($sesMessage->bcc)) {
  249. $i = 1;
  250. foreach($sesMessage->bcc as $bcc) {
  251. $rest->setParameter('Destination.BccAddresses.member.'.$i, $bcc);
  252. $i++;
  253. }
  254. }
  255. if(is_array($sesMessage->replyto)) {
  256. $i = 1;
  257. foreach($sesMessage->replyto as $replyto) {
  258. $rest->setParameter('ReplyToAddresses.member.'.$i, $replyto);
  259. $i++;
  260. }
  261. }
  262. $rest->setParameter('Source', $sesMessage->from);
  263. if($sesMessage->returnpath != null) {
  264. $rest->setParameter('ReturnPath', $sesMessage->returnpath);
  265. }
  266. if($sesMessage->subject != null && strlen($sesMessage->subject) > 0) {
  267. $rest->setParameter('Message.Subject.Data', $sesMessage->subject);
  268. if($sesMessage->subjectCharset != null && strlen($sesMessage->subjectCharset) > 0) {
  269. $rest->setParameter('Message.Subject.Charset', $sesMessage->subjectCharset);
  270. }
  271. }
  272. if($sesMessage->messagetext != null && strlen($sesMessage->messagetext) > 0) {
  273. $rest->setParameter('Message.Body.Text.Data', $sesMessage->messagetext);
  274. if($sesMessage->messageTextCharset != null && strlen($sesMessage->messageTextCharset) > 0) {
  275. $rest->setParameter('Message.Body.Text.Charset', $sesMessage->messageTextCharset);
  276. }
  277. }
  278. if($sesMessage->messagehtml != null && strlen($sesMessage->messagehtml) > 0) {
  279. $rest->setParameter('Message.Body.Html.Data', $sesMessage->messagehtml);
  280. if($sesMessage->messageHtmlCharset != null && strlen($sesMessage->messageHtmlCharset) > 0) {
  281. $rest->setParameter('Message.Body.Html.Charset', $sesMessage->messageHtmlCharset);
  282. }
  283. }
  284. $rest = $rest->getResponse();
  285. if($rest->error === false && $rest->code !== 200) {
  286. $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
  287. }
  288. if($rest->error !== false) {
  289. $this->__triggerError('sendEmail', $rest->error);
  290. return false;
  291. }
  292. $response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId;
  293. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  294. return $response;
  295. }
  296. /**
  297. * Trigger an error message
  298. *
  299. * @internal Used by member functions to output errors
  300. * @param array $error Array containing error information
  301. * @return string
  302. */
  303. public function __triggerError($functionname, $error)
  304. {
  305. if($error == false) {
  306. trigger_error(sprintf("SimpleEmailService::%s(): Encountered an error, but no description given", $functionname), E_USER_WARNING);
  307. }
  308. else if(isset($error['curl']) && $error['curl'])
  309. {
  310. trigger_error(sprintf("SimpleEmailService::%s(): %s %s", $functionname, $error['code'], $error['message']), E_USER_WARNING);
  311. }
  312. else if(isset($error['Error']))
  313. {
  314. $e = $error['Error'];
  315. $message = sprintf("SimpleEmailService::%s(): %s - %s: %s\nRequest Id: %s\n", $functionname, $e['Type'], $e['Code'], $e['Message'], $error['RequestId']);
  316. trigger_error($message, E_USER_WARNING);
  317. }
  318. else {
  319. trigger_error(sprintf("SimpleEmailService::%s(): Encountered an error: %s", $functionname, $error), E_USER_WARNING);
  320. }
  321. }
  322. }
  323. final class SimpleEmailServiceRequest
  324. {
  325. private $ses, $verb, $parameters = array();
  326. public $response;
  327. /**
  328. * Constructor
  329. *
  330. * @param string $ses The SimpleEmailService object making this request
  331. * @param string $action action
  332. * @param string $verb HTTP verb
  333. * @return mixed
  334. */
  335. function __construct($ses, $verb) {
  336. $this->ses = $ses;
  337. $this->verb = $verb;
  338. $this->response = new STDClass;
  339. $this->response->error = false;
  340. }
  341. /**
  342. * Set request parameter
  343. *
  344. * @param string $key Key
  345. * @param string $value Value
  346. * @param boolean $replace Whether to replace the key if it already exists (default true)
  347. * @return void
  348. */
  349. public function setParameter($key, $value, $replace = true) {
  350. if(!$replace && isset($this->parameters[$key]))
  351. {
  352. $temp = (array)($this->parameters[$key]);
  353. $temp[] = $value;
  354. $this->parameters[$key] = $temp;
  355. }
  356. else
  357. {
  358. $this->parameters[$key] = $value;
  359. }
  360. }
  361. /**
  362. * Get the response
  363. *
  364. * @return object | false
  365. */
  366. public function getResponse() {
  367. $params = array();
  368. foreach ($this->parameters as $var => $value)
  369. {
  370. if(is_array($value))
  371. {
  372. foreach($value as $v)
  373. {
  374. $params[] = $var.'='.$this->__customUrlEncode($v);
  375. }
  376. }
  377. else
  378. {
  379. $params[] = $var.'='.$this->__customUrlEncode($value);
  380. }
  381. }
  382. sort($params, SORT_STRING);
  383. // must be in format 'Sun, 06 Nov 1994 08:49:37 GMT'
  384. $date = gmdate('D, d M Y H:i:s e');
  385. $query = implode('&', $params);
  386. $headers = array();
  387. $headers[] = 'Date: '.$date;
  388. $headers[] = 'Host: '.$this->ses->getHost();
  389. $auth = 'AWS3-HTTPS AWSAccessKeyId='.$this->ses->getAccessKey();
  390. $auth .= ',Algorithm=HmacSHA256,Signature='.$this->__getSignature($date);
  391. $headers[] = 'X-Amzn-Authorization: '.$auth;
  392. $url = 'https://'.$this->ses->getHost().'/';
  393. // Basic setup
  394. $curl = curl_init();
  395. curl_setopt($curl, CURLOPT_USERAGENT, 'SimpleEmailService/php');
  396. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, ($this->ses->verifyHost() ? 1 : 0));
  397. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, ($this->ses->verifyPeer() ? 1 : 0));
  398. // Request types
  399. switch ($this->verb) {
  400. case 'GET':
  401. $url .= '?'.$query;
  402. break;
  403. case 'POST':
  404. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
  405. curl_setopt($curl, CURLOPT_POSTFIELDS, $query);
  406. $headers[] = 'Content-Type: application/x-www-form-urlencoded';
  407. break;
  408. case 'DELETE':
  409. $url .= '?'.$query;
  410. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  411. break;
  412. default: break;
  413. }
  414. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  415. curl_setopt($curl, CURLOPT_HEADER, false);
  416. curl_setopt($curl, CURLOPT_URL, $url);
  417. curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
  418. curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
  419. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  420. // Execute, grab errors
  421. if (curl_exec($curl)) {
  422. $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  423. } else {
  424. $this->response->error = array(
  425. 'curl' => true,
  426. 'code' => curl_errno($curl),
  427. 'message' => curl_error($curl),
  428. 'resource' => $this->resource
  429. );
  430. }
  431. @curl_close($curl);
  432. // Parse body into XML
  433. if ($this->response->error === false && isset($this->response->body)) {
  434. $this->response->body = simplexml_load_string($this->response->body);
  435. // Grab SES errors
  436. if (!in_array($this->response->code, array(200, 201, 202, 204))
  437. && isset($this->response->body->Error)) {
  438. $error = $this->response->body->Error;
  439. $output = array();
  440. $output['curl'] = false;
  441. $output['Error'] = array();
  442. $output['Error']['Type'] = (string)$error->Type;
  443. $output['Error']['Code'] = (string)$error->Code;
  444. $output['Error']['Message'] = (string)$error->Message;
  445. $output['RequestId'] = (string)$this->response->body->RequestId;
  446. $this->response->error = $output;
  447. unset($this->response->body);
  448. }
  449. }
  450. return $this->response;
  451. }
  452. /**
  453. * CURL write callback
  454. *
  455. * @param resource &$curl CURL resource
  456. * @param string &$data Data
  457. * @return integer
  458. */
  459. private function __responseWriteCallback(&$curl, &$data) {
  460. $this->response->body .= $data;
  461. return strlen($data);
  462. }
  463. /**
  464. * Contributed by afx114
  465. * URL encode the parameters as per http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?Query_QueryAuth.html
  466. * PHP's rawurlencode() follows RFC 1738, not RFC 3986 as required by Amazon. The only difference is the tilde (~), so convert it back after rawurlencode
  467. * See: http://www.morganney.com/blog/API/AWS-Product-Advertising-API-Requires-a-Signed-Request.php
  468. *
  469. * @param string $var String to encode
  470. * @return string
  471. */
  472. private function __customUrlEncode($var) {
  473. return str_replace('%7E', '~', rawurlencode($var));
  474. }
  475. /**
  476. * Generate the auth string using Hmac-SHA256
  477. *
  478. * @internal Used by SimpleDBRequest::getResponse()
  479. * @param string $string String to sign
  480. * @return string
  481. */
  482. private function __getSignature($string) {
  483. return base64_encode(hash_hmac('sha256', $string, $this->ses->getSecretKey(), true));
  484. }
  485. }
  486. final class SimpleEmailServiceMessage {
  487. // these are public for convenience only
  488. // these are not to be used outside of the SimpleEmailService class!
  489. public $to, $cc, $bcc, $replyto;
  490. public $from, $returnpath;
  491. public $subject, $messagetext, $messagehtml;
  492. public $subjectCharset, $messageTextCharset, $messageHtmlCharset;
  493. function __construct() {
  494. $this->to = array();
  495. $this->cc = array();
  496. $this->bcc = array();
  497. $this->replyto = array();
  498. $this->from = null;
  499. $this->returnpath = null;
  500. $this->subject = null;
  501. $this->messagetext = null;
  502. $this->messagehtml = null;
  503. $this->subjectCharset = null;
  504. $this->messageTextCharset = null;
  505. $this->messageHtmlCharset = null;
  506. }
  507. /**
  508. * addTo, addCC, addBCC, and addReplyTo have the following behavior:
  509. * If a single address is passed, it is appended to the current list of addresses.
  510. * If an array of addresses is passed, that array is merged into the current list.
  511. */
  512. function addTo($to) {
  513. if(!is_array($to)) {
  514. $this->to[] = $to;
  515. }
  516. else {
  517. $this->to = array_merge($this->to, $to);
  518. }
  519. }
  520. function addCC($cc) {
  521. if(!is_array($cc)) {
  522. $this->cc[] = $cc;
  523. }
  524. else {
  525. $this->cc = array_merge($this->cc, $cc);
  526. }
  527. }
  528. function addBCC($bcc) {
  529. if(!is_array($bcc)) {
  530. $this->bcc[] = $bcc;
  531. }
  532. else {
  533. $this->bcc = array_merge($this->bcc, $bcc);
  534. }
  535. }
  536. function addReplyTo($replyto) {
  537. if(!is_array($replyto)) {
  538. $this->replyto[] = $replyto;
  539. }
  540. else {
  541. $this->replyto = array_merge($this->replyto, $replyto);
  542. }
  543. }
  544. function setFrom($from) {
  545. $this->from = $from;
  546. }
  547. function setReturnPath($returnpath) {
  548. $this->returnpath = $returnpath;
  549. }
  550. function setSubject($subject) {
  551. $this->subject = $subject;
  552. }
  553. function setSubjectCharset($charset) {
  554. $this->subjectCharset = $charset;
  555. }
  556. function setMessageFromString($text, $html = null) {
  557. $this->messagetext = $text;
  558. $this->messagehtml = $html;
  559. }
  560. function setMessageFromFile($textfile, $htmlfile = null) {
  561. if(file_exists($textfile) && is_file($textfile) && is_readable($textfile)) {
  562. $this->messagetext = file_get_contents($textfile);
  563. } else {
  564. $this->messagetext = null;
  565. }
  566. if(file_exists($htmlfile) && is_file($htmlfile) && is_readable($htmlfile)) {
  567. $this->messagehtml = file_get_contents($htmlfile);
  568. } else {
  569. $this->messagehtml = null;
  570. }
  571. }
  572. function setMessageFromURL($texturl, $htmlurl = null) {
  573. if($texturl !== null) {
  574. $this->messagetext = file_get_contents($texturl);
  575. } else {
  576. $this->messagetext = null;
  577. }
  578. if($htmlurl !== null) {
  579. $this->messagehtml = file_get_contents($htmlurl);
  580. } else {
  581. $this->messagehtml = null;
  582. }
  583. }
  584. function setMessageCharset($textCharset, $htmlCharset = null) {
  585. $this->messageTextCharset = $textCharset;
  586. $this->messageHtmlCharset = $htmlCharset;
  587. }
  588. /**
  589. * Validates whether the message object has sufficient information to submit a request to SES.
  590. * This does not guarantee the message will arrive, nor that the request will succeed;
  591. * instead, it makes sure that no required fields are missing.
  592. *
  593. * This is used internally before attempting a SendEmail or SendRawEmail request,
  594. * but it can be used outside of this file if verification is desired.
  595. * May be useful if e.g. the data is being populated from a form; developers can generally
  596. * use this function to verify completeness instead of writing custom logic.
  597. *
  598. * @return boolean
  599. */
  600. public function validate() {
  601. if(count($this->to) == 0)
  602. return false;
  603. if($this->from == null || strlen($this->from) == 0)
  604. return false;
  605. // messages require at least one of: subject, messagetext, messagehtml.
  606. if(($this->subject == null || strlen($this->subject) == 0)
  607. && ($this->messagetext == null || strlen($this->messagetext) == 0)
  608. && ($this->messagehtml == null || strlen($this->messagehtml) == 0))
  609. {
  610. return false;
  611. }
  612. return true;
  613. }
  614. }