Recent Topics

1 Oct 17, 2003 04:08    

Alright! I finished...I think. ;) I generalized the code and removed almost all of the hardcoding. I left things like generated HTML in since it is easy to change.

Ok, the code involves 6 files, two of which can be created from scratch since they begin blank. All of these files need to be in your blog directory.
*THIS HACK HAS ONLY BEEN TESTED WITH VERSION 0.8.2.2 IF YOU WANT ONE FOR 0.8.6 WAIT FOR THE OFFICIAL RELEASE!*

First file is 'sendmail.php'
This file parses the information sent by the submission and generates a conformation page based on success/failure of the email address.
Save the following code as sendmail.php
Code:


<? 
require_once("b2config.php"); 
import_request_variables("P", "I_"); 
$to = $admin_email; 
$from = $I_contents; 
$from_header = "From: $from"; 
$subject = "Mailing List Addition"; 
if($form = !"") 
{ 
// is the $from email address in valid format? 
if(ereg("([[:alnum:]\.\-]+)(\@[[:alnum:]\.\-]+\.+)", $from)) 
{ 
if(file_exists("email_list.txt")) 
{ 
$newfile = fopen("email_list.txt", "r"); 
    flock($newfile, 2); 
   while(!feof($newfile)) 
   { 
     $duplicate = fgetss($newfile, 255); 
     // is email address submitted already on file? 
        if(eregi("$from", $duplicate)) 
       { 
         print("<HTML><Head><Title>Mailing List Error</Title></Head><BODY background=\"YOUR_BG.jpg\" text=\"white\">"); 
      print("<P ALIGN=\"CENTER\"><FONT SIZE=\"4\">This email <strong>$from</strong>"); 
         print(" is already in the database. <br>Please go back"); 
         print("</FONT></BODY></HTML>"); 
         flock($newfile, 3); 
      fclose($newfile); 
         exit; 
       } 
    } 
  flock($newfile, 3); 
  fclose($newfile); 
  $addemail = fopen("email_list.txt", "a"); 
  flock($addemail, 2); 
  fputs($addemail, "$from\n"); 
  flock($addemail, 3); 
  fclose($addemail); 

   //send mail - $subject & $contents come from surfer input 
   mail($to, $subject, $from, $from_header); 
   // redirect to correct Message--Edit HTML if you wish 
   print("<HTML><Head><Title>Subscribe Complete!</Title></Head><BODY background=\"YOUR_BG.jpg\" text=\"white\">"); 
      print("<P ALIGN=\"CENTER\"><FONT SIZE=\"4\">"); 
         print("Thank you for signing up for the mailing list.<br>Every time a new post is added, you will recieve an update via email."); 
         print("</FONT></BODY></HTML>"); 
    
} 
} 
else 
{ 
   print("<HTML><Head><Title>Mailing List Error</Title></Head><BODY background=\"YOUR_BG.jpg\" text=\"white\">"); 
      print("<P ALIGN=\"CENTER\"><FONT SIZE=\"4\">This email address: <strong>$from</strong>"); 
         print(" is not valid. <br>Please go back"); 
         print("</FONT></BODY></HTML>"); 
} 
} 
  else 
{ 
   print("<HTML><Head><Title>Mailing List Error</Title></Head><BODY background=\"YOUR_BG.jpg\" text=\"white\">"); 
      print("<P ALIGN=\"CENTER\"><FONT SIZE=\"4\">Please enter an email address.</FONT></BODY></HTML>");          
} 
?> 


Don't forget to edit the HTML to your liking.
Now, add the following HTML to your post page or where you want you're submission box.
Code:


<FORM ACTION="sendmail.php" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded"> 
<INPUT TYPE="TEXT" NAME="contents" SIZE="18"><br /> 
<INPUT TYPE="SUBMIT" NAME="Sign-up" VALUE="Submit"><br /> 
</form> 
 

The names must not be changed, but the layout, etc...

Next file is the unsubscribe.php--this handles the automatic unsubscribe from the mailing list.
Save the following as 'unsubscribe.php'
Code:


