Twitter URL Shortener: Part 2

 

Welcome to part 2 of this tutorial. In this we will finish off what we started and add the extra functionality. By the end of this tutorial we will have:

  1. Stats Page
  2. Admin Page to delete items and make them inactive
  3. Settings to add new users and change API key
  4. Work with Tweetie 2 for the iPhone/iPod touch

Download
live demo

Login

Username: alexbor
Password: password

Some changes

Let’s get started with just a few minor changes to the last tutorial. In the functions.php file, change the “json_to_jquery” function to this:

function json_to_jquery($type, $message, $url){
	$replying = array('error'=>'', 'message'=> '');
	$replying['error'] = "$type";
	$replying['message'] = "$message";
	$replying['shortUrl'] = "$url"; //changed from shortURL to shortUrl as that is how Tweetie reads it
	echo(json_encode($replying));
}

also, at the very top of this file, we want to add

$loggedIn = $_SESSION['loggedIn'];

which is a variable that will be used later to make sure that we are logged in. Finally inside of the add.js file update “$(‘#theLink’).val(e.shortURL);” to “$(‘#theLink’).val(e.shortUrl);”.

After doing that you will find that (once the API key is done) you will be able to use this with Tweetie.

Also, we will be adding more CSS classes and IDs so it’s best to change the current “main.css” file (in the CSS folder) to the following, to save from needing to go through the CSS later.

@charset "UTF-8";
/* CSS Document */
/* UTULITIES */
.clear{clear: both;}
.push{height: 30px;}
/* END */
/* ORDER PAGE CORRECTLY */
*{margin: 0; padding: 0;}
html{overflow-y: scroll;position: relative;}																/*  COLOUR  */
body{width: 100%; height: 100%; background: url(../images/theBG.png) repeat; background-color: #00ADED;color: white;}
/* END */

/* header  */
#header{width: 1000px;height: 153px;margin: 0 auto;}
/*  END  */
#stipWrap{width: 1000px; margin: 0 auto;}
#strip, #stripAdmin{		/*  CHANGE REPEAT  */
background:url("../images/strip.png") repeat scroll 0 0 transparent;
min-width:1000px;
position:inherit;
}
#strip{
height:270px;
}

