PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/externals/amazon-ses/ses.php

http://github.com/facebook/phabricator
PHP | 722 lines | 426 code | 105 blank | 191 comment | 76 complexity | 44c77681b090640f7b754df0be0f400a MD5 | raw file
Possible License(s): JSON, MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause, LGPL-2.0, MIT, LGPL-2.1, LGPL-3.0
  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.1
  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. // If you use exceptions, errors will be communicated by throwing a
  64. // SimpleEmailServiceException. By default, they will be trigger_error()'d.
  65. protected $__useExceptions = 0;
  66. public function useExceptions() { return $this->__useExceptions; }
  67. public function enableUseExceptions($enable = true) { $this->__useExceptions = $enable; }
  68. /**
  69. * Constructor
  70. *
  71. * @param string $accessKey Access key
  72. * @param string $secretKey Secret key
  73. * @return void
  74. */
  75. public function __construct($accessKey = null, $secretKey = null, $host = 'email.us-east-1.amazonaws.com') {
  76. if (!function_exists('simplexml_load_string')) {
  77. throw new Exception(
  78. pht(
  79. 'The PHP SimpleXML extension is not available, but this '.
  80. 'extension is required to send mail via Amazon SES, because '.
  81. 'Amazon SES returns API responses in XML format. Install or '.
  82. 'enable the SimpleXML extension.'));
  83. }
  84. // Catch mistakes with reading the wrong column out of the SES
  85. // documentation. See T10728.
  86. if (preg_match('(-smtp)', $host)) {
  87. throw new Exception(
  88. pht(
  89. 'Amazon SES is not configured correctly: the configured SES '.
  90. 'endpoint ("%s") is an SMTP endpoint. Instead, use an API (HTTPS) '.
  91. 'endpoint.',
  92. $host));
  93. }
  94. if ($accessKey !== null && $secretKey !== null) {
  95. $this->setAuth($accessKey, $secretKey);
  96. }
  97. $this->__host = $host;
  98. }
  99. /**
  100. * Set AWS access key and secret key
  101. *
  102. * @param string $accessKey Access key
  103. * @param string $secretKey Secret key
  104. * @return void
  105. */
  106. public function setAuth($accessKey, $secretKey) {
  107. $this->__accessKey = $accessKey;
  108. $this->__secretKey = $secretKey;
  109. }
  110. /**
  111. * Lists the email addresses that have been verified and can be used as the 'From' address
  112. *
  113. * @return An array containing two items: a list of verified email addresses, and the request id.
  114. */
  115. public function listVerifiedEmailAddresses() {
  116. $rest = new SimpleEmailServiceRequest($this, 'GET');
  117. $rest->setParameter('Action', 'ListVerifiedEmailAddresses');
  118. $rest = $rest->getResponse();
  119. $response = array();
  120. if(!isset($rest->body)) {
  121. return $response;
  122. }
  123. $addresses = array();
  124. foreach($rest->body->ListVerifiedEmailAddressesResult->VerifiedEmailAddresses->member as $address) {
  125. $addresses[] = (string)$address;
  126. }
  127. $response['Addresses'] = $addresses;
  128. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  129. return $response;
  130. }
  131. /**
  132. * Requests verification of the provided email address, so it can be used
  133. * as the 'From' address when sending emails through SimpleEmailService.
  134. *
  135. * After submitting this request, you should receive a verification email
  136. * from Amazon at the specified address containing instructions to follow.
  137. *
  138. * @param string email The email address to get verified
  139. * @return The request id for this request.
  140. */
  141. public function verifyEmailAddress($email) {
  142. $rest = new SimpleEmailServiceRequest($this, 'POST');
  143. $rest->setParameter('Action', 'VerifyEmailAddress');
  144. $rest->setParameter('EmailAddress', $email);
  145. $rest = $rest->getResponse();
  146. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  147. return $response;
  148. }
  149. /**
  150. * Removes the specified email address from the list of verified addresses.
  151. *
  152. * @param string email The email address to remove
  153. * @return The request id for this request.
  154. */
  155. public function deleteVerifiedEmailAddress($email) {
  156. $rest = new SimpleEmailServiceRequest($this, 'DELETE');
  157. $rest->setParameter('Action', 'DeleteVerifiedEmailAddress');
  158. $rest->setParameter('EmailAddress', $email);
  159. $rest = $rest->getResponse();
  160. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  161. return $response;
  162. }
  163. /**
  164. * Retrieves information on the current activity limits for this account.
  165. * See http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendQuota.html
  166. *
  167. * @return An array containing information on this account's activity limits.
  168. */
  169. public function getSendQuota() {
  170. $rest = new SimpleEmailServiceRequest($this, 'GET');
  171. $rest->setParameter('Action', 'GetSendQuota');
  172. $rest = $rest->getResponse();
  173. $response = array();
  174. if(!isset($rest->body)) {
  175. return $response;
  176. }
  177. $response['Max24HourSend'] = (string)$rest->body->GetSendQuotaResult->Max24HourSend;
  178. $response['MaxSendRate'] = (string)$rest->body->GetSendQuotaResult->MaxSendRate;
  179. $response['SentLast24Hours'] = (string)$rest->body->GetSendQuotaResult->SentLast24Hours;
  180. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  181. return $response;
  182. }
  183. /**
  184. * Retrieves statistics for the last two weeks of activity on this account.
  185. * See http://docs.amazonwebservices.com/ses/latest/APIReference/API_GetSendStatistics.html
  186. *
  187. * @return An array of activity statistics. Each array item covers a 15-minute period.
  188. */
  189. public function getSendStatistics() {
  190. $rest = new SimpleEmailServiceRequest($this, 'GET');
  191. $rest->setParameter('Action', 'GetSendStatistics');
  192. $rest = $rest->getResponse();
  193. $response = array();
  194. if(!isset($rest->body)) {
  195. return $response;
  196. }
  197. $datapoints = array();
  198. foreach($rest->body->GetSendStatisticsResult->SendDataPoints->member as $datapoint) {
  199. $p = array();
  200. $p['Bounces'] = (string)$datapoint->Bounces;
  201. $p['Complaints'] = (string)$datapoint->Complaints;
  202. $p['DeliveryAttempts'] = (string)$datapoint->DeliveryAttempts;
  203. $p['Rejects'] = (string)$datapoint->Rejects;
  204. $p['Timestamp'] = (string)$datapoint->Timestamp;
  205. $datapoints[] = $p;
  206. }
  207. $response['SendDataPoints'] = $datapoints;
  208. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  209. return $response;
  210. }
  211. public function sendRawEmail($raw) {
  212. $rest = new SimpleEmailServiceRequest($this, 'POST');
  213. $rest->setParameter('Action', 'SendRawEmail');
  214. $rest->setParameter('RawMessage.Data', base64_encode($raw));
  215. $rest = $rest->getResponse();
  216. $response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId;
  217. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  218. return $response;
  219. }
  220. /**
  221. * Given a SimpleEmailServiceMessage object, submits the message to the service for sending.
  222. *
  223. * @return An array containing the unique identifier for this message and a separate request id.
  224. * Returns false if the provided message is missing any required fields.
  225. */
  226. public function sendEmail($sesMessage) {
  227. if(!$sesMessage->validate()) {
  228. return false;
  229. }
  230. $rest = new SimpleEmailServiceRequest($this, 'POST');
  231. $rest->setParameter('Action', 'SendEmail');
  232. $i = 1;
  233. foreach($sesMessage->to as $to) {
  234. $rest->setParameter('Destination.ToAddresses.member.'.$i, $to);
  235. $i++;
  236. }
  237. if(is_array($sesMessage->cc)) {
  238. $i = 1;
  239. foreach($sesMessage->cc as $cc) {
  240. $rest->setParameter('Destination.CcAddresses.member.'.$i, $cc);
  241. $i++;
  242. }
  243. }
  244. if(is_array($sesMessage->bcc)) {
  245. $i = 1;
  246. foreach($sesMessage->bcc as $bcc) {
  247. $rest->setParameter('Destination.BccAddresses.member.'.$i, $bcc);
  248. $i++;
  249. }
  250. }
  251. if(is_array($sesMessage->replyto)) {
  252. $i = 1;
  253. foreach($sesMessage->replyto as $replyto) {
  254. $rest->setParameter('ReplyToAddresses.member.'.$i, $replyto);
  255. $i++;
  256. }
  257. }
  258. $rest->setParameter('Source', $sesMessage->from);
  259. if($sesMessage->returnpath != null) {
  260. $rest->setParameter('ReturnPath', $sesMessage->returnpath);
  261. }
  262. if($sesMessage->subject != null && strlen($sesMessage->subject) > 0) {
  263. $rest->setParameter('Message.Subject.Data', $sesMessage->subject);
  264. if($sesMessage->subjectCharset != null && strlen($sesMessage->subjectCharset) > 0) {
  265. $rest->setParameter('Message.Subject.Charset', $sesMessage->subjectCharset);
  266. }
  267. }
  268. if($sesMessage->messagetext != null && strlen($sesMessage->messagetext) > 0) {
  269. $rest->setParameter('Message.Body.Text.Data', $sesMessage->messagetext);
  270. if($sesMessage->messageTextCharset != null && strlen($sesMessage->messageTextCharset) > 0) {
  271. $rest->setParameter('Message.Body.Text.Charset', $sesMessage->messageTextCharset);
  272. }
  273. }
  274. if($sesMessage->messagehtml != null && strlen($sesMessage->messagehtml) > 0) {
  275. $rest->setParameter('Message.Body.Html.Data', $sesMessage->messagehtml);
  276. if($sesMessage->messageHtmlCharset != null && strlen($sesMessage->messageHtmlCharset) > 0) {
  277. $rest->setParameter('Message.Body.Html.Charset', $sesMessage->messageHtmlCharset);
  278. }
  279. }
  280. $rest = $rest->getResponse();
  281. $response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId;
  282. $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
  283. return $response;
  284. }
  285. /**
  286. * Trigger an error message
  287. *
  288. * @internal Used by member functions to output errors
  289. * @param array $error Array containing error information
  290. * @return string
  291. */
  292. public function __triggerError($functionname, $error)
  293. {
  294. if($error == false) {
  295. $message = sprintf("SimpleEmailService::%s(): Encountered an error, but no description given", $functionname);
  296. }
  297. else if(isset($error['curl']) && $error['curl'])
  298. {
  299. $message = sprintf("SimpleEmailService::%s(): %s %s", $functionname, $error['code'], $error['message']);
  300. }
  301. else if(isset($error['Error']))
  302. {
  303. $e = $error['Error'];
  304. $message = sprintf("SimpleEmailService::%s(): %s - %s: %s\nRequest Id: %s\n", $functionname, $e['Type'], $e['Code'], $e['Message'], $error['RequestId']);
  305. }
  306. if ($this->useExceptions()) {
  307. throw new SimpleEmailServiceException($message);
  308. } else {
  309. trigger_error($message, E_USER_WARNING);
  310. }
  311. }
  312. /**
  313. * Callback handler for 503 retries.
  314. *
  315. * @internal Used by SimpleDBRequest to call the user-specified callback, if set
  316. * @param $attempt The number of failed attempts so far
  317. * @return The retry delay in microseconds, or 0 to stop retrying.
  318. */
  319. public function __executeServiceTemporarilyUnavailableRetryDelay($attempt)
  320. {
  321. if(is_callable($this->__serviceUnavailableRetryDelayCallback)) {
  322. $callback = $this->__serviceUnavailableRetryDelayCallback;
  323. return $callback($attempt);
  324. }
  325. return 0;
  326. }
  327. }
  328. final class SimpleEmailServiceRequest
  329. {
  330. private $ses, $verb, $parameters = array();
  331. public $response;
  332. /**
  333. * Constructor
  334. *
  335. * @param string $ses The SimpleEmailService object making this request
  336. * @param string $action action
  337. * @param string $verb HTTP verb
  338. * @return mixed
  339. */
  340. function __construct($ses, $verb) {
  341. $this->ses = $ses;
  342. $this->verb = $verb;
  343. $this->response = new STDClass;
  344. $this->response->error = false;
  345. }
  346. /**
  347. * Set request parameter
  348. *
  349. * @param string $key Key
  350. * @param string $value Value
  351. * @param boolean $replace Whether to replace the key if it already exists (default true)
  352. * @return void
  353. */
  354. public function setParameter($key, $value, $replace = true) {
  355. if(!$replace && isset($this->parameters[$key]))
  356. {
  357. $temp = (array)($this->parameters[$key]);
  358. $temp[] = $value;
  359. $this->parameters[$key] = $temp;
  360. }
  361. else
  362. {
  363. $this->parameters[$key] = $value;
  364. }
  365. }
  366. /**
  367. * Get the response
  368. *
  369. * @return object | false
  370. */
  371. public function getResponse() {
  372. $params = array();
  373. foreach ($this->parameters as $var => $value)
  374. {
  375. if(is_array($value))
  376. {
  377. foreach($value as $v)
  378. {
  379. $params[] = $var.'='.$this->__customUrlEncode($v);
  380. }
  381. }
  382. else
  383. {
  384. $params[] = $var.'='.$this->__customUrlEncode($value);
  385. }
  386. }
  387. sort($params, SORT_STRING);
  388. // must be in format 'Sun, 06 Nov 1994 08:49:37 GMT'
  389. $date = gmdate('D, d M Y H:i:s e');
  390. $query = implode('&', $params);
  391. $headers = array();
  392. $headers[] = 'Date: '.$date;
  393. $headers[] = 'Host: '.$this->ses->getHost();
  394. $auth = 'AWS3-HTTPS AWSAccessKeyId='.$this->ses->getAccessKey();
  395. $auth .= ',Algorithm=HmacSHA256,Signature='.$this->__getSignature($date);
  396. $headers[] = 'X-Amzn-Authorization: '.$auth;
  397. $url = 'https://'.$this->ses->getHost().'/';
  398. // Basic setup
  399. $curl = curl_init();
  400. curl_setopt($curl, CURLOPT_USERAGENT, 'SimpleEmailService/php');
  401. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, ($this->ses->verifyHost() ? 2 : 0));
  402. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, ($this->ses->verifyPeer() ? 1 : 0));
  403. // Request types
  404. switch ($this->verb) {
  405. case 'GET':
  406. $url .= '?'.$query;
  407. break;
  408. case 'POST':
  409. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
  410. curl_setopt($curl, CURLOPT_POSTFIELDS, $query);
  411. $headers[] = 'Content-Type: application/x-www-form-urlencoded';
  412. break;
  413. case 'DELETE':
  414. $url .= '?'.$query;
  415. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  416. break;
  417. default: break;
  418. }
  419. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  420. curl_setopt($curl, CURLOPT_HEADER, false);
  421. curl_setopt($curl, CURLOPT_URL, $url);
  422. curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
  423. curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
  424. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  425. // Execute, grab errors
  426. if (!curl_exec($curl)) {
  427. throw new SimpleEmailServiceException(
  428. pht(
  429. 'Encountered an error while making an HTTP request to Amazon SES '.
  430. '(cURL Error #%d): %s',
  431. curl_errno($curl),
  432. curl_error($curl)));
  433. }
  434. $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  435. if ($this->response->code != 200) {
  436. throw new SimpleEmailServiceException(
  437. pht(
  438. 'Unexpected HTTP status while making request to Amazon SES: '.
  439. 'expected 200, got %s.',
  440. $this->response->code));
  441. }
  442. @curl_close($curl);
  443. // Parse body into XML
  444. if ($this->response->error === false && isset($this->response->body)) {
  445. $this->response->body = simplexml_load_string($this->response->body);
  446. // Grab SES errors
  447. if (!in_array($this->response->code, array(200, 201, 202, 204))
  448. && isset($this->response->body->Error)) {
  449. $error = $this->response->body->Error;
  450. $output = array();
  451. $output['curl'] = false;
  452. $output['Error'] = array();
  453. $output['Error']['Type'] = (string)$error->Type;
  454. $output['Error']['Code'] = (string)$error->Code;
  455. $output['Error']['Message'] = (string)$error->Message;
  456. $output['RequestId'] = (string)$this->response->body->RequestId;
  457. $this->response->error = $output;
  458. unset($this->response->body);
  459. }
  460. }
  461. return $this->response;
  462. }
  463. /**
  464. * CURL write callback
  465. *
  466. * @param resource &$curl CURL resource
  467. * @param string &$data Data
  468. * @return integer
  469. */
  470. private function __responseWriteCallback(&$curl, &$data) {
  471. if(!isset($this->response->body)) $this->response->body = '';
  472. $this->response->body .= $data;
  473. return strlen($data);
  474. }
  475. /**
  476. * Contributed by afx114
  477. * URL encode the parameters as per http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?Query_QueryAuth.html
  478. * 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
  479. * See: http://www.morganney.com/blog/API/AWS-Product-Advertising-API-Requires-a-Signed-Request.php
  480. *
  481. * @param string $var String to encode
  482. * @return string
  483. */
  484. private function __customUrlEncode($var) {
  485. return str_replace('%7E', '~', rawurlencode($var));
  486. }
  487. /**
  488. * Generate the auth string using Hmac-SHA256
  489. *
  490. * @internal Used by SimpleDBRequest::getResponse()
  491. * @param string $string String to sign
  492. * @return string
  493. */
  494. private function __getSignature($string) {
  495. return base64_encode(hash_hmac('sha256', $string, $this->ses->getSecretKey(), true));
  496. }
  497. }
  498. final class SimpleEmailServiceMessage {
  499. // these are public for convenience only
  500. // these are not to be used outside of the SimpleEmailService class!
  501. public $to, $cc, $bcc, $replyto;
  502. public $from, $returnpath;
  503. public $subject, $messagetext, $messagehtml;
  504. public $subjectCharset, $messageTextCharset, $messageHtmlCharset;
  505. function __construct() {
  506. $to = array();
  507. $cc = array();
  508. $bcc = array();
  509. $replyto = array();
  510. $from = null;
  511. $returnpath = null;
  512. $subject = null;
  513. $messagetext = null;
  514. $messagehtml = null;
  515. $subjectCharset = null;
  516. $messageTextCharset = null;
  517. $messageHtmlCharset = null;
  518. }
  519. /**
  520. * addTo, addCC, addBCC, and addReplyTo have the following behavior:
  521. * If a single address is passed, it is appended to the current list of addresses.
  522. * If an array of addresses is passed, that array is merged into the current list.
  523. */
  524. function addTo($to) {
  525. if(!is_array($to)) {
  526. $this->to[] = $to;
  527. }
  528. else {
  529. $this->to = array_merge($this->to, $to);
  530. }
  531. }
  532. function addCC($cc) {
  533. if(!is_array($cc)) {
  534. $this->cc[] = $cc;
  535. }
  536. else {
  537. $this->cc = array_merge($this->cc, $cc);
  538. }
  539. }
  540. function addBCC($bcc) {
  541. if(!is_array($bcc)) {
  542. $this->bcc[] = $bcc;
  543. }
  544. else {
  545. $this->bcc = array_merge($this->bcc, $bcc);
  546. }
  547. }
  548. function addReplyTo($replyto) {
  549. if(!is_array($replyto)) {
  550. $this->replyto[] = $replyto;
  551. }
  552. else {
  553. $this->replyto = array_merge($this->replyto, $replyto);
  554. }
  555. }
  556. function setFrom($from) {
  557. $this->from = $from;
  558. }
  559. function setReturnPath($returnpath) {
  560. $this->returnpath = $returnpath;
  561. }
  562. function setSubject($subject) {
  563. $this->subject = $subject;
  564. }
  565. function setSubjectCharset($charset) {
  566. $this->subjectCharset = $charset;
  567. }
  568. function setMessageFromString($text, $html = null) {
  569. $this->messagetext = $text;
  570. $this->messagehtml = $html;
  571. }
  572. function setMessageFromFile($textfile, $htmlfile = null) {
  573. if(file_exists($textfile) && is_file($textfile) && is_readable($textfile)) {
  574. $this->messagetext = file_get_contents($textfile);
  575. }
  576. if(file_exists($htmlfile) && is_file($htmlfile) && is_readable($htmlfile)) {
  577. $this->messagehtml = file_get_contents($htmlfile);
  578. }
  579. }
  580. function setMessageFromURL($texturl, $htmlurl = null) {
  581. $this->messagetext = file_get_contents($texturl);
  582. if($htmlurl !== null) {
  583. $this->messagehtml = file_get_contents($htmlurl);
  584. }
  585. }
  586. function setMessageCharset($textCharset, $htmlCharset = null) {
  587. $this->messageTextCharset = $textCharset;
  588. $this->messageHtmlCharset = $htmlCharset;
  589. }
  590. /**
  591. * Validates whether the message object has sufficient information to submit a request to SES.
  592. * This does not guarantee the message will arrive, nor that the request will succeed;
  593. * instead, it makes sure that no required fields are missing.
  594. *
  595. * This is used internally before attempting a SendEmail or SendRawEmail request,
  596. * but it can be used outside of this file if verification is desired.
  597. * May be useful if e.g. the data is being populated from a form; developers can generally
  598. * use this function to verify completeness instead of writing custom logic.
  599. *
  600. * @return boolean
  601. */
  602. public function validate() {
  603. if(count($this->to) == 0)
  604. return false;
  605. if($this->from == null || strlen($this->from) == 0)
  606. return false;
  607. if($this->messagetext == null)
  608. return false;
  609. return true;
  610. }
  611. }
  612. /**
  613. * Thrown by SimpleEmailService when errors occur if you call
  614. * enableUseExceptions(true).
  615. */
  616. final class SimpleEmailServiceException extends Exception {
  617. }