TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 12-04-2007, 05:52 PM   #1 (permalink)
The Contributor
Upcoming Programmer 
 
Matt83's Avatar
 
Join Date: Oct 2007
Location: Argentina
Posts: 72
Thanks: 18
Matt83 is on a distinguished road
Default Subscribe/Unsubscribe Newsletter script

I often get asked by my clients to provide in their website a feature to subscribe/unsubscribe to their newsletter. In simpler/coding words, allow website users to easily add or remove their emails from a database and provide an interface for the client to retrieve that information. Just to be clear, this script don't address the email sending phase, so far my clients always had their software to do this ( or i encourage them to get one). I added a little ajax in here, but you could of course remove this part and make it work in other way.

Ok, first of all, Lets take a look at the file structure of this mini project:

Code:
Configuration and Database connection:
/config.php
Mysql Class:
/mySQL.class.php
A script to process our data:
/subscribenews.php
The jQuery javascript framework:
/js/jquery.js
A function to send/receive data to/from subscribenews.php:            
/js/ajax.js
Our site html page:    
/index.html
An interface to retrieve emails form Database:
/get_emails.php
To start we gonna need to set up our database. Create a database or add to your existing database the following table:

Code:
# SQL to create emails table:

CREATE TABLE `emails` (
  `email` varchar(60) NOT NULL,
  PRIMARY KEY  (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Pretty simple, a table with only one field where we gonna hold the addresses. Once we have that done we have to set our configuration file:

config.php:

PHP Code:
<?php
// We define the password thats gonna be provided 
// to the client  to fetch the list of emails from the database.
// Try to use a better password than 123 ;-)

define("SITE_PASSWORD""123");

// Next, we set the database connection info:

$szHost "127.0.0.1";      // Database Host
$szUser "root";           // Database User
$szPass "root";           // Database Pass
$szDataBase "newsletter"// Database Name

// Now we connect to the database

$connection mysql_pconnect($szHost$szUser$szPass) or trigger_error(mysql_error(),E_USER_ERROR); 
mysql_select_db($szDataBase$connection);
?>
Following is our mySQL class file. Im not going to explain OOP, or get into detail of this class. No need to say you can use your own/preferred class or other method to handle your database duties:

mySQL.class.php:

PHP Code:
<?php 

require_once('config.php');

class 
mySQL
{
    public 
$result;
    
    function 
__construct($szSQL NULL)
    {
        global 
$szDataBase$connection;
        
mysql_select_db($szDataBase$connection);
        
        if(
$szSQL)    
            
$this->query($szSQL);        
    }    
    
    public function 
query($szSQL)
    {
        
$this->result mysql_query($szSQL) or die(mysql_error());
    }
    
    public function 
next_record()
    {
        return 
mysql_fetch_assoc($this->result);
    }
    
    public function 
load_array($szKeyfield)
    {
        
$return = array();
        while( 
$r $this->next_record() )
            
array_push($return,$r[$szKeyfield]);
            
        return 
$return;
    }
    
    public function 
num_rows()
    {
        return 
mysql_num_rows($this->result);
    }
    
    public function 
escape($value)
    {
        if (
get_magic_quotes_gpc())  
        { 
            
$value stripslashes($value); 
        } 

        if (!
is_numeric($value) || $value[0] == '0'
        { 
            
$value mysql_real_escape_string($value); 
        } 
    
        return 
$value;    
    }
    
    public function 
get_last_error()
    {
        
mysql_error();
    }
    
    public function 
free()
    {
        
mysql_free_result($this->result);
    }
}

?>
Ok, here comes the fun part (?) , subscribenews.php, the file thats gonna process the data coming from the website (an email address and the action to take: add or delete ).

subscribenews.php:

PHP Code:
<?php
// We include our mySQL class
include "mySQL.class.php";

// Right after that, the first thing we do is to run a 
// regular expression to see if the email we are getting 
// from the form is valid.

if (!preg_match('/^\w[\w+-]*(?:\.[\w+-]+)*@[a-z0-9-]+(?:\.[a-z0-9-])*\.[a-z]{2,4}$/i',$_GET['email']))
{
        echo 
'INVALID E-MAIL'// if its not valid we echo the error.
}

// Next, if it is valid, we want to check 
// we have an action to take:

else if( isset($_GET['delete']) || isset($_GET['add']) )
{    
         
// If there is an action  we create a new database object
    
$dbh = new mySQL();
        
// Paranoids as we have to be, we escape the
        // email address that comes from the form
    
$szEmail strtolower($dbh->escape($_GET['email'])); 
    
        
// Ok this is pretty simple, we ask if the variable $_GET['add'] is set:
    
if(isset($_GET['add']))
    {
        
// If 'add' is set then we first run a query 
        // to check  if that email is already in our database
        
$szResponse $dbh->query(sprintf("SELECT email FROM emails WHERE email = '%s'"$szEmail));
        
$szStatus $dbh->next_record();
        
        
// if the result is not empty then the email is already 
        // on the database so we echo and error 

        
if( $szStatus != "" 
        {    
            echo 
"E-mail already exists in database";        
        }    
        else
        {
        
// else we insert the email and echo a success message.
            
$dbh->query(sprintf("INSERT INTO emails (email) VALUES ('%s')"$szEmail));
            echo 
"E-mail added successfully";
        }
    }
    else 
    {
        
// Now if the action is 'delete' then we run a query 
        // to delete the email from the database

        
$dbh->query(sprintf("DELETE FROM emails WHERE email = '%s'",$szEmail));
        
        
// we check the affected rows and give back our status message:

        
if( mysql_affected_rows() != 1)
            echo 
"E-mail does not exist in database";
        else
            echo 
"E-mail deleted successfully";
    }
}
else
{
    echo 
'UNKNOWN ERROR'// In case something above goes wrong 
}
Ok, now that we have that done, we gonna create our website form to allow users to interact with the script, so first download jQuery and place it under /js folder, same place in which we are going to create our next file: ajax.js

(Also not going to get into detail about jQuery, you can use whatever framework you preffer)

js/ajax.js

Code:
// pretty simple function, we pass an url, some data 
// and the target where we want the action to happen

function request_action(jurl,jdata,jtarget)	
{
	$(jtarget).html('Processing request...');
		
	$.ajax(
	{
	   type: "GET",
	   url: jurl,
	   data: jdata,
	   success: function(data)
	   {
	     $(jtarget).html(data);
	   }
	});
};
So now that we have those two files we add this code to our website:


index.html:

Quote:
note: this is a very simple/incomplete example of an html file but its to show you how this script works:
HTML Code:
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/ajax.js" type="text/javascript"></script>

<input id="email" name="email" type="text" />

<input id="subscribe" name="subscribe" type="button" onclick="request_action('subscribenews.php','add&email='+$('#email').val(),'#target')" value="Subscribe"/>
<input id="unsubscribe" name="unsubscribe" type="button" onclick="request_action('subscribenews.php','delete&email='+$('#email').val(),'#target')" value="Unsubscribe"/>

<div id="target"></div>
In the code above, when a button is clicked we are simply calling for request_action with some parameters: the url where the action is going to happen, the parameters ( add or delete, and the email address ) and last the target were our success message is going to be displayed.

If you followed all the steps, you should have now a working script to add or remove emails from the database with some ajax flavor. So to conclude the script, last but not least, we gonna create get_emails.php, the interface for the client to retrieve the emails. This file will consist of a little form to ask for the password and a script to display the serialized emails.

get_emails:

PHP Code:
<?php
// We include our mySQL class
include "mySQL.class.php";

// if the form has been sent, we check the password

if($_POST['password'] == SITE_PASSWORD)
{

    
// If the password is correct then we return
    // the emails from the database in an array

    
$dbh = new mySQL("SELECT email FROM emails ORDER BY email");
    
$aEmails $dbh->load_array('email');
    
    
// We echo a little informative title
    
echo "<div><strong>Copy and Paste in your email app (".count($aEmails)." emails):</strong></div><br/>";
    
// then we echo the serialized list of emails:
    
echo implode(', '$aEmails);
}
else
{
    
// If the password is wrong:
    
if( isset($_POST['password']) )
        echo 
"<div>WRONG PASSWORD</div>";
?>

<form action="" method="post">
    <label>Password:</label><br/><input name="password" type="password" value="">
    <input name="ENTER" type="submit">

</form>
<? ?>
That will give something like this:

Quote:
Copy and Paste in your email app (2 emails):

matt83@something.com, another@email.com
which client can copy/paste into their email massive/sender/whatever application.

Well guys hope this help someone out there, and please as always, comments and critics are more than welcome.
Attached Files
File Type: zip newsletter.zip (18.6 KB, 2078 views)
__________________
http://www.mattvarone.com

Last edited by Matt83 : 12-05-2007 at 04:42 PM.
Matt83 is offline  
Reply With Quote
The Following 3 Users Say Thank You to Matt83 For This Useful Post:
cheap celine (03-24-2012), Gurnk (12-04-2007), webosb (01-24-2008)
Old 12-05-2007, 05:05 PM   #2 (permalink)
The Contributor
Upcoming Programmer 
 
Matt83's Avatar
 
Join Date: Oct 2007
Location: Argentina
Posts: 72
Thanks: 18
Matt83 is on a distinguished road
Default

I been playing recently with Protoype, so i thought as a good experience, to update this post with the alternative code needed to run the script with this Library.

First we need to make a modification to our index.html, we of course have to include the Prototype Library but also modify two values on our call to request_action:

index.html:

HTML Code:
<script src="js/prototype.js" type="text/javascript"></script>
<script src="js/ajax.js" type="text/javascript"></script>

<input id="email" name="email" type="text" />

<input id="subscribe" name="subscribe" type="button" onclick="request_action('suscribenews.php', 'add&email='+$('email').value, 'target')" value="Subscribe"/>
<input id="unsubscribe" name="unsubscribe" type="button" onclick="request_action('suscribenews.php', 'delete&email='+$('email').value, 'target')" value="Unsubscribe"/>

<div id="target"></div>
Once thats done we have to make another slightly change, but this time to ajax.js:

Code:
function request_action(jurl,jdata,jtarget)
{
	$(target).innerHTML = "Processing request...";
	var myAjax = new Ajax.Updater(jtarget, jurl, {	method: 'get',	parameters: jdata});
}
And thats it!, pretty simple and pretty similar. Hope you find it useful!
__________________
http://www.mattvarone.com
Matt83 is offline  
Reply With Quote
The Following User Says Thank You to Matt83 For This Useful Post:
webosb (01-24-2008)
Old 11-12-2008, 04:47 PM   #3 (permalink)
The Visitor
 
Join Date: Nov 2008
Posts: 1
Thanks: 0
sayumi is on a distinguished road
Default

thx for this script, it seems very useful!

can you plz tell me which mailingprograms you recommend to your clients?
I'm currently looking for one, for the company I'm working for
it should be one working on a mac though... they don't have any other computers here
sayumi is offline  
Reply With Quote
Old 11-12-2008, 05:24 PM   #4 (permalink)
The Contributor
 
Runar's Avatar
 
Join Date: Nov 2008
Location: Norway
Posts: 58
Thanks: 20
Runar is on a distinguished road
Default

Quote:
Originally Posted by sayumi View Post
can you plz tell me which mailingprograms you recommend to your clients?
If you do not have any special needs, I strongly recommend Thunderbird.
Send a message via MSN to Runar
Runar is offline  
Reply With Quote
Old 04-02-2010, 10:51 AM   #5 (permalink)
The Visitor
 
Join Date: Apr 2010
Posts: 1
Thanks: 0
tomdringer is on a distinguished road
Default Validate

Hi. Thanks for the script. Its awesome. I was wondering if there was a way I can get this to go through the W3C html validator (strict) as there are a couple of "&" signs in the code which can't be changed to &amp's.
Any ideas would be appreciated.

Thanks.
tomdringer is offline  
Reply With Quote
Old 07-21-2010, 04:06 PM   #6 (permalink)
The Visitor
 
Join Date: Jul 2010
Posts: 1
Thanks: 0
mitov is on a distinguished road
Default

Hi,

Thanks for this script! It's simple and perfect! I have one problem though...

Some emails have a '.' in their name... yet the form marks them as invalid...

How can i resolve this?

Regards,

Miro Mitov
mitov is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 11:19 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design