#linkForm{
height:30px;
margin-bottom:0;
margin-left:auto;
margin-right:auto;
margin-top:0;
padding-top:100px;
width:500px;
}
.label{color:white;font-size:30px;}
.smallInput{font-family: Helvetica, Verdana, Arial, sans-serif;background:none repeat scroll 0 0 #E9F0F8;border:1px solid #00ADED;color:#1E1C56;font-size:20px;padding:5px;}
#theLink{width:400px;}
#theLink:hover{background: #ffffff;}
#theLink:focus{color: #000000;}
.process{
background:#CC1B00;
color:white;
font-size:23px;
font-weight:bold;
height:0;
margin-left:250px;
position:absolute;
text-align:center;
width:500px;
overflow: hidden;
}
.processingC{padding: 5px;}
ul{font-family:helvetica;list-style:none outside none;margin-left:230px;margin-top:10px;display: none;}
ul li{display:inline-block;text-align:center;width:145px;}
ul li a{color:#2473A0;text-decoration:none;}
ul li a:hover{color:#E4E9E9;}
#message{
color:#CBCBCB;
font-family:Helvetica,Verdana,Arial,sans-serif;
font-size:25px;
font-weight:bold;
margin:0 auto;
padding-top:154px;
text-align:center;
width:1000px;
word-spacing:3px;
letter-spacing: 2px;
text-shadow:0 0 8px #00ADED;
}
.problem{
color:#CBCBCB;
font-family:Helvetica,Verdana,Arial,sans-serif;
font-size:25px;
font-weight:bold;
text-align:center;
width:1000px;
padding-top: 5px;
word-spacing:3px;
letter-spacing: 2px;
text-shadow:0 0 8px #00ADED;
}
/*  LOGIN FORM  */
.inform{color:white;padding:25px 0;text-align:center;}
.loginForm{text-align: center;}
.logOut{color:#B1B3B3;font-size:18px;font-style:italic;padding-top:5px;position:ab
solute;text-decoration:none;}
.logOut:hover, .admin:hover{color:white;}
.admin{color:#B1B3B3;font-size:18px;font-style:italic;padding-top:5px;float:right;text-decoration:none;}
.pright{padding-right: 10px;}
.shorturl, .longurl, .link{color: #CBCBCB; text-decoration: none;}

.shorturl:hover, .longurl:hover, .link:hover{color: white;}

Admin Page

If you have not already, create an admin folder on the home directory and inside this make two files “index.php” and “settings.php” and open the index.php file. This is going to be a large file that will paginate the links and then display them below with buttons to delete them with option to change if they are active or not. The pagination code is a slightly modified version of papermashup‘s and he explains what it means on that page. In this file add the following code:

<?php
require_once("../files/functions/functions.php"); // get our functions file
admin_page(); // this is a function we will create later to check if the user is logged in
	$tableName="url";		// the table to search
	$targetpage = "index.php"; 	// the file that this is in ... So ?page will work
	$limit = 10; // how many per page

	$query = "SELECT COUNT(*) as num FROM $tableName"; // get amount of items in database
	$total_pages = mysql_fetch_array(mysql_query($query)); // run/fetch
	$total_pages = $total_pages[num];	

	$stages = 3;
	$page = mysql_escape_string($_GET['page']);
	$pageRet = mysql_escape_string($_GET['page']);
	if($page){
		$start = ($page - 1) * $limit;
	}else{
		$start = 0;
	}
    // Get page data
	$query1 = "SELECT * FROM $tableName ORDER BY `id` DESC  LIMIT $start, $limit";
	$result = mysql_query($query1);

	// Initial page num setup
	if ($page == 0){$page = 1;}
	$prev = $page - 1;
	$next = $page + 1;
	$lastpage = ceil($total_pages/$limit);
	$LastPagem1 = $lastpage - 1;					

	$paginate = '';
	if($lastpage > 1)
	{
	$paginate .= "<div class='paginate'>";
		// Previous
		if ($page > 1){
			$paginate.= "<a href='$targetpage?page=$prev'>previous</a>";
		}else{
			$paginate.= "<span class='disabled'>previous</span>";	}

		// Pages
		if ($lastpage < 7 + ($stages * 2))	// Not enough pages to breaking it up
		{
			for ($counter = 1; $counter <= $lastpage; $counter++)
			{
				if ($counter == $page){
					$paginate.= "<span class='current'>$counter</span>";
				}else{
					$paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}
			}
		}
		elseif($lastpage > 5 + ($stages * 2))	// Enough pages to hide a few?
		{
			// Beginning only hide later pages
			if($page < 1 + ($stages * 2))
			{
				for ($counter = 1; $counter < 4 + ($stages * 2); $counter++)
				{
					if ($counter == $page){
						$paginate.= "<span class='current'>$counter</span>";
					}else{
						$paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}
				}
				$paginate.= "...";
				$paginate.= "<a href='$targetpage?page=$LastPagem1'>$LastPagem1</a>";
				$paginate.= "<a href='$targetpage?page=$lastpage'>$lastpage</a>";
			}
			// Middle hide some front and some back
			elseif($lastpage - ($stages * 2) > $page && $page > ($stages * 2))
			{
				$paginate.= "<a href='$targetpage?page=1'>1</a>";
				$paginate.= "<a href='$targetpage?page=2'>2</a>";
				$paginate.= "...";
				for ($counter = $page - $stages; $counter <= $page + $stages; $counter++)
				{
					if ($counter == $page){
						$paginate.= "<span class='current'>$counter</span>";
					}else{
						$paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}
				}
				$paginate.= "...";
				$paginate.= "<a href='$targetpage?page=$LastPagem1'>$LastPagem1</a>";
				$paginate.= "<a href='$targetpage?page=$lastpage'>$lastpage</a>";
			}
			// End only hide early pages
			else
			{
				$paginate.= "<a href='$targetpage?page=1'>1</a>";
				$paginate.= "<a href='$targetpage?page=2'>2</a>";
				$paginate.= "...";
				for ($counter = $lastpage - (2 + ($stages * 2)); $counter <= $lastpage; $counter++)
				{
					if ($counter == $page){
						$paginate.= "<span class='current'>$counter</span>";
					}else{
						$paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}
				}
			}
		}

				// Next
		if ($page < $counter - 1){
			$paginate.= "<a href='$targetpage?page=$next'>next</a>";
		}else{
			$paginate.= "<span class='disabled'>next</span>";
			}

		$paginate.= "</div>";
}
?>

This will create a variable containing the navigation and also allow us loop through the data that will be shown on this page. To do this we will had the following below that bulk of code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Make it short || Admin &rArr; <?php echo $username ; ?> <?php echo $title; ?></title>
		<!-- Start of CSS -->
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/main.css" />
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/admin.css" />
		<!-- Start of JS -->
 	<script type="text/javascript" src="<?php echo BASE_URL; ?>/files/js/jquery.js"></script>
 	<script type="text/javascript" src="<?php echo BASE_URL; ?>/files/js/add.js"></script>

<?php if($_GET['deleted']): //we will use this function to display a row saying "deleted" after we are redirected by out delete page. ?>
<script type="text/javascript">
$(function() {
	var deleted = document.location.hash.substr(1); // this gets the # value in the url
	$('p#' + deleted ).prepend("<h1 class='deleted'>DELETED</h1><p class='push'></p><hr /><p class='push'></p>");
});
</script>
<?php endif; ?>
</head>
<body>
<div id="header">
<p class="push"></p>
<?php echo "<a href='" . BASE_URL . "/files/process/logout.php' class='headLink Logout'>Logout " . $username . "?</a>"; ?>
<a class='headLink Settings right' href="<?php echo BASE_URL; ?>/admin/settings.php">Settings</a>
<a class='headLink Admin right active' href="<?php echo BASE_URL; ?>/admin/">Admin</a>
</div>
<div id="stripAdmin">
	<div id="stipWrap">
		<p class="push"></p>
		<?php echo $paginate; //display the navigation ?>
		<p class="push"></p>
		<p class="right">FYI: <?php echo $total_pages; //display the amount of records ?> URLS have been shortened</p>

		<?php
		$i = 0;
		while($row = mysql_fetch_array($result)): //for every result loop through this ?>
		<p class="push"></p>
		<p id="<?php echo $i;  ?>"></p>
		The full URL is:
		<a class="longurl" href="<?php echo urldecode($row['long']); ?>"><?php echo urldecode($row['long']); ?></a><br />
		The short URL is:
		<a class="longurl" href="<?php echo BASE_URL . "/". $row['short']; ?>"><?php echo BASE_URL . "/". $row['short']; ?></a><br />
		Clicks: <?php echo  $row['clicks']; ?><br />
		<p class="push"></p>
		This URL was added on <?php echo date("dS F Y g:i a", strtotime( $row['dateAdded'])); ?> and is currently set to 

				<form action="<?php echo BASE_URL; ?>/files/process/change_active.php" method="post">
					Active:
					<input <?php if($row['active'] == 1){?>checked=""<?php } // show as active is the url value is still active?>
					class="toggle" name="visible" value="1" type="radio" /><br />

					Inactive:
					<input <?php if($row['active'] == 0){?>checked=""<?php }?>
					name="visible" value="0" type="radio" class="toggle" />

					<input class="toggle" type="hidden" name="urlID" value="<?php echo $row['id']; ?>" /><br /> <!-- SO WE KNOW WHAT TO CHANGE -->
					<input class="toggle" type="hidden" name="page" value="<?php echo $pageRet; ?>" /><br /><!-- TO REDIRECT THE USER AT THE END -->
					<input class="toggle" type="hidden" name="ret" value="<?php echo $i; ?>" /><br /><!-- move user to item  on redirect-->
					<input type="submit" value="Change" />
				</form>

			<!-- Delete button -->
			<a class="delete " href="<?php echo BASE_URL; ?>/files/process/deleteItem.php?urlID=<?php echo $row['id']; ?>&page=<?php echo $pageRet; ?>&ret=<?php echo $i; ?>">Delete Item?</a>
			<p class="push"></p>
			<hr/> <!-- A line to separate -->
			// increment $i and end loop
		<?php $i++; endwhile;
			// display naviagtion
		echo $paginate;

		?>
	</div>
</div>
<div id="end"></div>
</body>
</html>

For that page, we will add the css file “admin.css” inside the css folder as this is just CSS for the admin page and there is no point loading it for people who are not logged in or don’t need it. We want to add:

body{font-family: "Lucida Grande", Verdana, Arial, sans-serif; font-size:18px;}
h1.large{
	color: white;
	font-size: 30px;
	font-weight: bold;
	font-family: "Lucida Grande", Verdana, Arial, sans-serif;
	padding: 10px;

}
.shorturl, .longurl, .link{color: #CBCBCB; text-decoration: none;}
.shorturl:hover, .longurl:hover, .link:hover{color: white;}
.right{float: right;padding-right: 20px;}
.toggle{width: 16px; height: 16px;}
.deleted{text-align: center;}
.headLink{color: white;text-decoration: none;}
.headLink:hover, .active{color: black;}
.delete{
background:none repeat scroll 0 0 transparent;
border:1px solid #CBCBCB;
color:#CBCBCB;
display:block;
float:right;
margin-top:-30px;
padding:5px;
text-align:right;
text-decoration:none;
width:110px;
}
.delete:hover{border: 1px solid red;color: red;}
.paginate{margin-top: 20px;padding-bottom: 20px;text-align: center;}
.paginate a, .disabled, .current{border:1px solid #CBCBCB;color:#CBCBCB;display: inline-block;padding:5px;text-align: center;margin:5px;text-decoration: none;}
.paginate a:hover{border:1px solid white;color:white;}
.disabled{border: none;}
.current{border: none;}
.tweetielink{text-decoration: none; color: white; font-size: 13px;}
.apiKeyBox{width: 700px; text-align: center;}

Function

In the functions.php file, go to the bottom and we will start writing some new functions that will be used in the tutorial.

function check_api_key($apiKey){ // checks if there is an API key present
	$existsQ = mysql_query("SELECT * FROM `users` WHERE `apiKey`='{$apiKey}' LIMIT 1");	// run a search to find it
	$exsitsRows = mysql_num_rows($existsQ);												// check amount of rows
	if($exsitsRows == 0 ){ 																// if there are 0 it was not found
		return false;
	}else{
		return true;
	}

}

function check_all_logins($loggedIn, $apiKey){ // this will check if we can allow the user to make urls shorter.
	if($loggedIn || !LOGIN_REQ){ // already logged in or they have a session saying logged in
		return true;
	}
	if(check_api_key($apiKey)){ // if API key was found...
		return true;
	}else{
		return false;
	}
}

function admin_page(){
	$loggedIn = $_SESSION['loggedIn'];
	if(!$loggedIn){
		header("Location:  ". BASE_URL . "/?show_loggin_area=1"); // we will add this in the index.php page, to have a way to show the
																	// login form even if the LOGIN_REQ field is set to false
		die();
	}
}

function get_user_info($username){ // get all information that is in the database about a specific use that is logged in
	$qur = mysql_query("SELECT * FROM `users` WHERE `username` ='{$username}' LIMIT 1;");
	$info = mysql_fetch_assoc($qur);
	return $info; // return as an array
}

function isNumber($i) { return (is_numeric($i) && !preg_match('/[[:^digit:]]/', $i) ? true : false); } // shows if a value is a number

function gen_api_key($email){ // will make a new API key for the user
    $toHash = time(); // the current time
    $toHash .= rand(0, 999999); // a random number
    $tohash .= $_SERVER['REMOTE_ADDR']; // the IP address of the user

    $toHash2 = rand(0, 999999);
    $toHash2 .= $email; // your email
    $hash1 = md5($toHash); // md5 the first hash
    $hash2 = md5($toHash2);  // md5 the second hash
  	$compleate =  $hash1 . $hash2;

  	return $compleate;
}

function get_data_for_url($shortURL){ // gets the user data from an API key
	$qur = mysql_query("SELECT * FROM `url` WHERE `short` = '{$shortURL}' LIMIT 1");
	if(mysql_num_rows($qur)){
		return mysql_fetch_assoc($qur);
	}else{
		return false;
	}
}

Now that the “admin_page()” function is set up we need to change the index.php in the home directory to show the login for when you are not have that variable in but you have been redirected with the variable to show the form. Open that page change the very top to the following:

<?php
require_once("files/functions/functions.php");
$loggedIn = $_SESSION['loggedIn'];
$username = $_SESSION['username'];
$url           = mysql_real_escape_string( strip_tags($_GET['url']));
$show_loggin_area = mysql_real_escape_string( strip_tags($_GET['show_loggin_area'])); // this gets the varible 

//echo $url;
if(strlen($url) >= 1){
	$redirect = true;
}else{
	$redirect = false;
}
if(!$redirect) :
?>

Then scroll down to

		<?php if( (LOGIN_REQ) && ($loggedIn != true) ){ ?>
				<h1 class="inform">Please login with the form below:</h1>
				<form class="loginForm" action="files/process/login.php" method="POST">
					<label for="username" class="label">Username:</label><br />
					<input type="text" id="username" class="smallInput" name="username"><br />

					<label for="password" class="label">Password:</label><br />
					<input type="password" id="password" class="smallInput" name="password"><br /><br />
					<input type="submit" value="Login me in!" />
				</form>

			<?php }else{ ?>
				<?php if($loggedIn){echo "<a href='" . BASE_URL . "/files/process/logout.php' class='logOut'>Logout " . $username . "?</a>"; } ?>
				<form id="linkForm" class="" action="files/process/add.php" method="post">
					<input value="Make me short..." type="text" class="smallInput" id="theLink" name="theLink"/>
					<input type="submit" id="submit" value="Shorten" />
				</form>		

				<ul class="postTo">
					<li class="tweetie"><a href="">Post With Tweetie</a></li>
					<li class="twitter"><a href="">Post To Twitter</a></li>
					<li class="facebook"><a href="">Share On Facebook</a></li>
				</ul>
		<?php }; ?>

and change it to

		<?php if( (LOGIN_REQ) && ($loggedIn != true) || ($show_loggin_area == true)  ){ ?>
				<h1 class="inform">Please login with the form below:</h1>
				<form class="loginForm" action="files/process/login.php" method="POST">
					<label for="username" class="label">Username:</label><br />
					<input type="text" id="username" class="smallInput" name="username"><br />

					<label for="password" class="label">Password:</label><br />
					<input type="password" id="password" class="smallInput" name="password"><br /><br />
					<input type="submit" value="Login me in!" />
				</form>

			<?php }else{ ?>				// link to logout
				<?php if($loggedIn){echo "<a href='" . BASE_URL . "/files/process/logout.php' class='logOut'>Logout " . $username . "?</a>";
								// link to settings page
					echo "<a href='" . BASE_URL . "/admin/settings.php' class='admin'>Settings</a>";
								// link to admin page
					echo "<a href='" . BASE_URL . "/admin/' class='admin pright'>Admin</a>";

				} ?>

This now makes sure that if you need to login to see the admin pages, even if LOGIN_REQ is set to false, it will show this form so you may login.

Change if active

Create a file change_active.php in the process folder and add the following:

<?php
require_once("../functions/functions.php");  // get the functions file
admin_page();
$error = false; // set this as default

$urlID = mysql_real_escape_string( strip_tags($_POST['urlID']) ); // The ID of item to change
$visible = mysql_real_escape_string( strip_tags($_POST['visible']) ); // If it will be visible or invisible
$page = mysql_real_escape_string( strip_tags($_POST['page']) ); // The page to redirect the user back to
$ret = mysql_real_escape_string( strip_tags($_POST['ret']) ); // The item to move the user to

// if "visible" does not have a value or not in integer, or urlID is less then/= to 0 or if urlID is not an integer
if( (strlen($visible) != 1) || (!isNumber($visible)) || (strlen($urlID)  <= 0) || (!isNumber($urlID)) ){
	$error = true;
	echo "ERROR!";
	$visible_or_id_not_valid = true;
}

if(!$error){ // if no error

	// check that the item exists
	$change = "
		SELECT * FROM `url` WHERE `id` = '{$urlID}' LIMIT 1;
	";
	$ran = mysql_query($change);
	$rows = mysql_num_rows($ran);
	if($rows != 1){
		$error = true;
	}else{ // it did exist so change it to the visible item that has been posted
		$setChange = "
			UPDATE `url` SET `active` =  '{$visible}' WHERE `id` ='{$urlID}' LIMIT 1 ;
		";
		mysql_query($setChange);
		// redirect to the page, and add a hash tag of the where to move
		// E.I. the "p" element the has a id of i
		header("Location: " .BASE_URL."/admin/index.php?page={$page}#{$ret}");
	}
}

This should now let you add change if it is active.

Delete Item

Next create a file called deleteItem.php and we will add this:

<?php
require_once("../functions/functions.php");  // get the functions file
admin_page();
$error = false; // set this as defalt
$urlID = mysql_real_escape_string( strip_tags($_POST['urlID']) ); // The ID of item to change
$page = mysql_real_escape_string( strip_tags($_POST['page']) ); // The page to redirect the user back to
$ret = mysql_real_escape_string( strip_tags($_POST['ret']) ); // The item to move the user to
	// if id is not set					and its not a number
if( (strlen($urlID)  <= 0) || (!isNumber($urlID)) ){
	$error = true; // error
	echo "ERROR!";
	$id_not_valid = true;
}

if(!$error){ // if no error

	// check if it is in the database
	$change = "
		SELECT * FROM `url` WHERE `id` = '{$urlID}' LIMIT 1;
	";
	$ran = mysql_query($change);
	$rows = mysql_num_rows($ran);
	if($rows != 1){
		$error = true;
	}else{	// was found so delete the item
		$setChange = "
			DELETE FROM `url` WHERE `url`.`id` = '{$urlID}' LIMIT 1;
		";
		mysql_query($setChange);
			// redirect the use back to the correct page and put deleted set
			// to true, this will show the jquery script that puts "deleted"
			// in the right place due to adding a #item
		header("Location: " .BASE_URL."/admin/index.php?page={$page}&deleted=1#{$ret}"); 

	}
}else{
	echo "And error was found.";
}
// print_r( $_POST );

The Settings page

This settings page will have a few useful items

  1. Display API key
  2. Generate new API key
  3. Display a link to copy into Tweetie 2 to use as your custom URL shortener
  4. Add new user

Open the settings.php page and add the following

<?php
require_once("../files/functions/functions.php");
admin_page();
$username = $_SESSION['username'];
$info = get_user_info($username);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Make it short || Admin &rArr; <?php echo $username ; ?> <?php echo $title; ?> || Settings</title>
		<!-- Start of CSS -->
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/main.css" />
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/admin.css" />
		<!-- Start of JS -->
 	<script type="text/javascript" src="<?php echo BASE_URL; ?>/files/js/jquery.js"></script>
 	<script type="text/javascript" src="<?php echo BASE_URL; ?>/files/js/add.js"></script>
</head>
<body>	

<div id="header">
<p class="push"></p>
<?php echo "<a href='" . BASE_URL . "/files/process/logout.php' class='headLink Logout'>Logout " . $username . "?</a>"; ?>
<a class='headLink Settings right active' href="<?php echo BASE_URL; ?>/admin/settings.php">Settings</a>
<a class='headLink Admin right ' href="<?php echo BASE_URL; ?>/admin/">Admin</a>
</div>

<div id="stripAdmin">
	<div id="stipWrap">
		<h1 class="large">Hello <?php echo $username; ?>,</h1>
			<!-- Putting the API key into a text box makes it more clear that this is what the user should copy (and makes it easier to copy that parts you want -->
		Your current API key is: <input type="text" value="<?php echo $info['apiKey'];?>" class="smallInput apiKeyBox" /><br /><br />
		Generate a new API key? <a class="link" href="<?php echo BASE_URL; ?>/files/process/newKey.php">Yes, please.</a><br />

		<p class="push"></p>

		<h1>Add new user</h1>
			<form action="<?php echo BASE_URL;?>/files/process/makeUser.php" method="POST">
				<input type="text" class="smallInput" value="Username" id="username" name="username" />(Username)<br /><br />
				<input type="text" class="smallInput" value="Email" id="email" name="email" />(Email)<br /><br />
				<input type="password" class="smallInput" id="password" name="password" /> (Password)<br /><br />
				<input type="submit" value="Add User" />
			</form>

		<?php
		//	print_r($info);
		?><br /><br />
		To get Tweetie to work, copy this into the "Custom URL" field in the app:<br /><br />
		<?php
			// gets the tweetie link that will allow the user to copy and past it
			echo "<a class='tweetielink' href=' " . BASE_URL . "/files/process/add.php?apiKey=" . $info['apiKey'] . "&theLink=%@'>" . BASE_URL . "/files/process/add.php?apiKey=" . $info['apiKey'] . "&theLink=%@</a>";
		?>
		<br /><br />

	</div>
</div>
<div id="end"></div>
</body>
</html> <?php
require_once("../files/functions/functions.php");
admin_page();
$username = $_SESSION['username'];
$info = get_user_info($username);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Make it short || Admin &rArr; <?php echo $username ; ?> <?php echo $title; ?> || Settings</title>
		<!-- Start of CSS -->
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/main.css" />
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/admin.css" />
		<!-- Start of JS -->
 	<script type="text/javascript" src="<?php echo BASE_URL; ?>/files/js/jquery.js"></script>
 	<script type="text/javascript" src="<?php echo BASE_URL; ?>/files/js/add.js"></script>
</head>
<body>	

<div id="header">
<p class="push"></p>
<?php echo "<a href='" . BASE_URL . "/files/process/logout.php' class='headLink Logout'>Logout " . $username . "?</a>"; ?>
<a class='headLink Settings right active' href="<?php echo BASE_URL; ?>/admin/settings.php">Settings</a>
<a class='headLink Admin right ' href="<?php echo BASE_URL; ?>/admin/">Admin</a>
</div>

<div id="stripAdmin">
	<div id="stipWrap">
		<h1 class="large">Hello <?php echo $username; ?>,</h1>
			<!-- Putting the API key into a text box makes it more clear that this is what the user should copy (and makes it easier to copy that parts you want) -->
		Your current API key is: <input type="text" value="<?php echo $info['apiKey'];?>" class="smallInput apiKeyBox" /><br /><br />
		Generate a new API key? <a class="link" href="<?php echo BASE_URL; ?>/files/process/newKey.php">Yes, please.</a><br />

		<p class="push"></p>

		<h1>Add new user</h1>
			<form action="<?php echo BASE_URL;?>/files/process/makeUser.php" method="POST">
				<input type="text" class="smallInput" value="Username" id="username" name="username" />(Username)<br /><br />
				<input type="text" class="smallInput" value="Email" id="email" name="email" />(Email)<br /><br />
				<input type="password" class="smallInput" id="password" name="password" /> (Password)<br /><br />
				<input type="submit" value="Add User" />
			</form>

		<?php
		//	print_r($info);
		?><br /><br />
		To get Tweetie to work, copy this into the "Custom URL" field in the app:<br /><br />
		<?php
			// gets the tweetie link that will allow the user to copy and past it
			echo "<a class='tweetielink' href=' " . BASE_URL . "/files/process/add.php?apiKey=" . $info['apiKey'] . "&theLink=%@'>" . BASE_URL . "/files/process/add.php?apiKey=" . $info['apiKey'] . "&theLink=%@</a>";
		?>
		<br /><br />

	</div>
</div>
<div id="end"></div>
</body>
</html>

That should be it for that page, we just need to make the two files that the forms submit to. They are “makeUser.php” and “newKey.php”. Start by making “makeUser.php” in the process file and add this:

<?php
require_once("../functions/functions.php");  // get the functions file
admin_page();
$error = false; // set this as defalt

$username = mysql_real_escape_string( strip_tags($_POST['username']) ); // Get the username that was posted
$email = mysql_real_escape_string( strip_tags($_POST['email']) ); // Get the email address
$password = mysql_real_escape_string( strip_tags($_POST['password'])); // get the password

if(strlen($username) < 5 ){ 	// if the username is above 5 char
	$error = true;			// if its not set an error
	$errorMessages['username'] = "Please write a username"; // what the error is
}
if(strlen($password) < 5){ // same with password
	$error = true;
	$errorMessages['password'] = "Please write a password";
}

if(preg_match("/ /", $username)){ // check that the username has no white space.
	$error = true;
	$errorMessages['spaces'] = "Username cannot contain white space";
}

if(preg_match("/ /", $username)){ // check that the username has no white space.
	$error = true;
	$errorMessages['spaces'] = "Username cannot contain white space";
}
			// validate email address
if (!preg_match('/^[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $email)) {
	$errorMessages['email'] = "Please enter a VALID email address";
	$error = true;
}

// if no error
if(!$error){ // if no error
	$password = md5($password); // hash the password
		// we will check if the use is in the database already
	$newQuery = mysql_query("SELECT *
		FROM `users`
		WHERE `username` =  '{$username}'
		OR `email` = '{$email}'
		LIMIT 1");

	$newRows = mysql_num_rows($newQuery);
	if($newRows == 0){ // if no info was found with either email or username
		$apiKey = gen_api_key($info['email']); // create an API key for that user
		// then insert them into the database
	mysql_query("INSERT INTO `users` (`username` ,`password` ,`email`, `apiKey`)
				VALUES ('{$username}', '{$password}', '{$email}', '$apiKey') ");
		// and redirect them back to the settings page
	header("Location: " . BASE_URL  . "/admin/settings.php");
	}else{ // if they were
		$error = true;//set an error
		$errorMessages['inAlread'] = "The username or email address is in use already!";
	}

}
if($error){ // if there is an errir
	foreach( $errorMessages as $errorMessage ){ // for every error message
		echo "Problem: " . $errorMessage . "<br />"; // echo it out
	}
}

And finally for the admin pages, we want create the “newKey.php” page to make the new API key. In the newKey.php file we will add a small bit of code, as we have the functions that we need set up:

<?php
require_once("../functions/functions.php");  // get the functions file
admin_page();  // will check if user is logged in, if not it will redirect and stop the script running
$error = false; // set this as defalt

$user = get_user_info($_SESSION['username']); // make sure we have  everything we need

$newAPI = gen_api_key($user['email']); // gen the user a new code
// update their row in the database
mysql_query("UPDATE `users` SET `apiKey` = '{$newAPI}' WHERE `id` ={$user['id']} LIMIT 1");
// and finally redirect them back to the settings page
header("Location: " . BASE_URL . "/admin/settings.php");

And that is all we need to make a new API Key for a user. Next, we just have to make the “stats” page which will show users that are not logged in how many clicks a link has gotten. For this, open the stats folder we made in the last tutorial (inside files then a folder called stats) we want to add another .htaccess file here and put inside it the following code:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]

Stats

Put an index.php file inside this stats folder, and here we will create the way to display info about the URL.

<?php
require_once("../functions/functions.php");
$url            = mysql_real_escape_string( strip_tags($_GET['url']));
$data 			= get_data_for_url($url); // get the data from the database
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Make it short || Stats</title>
		<!-- Start of CSS -->
	<link rel="stylesheet" type="text/css" href="<?php echo BASE_URL; ?>/files/css/main.css" />
		<!-- Start of JS -->
 	<script type="text/javascript" src="files/js/jquery.js"></script>
 	<script type="text/javascript" src="files/js/add.js"></script>
 	<style>
 		#stipWrap{
 			font-size: 20px;
 			text-align: center;
 		}
 	</style>
</head>
<body>
<div id="header">
	<div class="process"><div class="processingC"></div></div>
</div>
<div id="strip">
	<div id="stipWrap">
		<?php //print_r($data); ?>
		<p class="push"></p>
		<h1>Stats</h1><br />
		URL = <a class="longurl" href="<?php echo urldecode( $data['long'] ); ?>"><?php echo urldecode( $data['long'] ); ?></a><br />
		Short URL = <a class="shorturl" href="<?php echo BASE_URL . $data['short']; ?>"><?php echo BASE_URL . $data['short']; ?></a><br />
		Date Added	= <?php echo date("dS F Y g:i a", strtotime( $data['dateAdded'])); ?><br />
		Clicks	= <?php echo $data['clicks']; ?><br />
		Last Clicked	= <?php echo date("dS F Y g:i a", strtotime( $data['lastClicked'])); ?><br />

	</div>
</div>
<div id="end"></div>
</body>
</html>

And that should be done! We now have a full featured URL shortener set up, I hope that you found this interesting and you can download all the completed files here

Be Sociable, Share!

Related posts:

  1. Create URL Shortener For Twitter Using PHP
  2. Cross Browser Placeholder Text For Input Fields


Written by brenelz

Hello everyone, I'm Brenley Dueck or better known as Brenelz. I currently run my own business called Brenelz Web Solutions which focuses primary on winnipeg website design. The web technologies I most specialize in are CSS, jQuery, AJAX, PHP, and the MySQL database. Please make sure to follow me on twitter.

 

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
connect with me!