Utklippstavle

Legg inn en helt ny kode

Valgmuligheter

ZtigO sendte inn denne php-koden 23.07.2009 kl. 13:02.

  1. <?php
  2. /**
  3.  * nerdMail class
  4.  * @author Stig Magnus Halvorsen (ZtigO)
  5.  * @version 1.0.2
  6.  *
  7.  * http://nerdvar.com/
  8.  *
  9.  * A class using PHPs mail() function to send
  10.  * emails as text and/or HTML with or without
  11.  * attachments. Highly customizeable headers
  12.  * and with a emailadress validator and anti
  13.  * email injection function.
  14. */
  15. class nerdMail {
  16. /**
  17.   * define the required variables
  18.   */
  19. public $text;
  20. public $html;
  21. public $subject;
  22. public $sender;
  23. public $returnPath;
  24. protected $receivers = array();
  25. protected $Cc = array();
  26. protected $Bcc = array();
  27. protected $headers = array("keys" => array(), "values" => array());
  28. protected $headerKeys = array();
  29. protected $attachments = array();
  30.  
  31. /**
  32.   * The list of accepted encoding of attachments
  33.   * default is BASE64
  34.   * Must be uppercase!
  35.   */
  36. protected $enctypes = array("OCTET", "BASE64", "TEXT", "BIT7");
  37.  
  38. /**
  39.   * The list of not overrideable headers
  40.   * To prevent different unwanted results
  41.   * The standards shouldn't be removed
  42.   * Must be uppercase!
  43.   */
  44. protected $protectedHeaders = array("TO", "CC", "BCC", "FROM", "SUBJECT", "CONTENT-TYPE");
  45.  
  46. /**
  47.   * function $this->parseMail() or nerdMail::parseMail()
  48.   * Based upon Hellkeepa's Val_email() function
  49.   * Validates the email with a regular expression, then
  50.   * checks if the mail server exists using checkdnsrr()
  51.   *
  52.   * @param string $email
  53.   * @return boolean
  54.  */
  55. public static function parseMail($email) {
  56. $RegExp = "/^[a-z][\\w\\pL\\.-]*[a-z0-9]@[a-z0-9][\\w\\pL\\.-]*[a-z0-9]\\.[a-z][a-z\\.]*[a-z]\\z/ui";
  57.  
  58. if (preg_match ($RegExp, $email)) {
  59. $domain = explode("@", $email);
  60. $mailserver = $domain[(count($domain) - 1)];
  61.  
  62. if (checkdnsrr($mailserver, 'MX')) {
  63. return true;
  64. }
  65. }
  66.  
  67. return false;
  68. }
  69.  
  70. /** function $this->antiInjection or nerdMail::antiInjection
  71.   * looks for email injection attempts in $field by checking
  72.   * for line breaks and horizontal tabs
  73.   *
  74.   * @param string|int $field
  75.   * @return boolean
  76.   */
  77. public static function antiInjection ($field) {
  78. if (preg_match("(\r|\n)", $field)) {
  79. return true;
  80. } else {
  81. return false;
  82. }
  83. }
  84.  
  85. /** function $this->addMail
  86.   * type: to, cc or bcc
  87.   * email: address to add
  88.   * parse: true -> validate $email
  89.   *
  90.   * Use it to populate the list of recipients
  91.   * to for regular recievers, cc for carbon copy
  92.   * and bcc for blind carbon copy
  93.   *
  94.   * @param "to"|"cc"|"bcc" $type["to"]
  95.   * @param string $email
  96.   * @param boolean $parse[false]
  97.   * @return boolean
  98.   */
  99. public function addMail($type, $email, $parse = false) {
  100. if (empty($email)) {
  101. return false;
  102. }
  103.  
  104. if ($parse) {
  105. if (!$this->parseMail($email)) {
  106. return false;
  107. }
  108. } else {
  109. if ($this->antiInjection($email)) {
  110. return $email;
  111. }
  112. }
  113.  
  114. switch ($type) {
  115. case "to":
  116. $this->receivers[] = $email;
  117. break;
  118. case "cc":
  119. $this->Cc[] = $email;
  120. break;
  121. case "bcc":
  122. $this->receivers[] = $email;
  123. break;
  124. default:
  125. $this->receivers[] = $email;
  126. }
  127. return true;
  128. }
  129.  
  130. /** function $this->addHeader
  131.   * Use it to add extra headers or to
  132.   * override the nerdMail default ones
  133.   *
  134.   * Examples:
  135.   * $this->addHeader("List-Unsubscribe", "<http://nerdvar.com/unsubscripe.php>");
  136.   * $this->addHeader("Message-Id: 123xxx@nerdvar.com");
  137.   *
  138.   * @param string $key
  139.   * @param boolean $val[false]
  140.   * @return boolean
  141.   */
  142. public function addHeader ($key, $val = false) {
  143. if (empty($key) || empty($val)) {
  144. return false;
  145. }
  146.  
  147. /** Check for injectionattempt */
  148. if ($this->antiInjection($key) or $this->antiInjection($val)) {
  149. return false;
  150. }
  151.  
  152. if ($val == false) {
  153. $val = explode(":", $key);
  154. $key = $val[0];
  155. $val = $val[1];
  156. } else {
  157. if (substr($key, -1) == ":") {
  158. $key = substr($key, 0, -1);
  159. }
  160. }
  161.  
  162. if (substr($key, -1) == ":") { $key = substr($key, 0, -1); }
  163.  
  164. $this->headers["keys"][] = $key;
  165. $this->headerKeys[] = strtolower($key);
  166. $this->headers["values"][] = $val;
  167. return true;
  168. }
  169.  
  170. /** function $this->attach
  171.   * filePath: http://example.com/myfile.jpg, myfile.txt, etc
  172.   * contenttype: image/jpeg, plain/text, etc..
  173.   * encoding: BASE64, BIT7, etc.. Must be in $enctypes array
  174.   *
  175.   * Adds and validates file to attach in the attachment list
  176.   *
  177.   * @param string $filePath
  178.   * @param string $contenttype["OCTET"]
  179.   * @param string $encoding["BASE64"]
  180.   * @return boolean
  181.   */
  182. public function attach ($filePath, $contenttype = "OCTET", $encoding = "BASE64") {
  183. if (empty($filePath)) {
  184. return false;
  185. }
  186. if (trim($contenttype) == "") {
  187. $contenttype = "OCTET";
  188. }
  189. if (trim($encoding) == "") {
  190. $encoding = "BASE64";
  191. }
  192.  
  193. $data = file_get_contents($filePath);
  194.  
  195. if ($data) {
  196. $thisEnc = strtolower($encoding);
  197. if ((strtoupper($encoding) == "BASE64") or (!in_array(strtoupper($encoding), $this->enctypes))) {
  198. $data = base64_encode($data);
  199. $thisEnc = "base64";
  200. }
  201.  
  202. $this->attachments["encoding"][] = $thisEnc;
  203. $this->attachments["data"][] = chunk_split($data);
  204. $this->attachments["name"][] = basename($filePath);
  205.  
  206. if (preg_match("!^".TEXT."!i", $contenttype) && !preg_match("!;charset=!i", $contenttype)) {
  207. $this->attachments["cType"][] = "text/plain; charset=UTF-8";
  208. }
  209. elseif ($contenttype == OCTET) {
  210. $this->attachments["cType"][] = "application/octet-stream";
  211. } else {
  212. $this->attachments["cType"][] = $contenttype;
  213. }
  214.  
  215. unset($data);
  216. return true;
  217. } else {
  218. unset($data);
  219. return false;
  220. }
  221. }
  222.  
  223. /** function $this->send
  224.   * This completes the mailing by putting it all togheter and
  225.   * sending it out. Returns false on failure and fails if it's
  226.   * missing some required vars
  227.   *
  228.   * @return mixed
  229.   */
  230. public function send() {
  231. $sendData = array();
  232. $headerKeys = array();
  233. $i = 0;
  234.  
  235. /** Define the multipart email hdr info */
  236. $boundary1 = rand(0,9)."-".rand(10000000000,999999999)."-".rand(10000000000,999999999)."=:".rand(10000,99999);
  237. $boundary2 = rand(0,9)."-".rand(10000000000,999999999)."-".rand(10000000000,999999999)."=:".rand(10000,99999);
  238.  
  239. /** Check wether it's any attachments or not and sets multitype */
  240. if (count($this->attachments["name"]) > 0) {
  241. $multiType = "mixed"; $attach = true;
  242. } else {
  243. $multiType = "alternative"; $attach = false;
  244. }
  245.  
  246. /** Verify that the required variables are set */
  247. if (empty($this->sender) or ((count($this->receivers) == 0) && (count($this->Cc) == 0) && (count($this->Bcc) == 0)) or (empty($this->text) && empty($this->html))) {
  248. return false;
  249. }
  250.  
  251. /** Validate Subject */
  252. if (empty($this->subject) or $this->antiInjection($this->subject)) {
  253. $this->subject = "(No subject)";
  254. }
  255.  
  256. /** Add the receivers */
  257. while ($i < count($this->receivers)) {
  258. $sendData["receivers"] .= $this->receivers[$i];
  259. $i++;
  260.  
  261. if ($i != count($this->receivers)) {
  262. $sendData["receivers"] .= ", ";
  263. }
  264. }
  265. $i = 0;
  266.  
  267. /** Add the Carbon Copy receivers (CC) */
  268. while ($i < count($this->Cc)) {
  269. $sendData["Cc"] .= $this->Cc[$i];
  270. $i++;
  271.  
  272. if ($i != count($this->Cc)) {
  273. $sendData["Cc"] .= ", ";
  274. }
  275. }
  276. $i = 0;
  277.  
  278. /** Add the Blind Carbon Copy receivers */
  279. while ($i < count($this->Bcc)) {
  280. $sendData["Bcc"] .= $this->Bcc[$i];
  281. $i++;
  282.  
  283. if ($i != count($this->Bcc)) {
  284. $sendData["Bcc"] .= ", ";
  285. }
  286. }
  287. $i = 0;
  288.  
  289. /** Add the Headers **/
  290. if (!in_array("mime-version", $this->headerKeys)) {
  291. $headers .= "MIME-Version: 1.0\r\n";
  292. }
  293.  
  294. $headers .= "Content-Type: multipart/$multiType; boundary=\"$boundary1\"\r\n";
  295. $headers .= "From: ".$this->sender."\r\n";
  296.  
  297. if (!in_array("reply-to", $this->headerKeys)) {
  298. $headers .= "Reply-To: ".$this->sender."\r\n";
  299. }
  300.  
  301. if (count($this->headers["keys"]) > 0) {
  302. while ($i < count($this->headers["keys"])) {
  303. /** Make sure the header isn't in the blocked list */
  304. if (!in_array(strtoupper($this->headers["keys"][$i]), $this->protectedHeaders)) {
  305. $headers .= $this->headers["keys"][$i].": ".$this->headers["values"][$i]."\r\n";
  306. }
  307. $i++;
  308. }
  309. $i = 0;
  310. }
  311.  
  312. if ($sendData["Cc"]) {
  313. $headers .= "Cc: ".$sendData["Cc"]."\r\n";
  314. }
  315. if ($sendData["Bc"]) {
  316. $headers .= "Bcc: ".$sendData["Cc"]."\r\n";
  317. }
  318.  
  319. $headers .= "\n";
  320.  
  321. /** Add the mail body */
  322. if (!$attach) {
  323. $body = "MIME-Version: 1.0\r\nContent-Type: multipart/alternative; boundary=\"$boundary1\"\r\n\r\n";
  324.  
  325. if (!empty($this->text)) {
  326. $body .= "--$boundary1\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->text."\n\n";
  327. }
  328. if (!empty($this->html)) {
  329. $body .= "--$boundary1\nContent-Type: text/html; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->html."\n\n";
  330. }
  331. } else {
  332. $body = "--$boundary1\nContent-Type: multipart/alternative; boundary=\"$boundary2\"\r\n\r\n";
  333.  
  334. if (!empty($this->text)) {
  335. $body .= "--$boundary2\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->text."\n\n";
  336. }
  337. if (!empty($this->html)) {
  338. $body .= "--$boundary2\nContent-Type: text/html; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->html."\n\n";
  339. }
  340. $body .= "--$boundary2--\n\n";
  341.  
  342. /** Add attachments */
  343. while ($i < count($this->attachments["name"])) {
  344. $body .= "--$boundary1\nContent-Type: ".$this->attachments["cType"][$i]."; name=\"".$this->attachments["name"][$i]."\"\nContent-Transfer-Encoding: ".$this->attachments["encoding"][$i]."\nContent-Disposition: attachment; filename=\"".$this->attachments["name"][$i]."\"\n\n";
  345. $body .= $this->attachments["data"][$i];
  346. $i++;
  347. }
  348. $i = 0;
  349. }
  350.  
  351. $body .= "--$boundary1--";
  352.  
  353. /** Send the final mail */
  354. if (!empty($this->returnPath) && $this->parseMail($this->returnPath)) {
  355. return mail($sendData["receivers"], $this->subject, $body, $headers, "-f".$this->returnPath);
  356. }
  357. else {
  358. return mail($sendData["receivers"], $this->subject, $body, $headers);
  359. }
  360. }
  361. }
  362.  
  363. /** checkdnsrr() FUNCTION FOR WINDOWS SERVER WITH PHP VERSIONS LOWER THAN 5.3
  364.   * Checks for existence and creates the function if it doesn't, parameter
  365.   * data is validated to avoid shell injection
  366.   *
  367.   * It's being used by the $nerdMail->pasreMail() function
  368.   *
  369.   * @param string $hostName
  370.   * @param string $recType[""]
  371.   * @return boolean
  372. */
  373. if (!function_exists('checkdnsrr')) {
  374. /** List of accepted recTypes */
  375. $accepted = array('A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY');
  376.  
  377. function checkdnsrr($hostName, $recType = "") {
  378. global $accepted;
  379.  
  380. if(!empty($hostName)) {
  381. /** validate the recType */
  382. if(!in_array($recType, $accepted)) $recType = "MX";
  383.  
  384. /** Validate domain/host name */
  385. if (gethostbynamel($hostName) or gethostbynamel(gethostbyaddr($hostName))) {
  386. @exec("nslookup -type=$recType $hostName", $result);
  387.  
  388. foreach ($result as $line) {
  389. if(preg_match("^$hostName",$line)) {
  390. return true;
  391. }
  392. }
  393. }
  394. return false;
  395. }
  396. return false;
  397. }
  398. }
  399. ?>

Tilbake til toppen ^

Emneord (tags): php, class, mail, epost, vedlegg