Saturday, March 22, 2008

PHP MySQL Image Gallery

On the previous tutorial you already know how to upload and download files to the server. Now we're gonna reuse the codes to build an image gallery. It's a simple image gallery where the admin ( that's you ) is the only one who can add/modify/delete the album and images. The "normal folks" can only browse around the image gallery checking out the images from one album to another

The admin section contain the following :
Add New Album
Album List
Edit & Delete Album
Add Image
Image List
Edit & Delete Image

And the visitor page contain these :
Display Album List
Display Image List
Display Image Detail

Now, before we go straight to the codes we need to talk about the database design, directory layout, and configurations.
Database Design

For a simple image gallery like this we only need two tables, tbl_album and tbl_image. Here is the SQL to create these tables

Source code : image-gallery.sql
CREATE TABLE tbl_album (
al_id INT NOT NULL AUTO_INCREMENT,
al_name VARCHAR(64) NOT NULL,
al_description TEXT NOT NULL,
al_image VARCHAR(64) NOT NULL,
al_date DATETIME NOT NULL,
PRIMARY KEY(al_id)
);


CREATE TABLE tbl_image (
im_id INT NOT NULL AUTO_INCREMENT,
im_album_id INT NOT NULL,
im_title VARCHAR(64) NOT NULL,
im_description TEXT NOT NULL,
im_type VARCHAR(30) NOT NULL,
im_image VARCHAR(60) NOT NULL,
im_thumbnail VARCHAR(60) NOT NULL,
im_date DATETIME NOT NULL,
PRIMARY KEY(im_id)
);
Directory Layout

The image below show the file organization for the image gallery



The images directory is where we kept all of the images. The image icons are stored in the thumbnail sub-directory uder the gallery. Please remember to set write access to the album, gallery, and thumbnail directories otherwise the gallery script will not be able to save the images.
Configurations

There are some constants in the config file that you should change :
ALBUM_IMG_DIR, GALLERY_IMG_DIR
These are the absolute path to the images directories

THUMBNAIL_WIDTH
The PHP script will create a thumbnail ( icons ) for each image that you upload. In addition when you add an album image that image will also resized automatically.

One more note. If you want to test this gallery on your own computer please make sure you already have GD library installed. To check if GD library is installed on your system save the following code and run it.
if (function_exists('imagecreate')) {
echo 'OK, you already have GD library installed';
} else {
echo 'Sorry, it seem that GD library is not installed/enabled';
}
?>

This is a very simple form where you can enter the album name, description and image. After you click the "Add Album" button the script will do the followings :
Save the album image, resize it if necessary
Save the album information to database

Below is the screenshot of the form:



And here is the code snippet :

Example : admin/add-album.php
Source code : admin/add-album.phps

require_once '../library/config.php';
require_once '../library/functions.php';

if(isset($_POST['txtName']))
{
$albumName = $_POST['txtName'];
$albumDesc = $_POST['mtxDesc'];

$imgName = $_FILES['fleImage']['name'];
$tmpName = $_FILES['fleImage']['tmp_name'];

// we need to rename the image name just to avoid
// duplicate file names
// first get the file extension
$ext = strrchr($imgName, ".");

// then create a new random name
$newName = md5(rand() * time()) . $ext;

// the album image will be saved here
$imgPath = ALBUM_IMG_DIR . $newName;

// resize all album image
$result = createThumbnail($tmpName, $imgPath, THUMBNAIL_WIDTH);

if (!$result) {
echo "Error uploading file";
exit;
}

if (!get_magic_quotes_gpc()) {
$albumName = addslashes($albumName);
$albumDesc = addslashes($albumDesc);
}

$query = "INSERT INTO tbl_album (al_name, al_description, al_image, al_date)
VALUES ('$albumName', '$albumDesc', '$newName', NOW())";

mysql_query($query)
or die('Error, add album failed : ' . mysql_error());

// the album is saved, go to the album list
echo "";
exit;
}



Since we save the images as files instead inserting them to the database we need to make sure there won't be any name duplication problem. To prevent this we just generate some random name for every images that we upload. Take a look at code below :
$ext = strrchr($imgName, ".");
$newName = md5(rand() * time()) . $ext;
The first line is to extract the file extension from the file name. As an example let say we upload an image named "hyperalbum.jpg". Then strrchr("hyperalbum.jpg", ".") will return ".jpg". On the second line we generate a random number using rand() multiply it with current time and generate the hash code using md5(). It is a very common practice to use the combination of md5(), rand() and time() functions to generate a random name. After we append the file extension to the new name we can then use it to save the uploaded image.

But before we save the image we need to resize the image if it's too large. As you can see in the album list we only need small images for the album icons. To make the thumbnail we use createThumbnail() function defined in functions.php . Once everything is saved we print a little javascript code to go to the album list page. Note that we cannot simply use header("Location: index.php?page=list-album") to redirect to the album list page since a call to header() will only have an effect when no other output in sent before the call.

Admin : Album List

When your first login to the admin area and after adding a new album you can see this page. There's nothing really interesting on this one. It just a plain list of albums where we can see the albums we have and how many images on each album. Here is the snapshot :



In the "Images" column you can see how many images contained in an album. If you click on the number you will go to the image list so can see all the images in a particular album. And i'm sure i don't need to explain what that button with "Add Album" written on it does.

If you re-read the sql containing the table definitions of this gallery you can see that tbl_album doesn't contain any column storing the number of images in it. That number is the result of the left join in the sql query. You can see the sql code below.
$sql = "SELECT al_id,
al_name,
al_image,
COUNT(im_album_id) AS al_numimage
FROM tbl_album al
LEFT JOIN tbl_image im ON al.al_id = im.im_album_id
GROUP by al_id
ORDER BY al_name ";

In this query we must use LEFT JOIN instead of INNER JOIN because an album can have zero image in it. If we use INNER JOIN then the empty albums will not be shown in the list.

Now, if you right click on an album icon and view it's properties you can see that the url fo the icon is pointing to a PHP script instead of an image. The url look like this : viewImage.php?type=album&name=3b6a267a967d7535ff3b1ebc3d9e3c1e.jpg

In this image gallery whenever we would want to display an album or image icon or the full-size image we always use the viewImage.php file instead of linking to the actual image. There are several reasons to do this. The first is so you could move the images directory outside of your web root to prevent leechers from taking all the images.

The image gallery in our example doesn't do this. You could go to the images directory and list all the images in the gallery. If you set the value of ALBUM_IMG_DIR and GALLERY_IMG_DIR to a directory outside your webroot then you can prevent this. For example if your web root is /home/myname/public_html you can set ALBUM_IMG_DIR to /home/myname/images/album and GALLERY_IMG_DIR to /home/myname/images/gallery/.

The second reason is that you may want to restrict the access your gallery. For example the visitors must login before they can see the images. In viewImage.php you could check for the session variable to determine that. So if the visitors hasn't login yet you just display some blank or warning images

You can checkout the code here. It's really a simple script which requires two inputs. The type of image you wish to display ( album icon, image icon or full size image ) and the image file name. Then we only need to set the appropriate headers, read the image file and send it to the browser.

Next we'll see how to modify & delete an album.

No comments: