Asp.Net asynchronous file upload using jquery

In Asp.net ajax, we have AsyncFileUpload control for uploading files asynchronously. If you are using JQuery with in your Asp.net application, then using microsoft ajax AsyncFileUpload control is not a good practice to upload files asynchronously. Form Last couples of days I was trying to upload and delete files asynchronously using JQuery in Asp.Net and finally I was able to upload and delete files asynchronously. Here I am sharing my asynchronous file upload code. For getting file size before upload refer the article Get file size before upload using jquery.

In order to get the things going well, you’ll need the following :-

  1. JQuery 1.4 or above. You can download it form here

  2. JQuery File Upload plugin You can download it form here

Simple File Upload Control

When you will run this code, you will find the below screen for uploading the files. This is a simple file upload control with browse button.

Change style of browse button

To achieve this, I am uisng css to change the default style of file upload control. Basically I put the file upload control in a wrapper and this wrapper will be shown to the user in-place of file upload control as shown below:

Now you can upload file to the server on single click after browsing the file. For uploded file you can also provide the description. By default it is showing the file name. You can change this description as you wish.

Every time when you will come on this page a new folder will be created and yours uploaded files will be saved in this newly created folder.

Check file extension to be upload

In this demo, I am also checking the file extension to be upload. You can define your own extension of file to be upload. If you try to upload the file that is not present in extensions list it will show the below error message.

View/Download file from Server

You can view or download the uploaded file from the server. When you will click the view link then you will see the below option in IE for save and open file from the server.

Delete file from Server

When you will click on the delete link , it will ask for confirmation. If you click ok, then it will delete the file. Screen shots for the file deleting process are shown as –

 

Advertisements

Add Author Image in Google Search

Introduction

This is super simple to do with many people asking how we do it. This awesome feature makes it so that in search results for your site, your picture is shown alongside – demo. It’s been shown that people are more drawn to results that have a person’s picture next to them, and it’s not at all hard to do for the additional hits.

The Before

The first thing to do before you set up the tag that you need is to register on Google Plus, you will want to make sure that you’ve given yourself a profile picture – this is the image that will display alongside the search result.

When you’ve got yourself a shiny profile picture, you need to add your site link to your profile in the Contributor To section, this is to prove to Google that you’re actually related to the site, and not just being a fool.

Finally, you want to grab your profile link – for me that would be: https://plus.google.com/109699957362436337904/posts

The During

Now we simply add a tag to the page header to show that we’re the author for the post, we place a link element within the head section of the site, so using my above profile link it’d be:

<link rel="author" href="https://plus.google.com/109699957362436337904/posts">

Here on Codular we give each author their own author tag on their page, but don’t add any author tags to non-article pages, for the sole reason that those pages contain information from all the different authors.

The After

That should be it now – it can take a while for the changes to be reflected within the Google search results, but this is no different to the standard schedule that Google will use to index your site.

You can test that you’ve set everything up correctly by running your site through this helpful tool from Google.

Introduction to Regular Expressions

Introduction

Regular expressions are awesome. Regular expressions are confusing. They are used widely to match certain patterns of strings within another string, and can commonly be used for email address validation, URL validation and even for stripping non-alphanumeric characters from a string. If you skim the surface of regex, it can be rather fun and easy, but diving deeper and combining regular expression syntax things can get complicated and confusing quickly!

The Basics

Let’s start with a very simple scenario, if we have the phrase The cat sat on the mat. and want to see if the string contains the word cat using JavaScript’s Regex.test(String) method we’d use the following:

var s = 'The cat sat on the mat.';
if(/cat/.test(s)){
    alert('We found a cat!');
} 

With the regular expression of /cat/ you can see that we’ve found a cat – as expected.

Simple grouping

This is all well and good, but what if we want to check if the phrase has cat, sat or mat in it? For multiple options we place them in brackets () and separate them by a pipe |. So we could in theory use the regex of:

/(cat|sat|mat)/

That would work, but I personally think that’s a lot of repetitiveness, so why don’t we break that down a bit. We can simplify that down to:

/(c|s|m)at/

What this is matching is a c or s or m followed immediately by at, so cat, sat or mat, with me so far? Let’s complicate it a bit more, but keep it with simple strings.

Repetition repetition

Let’s change the string that we have to Hey, look look a book on a stool, now we want to match the word look, simple, use /look/, no problems there. But let’s think about that, we have repeated letters, I don’t like repetitiveness.

/lo{2}k/

That will work the same, might look complicated, and yes, it’s overcomplicating this, but it highlights the scenario well. We can get a number of occurances of a string by using curly braces with a number in. So for three occurances we could use {3} and {9} for nine, straight forward.

Match look look (which is two occurances of look followed by a space) with /(look ){2}/ or even /(lo{2}k ){2}/ – we’re not getting complex yet! That’s all cool, but what if we want to match a string that could be look, loook, looook or loooook but not looooook.

/(look|loook|looook|loooook)/

Yea, sod that, it’s just ridiculous! We can put a comma after our first number in those braces to insert a number of occurances to go up to. So in our case we can use:

/lo{2,5}k/

Nice, neater and simple to understand. So let’s throw everything together for now, we want to match the word book, look, loook and looook so we could use any of the following:

  • /(book|look|loook|looook)/
  • /(boo|lo(o|oo|ooo))k/
  • /(bo{2}|lo{2,4})k/

There’s many possibilities, why not tweet us if you have a better alternative!

