// If our gallery contains images, show either the selected// image, or if there are none selected, then show the first one.if file_exists$thumb && is_file$thumb {... In Figure 7-4, an i
Trang 1obj.innerHTML = xmlhttp.responseText;
}}xmlhttp.send(null);
document.getElementById("errordiv").innerHTML = "";
document.getElementById("middiv").innerHTML = "<b>Loading </b>";}
function refreshView(){
// Reload the full-size image
setTimeout ('runajax ("middiv","midpic.php")',refreshrate);
// Reload the navigation
setTimeout ('runajax ("picdiv","picnav.php")',refreshrate);}
function uploadimg(theform){
// Update user status message
runajax("errordiv", "delpic.php?pic=" + theimg);
refreshView();
}
Trang 2function imageClick(img){
updateStatus();
runajax('middiv', 'midpic.php?curimage=' + img);
runajax('picdiv', 'picnav.php?curimage=' + img);
}
<?php
//config.php// Max dimensions of generated images
$GLOBALS['allowedfiletypes'] = array(
'jpg' => array('load' => 'ImageCreateFromJpeg',
'save' => 'ImageJpeg'),'jpeg' => array('load' => 'ImageCreateFromJpeg',
'save' => 'ImageJpeg'),'gif' => array('load' => 'ImageCreateFromGif',
'save' => 'ImageGif'),'png' => array('load' => 'ImageCreateFromPng',
'save' => 'ImagePng'));
Trang 3// Number of images per row in the navigation.
{
$images = array();
if (is_dir($GLOBALS['imagesfolder'])) {
$files = scandir ($GLOBALS['imagesfolder']);
foreach ($files as $file) {
$path = $GLOBALS['imagesfolder'] '/' $file;
}// Calculate the new dimensions based on maximum allowed dimensions.function calculateDimensions($width, $height, $maxWidth, $maxHeight){
$ret = array('w' => $width, 'h' => $height);
$ratio = $width / $height;
Trang 4if ($width > $maxWidth || $height > $maxHeight) {
}// A function to change the size of an image
function createThumb($img, $maxWidth, $maxHeight, $ext = ''){
$path = $GLOBALS['imagesfolder'] '/' basename($img);
if (!file_exists($path) || !is_file($path))return;
$pathinfo = pathinfo($path);
$extension = $pathinfo['extension'];
if (!array_key_exists($extension, $GLOBALS['allowedfiletypes']))return;
Trang 5// Check for a valid file upload.
if (!isset($_FILES['myfile']) || $_FILES['myfile']['error'] != UPLOAD_ERR_OK)exit;
// Check for a valid file type
if (in_array($_FILES['myfile']['type'], $GLOBALS['allowedmimetypes'])){// Finally, copy the file to our destination directory
$dstPath = $GLOBALS['imagesfolder'] '/' $_FILES['myfile']['name'];move_uploaded_file($_FILES['myfile']['tmp_name'], $dstPath);
require_once ("functions.php");
$imgarr = getImages();
Trang 6// If our gallery contains images, show either the selected// image, or if there are none selected, then show the first one.
if (file_exists($thumb) && is_file($thumb)) {
<a href="delpic.php?pic=<?= $curimage ?>"
onclick="removeimg ('<?= $curimage ?>'); return false">
<img src="delete.png" alt="Delete image" />
</a>
</div>
<?php
}}elseecho "Gallery is empty.";
?>
<?php
//picnav.phprequire_once ("config.php");
require_once ("functions.php");
Trang 7//Find a total amount of images.
$numtoshow = min($numimages, $GLOBALS['maxperrow']);
$firstidx = max(0, $selectedidx - floor($numtoshow / 2));
if ($firstidx + $numtoshow > $numimages)
$firstidx = $numimages - $numtoshow;
for ($i = $firstidx; $i < $numtoshow + $firstidx; $i++) {
if (!file_exists($thumb) || !is_file($thumb))continue;
?>
<td<?php if ($selected) { ?> class="selected"<?php } ?>>
<a href="sample7_1.php?curimage=<?= $file ?>"
onclick="imageClick('<?= $file ?>'); return false">
<img src="<?= $thumb ?>" alt="" />
</a>
</td>
<?php
Trang 8Here, you see what to expect when you run the image gallery application in your web
browser Figure 7-1 shows how the gallery looks after a series of images have been
uploaded to it (in this case, it’s a gallery of cute little kitties)
In Figure 7-2, you can see how some simple CSS effects provide the gallery with amuch nicer user experience In this case, a border is simply added to the image when the
user hovers over the image with their mouse
Figure 7-3 shows how easy it is to upload an image to the gallery—just select it fromyour local hard disk and then click the submit button!
In Figure 7-4, an image has just been deleted, and the display has been updated toindicate this to the user
Trang 9Figure 7-2.CSS animation provides a nifty layer of fun to your gallery navigation.
Trang 10Figure 7-4.Kitten not looking all that cute anymore? No problem—simply remove the
image.
How It Works
All right, so you have had a good look at the code and witnessed what the end result looks
like Now let’s take some time to understand how it works The main file to have a look at
is the sample7_1.phpfile This file is the wrapper that holds the rest of the code in place,
and it’s where you would go in order to use the gallery Let’s have a look
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
easier to maintain and simpler to move around In this case, the style sheet has been
moved into a file called style.css(shown previously in Listing 7-1)
Trang 11Likewise, most of the JavaScript in the photo gallery has been moved into an externalfile called functions.js, which controls all of the Ajax-based functionality in the photogallery We will go over more on that as you progress through this example.
<script type="text/javascript" src="functions.js"></script>
The first divwill contain the main viewing functionality of the gallery This is whereyou’ll be able to see the large image, as well as delete it from your gallery
<! Messages >
<div id="errordiv"></div>
The following code includes the gallery navigation, which is one of the more complexand unique portions of the photo gallery Like I mentioned before, I am rather tired of
generic next/previous navigation, and enjoy a more visual experience (this is a photo
gallery, after all) This pane will display a thumbnail of the currently selected photo, aswell as the photos directly before it on its left, and the photos directly after it on the right.Clicking an image in this pane will load it into the large image pane
<! Image navigation >
<div id="picdiv"><?php require_once ("picnav.php"); ?></div>
</div>
Trang 12The following code is where the actual image upload occurs This part is rather lar to Chapter 6 in that you are loading the image-processing script into an invisible
simi-iframeto give users the feeling that everything is happening dynamically, without the
page refreshing
It is important to remember the enctypeargument in the formtag Without the
enctypebeing properly set, the browser will not know that there could be files attached
<h2>Add An Image</h2>
<form action="process_upload.php" method="post" target="uploadframe"
enctype="multipart/form-data" onsubmit="uploadimg(this); return false">
<input type="file" id="myfile" name="myfile" />
<input type="submit" value="Submit" />
<iframe id="uploadframe" name="uploadframe" src="process_upload.php">
</iframe>
</form>
</body>
</html>
We will now go over the external JavaScript file In it resides the functions necessary
to run and maintain the majority of the Ajax functionality of the photo gallery (hidden
The first function created is used while loading or reloading images in the gallery
It is used to update the status messages in the application, first by clearing out any
error messages that exist, and then by updating the main image holder to display a
loading message
//Function to show a loading message
function updateStatus(){
document.getElementById("errordiv").innerHTML = "";
document.getElementById("middiv").innerHTML = "<b>Loading </b>";
}
Trang 13Next is a function called refreshView This function is used to reload the gallery Itdoes this by reloading the main image container, and then reloading the navigation strip.Since this needs to be done in several places, we made a function out of it (when animage is uploaded, and when an image is deleted).
The function works by using Ajax to reload the midpic.phpand picnav.phpscripts Weput each of these calls into the JavaScript setTimeoutfunction, which means the browserwaits the time specified by refreshratebefore loading those scripts
function refreshView(){
// Reload the full-size image
setTimeout ('runajax ("middiv","midpic.php")',refreshrate);
// Reload the navigation
setTimeout ('runajax ("picdiv","picnav.php")',refreshrate);
}
As shown in sample7_1.php, when the user uploads an image, the uploadimgfunction
is called The code for this function, shown following, first updates the status to the user
to indicate that something is occurring Next, the form is submitted to the hidden iframe
(i.e., the image is uploaded), and finally, the gallery is refreshed
function uploadimg(theform){
// Update user status message
Next, the removeimgfunction, which is called when a user clicks the Delete link beside
a gallery image, is defined This function simply uses Ajax to load the delpic.phpscript(which we will look closer at shortly), and then refreshes the gallery
function removeimg(theimg){
runajax("errordiv", "delpic.php?pic=" + theimg);
refreshView();
}
Trang 14Last is the imageClickfunction, which is called when an image is clicked from thegallery navigation These function calls could be embedded directly into each image’s
onclickevent, but instead, a separate function that cleans up the code has been created
This code simply refreshes the gallery, with the clicked image as the image that is to be
selected
function imageClick(img){
updateStatus();
runajax('middiv', 'midpic.php?curimage=' + img);
runajax('picdiv', 'picnav.php?curimage=' + img);
}
All right, so now that you have a solid wrapper and a means to make server requeststhrough JavaScript, let’s have a look at some of the server-side processes that are being
triggered First up is the midpic.phpfile, which controls the currently viewed image
The first aspect to notice is the inclusion of the configuration file (config.php) andthe functions.phpfile The configuration (viewable in the Listing 7-3) merely allows
you to customize the gallery to your preferences (again, keeping things modular) The
functions.phpfile (also viewable in the code section) merely houses a few functions for
maintaining the site
<?php
//midpic.php
require_once ("config.php");
require_once ("functions.php");
Next, the getImagesfunction (which is defined in functions.php) is called The
getImagesfunction returns an array of all the images in the gallery If one or more images
exist in the gallery, the image selected by the user will be outputted (specified by the
curimageURL parameter) If an image has not been selected (such as on the initial load),
the first image will instead be chosen If no images are found, a message will be displayed
Trang 15At this point, you have an image to be displayed, but you want to display it withinthe maximum dimensions specified in the configuration file (config.php) To do this,you create a resized version of the image by calling the createthumbfunction defined in
functions.php You pass in the maxwidthand maxheightconfiguration parameters to mine the size of the new image
deter-// Create a smaller version in case of huge uploads
$thumb = createthumb($curimage,
$GLOBALS['maxwidth'],
$GLOBALS['maxheight'],'_big');
Now that you’ve potentially created a new image, you just need to make sure the pathreturned by the createthumbfunction refers to a valid file Assuming it does, you outputthe image, as well the link to delete the image with
if (file_exists($thumb) && is_file($thumb)) {
<a href="delpic.php?pic=<?= $curimage ?>"
onclick="removeimg ('<?= $curimage ?>'); return false">
<img src="delete.png" alt="Delete image" />
?>
OK, let’s move on to the more complicated PHP aspect of the gallery The picnav.php
file’s goal it to show a visual thumbnail representation of the currently selected image, aswell as the images directly before and after the selected image The thing that makes this
Trang 16complicated is that your goal is to always show as many images as possible (subject
to the maxperrowsetting), while trying to keep the selected image in the middle of the
navigation
First, you include your external files again Note that this was done using the
require_oncefunction, as there may be instances in which both picnav.phpand midpic.php
are loaded at the same time This prevents functions and variables from being defined
multiple times (which will result in PHP errors)
Additionally, a list of the images in the gallery is retrieved, and the number of imagesfound is stored in $numimagesfor future use The code also checks that there actually are
images found—otherwise, there will be nothing to display
this to determine which images to show before and after the selected image By using
array_search, you can determine the index in the array of the image (remembering that
array indexes start at 0)
dis-images to show and which image to show first
To determine the number of images to show, you first look at the maximum you canshow, which is specified by the maxperrowsetting Obviously, you can’t show more images
than are available, so you use minto determine the smaller of the two numbers This is the
number of images you will show at one time
Trang 17To determine the first image to show, you divide $numtoshowby 2 and subtract thisnumber from the index of the selected image ($selectedidx) This effectively “centers” theselected image Obviously, though, if the selected image is the first image in the gallery,then there can be no images to the left of it—so you use maxto make sure the number isgreater that or equal to 0.
The final two lines check for a special case, where one of the last images in the gallery
is selected If the last image were centered in the display, then there would be nothing todisplay to its right (unless you repeated from the first image, which you are not doing inthis gallery) So, to handle this, you check whether centering the image will result in therenot being enough images after it—if there aren’t, the value of $firstidxis adjusted so thatthis won’t occur
<table id="navtable">
<tr>
<?php
$numtoshow = min($numimages, $GLOBALS['maxperrow']);
$firstidx = max(0, $selectedidx - floor($numtoshow / 2));
if ($firstidx + $numtoshow > $numimages)
$firstidx = $numimages - $numtoshow;
Now, you must loop over all the images to be displayed You are going to loop
$numtoshowtimes, starting with the $firstidximage Additionally, since you want to light the selected image, you must know when the loop is processing the selected image.This allows you to change the CSS class applied for this one image
high-for ($i = $firstidx; $i < $numtoshow + $firstidx; $i++) {
$file = $imgarr[$i];
$selected = $selectedidx == $i;
As you did when displaying the main image, you must now create a resized version ofthe current image to display In this case, you are displaying a small thumbnail, so youpass in the maxwidththumband maxheightthumbsettings Additionally, you again make surethat a valid file was returned, skipping the current loop if there is no thumbnail (using
continue)
$thumb = createthumb($file,
$GLOBALS['maxwidththumb'],
$GLOBALS['maxheightthumb'],'_th');