home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 4 / hacker04 / 04_HACK04.ISO / src / PHP / phpmailinglist.php3.txt < prev    next >
Encoding:
Text File  |  2002-05-06  |  15.0 KB  |  355 lines

  1. PHP mailing list 
  2.  
  3. Users sign up on one page w/name and email. Email is checked for auth. Name and email added to Mysql database. "Broadcaster" fills out a form page with header, body, and footer of the email. Header and footer are saved for later. Mail is sent to all users in the database with a personal "Dear (name they entered)" at the top of the email. Sender can upload text, log off, and the script will continue to send out all emails. Sleep function for slowing down send rate. Log file written upon script completion of unsendable emails. Uses php mail() function (sendmail). 
  4.  
  5.  
  6. <?php 
  7. ////////////////// mailing_list.php3 ///////////////////////// 
  8. /////////////////////////  SIGNUP PAGE /////////////////////////////////////////////////////// 
  9. /* All code by David Fox except validateEmail function 
  10.    Use it happily, anywhere, with credits. 
  11.     
  12.    You use this signup with send_mailing_list.php3 which sends the newsletter. 
  13.     
  14.    What would be really cool, since the letters will already be customized w/ the users name (if they enter it), is 
  15.    another database table with user preferences linked to the mailing_list table. That would allow you to program some 
  16.    cool stuff in send_mailing_list.php3 to add even more personalization... such as new products, headlines, whatever 
  17.    the user actually wants to see. You could put checkboxes or dropdowns in here to select stuff. 
  18.     
  19.    REQUIRED: 
  20.    MySQL table creation SQL: 
  21.                       
  22.    CREATE TABLE mailing_list (id INT(30) NOT NULL PRIMARY KEY AUTO_INCREMENT, email VARCHAR(100) NOT NULL, name VARCHAR(100), timestamp TIMESTAMP, UNIQUE (email)); 
  23.  
  24.  
  25.    validateEmail function 
  26.    By: Jon S. Stevens jon@clearink.com 
  27.    Copyright 1998 Jon S. Stevens, Clear Ink 
  28.    This code has all the normal disclaimers. 
  29.    It is free for any use, just keep the credits intact. 
  30.    It will return an array. $return[0] is whether it was a valid  
  31.    email or not and $return[1] is the SMTP error message if there was one.*/ 
  32.     
  33. function validateEmail ($email){    
  34.    global $SERVER_NAME; 
  35.     
  36.    $return = array(false,  "" ); 
  37.    list ($user, $domain) = split( "@", $email, 2); 
  38.    $arr = explode( ".", $domain);    
  39.    $count = count ($arr); 
  40.    $tld = $arr[$count - 2] .  "." . $arr[$count - 1]; 
  41.    if(checkdnsrr($tld,  "MX")) { 
  42.       if(getmxrr($tld, $mxhosts, $weight)) { 
  43.          for($i = 0; $i < count($mxhosts); $i++){ 
  44.                $fp = fsockopen($mxhosts[$i], 25); 
  45.             if ($fp){ 
  46.                $s = 0; 
  47.                $c = 0; 
  48.                $out =  ""; 
  49.                set_socket_blocking($fp, false); 
  50.                do { 
  51.                   $out = fgets($fp, 2500); 
  52.                   if(ereg( "^220", $out)){ 
  53.                            $s = 0; 
  54.                      $out =  ""; 
  55.                      $c++; 
  56.                   } 
  57.                   else if(($c > 0) && ($out ==  "")){  
  58.                      break;  
  59.                   } 
  60.                   else {  
  61.                      $s++; 
  62.                   } 
  63.                   if($s == 9999) {  
  64.                      break; 
  65.                   } 
  66.                } while($out ==  ""); 
  67.                set_socket_blocking($fp, true); 
  68.                fputs($fp,  "HELO $SERVER_NAME\n"); 
  69.                $output = fgets ($fp, 2000); 
  70.                fputs($fp,  "MAIL FROM: <info@" . $tld .  ">\n" ); 
  71.                $output = fgets($fp, 2000); 
  72.                fputs($fp,  "RCPT TO: <$email>\n");             
  73.                $output = fgets($fp, 2000); 
  74.                if(ereg(  "^250", $output )) { 
  75.                   $return[0] = true; 
  76.                }  
  77.                else { 
  78.                   $return[0] = false; 
  79.                   $return[1] = $output; 
  80.                } 
  81.                fputs ($fp,  "QUIT\n"); 
  82.                fclose($fp); 
  83.                if($return[0] == true){  
  84.                   break;  
  85.                } 
  86.             } 
  87.          } 
  88.       } 
  89.    } 
  90.    return $return; 
  91.  
  92. // format the email body so it has soft returns after set number chars 
  93. function format_mail($str, $char_len) { 
  94.     // $char_len = number of characters till return 
  95.    $str = stripslashes($str); 
  96.    while(strlen($str) != 0) { 
  97.       $len = strrpos(substr($str, 0, $char_len - 1),  " "); 
  98.        // in case of no spaces 
  99.       if(!$len) {  
  100.          $len = $char_len - 1; 
  101.       } 
  102.    $str_out .= substr($str, 0, $len) .  "\n"; 
  103.    $str = substr($str, $len, strlen($str)); 
  104.    } 
  105.    return $str_out; 
  106.  
  107. ////////////// END FUNCTIONS //////////////////////////////// 
  108.  
  109. define( "SENDER",  "newsletter@mydomin.com"); 
  110. define( "SUBJECT",  "Newsletter confirmation email"); 
  111.  
  112. define( "DATABASE",  "mydb"); 
  113. define( "HOST",  "localhost"); 
  114. define( "USER",  "httpd"); 
  115. define( "PASSWORD",  ""); 
  116.  
  117. // It would make sense to put this into a file... maybe so you could build an administrative interface to change it... 
  118. $body =  "This is a confirmation email to verify your subscription to the newsletter."; 
  119.  
  120. // put in carriage returns so email is cool.. wrap at 76 chars 
  121. $body = format_mail($body, 76); 
  122.  
  123. if($action){ 
  124.    if($address) { 
  125.        // does it at least LOOK like an email address? 
  126.       if(eregi( "([_\.0-9a-z-]+@)([0-9a-z][0-9a-z-]+\.)+([a-z]{2,3})", $address)) { 
  127.           // it does.. lets see if it REALLY is w/ Jon's cool function. 
  128.          $ary_address = validateEmail($address); 
  129.           
  130.          if($ary_address[0]) { 
  131.              // it IS an email address... or at least an email server. Put it in the database. 
  132.              // Use replace so we don't duplicate email addresses (unique field).  
  133.             $db_link = @mysql_connect(HOST, USER, PASSWORD)  or $errors[] = mysql_error(); 
  134.             @mysql_select_db(DATABASE, $db_link) or $errors[] = mysql_error(); 
  135.              
  136.              // could set this as the default in the database.. but you'd have to check anyway. 
  137.             if(!$name) { $name =  "Subscriber"; } 
  138.              // SQL 
  139.             $sql =  "REPLACE INTO mailing_list (email, name) VALUES('" . $address .  "','" . $name .  "')"; 
  140.              
  141.             $db_results = @mysql_query($sql, $db_link) or $errors[] = mysql_error(); 
  142.              
  143.              // check for db errors 
  144.             if(!$errors) { 
  145.                $confirm = True; 
  146.                if($confirmation) { 
  147.                    // send confirmation email       
  148.                   if(@mail($address, SUBJECT, $body,  "From: " . SENDER)){ 
  149.                      $message =  "Thank you. You will receive a confirmation email soon to verify your subscription";    
  150.                   } 
  151.                   else { 
  152.                       // couldn't send mail, but db action was OK 
  153.                      $message =  "You have been successfully subscribed, but here was a problem sending your confirmation email.<br>You should, however receive your newsletter soon."; 
  154.                   } 
  155.                } 
  156.                else { 
  157.                   $message =  "Thank you. You should receive your newsletter soon."; 
  158.                } 
  159.             } 
  160.             else { 
  161.                 // db error message 
  162.                $confirm = False; 
  163.                $message =  "There was an error processing your subscription. Please wait a moment, and try again.<br>"; 
  164.             } 
  165.          } 
  166.          else {  
  167.              // validateEmail came back false, display error.  
  168.             $confirm = False; 
  169.             $message =  "Your email address appears to be a valid, but does not respond.<br>"; 
  170.             $message .=  "Please check to see that the address is a valid email address"; 
  171.          } 
  172.       } 
  173.       else { 
  174.           // ereg test failed. It doesn't even LOOK like an email address. 
  175.          $confirm = False; 
  176.          $message =  "This does not appear to be a valid email address.<br>Please check to see that the address has been entered properly.<br>"; 
  177.       } 
  178.    } 
  179.     // they didn't enter anything 
  180.    else { $message =  "You must enter an email address to subscribe!"; } 
  181. else { 
  182.     // default message 
  183.    $message =  "Enter your email address to sign up for the mailing list."; 
  184.  
  185. print( "<center>\n"); 
  186. print($message); 
  187.  
  188. if(!$confirm){ 
  189. // form 
  190. print( "<form action=\"mailing_list.php3\" method=\"post\">\n"); 
  191. print( "<h1>newsletter signup </h1>\n"); 
  192. print( "<table cellspacing=\"2\" cellpadding=\"3\" border=\"1\">\n"); 
  193. print( "<tr><td>Your email address:</td><td><input type=\"text\" name=\"address\" size=\"35\" value=\"" . $address .  "\"></td></tr><br>"); 
  194. print( "<tr><td>Your name:</td><td><input type=\"text\" name=\"name\" size=\"35\" value=\"" . $name .  "\"></td></tr>"); 
  195. print( "<tr align=\"center\"><td colspan=\"2\">Click here to receive a confirmation email  <input type=\"checkbox\" name=\"confirmation\" value=\"true\" checked></td></tr>"); 
  196. print( "<tr align=\"center\" bgcolor=\"#cccccc\"><td colspan=\"2\"><input type=\"submit\" name=\"action\" value=\"signup!\"></td></tr></table>"); 
  197. print( "</form><center>"); 
  198. ?> 
  199. <?php 
  200. /////////////////// send_mailing_list.php3 ///////////////////////// 
  201. /*    Quick broadcast mailing list sender. Works with mailing_list.php3 
  202.    Code by David Fox. 
  203.    Use it happily, anywhere, with credits.  
  204.    Better yet.. expand it into something better */ 
  205.  
  206. function format_mail($str, $char_len) { 
  207.     // $char_len = number of characters till return 
  208.    $str = stripslashes($str); 
  209.    while(strlen($str) != 0) { 
  210.       $len = strrpos(substr($str, 0, $char_len - 1),  " "); 
  211.        // in case of no spaces 
  212.       if(!$len) {  
  213.          $len = $char_len - 1; 
  214.       } 
  215.    $str_out .= substr($str, 0, $len) .  "\n"; 
  216.    $str = substr($str, $len, strlen($str)); 
  217.    } 
  218.    return $str_out; 
  219. ////////////// END FUNCTIONS //////////////////////////////// 
  220.  
  221. define( "SENDER",  "newsletter@mydomain.com"); 
  222.  
  223. define( "DATABASE",  "mydb"); 
  224. define( "HOST",  "localhost"); 
  225. define( "USER",  "httpd"); 
  226. define( "PASSWORD",  ""); 
  227. define( "SLEEP", 1);  // amount of seconds to sleep between mailings. Usefull for mellowing out your mailing rate to be nice to the server. Can be zero. 
  228. // the script is set to contiue executing after you log off.. so set and forget. 
  229.  
  230. // where you want the header and footer files to live 
  231. define( "NEWSLETTER_FILE_PATH",  "text/"); 
  232.  
  233. if($action && $subject && $body) { 
  234.     // save the header and footer for later 
  235.    if($file = @fopen(NEWSLETTER_FILE_PATH .  "news_header.txt",  "w")) { 
  236.       if(!@fputs($file, $header)) { 
  237.          print( "Header file could not be written to.<br>"); 
  238.       } 
  239.       fclose($file); 
  240.    } 
  241.    else { 
  242.       print( "Header file could not be opened/created<br>"); 
  243.    } 
  244.     
  245.    if($file = @fopen(NEWSLETTER_FILE_PATH .  "news_footer.txt",  "w")) { 
  246.       if(!@fputs($file, $footer)) { 
  247.          print( "Footer file could not be written to.<br>"); 
  248.       } 
  249.       fclose($file); 
  250.    } 
  251.    else { 
  252.       print( "Footer file could not be opened/created<br>"); 
  253.    } 
  254.     
  255.     // format the newsletter w/ soft returns at 76 chars 
  256.    $body = format_mail($body, 76); 
  257.    if($header) { $header = format_mail($header, 76); } 
  258.    if($footer) { $footer = format_mail($footer, 76); } 
  259.     
  260.     // db connect and select 
  261.    $db_link = mysql_connect(HOST, USER, PASSWORD) or die(mysql_error()); 
  262.    mysql_select_db(DATABASE, $db_link) or die(mysql_error()); 
  263.  
  264.     // query.. get all the subscribers 
  265.    $sql =  "SELECT email, name, timestamp FROM mailing_list"; 
  266.    $db_results = mysql_query($sql, $db_link) or die(mysql_error()); 
  267.     
  268.  
  269.     // fill up the buffer so flush() will work. As soon as user sees. sending mail... they can be sure the text has been uploaded. 
  270.    print( "                    "); 
  271.    print( "                    "); 
  272.    print( "                    <br>"); 
  273.     // Ignore user abort so user can disconnect and have a snack while mail is being sent. 
  274.    ignore_user_abort(); 
  275.    print( "SENDING MAIL...........<p>"); 
  276.    flush(); 
  277.     // send the mail one at a time. sleep if specified.  
  278.    while($row = mysql_fetch_row($db_results)) { 
  279.       set_time_limit(SLEEP + 30); 
  280.       if(mail($row[0], $subject,  "Dear " . $row[1] .  ",\n\n" . $header .  "\n\n" . $body .  "\n\n" . $footer,  "From: " . SENDER)){ 
  281.          print($row[0] .  "... sent<br>\n"); 
  282.       } 
  283.       else{ $errors[] = $row[0]; } 
  284.       if(SLEEP) { sleep(SLEEP); } 
  285.    } 
  286.     
  287.     // display any mails that weren't sent. write log. 
  288.    $file = @fopen(NEWSLETTER_FILE_PATH .  "send_log.txt",  "w"); 
  289.    if($errors) { 
  290.       print( "Some mail could not be sent:<p>\n"); 
  291.       for($i = 0; $i < count($errors); $i++) { 
  292.          @fputs($file, $errors[$i] .  " could not be sent.\n"); 
  293.          print($errors[$i] .  " could not be sent.<br>\n"); 
  294.       } 
  295.    } 
  296.    else { 
  297.        // no errors. yea. 
  298.       print( "List was sent out without errors.<br>"); 
  299.       @fputs($file,  "List was sent out without errors.\n"); 
  300.    } 
  301.    fclose($file); 
  302. else { 
  303.     
  304.     // Either the page is coming up fresh or there's no body or subject 
  305.    print( "<center>"); 
  306.     
  307.    if($action) { 
  308.       if(!$body) { print( "There is no text in the body.<br>"); } 
  309.       if(!$subject) { print( "There is no text in the subject line.<br>"); } 
  310.    } 
  311.     
  312.    print( "<form action=\"send_mailing_list.php3\" method=\"post\">\n"); 
  313.    print( "<h1>send newsletter</h1> <p>\n"); 
  314.    print( "<table cellspacing=\"2\" cellpadding=\"3\" border=\"1\">\n\t<tr>\n\t\t<td align=\"right\">Subject of this newsletter:</td>\n\t\t<td><input type=\"text\" name=\"subject\" size=\"35\" value=\"" . $subject .  "\"></td>\n\t</tr>\n"); 
  315.     
  316.     // Header input. If a header already exists, the text will appear inside 
  317.    print( "\t<tr>\n\t\t<td align=\"right\">Header Text:</td>\n\t\t<td><textarea cols=\"35\" rows=\"5\" name=\"header\">"); 
  318.    if($header) { 
  319.       print($header); 
  320.    } 
  321.    else { 
  322.       $file = NEWSLETTER_FILE_PATH .  "news_header.txt"; 
  323.       if(file_exists($file)){ include($file); } 
  324.    } 
  325.    print( "</textarea></td>\n\t</tr>\n"); 
  326.     
  327.     // Body input 
  328.    print( "\t<tr>\n\t\t<td align=\"right\">Newsletter Body:</td>\n\t\t<td><textarea cols=\"35\" rows=\"5\" name=\"body\">" . $body .  "</textarea>"); 
  329.     
  330.     // Footer input. If a footer already exists, the text will appear inside 
  331.    print( "\t<tr>\n\t\t<td align=\"right\">Footer Text:</td>\n\t\t<td><textarea cols=\"35\" rows=\"5\" name=\"footer\">"); 
  332.    if($footer) { 
  333.       print($footer); 
  334.    } 
  335.    else { 
  336.       $file = NEWSLETTER_FILE_PATH .  "news_footer.txt"; 
  337.       if(file_exists($file)){ include($file); } 
  338.    } 
  339.    print( "</textarea></td>\n\t</tr>\n"); 
  340.     
  341.    print( "\t<tr bgcolor=\"#cccccc\">\n\t\t<td colspan=\"2\" align=\"center\"><input type=\"submit\" name=\"action\" value=\"send!\"></td>\n\t</tr>"); 
  342.    print( "</table></form><center>"); 
  343.  
  344.  
  345. ?> 
  346.  
  347.