One character from a selection

Above we’ve used (b|l) and (c|s|m) which again, is pretty awesome and slender regex, but why do something half-arsed? Let’s take that a step further and introduce some square brackets [] – these denote a collection of characters that can be used – but only one of them, and one occurance.

  • /(b|l)/ becomes /[bl]/
  • /(c|s|m)/ becomes /[csm]/

Nice, and simple, and we can of course use the braces after them to make x occurances be allowed…

`/[acmst]{2,3}/`

This will match any one of the following:

  • ac
  • am
  • as
  • at
  • acm
  • acs
  • act
  • amc
  • ams
  • amt

And so forth but will only match 2 or 3 characters, so might match in the word ham or cat or Birmingham.

Optional matching

Anything that’s preceeded by a question mark ?, will be classed as optional, so if we were to have a regular expression to match either flow or flo, we could use the following:

/flow?/

That will mean that the w is an optional match, and isn’t required to be matched.

Ranges

For a range of letters or numbers we are able to separate the first and last by a hyphen. This will then match anything that’s within that range, saving us from writing out all of the letters from a to z, we can use a-z. Also 0-9 and A-Z are available to use. So let’s match two capital letters, then one lowercase then a number:

/[A-Z]{2}[a-z][0-9]/

It’s as simple as that.

‘Not’ operator

When we’re using square bracket matching we might want instead to list characters that shouldn’t be matched, we can do that by making sure the first character in the brackets is actually a caret ^. So for example to match anything that isn’t alphanumeric we could use the regex:

/[^a-zA-Z0-9]/

Dot notation

If we want to just match whatever is between two characters we can use a ., this will match any character (except for a newline character), and so can be handy at times. This is the same as using the regular expression /[^\r\n]/, and is normally followed by a multiple occurance selector.

Multiple occurrences

We’ve already seen the brace method in use to select multiples of a string, but what if we don’t know how many there will be, what if we just want to blanket catch? This is where we have two symbols that we can use, but be careful using them!

  • * – matches 0 or more occurances, the same as {0,}
  • + – matches 1 or more occurances, the same as {1,}

You need to be careful because both of the above symbols are greedy, meaning that if you had the regular expression of /<.*>/ used against the string <strong>Testing</strong>, this wouldn’t match the first <strong> tag as you would hope, infact it matches the whole string.

This is where we use the previously mentioned question mark – /<.*?>/ – this makes it not greedy and will then match the first <strong> tag as originally hoped.

Start and end of line

All of the expressions that we’ve used so far will match at any point in a line. We might at some point want to only select the letter at the start of the line, or perhaps a number at the end of the line. We can do this by using two special symbols:

  • ^ – will match the start of the line
  • $ – will match the end of a line

So to match a line that doesn’t end is a semicolon we could use some handy regex:

/[^;]$/

Match Modifiers

That trailing slash that you see can be followed by different letters to alter the behaviour of the regular expression:

  • i – Case insensitite matching is enabled, meaning you can put all of your regular expressions in lower case and they will match upper case too.
  • m – Enables multi-line mode, the caret and dollar match both before and after newlines.
  • s – Enables single-line mode, the dot will match new-line characters now as well

I personally rarely use anything other than the i modifier as it saves having to worry about matching capital letters too.

Predefined Groups

There are a few predefined groups for any number, whitespace or letter, they also have negatives:

  • \w – any word character including letters, digits and underscores
  • \s – any whitespace characters including tabs, spaces and line breaks
  • \d – any digit 0-9

The negations for each of these is as simple as using the capital letter, \W, \S and \D respectively.

Escaping Characters

Finally, you’ll realise that we’ve used a lot of characters as identifiers, modifiers and match helpers. But what if we want to match that symbol (such as $) in our regular expression? Simple, just preceed it with a backslash much like you would when you escape quotes inside quotes etc. Let’s try matching a PHP variable that is just letters:

/\$([a-z]+)/

Futher Thoughts and Ideas

A lot of what I’ve shown you has matchers all grouped in brackets, in most cases when you’re matching you’re looking to use the matched string in a separate section, this is what the brackets will do – they are classed as a capturing group. If you want to change this group to not being captured, you can put a ?: straight after the opening bracket, this means that it will match the regex still, but just won’t capture what’s been matched.

If you’re not thoroughly confused yet, you will be when you look into other items such as lookaheads, lookbehinds and boundaries – but those are beyond the scope of this basic tutorial for now.

Some final examples

Change a string (alpha-numeric and underscore) that is followed by .php into /testing/{string}/index.php where {string} is what we matched, we’ll firstly write the regular expression, there are multiple options we can do – take a look below:

/(\w+)\.php/
/([a-z0-9-]+)\.php/i
/(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|_|0|1|2|3|4|5|6|7|8|9)\.php/i

The last one is mostly for example, and should really not be used – at all!

Now to replace what we’ve matched with the output, firstly javascript:

var s = 'login.php';
s = s.replace(/(\w+)\.php/, '/testing/$1/index.php');

Finally PHP:

$s = 'login.php';
$s = preg_replace("/(\w+)\.php/", "/testing/$1/index.php", $s);

The Challenge

There are a lot of examples on the internet of various matching regular expressions – but why don’t you try to come up with a regular expression to match the word bacon, dog and baton but not baconz in the following sentence. When you’ve got a solution why don’t you tweet us with it.

Uploading Files with PHP