<? 
require_once("b2config.php"); 
import_request_variables("G","I_"); 
$id = $I_id; 
if($id != "") 
{ 
$emails = file("email_list.txt"); 
  for($index = 0; $index < count($emails); $index++) 
  { 
    if(ereg("$id", $emails[$index])) 
    { 
      $emails[$index] = ""; 
      $thefile = fopen("email_list.txt", "w"); 
         flock($thefile, 2); 
      for($newindex = 0; $newindex <count($emails); $newindex++) 
        { 
          if($emails[$newindex] != "") 
          { 
            fputs($thefile, "$emails[$newindex]"); 
          } 
        } 
      flock($thefile, 3); 
   fclose($thefile); 
   //Edit html to liking      
   print("<HTML><Head><Title>Unsubscribe</Title><BODY background=\"YOUR_BG.jpg\" text=\"white\">"); 
   print("<P align=\"Center\"><font=\"4\">This email <strong>$id</strong>"); 
      print(" has successfully been removed from the"); 
      print(" database.</font></BODY></HTML>"); 
   mail("$admin_email", "Mailing List Unsubscribe", "$id", "From: $id"); 
    } 
  } 
} 
?> 

This code only works if an email address is sent to it via get.
Now, create a blank file named 'email_list.txt'
This file will store the emails for the mailing list.

Next is the admin interface. I put it all into a single file for space and security. It controls adding, removing, and mailing from the mailing list.

Save the following code as 'mailinglist.php' Don't forget to change the 'b2menutop.txt' file to add this.
Code:


<?php 
import_request_variables("P", "P_"); 
import_request_variables("G", "G_"); 
$action=$P_action; 
$error=""; 
$mm=""; 
$rm=""; 
$title = "Mailing List"; 
/* <Mailing List> */ 

   $standalone=0; 
   require_once("b2config.php"); 
   require_once($b2inc."/b2template.functions.php"); 
   require_once($b2inc."/b2verifauth.php"); 
   require_once($b2inc."/b2vars.php"); 
   require_once($b2inc."/b2functions.php"); 
   require_once($b2inc."/xmlrpc.inc"); 
   require_once($b2inc."/xmlrpcs.inc"); 
   get_currentuserinfo(); 
   //Set user Level 
                if ($user_level <= 8) { 
      die("You have no right to send mail for this blog.<br>Ask for a promotion to your <a href=\"mailto:$admin_email\">blog admin</a> :)"); 
   } 

