Programming - PHP - Alternative way to add images to your posts

Posted on 04/02/2009 17:00

Category: Programming


Hello folks!

As I was writing my previous post (the one about my awesome vacations :P) I stumbled across a little problem in my post edit thingie: it had no image handling.

Since I wanted to add some photos so you could actually see some of the beautiful sights I talked about, I immediately started thinking of ways to easily implement a "Add new image to post" feature capable of creating thumbnails aswell (since I'm a really nice guy and wouldn't want to strain your browsers with megabytes of data ;D).

The first, and most obvious, thing that came to mind was creating some kind of upload form (in a popup or using AJAX) that would accept an image file, process it, create a thumbnail and add the image code to the html of the post. The problem with this method is that it would take lots of time to implement correctly or would require extensive code tweaking to some third-party upload library in order to adapt it to my own needs.

While I was reflecting upon this issue, a cunning idea started to form in my mind. What if instead of using a local file I used a file already in the net? This way the need for an upload form (atleast in my site) would no longer be. That's how I came up with the following script.

In a nutshell, what this script does is parse your post (or any other block of text) looking for 'handleimg' tags. These tags will contain a link to an external image resource and an optional caption. When it finds such an entry, it will copy the external image to a folder in your server and create a thumbnail out of it. In the end, it replaces the old 'handleimg' tag with the proper 'a' and 'img' tags.

Example: <handleimg>http://www.lol.com/lol.png "A lol image"</handleimg>

The actual code

By now you must be tired of my mambo-jambo so I'll jump in right to the code:

  1. $content = preg_replace_callback('%\s*([^ <>]+)\s*(?:"([^"]*)")?%', 'replaceHandleImage', $_POST['entry_content']);

The above piece of code uses regular expressions to parse the post's text ($_POST['entry_content']) looking for 'handleimg' tags and calls the replaceHandleImage function whenever it finds one.

  1. function replaceHandleImage($matches)
  2. {
  3. $blogBase = "../blog";
  4. $blogImagesFolder = $blogBase . "/images"; //folder for the real-size images
  5. $blogThumbsFolder = $blogBase . "/images/thumbs"; //folder for the thumb images
  6.  
  7. $imageURL = $matches[1]; //location of the image to copy to server (as caught by regexp)
  8. $imageCaption = $matches[2]; //caption of the image (as caught by regexp)
  9.  
  10. $imageName = basename($imageURL); //Filename of the image
  11.  
  12. $imagePath = $blogImagesFolder . "/" . $imageName; //path to the real-size image
  13. $thumbPath = $blogThumbsFolder . "/" . $imageName; //path to the thumb image
  14.  
  15. try {
  16. //Check if directories exist, if not create them
  17. if (!is_dir($blogBase)) {
  18. if (!mkdir($blogBase)) {
  19. throw new Exception("Error while creating image directory.");
  20. }
  21. }
  22.  
  23. if (!is_dir($blogImagesFolder)) {
  24. if (!mkdir($blogImagesFolder)) {
  25. throw new Exception("Error while creating image directory.");
  26. }
  27. }
  28.  
  29. if (!is_dir($blogThumbsFolder)) {
  30. if (!mkdir($blogThumbsFolder)) {
  31. throw new Exception("Error while creating thumbs directory.");
  32. }
  33. }
  34.  
  35. //Copy the remote image into your local server. This will be your real-size image
  36. if (!copy($imageURL, $imagePath)) {
  37. throw new Exception("Error while copying image to the server");
  38. }
  39.  
  40. //Create the thumbnail from the real-size image
  41. if (!smart_resize_image($imagePath, 256, 128, true, $thumbPath, false)) {
  42. throw new Exception("Error while saving thumbnail");
  43. }
  44.  
  45. return slimboxImage($imagePath, $thumbPath, $imageCaption);
  46.  
  47. } catch (Exception $e) {
  48. //Delete created images if there are any
  49. unlink($imagePath);
  50. unlink($thumbPath);
  51. return $matches[0]; //If there was an error return original content cause we don't want to replace
  52. }
  53. }

This is the actual replaceHandleImage function. This function takes an array argument called $matches that holds the values caught by the regex: [0] - entire string, [1] - url, [2] - caption.

We start by defining some path variables (don't forget to change them according to your needs). These paths reference the external image as well as the future placeholders of our own image.
We then check if the afore mentioned paths exist and if not, we create the necessary directories.

Now it's time to copy the remote image to our server using the $imagePath variable and the function copy(). Once this is done we create a thumbnail from the specified image. In this step you can use any image resize function you want. The one I'm using in this script is smart_resize_image by hakunin.

If we got this far without any errors we can now construct and return the XHTML compliant text that will replace the old tags via preg_replace_callback. Since I'm using Slimbox to show my images I encapsulated that part in yet another function although you could construct the new tags inline. If, for any reason, we detect an error during the execution of the script, we delete all data regarding this image and return the totality of the string match so that there is no tag change.

  1. function slimboxImage($imagePath, $thumbPath, $caption = "")
  2. {
  3. return "<a class='slimboxLink' title='" . $caption . "' rel='lightbox' href='" . $imagePath . "'><img class='slimboxImage' title='" . $caption . "' src='" . $thumbPath . "' alt='" . $caption . "' /></a>";
  4. }

And that's it. For a sample result check my previous post. As usual, I appreciate any type of feedback and keep in mind that the code may pose a security risk because it doesn't check for the filetype of the image being treated. Therefore, if you intend on making such a feature available to the public audience don't forget to add that extra check ;)

Best Regards,
Revolt

 
 
 
 

There are no comments

 
 
 
 

Write a Comment:

(Only seen by the admin)
captcha