Introduction

You can’t go on any site nowadays without seeing an option to upload an image. All of the big sites are doing it, however it’s one of those things that is very poorly covered in PHP articles across the internet. We’ll cover the basic upload process and then in a future article move on to additional things like image resizing and cropping.

The HTML Form

With this, you’ll be using an input of type file, this will give the user an input which when clicked will give the user a browse box to choose the file to upload. The form that you put this in must have an enctype of multipart/form-data.

<form method='post' enctype='multipart/form-data' action='upload.php'>
    File: <input type='file' name='file_upload'>
    <input type='submit'>
</form>

The PHP

Normally when a form is posted to a PHP page, you can get the values of fields by looking in the $_POST global array, however, file uploads get put in a separate one called $_FILES. This is indexed with the name of the file input that you chose before, so in our case we’ll be looking into the $_FILES['file_upload'] array. There are a few different values within this array that you use: name, type, size, tmp_name, error.

When uploading, running a print_r on $_FILES will return something similar to this:

Array
(
    [file_upload] => Array
    (
        [name] => e4f.png
        [type] => image/png
        [tmp_name] => /Applications/MAMP/tmp/php/phpodzfRk
        [error] => 0
        [size] => 328119
    )
)

The process we’re going to use is pretty straight forward:

  • Check if there are any errors in the upload.
  • Check if the file type is allowed.
  • Check that the file is under our file size limit.
  • Check that the file doesn’t already exist (based on name).
  • Finally upload the file.

Check if there are any errors in the upload.

If the error number is greater than 0, there’s an error. So simply, we can do:

if($_FILES['file_upload']['error'] > 0){
    die('An error ocurred when uploading.');
}

Check if the file type is allowed.

We only want to allow .png files to be uploaded, so we’re going to have to make sure that the type is image/png, again simply:

if($_FILES['file_upload']['type'] != 'image/png'){
    die('Unsupported filetype uploaded.');
}

Check that the file is under our file size limit.

Sizes are all based in bytes, so if we don’t want any files bigger than 500kb uploading, we’ll have to check that the size is less than 500000:

if($_FILES['file_upload']['size'] > 500000){
    die('File uploaded exceeds maximum upload size.');
}

Check that the file doesn’t already exist (based on name).

We’re going to be putting our files in a directory called upload. You need to make sure that you CHMOD this directory to have the required permissions for writing. We will simply use the PHP function file_exists():

if(file_exists('upload/' . $_FILES['file_upload']['name'])){
    die('File with that name already exists.');
}

There is no reason that you can’t prepend, or append the timestamp of the upload to the name to make it unique, and in some cases might be a sensible thing to do.

Finally upload the file.

Finally, we want to upload the file, as at this point if the script is still running the file is safe to upload. We will simply move the file using the move_uploaded_file function from its current temporary location to where we want it:

if(!move_uploaded_file($_FILES['file_upload']['tmp_name'], 'upload/' . $_FILES['file_upload']['name'])){
    die('Error uploading file - check destination is writeable.');
}

Upload Security

One of the vital things to realise is that are potentially allowing anything to be uploaded to your site which could be used to maliciously take over your server. You should be sure to employ some common sense when doing this, and some of the below methods will help you go someway to making your uploads secure. There are plenty of other methods you could use.

Storage location

When allowing a user to upload files, you should store them outside the web root, this means a directory that is not inside the www or public_html directory on most systems. This means that if someone manages to upload a script or something to your site intead of an image they will not be able to access it.

You can then display the images through a separate PHP file that will load the image and explicitly set the headers for the image and output it to the user using specific PHP image functions such as imagecreatefrompng so if it’s not an image the display will fail.

Make sure you never allow direct access to the file from the web, that could just get very nasty

Verify upload is an image

One of the best things to do when uploading is to ensure that it is an actual image that is being uploaded, you can do this by passing the uploaded file through a PHP image function such as getimagesize(), this will return false if the file is not an image:

if(!getimagesize($_FILES['file_upload']['tmp_name'])){
    die('Please ensure you are uploading an image.');
}

This will check that the file is an image, and die telling the user to ensure that it’s an image that is being uploaded and not just a malicious file pretending to be an image.

Disable script execution

Another thing to do, is to use some .htaccess code to disable the execution of scripts within your uploads file. Something along the lines of the code below in a .htaccess file in your uploads directory should help:

AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI

Chown Uploads Directory

You should definitely change the owner of the uploads directory, make it so that it’s owned by apache and that it has the permissions 770 and it shouldn’t be accessible by any user. However, the directory will still be modifiable through your various PHP scripts. This method might not be possible on shared hosting environments where you don’t have root permissions.

Other ideas

You can check the extension against a list of blacklisted extensions such as .php, .js, .pl, .py etc. But you shouldn’t rely on this as your only security check that you use.

Complete

It’s as simple as that, one thing to think about is if you’re uploading files, you will probably want to store a history of who uploaded the file and when in a database. Find below the complete PHP code:

<?php

// Check for errors
if($_FILES['file_upload']['error'] > 0){
    die('An error ocurred when uploading.');
}

if(!getimagesize($_FILES['file_upload']['tmp_name'])){
    die('Please ensure you are uploading an image.');
}

// Check filetype
if($_FILES['file_upload']['type'] != 'image/png'){
    die('Unsupported filetype uploaded.');
}

// Check filesize
if($_FILES['file_upload']['size'] > 500000){
    die('File uploaded exceeds maximum upload size.');
}