//Self Containing the Code -- if hidden for each FORM function is returned, that switch statement executes 
switch($action) 
{ 
   case "sendmail": 
//The Following is SENDMAIL code until end in comments--Sends mass mail       
$from="From: $user_nickname <$user_email>"; 
if($P_subject !="") 
{ 
   if($P_body !="") 
   { 
      $file=fopen("email_list.txt", "r"); 
      flock($file, 2); 
      while(!feof($file)) 
      { 
      $to = fgetss($file, 255); 
      $body = "------------------------------------------------------ ------------------------------ 
         This email is not spam. You signed up for this list at $siteurl. 
         You can unsubscribe by following the link at the bottom of  this email message. 
         ------------------------------------------------------------- --------------------- 
         $P_body 
         ------------------------------------------------------------- ------------------------ 

         If you would like to unsubscribe from the $user_url 
         post update email list, just click the link below 
         $siteurl/unsubscribe.php?id=$to 
         if the link above does not show in your email 
         program just cut and paste it to your browser. 
         ------------------------------------------------------------- ------------------------ 
         "; 
   mail($to, $P_subject, $body, $from); 
   } 
   flock($file, 2); 
   fclose($file); 
   header("location: mailinglist.php?error=Mass Mail Sent"); 
   exit;  
   } 
   else 
   { 
      header("location: mailinglist.php?error=No Body&subject=$P_subject"); 
      exit; 
   } 
} 
else 
{ 
   header("location: mailinglist.php?error=No Subject&body=$P_body"); 
   exit; 
} 
//End of SENDMAIL 
   break; 

   case "removemail": 
   //The Following is REMOVEMAIL until comment ends it--Removes emails from list 
$id = $P_selection; 
if($id != "") 
{ 
$emails = file("email_list.txt"); 
  for($index = 0; $index < count($emails); $index++) 
  { 
if(ereg("$id", $emails[$index])) 
    { 
      $emails[$index] = ""; 
      $thefile = fopen("email_list.txt", "w"); 
         flock($thefile, 2); 
      for($newindex = 0; $newindex <count($emails); $newindex++) 
        { 
          if($emails[$newindex] != "") 
          { 
            fputs($thefile, "$emails[$newindex]"); 
          } 
        } 
      flock($thefile, 3); 
   fclose($thefile);      
   header("location: mailinglist.php?rm=Address Successfully Removed"); 

    } 
  } 
} 
//End of REMOVEMAIL 
   break; 

   case "addmail": 
   //The following is ADDMAIL until comment ends it--adds email to list 
$from=$P_mail; 
if($form = !"") 
{ 
// is the $from email address in valid format? 
if(ereg("([[:alnum:]\.\-]+)(\@[[:alnum:]\.\-]+\.+)", $from)) 
{ 
if(file_exists("email_list.txt")) 
{ 
$newfile = fopen("email_list.txt", "r"); 
    flock($newfile, 2); 
   while(!feof($newfile)) 
   { 
     $duplicate = fgetss($newfile, 255); 
     // is email address submitted already on file? 
        if(eregi("$from", $duplicate)) 
       { 
         header("location:  mailinglist.php?mm=Address Already Exists"); 
         exit; 
       } 
    } 
  flock($newfile, 3); 
  fclose($newfile); 
  $addemail = fopen("email_list.txt", "a"); 
  flock($addemail, 2); 
  fputs($addemail, "$from\n"); 
  flock($addemail, 3); 
  fclose($addemail); 

   //send mail - $subject & $contents come from surfer input 

   // redirect back to url visitor came from 
header("location: mailinglist.php?mm=Address Added Successfully"); 
exit;  
} 
} 
else 
{ 
   header("location: mailinglist.php?mm=Not a Valid Address&email=$id"); 
   exit; 
} 
} 
  else 
{ 
$mm="Enter an Address"; 
exit;          
} 
//End of ADDMAIL 
   break; 
} 
//End of Switch() 
include ("./b2header.php"); 

?> 
  
          
    
<?php echo $blankline ?> 
<?php echo $tabletop ?> 
          
<CENTER> 
<P> 
<TABLE BORDER="0" WIDTH="700" HEIGHT="308"> 
   <TR> 
      <TD> 
         <FORM ACTION="mailinglist.php" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded"> 
         <input type=hidden name="action" value="sendmail"> 
         <CENTER> 
         <font color="red"><?php echo $G_error ?> 
         </font> 
         <P>Subject</P> 

         <P><?php print("<INPUT TYPE=\"TEXT\" NAME=\"subject\" value=\"$G_subject\" SIZE=\"25\">"); ?></P> 

         <P>Body</P> 

         <P><?php print("<TEXTAREA NAME=\"body\" ROWS=\"7\" COLS=\"52\">$G_body</TEXTAREA>");?></P> 

         <P><INPUT TYPE="SUBMIT" NAME="submit" VALUE="Send Mass Mailing"> 

         </CENTER> 
         </form> 
      </TD> 
      <CENTER> 
      <TD> 
         <FORM ACTION="mailinglist.php" METHOD="POST" ENCTYPE="application/x-www-form-urlencoded"> 
         <input type="hidden" name="action" value="removemail"> 
         <Center>Email Address Removal<br /> 
         <font color="red"> 
         <?php 
         $rm=$G_rm; 
         print("$rm"); 
         ?> 
         </font> 
         <br /> 
         <SELECT NAME="selection"> 
         <?php 
         $file=fopen("email_list.txt", r); 
         $count=0; 
         flock($file, 2); 
         while(!feof($file)) 
         { 
            $ea=fgetss($file, 255); 
            if($count==0) 
            { 
               print("<option selected>$ea</option>"); 
               $count+=1; 
            } 
            else 
            { 
               print("<option>$ea</option>"); 
            } 
         } 
         flock($file, 3); 
         fclose($file); 
         ?> 
          
         </SELECT><br /> 
         <INPUT TYPE="SUBMIT" NAME="Submit" VALUE="Remove"></P> 
         </FORM> 
         </center> 
         <br /><br /> 
         <Center>Add Email Address<br /> 
         <font COLOR="red"> 
         <?php 
         $mm=$G_mm; 
         print("$mm"); 
         ?> 
         <br /> 
         <FORM ACTION="mailinglist.php" METHOD="POST"> 
         <input type="hidden" name="action" value="addmail"> 
         <?php 
         $email=$I_email; 
         print("<INPUT TYPE=\"text\" NAME=\"mail\" SIZE=\"25\" value=\"$email\">"); 
         ?> 
         <INPUT TYPE="SUBMIT" NAME="Addemail" VALUE="Add Email"> 
         </form> 
         </CENTER> 
      </TD> 
      </CENTER> 
   </TR> 
