Utklippstavle
Valgmuligheter
ZtigO sendte inn denne php-koden 23.07.2009 kl. 13:02.
<?php /** * nerdMail class * @author Stig Magnus Halvorsen (ZtigO) * @version 1.0.2 * * http://nerdvar.com/ * * A class using PHPs mail() function to send * emails as text and/or HTML with or without * attachments. Highly customizeable headers * and with a emailadress validator and anti * email injection function. */ class nerdMail { /** * define the required variables */ public $text; public $html; public $subject; public $sender; public $returnPath; protected $receivers = array(); protected $Cc = array(); protected $Bcc = array(); protected $headers = array("keys" => array(), "values" => array()); protected $headerKeys = array(); protected $attachments = array(); /** * The list of accepted encoding of attachments * default is BASE64 * Must be uppercase! */ protected $enctypes = array("OCTET", "BASE64", "TEXT", "BIT7"); /** * The list of not overrideable headers * To prevent different unwanted results * The standards shouldn't be removed * Must be uppercase! */ protected $protectedHeaders = array("TO", "CC", "BCC", "FROM", "SUBJECT", "CONTENT-TYPE"); /** * function $this->parseMail() or nerdMail::parseMail() * Based upon Hellkeepa's Val_email() function * Validates the email with a regular expression, then * checks if the mail server exists using checkdnsrr() * * @param string $email * @return boolean */ public static function parseMail($email) { $RegExp = "/^[a-z][\\w\\pL\\.-]*[a-z0-9]@[a-z0-9][\\w\\pL\\.-]*[a-z0-9]\\.[a-z][a-z\\.]*[a-z]\\z/ui"; if (preg_match ($RegExp, $email)) { $domain = explode("@", $email); $mailserver = $domain[(count($domain) - 1)]; if (checkdnsrr($mailserver, 'MX')) { return true; } } return false; } /** function $this->antiInjection or nerdMail::antiInjection * looks for email injection attempts in $field by checking * for line breaks and horizontal tabs * * @param string|int $field * @return boolean */ public static function antiInjection ($field) { if (preg_match("(\r|\n)", $field)) { return true; } else { return false; } } /** function $this->addMail * type: to, cc or bcc * email: address to add * parse: true -> validate $email * * Use it to populate the list of recipients * to for regular recievers, cc for carbon copy * and bcc for blind carbon copy * * @param "to"|"cc"|"bcc" $type["to"] * @param string $email * @param boolean $parse[false] * @return boolean */ public function addMail($type, $email, $parse = false) { if (empty($email)) { return false; } if ($parse) { if (!$this->parseMail($email)) { return false; } } else { if ($this->antiInjection($email)) { return $email; } } switch ($type) { case "to": $this->receivers[] = $email; break; case "cc": $this->Cc[] = $email; break; case "bcc": $this->receivers[] = $email; break; default: $this->receivers[] = $email; } return true; } /** function $this->addHeader * Use it to add extra headers or to * override the nerdMail default ones * * Examples: * $this->addHeader("List-Unsubscribe", "<http://nerdvar.com/unsubscripe.php>"); * $this->addHeader("Message-Id: 123xxx@nerdvar.com"); * * @param string $key * @param boolean $val[false] * @return boolean */ public function addHeader ($key, $val = false) { if (empty($key) || empty($val)) { return false; } /** Check for injectionattempt */ if ($this->antiInjection($key) or $this->antiInjection($val)) { return false; } if ($val == false) { $val = explode(":", $key); $key = $val[0]; $val = $val[1]; } else { if (substr($key, -1) == ":") { $key = substr($key, 0, -1); } } if (substr($key, -1) == ":") { $key = substr($key, 0, -1); } $this->headers["keys"][] = $key; $this->headerKeys[] = strtolower($key); $this->headers["values"][] = $val; return true; } /** function $this->attach * filePath: http://example.com/myfile.jpg, myfile.txt, etc * contenttype: image/jpeg, plain/text, etc.. * encoding: BASE64, BIT7, etc.. Must be in $enctypes array * * Adds and validates file to attach in the attachment list * * @param string $filePath * @param string $contenttype["OCTET"] * @param string $encoding["BASE64"] * @return boolean */ public function attach ($filePath, $contenttype = "OCTET", $encoding = "BASE64") { if (empty($filePath)) { return false; } if (trim($contenttype) == "") { $contenttype = "OCTET"; } if (trim($encoding) == "") { $encoding = "BASE64"; } $data = file_get_contents($filePath); if ($data) { $thisEnc = strtolower($encoding); if ((strtoupper($encoding) == "BASE64") or (!in_array(strtoupper($encoding), $this->enctypes))) { $data = base64_encode($data); $thisEnc = "base64"; } $this->attachments["encoding"][] = $thisEnc; $this->attachments["data"][] = chunk_split($data); $this->attachments["name"][] = basename($filePath); if (preg_match("!^".TEXT."!i", $contenttype) && !preg_match("!;charset=!i", $contenttype)) { $this->attachments["cType"][] = "text/plain; charset=UTF-8"; } elseif ($contenttype == OCTET) { $this->attachments["cType"][] = "application/octet-stream"; } else { $this->attachments["cType"][] = $contenttype; } unset($data); return true; } else { unset($data); return false; } } /** function $this->send * This completes the mailing by putting it all togheter and * sending it out. Returns false on failure and fails if it's * missing some required vars * * @return mixed */ public function send() { $sendData = array(); $headerKeys = array(); $i = 0; /** Define the multipart email hdr info */ $boundary1 = rand(0,9)."-".rand(10000000000,999999999)."-".rand(10000000000,999999999)."=:".rand(10000,99999); $boundary2 = rand(0,9)."-".rand(10000000000,999999999)."-".rand(10000000000,999999999)."=:".rand(10000,99999); /** Check wether it's any attachments or not and sets multitype */ if (count($this->attachments["name"]) > 0) { $multiType = "mixed"; $attach = true; } else { $multiType = "alternative"; $attach = false; } /** Verify that the required variables are set */ if (empty($this->sender) or ((count($this->receivers) == 0) && (count($this->Cc) == 0) && (count($this->Bcc) == 0)) or (empty($this->text) && empty($this->html))) { return false; } /** Validate Subject */ if (empty($this->subject) or $this->antiInjection($this->subject)) { $this->subject = "(No subject)"; } /** Add the receivers */ while ($i < count($this->receivers)) { $sendData["receivers"] .= $this->receivers[$i]; $i++; if ($i != count($this->receivers)) { $sendData["receivers"] .= ", "; } } $i = 0; /** Add the Carbon Copy receivers (CC) */ while ($i < count($this->Cc)) { $sendData["Cc"] .= $this->Cc[$i]; $i++; if ($i != count($this->Cc)) { $sendData["Cc"] .= ", "; } } $i = 0; /** Add the Blind Carbon Copy receivers */ while ($i < count($this->Bcc)) { $sendData["Bcc"] .= $this->Bcc[$i]; $i++; if ($i != count($this->Bcc)) { $sendData["Bcc"] .= ", "; } } $i = 0; /** Add the Headers **/ if (!in_array("mime-version", $this->headerKeys)) { $headers .= "MIME-Version: 1.0\r\n"; } $headers .= "Content-Type: multipart/$multiType; boundary=\"$boundary1\"\r\n"; $headers .= "From: ".$this->sender."\r\n"; if (!in_array("reply-to", $this->headerKeys)) { $headers .= "Reply-To: ".$this->sender."\r\n"; } if (count($this->headers["keys"]) > 0) { while ($i < count($this->headers["keys"])) { /** Make sure the header isn't in the blocked list */ if (!in_array(strtoupper($this->headers["keys"][$i]), $this->protectedHeaders)) { $headers .= $this->headers["keys"][$i].": ".$this->headers["values"][$i]."\r\n"; } $i++; } $i = 0; } if ($sendData["Cc"]) { $headers .= "Cc: ".$sendData["Cc"]."\r\n"; } if ($sendData["Bc"]) { $headers .= "Bcc: ".$sendData["Cc"]."\r\n"; } $headers .= "\n"; /** Add the mail body */ if (!$attach) { $body = "MIME-Version: 1.0\r\nContent-Type: multipart/alternative; boundary=\"$boundary1\"\r\n\r\n"; if (!empty($this->text)) { $body .= "--$boundary1\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->text."\n\n"; } if (!empty($this->html)) { $body .= "--$boundary1\nContent-Type: text/html; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->html."\n\n"; } } else { $body = "--$boundary1\nContent-Type: multipart/alternative; boundary=\"$boundary2\"\r\n\r\n"; if (!empty($this->text)) { $body .= "--$boundary2\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->text."\n\n"; } if (!empty($this->html)) { $body .= "--$boundary2\nContent-Type: text/html; charset=UTF-8\nContent-Transfer-Encoding: 7bit\n\n".$this->html."\n\n"; } $body .= "--$boundary2--\n\n"; /** Add attachments */ while ($i < count($this->attachments["name"])) { $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"; $body .= $this->attachments["data"][$i]; $i++; } $i = 0; } $body .= "--$boundary1--"; /** Send the final mail */ if (!empty($this->returnPath) && $this->parseMail($this->returnPath)) { return mail($sendData["receivers"], $this->subject, $body, $headers, "-f".$this->returnPath); } else { return mail($sendData["receivers"], $this->subject, $body, $headers); } } } /** checkdnsrr() FUNCTION FOR WINDOWS SERVER WITH PHP VERSIONS LOWER THAN 5.3 * Checks for existence and creates the function if it doesn't, parameter * data is validated to avoid shell injection * * It's being used by the $nerdMail->pasreMail() function * * @param string $hostName * @param string $recType[""] * @return boolean */ if (!function_exists('checkdnsrr')) { /** List of accepted recTypes */ $accepted = array('A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'); function checkdnsrr($hostName, $recType = "") { global $accepted; if(!empty($hostName)) { /** validate the recType */ if(!in_array($recType, $accepted)) $recType = "MX"; /** Validate domain/host name */ if (gethostbynamel($hostName) or gethostbynamel(gethostbyaddr($hostName))) { @exec("nslookup -type=$recType $hostName", $result); foreach ($result as $line) { if(preg_match("^$hostName",$line)) { return true; } } } return false; } return false; } } ?>