// Check if the file exists
if(file_exists('upload/' . $_FILES['file_upload']['name'])){
    die('File with that name already exists.');
}

// Upload file
if(!move_uploaded_file($_FILES['file_upload']['tmp_name'], 'upload/' . $_FILES['file_upload']['name'])){
    die('Error uploading file - check destination is writeable.');
}

die('File uploaded successfully.');

PHP and jQuery Contact Form

Introduction

Contact forms, are generally easy things to create. The issue that many people have with them is that they’re not too sure about how to send an email out after the contact form has been filled in. Many people also want to make the form use AJAX, to make it all sexy but struggle when it gets to that section. This tutorial will guide you through how to firstly build a contact form that normally posts, but then also extends to introduce how to use the $.ajax() method of jQuery.

The Form

We’ll throw in a few different types of fields here so that we can learn how to manipulate them all, nothing complex here, just a nice simple bit of HTML:

<form method='post' action='/contact.php'>
    Name: <input type='text' name='name' required><br>
    Email: <input type='email' name='email' required><br>
    Gender: <select name='gender'>
        <option value='m'>Male</option>
        <option value='b'>Bacon</option>
        <option value='f'>Female</option>
    </select><br>
    Bacon: <input type='radio' name='bacon' value='smoked' checked> <input type='radio' name='bacon' value='unsmoked'><br>
    Check Me: <input type='checkbox' name='checkme'><br>
    <input type='submit' value='Send'>
</form>

You’ll see in there the addition of the required attribute, and also type='email', these are new in HTML5 and are a form of validation that is enforceed by the browser.

Receiving Data

Nothing here needs to be complex, we’re going to be using the global array $_POST, and simply going through each field, checking that the fields that are required are provided, and then forming an email message to send out. There’s no reason that you can’t take the fields and store them in a database.

Check the required fields

Here we’ll be using a method called empty() which checks, amongst other things, that the variable is both provided and not blank:

if(empty($_POST['name']) || empty($_POST['email'])){
    die('Please ensure name and email are provided.');
}

Dealing with the select

Dealing with a select is pretty easy, there’s no validation or that to do in our case, however, if you have a default value for your select that shouldn’t be selectable you will want to check that. Eg: If we had a default option with text ‘Please Select’ and a value of ‘-‘:

if($_POST['gender'] == '-'){
    die('Please ensure you have selected a gender.');
}

Checkboxes aren’t normal

A checkbox is either sent, or it’s not. This means that you’ll want to check that the field is set within the $_POST array. So in this example, we’ll alter a string if the checkbox is checked compared to if it’s not. Using isset() we can see if the field has been sent through with the form or not:

if(isset($_POST['checkme'])){
    $checkString = 'I have been checked.';
}else{
    $checkString = 'I have not been checked.';
}

Compose The Email

Now we can begin to write the message that we’re going to send off to ourselves letting us know that someone has contacted us, we’ll do that using this code:

// Blank message to start with so we can append to it.
$message = '';

// Check that name & email aren't empty.
if(empty($_POST['name']) || empty($_POST['email'])){
    die('Please ensure name and email are provided.');
}

// Check the checkbox
$checkString = 'I have not been checked.';
if(isset($_POST['checkme'])){
    $checkString = 'I have been checked.';
}

// Construct the message
$message .= <<<TEXT
    Name: {$_POST['name']}
    Email: {$_POST['name']}
    Gender: {$_POST['gender']}
    Bacon: {$_POST['bacon']}    
    {$checkString}
TEXT;

Here you’ll see some crazy syntax in the form of <<<TEXT and TEXT;, this is called Heredoc. I tend to use it because at times it looks neater, and cleaner, also Sublime Text 2 syntax highlights code in those blocks based on the word you put after the <<< eg: <<<XML as XML etc.

Send the Email

We’ll be using the mail() function here, this is really simple, it takes a few parameters that let you specify email, subject, message and some additional headers. We are going to send an email to test@testdomain.com, with a subject You have been contacted, and our prewritten message above, and setting the email being sent from Your Site.

$to = 'test@testdomain.com';
$subject = 'You have been contacted!';
$from = 'Your Site';
$fromEmail = 'YourSite@domain.com';

$header = 'From: ' . $from . '<' . $fromEmail . '>';

if(!mail($to, $subject, $message, $header)){
    die('Error sending email.');
}else{
    die('Email sent!');
}

Security Thoughts

If you’re going to be inserting data into your database, you want to make sure that you are fully aware of any potential issues with SQL injections, which you should be able to deal with by escaping dangerous characters. If you’re using MySQLi you can do this by using the mysqli::escape_string() method.

One consideration to make is whether you want to strip out the html elements that may have been entered using the strip_tags() method. One other precaution you can make is to ensure that your email is sent strictly as plain text, instead of setting a HTML header.

Data validation is vital, while we’re doing some client side validation through our use of type='email' in the email field, this isn’t supported in all browsers. Also, you shouldn’t rely on client side validation as being secure or anything as ultimately data being posted to a server can be spoofed. You might want to look at doing some regular expression checks on the email address that is submitted by the user – this will be covered in a future article on Codular.

A final consideration to make is the addition of a unique ID or something that gets sent across with the form. This would go someway to possibly posting malicious data over to you and causing issues. This unique ID could be a unique hash of a timestamp and the user’s IP or something.