</TABLE> 

</CENTER> 

<?php echo $tablebottom ?> 

<?php 


/* </Mailing List> */ 
include($b2inc."/b2footer.php") ?> 

The code sets the from info based on the logged in user--set admin privledges to change who can get at it.

Next is the auto-update for sending updates about posts. This file, when run, sends an email that lists:

number of new posts since last run
a url the most recent posts, by day
which catagories have been updated
a url to the updated catagories

If you want this to run from server side, you need to schedule it. If its a UNIX box, check with you administrator to see if you can use crontab. online.
Save the following as 'auto.php'
Code:


<?php /* Don't remove this line, it calls the b2 function files ! */ $blog=1; include ("blog.header.php"); 

//What you would like displayed as the nick in the 'from' line 
$nick="YOUR NICK"; 

//Subject of the email 
$subject="I've updated my posts!"; 

//Check to make sure it hasn't been run yet. 
$auto_check=fopen("auto.txt", "r"); 
flock($auto_check, 2); 
$check=fgetss($auto_check, 9); 
flock($auto_check, 3); 
fclose($auto_check); 
//Correct for blank file 
if($check=="") 
{$check="yesterday";} 

//If it hasn't been run, run the script and update the check file 
if(strtotime($check)<strtotime(date("Ymd"))) 
{ 
$stamp=date("Ymd"); 
$auto_update=fopen("auto.txt", "w"); 
flock($auto_update, 2); 
fputs($auto_update, "$stamp"); 
flock($auto_update, 3); 
fclose($auto_update); 
$my_date=mktime(0,0,0,date("m"),date("d")-1,date("Y")); 
$my_date = date("Ymd",$my_date); 
$its_date=""; 

//If it can run, get info for email--DON'T TOUCH THIS SECTION UNLESS YOU KNOW WHAT YOU ARE DOING!! 
$count=0; 
$o_count=0; 

//Begin to loop to check for new posts 
$my_array_cat=array(); 
$my_array_num=array(); 
while($row = mysql_fetch_object($result)) { start_b2(); 
$its_date=mysql2date('Ymd', $postdata['Date']); 
if($its_date>=$my_date) 
{ 
        $in_count=0; 
        $is_found=0; 
        foreach($my_array_cat as $cat) 
        { 
                $in_count+=1; 
                if($postdata['Category']==$cat) 
                { 
                        $is_found=1; 
                        $my_array_num[$in_count]=($my_array_num[$in_count]+1); 
                } 
         } 
         if($is_found==0) 
         { 
                $my_array_cat[$in_count+1]=$postdata['Category']; 
                $my_array_num[$in_count+1]=1; 
                $count+=1; 
         } 
         $o_count+=1; 
                        

} 
}  



//Ian's code--Send the email 
   if($count!=0) 
   { 
      if($count > 1){$suffix = "s";} 
      else {$suffix = "";} 
      $from="From: $nick $admin_email"; 
      $file=fopen("email_list.txt", "r"); 
      flock($file, 2); 
      while(!feof($file)) 
      { 
         $to = fgetss($file, 255); 
         $body="------------------------------------------------------------------------------------ 
         This email is not spam. You signed up for this list at $siteurl. 
         You can unsubscribe by following the link at the bottom of  this email message. 
         ---------------------------------------------------------------------------------- 

         I've got $o_count new post$suffix on my webpage. 
         If you would like to see the post$suffix, go to: 
         $siteurl/$blogfilename?m=$my_date 
         Here's what's been added: 
         "; 
         //Add info to mail about which sections have been updated 
         for($i=1;$i<=$count;$i+=1) 
              { 
                     $cat=get_the_category_by_ID($my_array_cat[$i]); 
                      $my_output="::$cat::($my_array_num[$i])--> $pathserver/$blogfilename?cat=$my_array_num[$i]\n"; 
                      $body=$body.$my_output; 
              } 
         $body2="--$nick 
    
         ------------------------------------------------------------------------------------- 
         If you would like to unsubscribe from the $siteurl 
         post update email list, just click the link below 
         $siteurl/unsubscribe.php?id=$to 
         if the link above does not show in your email 
         program just cut and paste it to your browser. 
         ------------------------------------------------------------------------------------- 
         "; 
         $body=$body.$body2; 
         mail($to, $subject, $body, $from); 
      } 
      flock($file, 3); 
      fclose($file); 
   }//Edit HTML to liking 
   print("<HTML><HEAD><TITLE>Script Executed Successfully</TITLE><BODY><CENTER>The script as been run. You will not be allowed to run it again "); 
   print("until tomorrow.</CENTER></BODY></HTML>"); 
} 
else 
{ 
      print("<HTML><HEAD><TITLE>ERROR</TITLE><BODY><CENTER>THIS SCRIPT HAS ALREADY BEEN RUN. YOU CANNOT RUN IT AGAIN TODAY."); 
   print("</CENTER></BODY></HTML>"); 
} 

   //End of Ian's code 