sha2(date('dmYHi') . $_SERVER['REMOTE_ADDR']);

You can then check that the submitted ID is the same on the recipient page – this token of course would only be valid for 1 minute, which is plenty of time to submit a simple contact form. You should of course look to throw in additional unique fields for the user, perhaps a unique ID that’s also sent across with the form?

Allowing user’s to do whatever they want (ie submitting a free text form) is a very risky business and is definitely something you should take extreme caution with, but with some basic steps you’ll soon be more secure than you were to start with!

Complete

And just as quickly as we started, we have finished, the basic part anyway. The full PHP is available just below, read on to look at how we can make this form post using jQuery’s $.post() function.

<?php

// Blank message to start with so we can append to it.
$message = '';

// Check that name & email aren't empty.
if(empty($_POST['name']) || empty($_POST['email'])){
    die('Please ensure name and email are provided.');
}

// Check the checkbox
$checkString = 'I have not been checked.';
if(isset($_POST['checkme'])){
    $checkString = 'I have been checked.';
}

// Construct the message
$message .= <<<TEXT
    Name: {$_POST['name']}
    Email: {$_POST['name']}
    Gender: {$_POST['gender']}
    Bacon: {$_POST['bacon']}    
    {$checkString}
TEXT;

// Email to send to
$to = 'test@testdomain.com';

// Email Subject
$subject = 'You have been contacted!';

// Name to show email from
$from = 'Your Site';

// Domain to show the email from
$fromEmail = 'YourSite@domain.com';

// Construct a header to send who the email is from
$header = 'From: ' . $from . '<' . $fromEmail . '>';

// Try sending the email
if(!mail($to, $subject, $message, $header)){
    die('Error sending email.');
}else{
    die('Email sent!');
}

jQuery-ify Your Form

Our PHP code that we wrote just before should work absolutely fine. We need to add an id to the form and all of its elements, except for the radio button which we’ll give a class, so that we can access them through JS.

We can now use the following jQuery code:

$(function(){
    $('#form').submit(function(e){

        // Stop the form actually posting
        e.preventDefault();

        // Send the request
        $.post('/contact.php', {
            name: $('#name').val(),
            email: $('#email').val(),
            gender: $('#gender').val(),
            bacon: $('.bacon:checked').val(),
            checkme: $('#checkme').is(':checked')
        }, function(d){
            // Here we handle the response from the script
            // We are just going to alert the result for now
            alert(d);
        });
    });
});

Firstly, we’re stopping the form from submitting using e.preventDefault() as it normally would because we’re sending the request through the AJAX post instead.

We next use $.post() which takes 3 parameters, the first being the URL that we’re posting to, the next being an object of data to send, and finally a callback function that will get the data from the script.

Getting the value of the fields is as simple as using .val() in two cases we have used the CSS selector of :checked which will only select the checked item – but in the case of the checkbox we are checking that it is checked by using .is().

We are just alerting out the response at the moment, but there’s no reason you can’t just put that in a div that has and id of result using some code like:

$('#result').html(d);

It might be worth looking at disabling the submit button when the user hits submit so that it’s not submitted multiple times. You can do this using some jQuery similar to below if you give the submit button an id of submit-button:

$('#submit-button').attr('disabled', 'disabled')

The Final Frontier

And that is the end, hope you’ve found it helpful and it’s solved some/any questions that you might have had. Find below the jQuery’d HTML, the PHP we use is exactly the same as above.

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Sample Contact Form</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
    <script>
    $(function(){
        $('#form').submit(function(e){

            // Stop the form actually posting
            e.preventDefault();

            // Send the request
            $.post('/contact.php', {
                name: $('#name').val(),
                email: $('#email').val(),
                gender: $('#gender').val(),
                bacon: $('.bacon:checked').val(),
                checkme: $('#checkme').is(':checked')
            }, function(d){
                console.log(d);
                // Here we handle the response from the script
                // We are just going to alert the result for now
                alert(d);
            });
        });
    });
    </script>
</head>
<body>  
    <form method='post' action='/contact.php' id='form'>
        Name: <input type='text' name='name' required id='name'><br>
        Email: <input type='email' name='email' required id='email'><br>
        Gender: <select name='gender' id='gender'>
            <option value='m'>Male</option>
            <option value='b'>Bacon</option>
            <option value='f'>Female</option>
        </select><br>
        Bacon: <input type='radio' class='bacon' name='bacon' value='smoked' checked> <input type='radio' class='bacon' name='bacon' value='unsmoked'><br>
        Check Me: <input type='checkbox' id='checkme' name='checkme'><br>
        <input type='submit' value='Send'>
    </form>
</body>
</html>

Build It: URL Shortener

Introduction

Every time you look on Twitter at a URL someone has posted it’s been shortened to a t.co url – awesome huh? There’s many others out there like bit.ly. What if you want to write your own? Well, you could use your domain with bit.ly if you wanted, but how about having your own system running on your own server. Well here I guide you through how to do it from the SQL databases, all the way to writing an API for URL shortening.

Outline

We’re going to be using MySQLi, and a lot of object oriented PHP, for some good measure we’ll be throwing in some regular expressions too. We’ll start with the database structure and then build a simple shortener class to use. We’ll go via logging hits to a URL, and come full circle to writing a neat API that you can use anywhere to generate a URL of your choosing.

Complete source code and video walk through are available at the bottom of the article.

The database

URLs

We need a table for the URLs to be stored in, and one for the hits as well. All we really need for the URL is the place to direct to, an ID, IP of who added it and when it was created.

The following SQL will create a table called urls where we’ll store all of the shortened URLs:

CREATE TABLE  `urls` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `url` VARCHAR( 255 ) NOT NULL ,
    `ip` VARCHAR( 39 ) NOT NULL ,
    `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = INNODB, CHARSET = UTF8;

Nothing too complicated here – we have to ensure that we have the primary key setup as we will be searching based on that – and the last thing we want is to compromise the speed of the queries by not indexing.

Hit counting

For hit counting we’ll just store the IP, the time and the URL that the user is accessing:

CREATE TABLE  `hits` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `url` INT UNSIGNED NOT NULL ,
    `ip` VARCHAR( 39 ) NOT NULL ,
    `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = INNODB, CHARSET = UTF8;

Very similar to our other table, except that we have the URL as an integer here as this will ultimately form as a foreign key to the urls table that we earlier made.

You might at some point want to log what system or method your links were created through – this could be the API or a web interface. Ultimately you could add an extra column to the database called method which would be an integer, with 1 being web and 2 being API – we won’t be doing that currently.

The URL Class

Now that we have the database set up as we want we’re going to go ahead and create one file called Urls.class.php – this will handle everything that we need, instantiate a database connection, create a URL, check a URL exists etc.

Constructor

We only want to instantiate the database connection once so we’ll assign an instance of the MySQLi object to a private static variable called _connection.

if(is_null(self::$_connection)){
    self::$_connection = new mysqli('localhost', 'root', 'root', 'personal');
}

Also, you need to ensure that you’re storing the user’s IP at some point so that you can put it into the database, for this we will be using the value that is stored in the global array $_SERVER, using index REMOTE_ADDR.

Adding a URL

Adding a URL is as simple as running an INSERT query on the url table that we created earlier. We’ll be passing through a parameter called $link to the variable which will be the URL that we should store.

We’ll be using prepared statements here so that we don’t need to worry about escaping characters in the queries. If the query executes successfully you should be sure to return the ID of the inserted link by using the variable insert_id which is in the MySQLi statement.

$query = self::$_connection->prepare("INSERT INTO `urls` (`url`, `ip`) VALUES (?, ?)");
$query->bind_param('ss', $link, $this->userIP);
$query->execute();
return $query->insert_id;

Be sure to include error checking as well with all of your database interactions.

Getting a URL

A simple SELECT statement which is just going to be passed an ID to get from the database. This can pretty much follow the same process as the previous method, except returning the result URL.

Nice and simple …

$query = self::$_connection->prepare("SELECT `url` FROM `urls` WHERE `id` = ?");
$query->bind_param('i', $id);
$query->execute();
$query->bind_result($url);
$query->fetch();
return $url;

This just runs the query, binds the result to the variable $url and then returns that URL for us to use – perhaps to redirect the user to.

Storing a hit

Storing a hit is nothing spectacular, we’re just going to insert a new row into the hits table every time that someone access the link.

$query = self::$_connection->prepare("INSERT INTO `hits` (`url`, `ip`) VALUES (?, ?)");
$query->bind_param('is', $linkId, $this->userIP);
$query->execute();
return TRUE;

Nothing to return other than a success so that we know that the query has been executed, of course you should be doing some error checking to ensure that the query has actually executed – don’t just assume that it has.

Class complete

Now that we’ve got the basics of the class written, we can look to write some of the other pages. There are 2 other pages to write:

  1. The page that the user gets taken to as the short URL page
  2. The page that gets the URL to shorten, shortens it and returns the short URL.

Redirect user to short url

To start with we’ll just have the user go to a page called redirect.php which will take a GET parameter of id which is an integer – so for example for URL 7 we’d have them go to redirect.php?id=7.

On this page we will look up the URL, and if there is a result we’ll add a hit and then redirect them off to the URL. If there is no result we’ll just say that there’s no result to redirect the user to. To check if the URL exists we’ll just look for a NULL response.

include('Urls.class.php');

$l = new Urls();
$link = $l->getShort($_GET['id']);

if(is_null($link)){
    die('Unknown short URL.');
}

$l->addHit($_GET['id']);

header('Location: ' . $link);

To redirect the user off we can use a simple header function setting the Location parameter as above. Remember always to add in error checking – making sure that the actual URL exists and that the user has set an ID to redirect off to.

What if…

This looks ugly – it defeats the object to have people going to http://site.com/redirect.php?id=151 or whatever to redirect. Lets look at how to glamourise this in two ways:

  1. An alphanumeric id for the url eg: ahc1
  2. URL such as http://site.com/ahc1

We’ll need to write a method that will convert from an ID to a nice string, and one that will convert back. We can do that using the following methods:

function numToAlpha($num){
    $return = "";
    $alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-_";
    $n = floor($num/strlen($alpha));
    if($n > 0)
        $return .= numToAlpha($n);
    $return .= $alpha[$num % strlen($alpha)];
    return $return;
}

function alphaToNum($s){
    $alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-_";
    $return = 0;
    $i = strlen($s);
    $s = strrev($s);
    while(isset($s[--$i])){
        $return += strpos($alpha, $s[$i]) * pow(strlen($alpha), $i);
    }
    return $return;
}

You can build these in to your URL class as static methods, also you can make them use the same $alpha string too.