?> 
 

After this, all you need to do is create a blank file named 'auto.txt' This file is for checking when the script was last run to prevent it from being run more than once a day.

Changing the script to update on a post-by-post basis is slightly different.
Open 'b2edit.php' and locate the 'case: "update" '

Add the code from 'auto.php' after the user_level check and it will run everytime you hit 'blog this!'

I think that's all there is to it. If I left something out, or something doesn't work, let me know. I've tested it, and all I find is a typo from time to time.
Best of luck,
t3dworld

2 Jan 03, 2005 20:46

This is a great code, but do you have one of these for b2evo version 0.9.0.11?

3 Jan 06, 2005 09:12

Unfortunately, I don't have any updated code for newer versions. I had developed a more *integrated* version with more features for a slightly later version of B2, but that was last year. Since then I have not been closely following the developement of B2. However, unless the way the administration system is setup has drastically changed, you should be able to very easily adapt this code to work with a new version of B2.

Aside from that, I have no plans for updating the code as I'm quite content with the way my blog runs at the moment. I might consider re-opening the project if enough interest is displayed, but any work would have to wait until next term when I have more time.

If anyone wants to use this code as a basis for a newer, enhanced version of a mailing list hack/feature, please feel free to do so. I will happily comment/explain the features of the code.

Best of luck, and happy coding!
t3dworld

4 Jan 07, 2005 04:13

I think this code would be great to include in future b2evo versions.

5 Jan 09, 2005 03:36

I'd like to see it also in the core and it is not that difficult really, but we should first think about what we might need everything, because this should not handle only mass mailing but also subscribing to posts/blogs, with single messages (per posts) or even as digests.

You'd have to register with the blog first and would be allowed to at least access your subscriptions in the admin UI.

Would be very interesting indeed.

But I've no time ATM either.. :/

6 Jan 11, 2005 00:00

Unless someone other than the developers come up with a mailing list hack it's not going to happen. Making it over-complicated like RSS hacks, or requiring people to become members of a blog is a sure-fire way of ensuring such a widely used SIMPLE concept as a mailing list, which is used by many of the other blog software, ensures it'll never come to b2evolution.

Keep it simple like how mailing lists are done with the other software. Allow people to drop in their email address into a Subscribe/unsubscribe box and send them an email with optional summary of the new blog entry (or unsubscribe them if they requested). Click. Done. Add a panel to modify the subscribers list and add optional summary or comments and you're done. Want to add something fancy options later - sure go for it. But keep it simple, get it working then add more features and options. Not all blogs require people to be members to get updates, so keep that optional always.

Anytime you limit choice or options you've sacrified functionality and desirability.


Form is loading...