Once you’ve done that, we can now look to change our previous redirect code a little, where we were previously passing in $_GET['id'] to the getShort() and addHit() methods we can now pass in Urls::alphaToNum($_GET['id']) where id is the shortened URL string such as ahc1. You can test that’s all working by using the same redirect.php?id=ahc1 path.

Now let’s make that neater, we’ll need to write a .htaccess rule to change any URL ending one of our predefined characters to the reirect path. To do this we use a thing called mod_rewrite. Firstly we need to construct a regular expression that will match any of the characters in our $alpha string, we can do that using the following:

([a-zA-Z0-9_\-\+]+)

This will match 1 or more occurances of the items within the square brackets, we can then choose where to put that in the rewrite by using the string $1:

# Turn on the rewrite engine
RewriteEngine On

# Don't rewrite any directory or file that exists: 
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d

# Rewrite!
RewriteRule ^([a-zA-Z0-9_\-\+]+)$ redirect.php?id=$1

With that, you should be able to go to http://site.com/ahc1 and it will automatically do exactly the same as going to the redirect.php path. You can now place this .htaccess file (that’s the name of it by the way) in the same directory as the redirect.php file. This would normally be the domain’s root directory.

Page to shorten URL

Finally we need a page to shorten the URL – this will simply take in a URL, insert it into the URL and then kick back the url that the user should use. Remember, this will no longer be an id at the end of the URL – this will be a string of characters from our earlier $alpha string.

The long and short of it is as simple as doing this:

include('Urls.class.php');

if(empty($_GET['url'])){
    die('Please provide a URL to shorten.');
}

$l = new Urls();
$linkId = $l->addShort($_GET['url']);

echo 'http://site.com/' . Urls::numToAlpha($linkId);

You could add in the ability to check if a URL exists by adding a method to the Urls class called checkShort() for example.

The End

That is the basic idea behind creating a URL shortener, however there are many other features that you could add in such as:

  • Check if the URL exists before adding it to the database
  • Add a URL filter – so that flagged URLs don’t get added to the system
  • Valid URL checking – run a check to see if the URL is actually valid

Overall, you should now be able to create and run your own URL shortening service – go have a play!

Support and Download

All of our Build-It articles are more full featured than our basic tutorials in that we offer a video tutorial as well as full source code to download. However, to maintain Codular, we offer these at a very low cost of $2.99. Don’t look at it as paying for the files, see it as a donation, but getting something awesome back.

If you’re interested in downloading simply click here to do so, PayPal is required for now. Look out for us on Twitter where we might give away discount codes for up to 50% off.

jQuery Autocomplete Dropdown

Introduction

Here we’re going to be building a predictive/autofill drop down box that will let your users see suggestions based on what they’re typing. This can be commonly seen on Facebook and Google when searching or tagging users. I suggest you take a look at the awesome JSON article that we have before starting. We’ll also be using jQuery, which is a super powerful JavaScript library.

HTML & CSS

We need to start by getting some HTML written up to hold our search box, and results. We’ll be showing our results in a simple unordered list, with each list item containing a span that has the name, and a span underneath with a little bit of a description.

Something along the lines of the following should work well:

<div class='suggest-holder'>  
    <input type='text' class='suggest-prompt'>
    <ul>
        <li>
            <span class='suggest-name'>Michael</span>
            <span class='suggest-description'>The Writer</span>
        </li>
        <li>
            <span class='suggest-name'>Ben</span>
            <span class='suggest-description'>The Other Writer</span>
        </li>
        <li>
            <span class='suggest-name'>Ben</span>
            <span class='suggest-description'>The CodeIgniter Writer</span>
        </li>
    </ul>
</div>

Of course, that is all well and good, but at the moment it looks dreadful, let’s give it some very basic styling with CSS, I’ve just used the following:

.suggest-holder {
    width: 150px;
}
    .suggest-holder input {
        width: 146px;
        border: 1px solid rgba(0,120,0,.6);
    }
    .suggest-holder ul {
        display: none;
        list-style: none;
        margin: 0;
        padding: 0;
        border: 1px solid rgba(0,120,0,.6);
        margin-top: -6px;
    }
        .suggest-holder li {
            padding: 5px;
        }
        .suggest-holder li:hover {
            cursor: pointer;
        }
        .suggest-holder li:hover, li.active {
            background: rgba(0,120,0, .2);
        }
            .suggest-name {
                font-weight: bold;
                display: block;
                height: 15px;
            }
            .suggest-description {
                font-style: italic;
                font-size: 11px;
                color: #999;
            }

This will just give us a nice section that we can use, at the moment the whole drop down will be visible, this is not what we want, so go ahead and drop a display: none; on the ul that we have. Also, we don’t need the li elements that we have within the ul, but just remember the markup so that we can use them later to inject results with JS.

The JS

There are a few parts to this:

  1. The array storing data
  2. Keyup event on the input
  3. Selection of the item
  4. Show selected items

Array storing data

We’re going to just store the items in a array of objects so that we can then traverse them to return the results that we want, for this we don’t need a complex array, something simple like:

var data = [
    {
        name: 'Michael',
        description: 'The Writer'
    },
    {
        name: 'Ben',
        description: 'The Other Writer'
    },
    {
        name: 'Joel',
        description: 'The CodeIgniter Writer'
    }
];

Now that we have the array of objects, let’s look into taking the user’s key presses…

Keyup event on the input

For this we’re going to use the jQuery .on() method which let’s us define a few different events to listen to on an element, for now we will listen to the keyup method.

$('.suggest-holder input').on({
    keyup: function(e){

    }
});

Select Item

We select the items to show within the keyup event, for this we’re going to run some very basic logic:

  • Clear the ul element
  • Construct a Regular Expression to use to search
  • Loop through array
  • Check if search term is in the name of the person
  • For each result append a new li element with the correct children

The code below should do that for us:

// Clear the ul
$('.suggest-holder ul').empty();

// Cache the search term
$search = $(this).val();

// Search regular expression
$search = new RegExp($search.replace(/[^0-9a-z_]/i), 'i');

// Loop through the array
for(var i in data){
    if(data[i].name.match($search)){
        $('.suggest-holder ul').append($("<li><span class='suggest-name'>" + data[i].name + "</span><span class='suggest-description'>" + data[i].description + "</span></li>"));
    }
}

That will then append all matched items to the holder ul, note here that we’re removing any letter is that not alphanumeric or underscore from the search before matching with items in the object.

We need to use the below line to show the list of suggestions:

// Show the ul
$('.suggest-holder ul').show();

Show the selected items

We need someway to show what items have been selected by the users, to do that we need to add an event listener to each li that will simply add the item to an element on the page:

For this, we’re not going to do anything special, but we’re going to simply add a new li for each thing that is selected to a ul – we’ll just give it an id of selected-suggestions

$('.suggest-holder li').on('click', function(){
    $('#selected-suggestions').append($('<span>' + $(this).find('.suggest-name').html() + '</span>'));
});

Nothing too complex there, but enough to make it so that we can see what has been selected from the drop-down list that we show.

Basics Complete

This is a very crude system that we have in place, now we can push this a lot further to make it a completely awesome system for people to use, to do that we’ll be pushing the keyup method of the input a lot further, and expanding the code there.

Pushing it further

The main slightly more advanced things that we want to add are:

  • Keyboard navigation
  • Enter and Esc key support
  • Remove selected items

Keyboard navigation

Here there are 2 different keys that we want to listen to:

  • Up arrow: Move selection up
  • Down arrow: Move selection down

For this we want to set a global integer that will store which number of item we’re onto, and then when you press one of the keys it will alter this number and then set a class of active that we set the CSS for earlier to the correct li:

if(e.which == 38){
    // Down arrow
    index--;

    // Check that we've not tried to select before the first item
    if(index < 0){
        index = 0;
    }

    // Set a variable to show that we've done some keyboard navigation
    m = true;
}else if(e.which == 40){
    // Up arrow
    index++;

    // Check that index is not beyond the last item
    if(index > $('.suggest-holder li').length - 1){
        index = $('.suggest-holder li').length-1;
    }

    // Set a variable to show that we've done some keyboard navigation
    m = true;
}

// Check we've done keyboard navigation
if(m){
    // Remove the active class
    $('.suggest-holder li.active').removeClass('active');
    $('.suggest-holder li').eq(index).addClass('active');
} 

We will integrate this into the rest of the code at the very end.

Enter and Esc key support

This is pretty simple, we want to be able to make it so that users can do everything from the keyboard:

  • Esc: Hides the drop down
  • Enter: Selects the active item & reset the previous keyboard index to -1

To do that, we’ll again, use the keyup event and listen for the above keys using the following code:

if(e.which == 27){
    // Esc key
    $('.suggest-holder ul').hide();
}else if(e.which == 13){
    // Enter key
    if(index > -1){
        index = -1;
        $('#selected-suggestions').append($('<span>' + $('.suggest-holder li.active').find('.suggest-name').html() + '</span>'));
        $('.suggest-holder li.active').removeClass('active');
    }
}

Of course, what we might want to do here is actually create a function for adding items to the selected list, this should take the element as a variable and will tidy up some of the code. But we’ll get to the refactored code at the end!

Extra thoughts

One thing you’ll notice if you run the code now is that when using the up and down arrows, the cursor jumps to the start or end of the text entered. To fix that we listen to the keydown event and preventDefault() on the event for those keys:

if(e.which == 38 || e.which == 40 || e.which == 13){
    e.preventDefault();
}

Secondly, you’ll want to add in some code that will hide the suggestions drop down when the user clicks anywhere other than on one of the suggestions or input box, to do that we want to attach a click event to the body element, which will check if you’ve clicked one of the li elements or the input – if not, hide:

$('body').on('click', function(e) {
    if (!$(e.target).closest('.suggest-holder li, .suggest-holder input').length) {
        $('.suggest-holder ul').hide();
    };
});

Finally, you’ll want to make it so that when you click within the box with something already being entered in it, that it reshows the suggestions box, for this you will want to listen to the focus event and just show the ul.

Pushing Further

This is a very basic start on how to accomplish a basic suggestion box, but what you might want to do is have it so that when you click on one of the items it gets removed from the dropdown, with the option then for people to delete the selected suggestions. There are a few ways to do this:

  • Remove the item from the suggestions dropdown.
  • Store some unique identifying information about that item to the selected item li.
  • When adding items to the suggestions box, check that they are not in the selected items.
  • When you delete one of the selected items, you can simply delete the item completely, the above logic will then pick it up as being removed.

The End

One major thing to remember is to refactor the code when you’ve finished it – as this has been written in sections, the code is going to be a lot less optimised than it could be. Take a look at the full complete version, including refactored code on our demo page.