How to add image uploading to your forms with Symfony 1.2 and Doctrine, from beginning to end

I’m still very new to Symfony 1.2 and its form framework. Reading through documentation, discussion forums and blog posts, I couldn’t find a tutorial which had everything I needed in an image upload. Having finished an image upload for the first time, I decided to write such a tutorial.

This tutorial requires Symfony 1.2, the Doctrine ORM plugin and the PHP GD library. You should already have all of these elements installed, and be familiar with them.

We’ll start at the beginning. I’m going to make an uploader for a background image to attach to a Website model. Make sure you have a field in your model to store the image file name:

Website:
  columns:
    background_image:  string(255)

And rebuild your model:

symfony doctrine:build-all-reload

Now open the form class generated from your schema.

You’re going to add a widget and a validator for the image upload. The widget will also allow the user to view the image after it has been uploaded, and delete it if necessary. The validator will make sure the image upload is not required (it is required by default). There is also a second validator, sfValidatorPass, because the widget we are using adds a checkbox widget giving the user the option to delete the file.

You’ll also override the doSave() method and updateObject() methods. The doSave() method will handle the upload (if there is one), create a new file name for the image, and save the image both to the file system and the background_image field automatically. Since the background_image field is automatically set with the full path of the file, you will use updateObject() to remove the path and just store the file name. If you move your project to another system, the file path will change and so we want to store just the file name.

Also in doSave(), you will handle the case where the user has checked off the “delete image” checkbox, which is automatically named background_image_delete.

Here is the code so far under lib/form/doctrine/WebsiteForm.class.php:

class WebsiteForm extends BaseWebsiteForm
{
  public function configure()
  {
    $this->widgetSchema['background_image'] = new sfWidgetFormInputFileEditable(array(
      'file_src' => '/'.basename(sfConfig::get('sf_upload_dir')).'/'.$this->getObject()->getBackgroundImage(),
      'is_image' => true,
      'edit_mode' => strlen($this->getObject()->getBackgroundImage()) > 0,
      'template'  => '
<div>%file%
%input%
%delete% %delete_label%</div>
'
    ));
 
    $this->validatorSchema['background_image'] = new sfValidatorFile(array(
      'required' => false,
      'mime_types' => 'web_images'
    ));
    $this->validatorSchema['background_image_delete'] = new sfValidatorPass();
  }
 
  protected function doSave ( $con = null )
  {
    $upload = $this->getValue('background_image');
 
    if ( $upload )
    {
      $filename = sha1($upload->getOriginalName().microtime().rand()).$upload->getExtension($upload->getOriginalExtension());
      $filepath = sfConfig::get('sf_upload_dir').'/'.$filename;
 
      $oldfilepath = sfConfig::get('sf_upload_dir').'/'.$this->getObject()->getBackgroundImage();
      if ( file_exists($oldfilepath) )
      {
        unlink($oldfilepath);
      }
 
      $upload->save($filepath);
    }
 
    $delete = $this->getValue('background_image_delete');
    if ( $delete )
    {
      $filename = $this->getObject()->getBackgroundImage();
      $filepath = sfConfig::get('sf_upload_dir').'/'.$filename;
      @unlink($filepath);
      $this->getObject()->setBackgroundImage(null);
    }
 
    return parent::doSave($con);
  }
 
  public function updateObject($values = null)
  {
    $object = parent::updateObject($values);
    $object->setBackgroundImage(str_replace(sfConfig::get('sf_upload_dir').'/', '', $object->getBackgroundImage()));
    return $object;
  }
 
}

This should work well for the most part. But what if the image is 2000 pixels in width? It will be very disruptive to display such a large image.

That’s where sfThumbnailPlugin comes in.

Install the plugin if you haven’t already done so:

$ symfony plugin:install sfThumbnailPlugin
$ php symfony cc

Now create a new directory to store your thumbnails:

$ mkdir /web/uploads/thumbnails

You’ll probably want to use this directory in other modules or applications in your project. Add a new setting called sf_thumbnail_dir in your project configuration:

config/ProjectConfiguration.class.php

...
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    ...
    sfConfig::set('sf_thumbnail_dir', sfConfig::get('sf_upload_dir').'/thumbnails');
    ...
  }
}

Now all that’s left to do is create and store the thumbnail from the doSave() method of your form class, and make sure that your form displays the thumbnail and not the source image in your configure() method.

Modify the widget settings so that it displays the thumbnail. Note that I’ve …’d most of the parts that don’t change:

lib/form/doctrine/WebsiteForm.class.php

class WebsiteForm extends BaseWebsiteForm
{
  public function configure()
  {
    ...
    $this->widgetSchema['background_image'] = new sfWidgetFormInputFileEditable(array(
      'file_src' => '/'.basename(sfConfig::get('sf_upload_dir')).'/'.basename(sfConfig::get('sf_thumbnail_dir')).'/'.$this->getObject()->getBackgroundImage(),
      'is_image' => true,
      'edit_mode' => strlen($this->getObject()->getBackgroundImage()) > 0,
      'template'  => '
<div>%file%
%input%
%delete% %delete_label%</div>
'
    ));
    ...
  }
 
  protected function doSave ( $con = null )
  {
    $upload = $this->getValue('background_image');
 
    if ( $upload )
    {
      ...
      $thumbnailpath = sfConfig::get('sf_thumbnail_dir').'/'.$filename;
      ...
      $oldthumbnailpath = sfConfig::get('sf_thumbnail_dir').'/'.$this->getObject()->getBackgroundImage();
      if ( file_exists($oldthumbnailpath) )
      {
        unlink($oldthumbnailpath);
      }
 
      ...
      $thumbnail = new sfThumbnail(150, 150, true, true, 75, 'sfGDAdapter');
      $thumbnail->loadFile($filepath);
      $thumbnail->save($thumbnailpath);
    }
 
    $delete = $this->getValue('background_image_delete');
 
    if ( $delete )
    {
      ...
      $thumbnailpath = sfConfig::get('sf_thumbnail_dir').'/'.$filename;
      @unlink($thumbnailpath);
      ...
    }
  }
 
  ...
 
}

And that’s all there is to it. Note that there is no template file here because the form framework handles the view of the form inputs.

ShareThis

2 comments so far:

wholesales says: * Canada Goose Expedition

* Canada Goose Expedition Men's Shiny red-colored Parka specific design,canada goose for saletop material,great design,all these you can locate it.Well-know brand Canada Goose Outlet would be your very first option to sustain you cozy from chilly days.Try it right now.cheap canada goose
* specific design with durable and well-insulated materials;canada goose jackets
good duck down;nylon lining.
* Relaxed fit;an aboundance of large pockets.canada goose parka

* Two way and adjustable;storm flap over entrance zipper;tunnel-shaped hood with adjustable bracing wire.
* Mid-thigh length.Canada Goose Chilliwack Parka

* users who bought this item place on also like to choose Canada Goose Expedition Men's Sea Blue Parka,canada goose onlineor other serie Canada Goose Solaris Parka.

cheapest monclerMoncle will certainly bring an individual trough this as well as effectively in to the following. moncler jacketsWithin the frosty winter months, you must wish to contain the supplies to protect you and the loved ones in the frosty and freeze temperature, especially for those individuals who're such as exterior sports activity.moncler vests on sale lumination cozy and also ,moncler jackets sale, fashion moncler jackets maybe your first option due to the fact it really is well-known with the skiing garments. cheapest moncler jacketsfinding a skilled service provider of moncler, The moncler outlet has got the newest style of 2011 new moncler, most of these types tend to be fashion as well as adequate so that you can choose,particularly for girls that are higher on style.cheap moncler saleThank you for visiting choice the Moncler jackets,I will be going to be at your srvice ould like period.Moncler Neckcloth & Hat are inside best quality genuineness as wellmoncler jackets online as specialist services. we ensure your 100% fulfillment So if you are hazarded from the range of moncler hat neckcloth, here you'll find your ex girlfriend! moncler coats salesubscribe to us to be able to renew your own Moncler experience!Thank you for visiting decide on and purchase other cheap moncler sale, this sort of since Moncler Jackets.moncler jackets men

moncler jackets women

North Face Womens Denali Gore Tex Waterproof Jacket White Sale.the north faceThe patented GORE-TEX membrane makes garments 100% waterproof, cheap north facewindproof and breathable so that you stay dried out and at ease below any conditions. By 1978, the north face jacketsGORE-TEX fabric was launched as well since the world met the 1st truly waterproof, breathable outerwear. Thanks to our responsibility to unending innovation and creativity, the north face salewater-resistant and breathable GORE-TEX products have ongoing to improve and evolve to keep in motion using the altering needs of our customers. Cheap North Face Womens Jackets, wholesale North Face Jackets online sale, north face outletwelcome to buy! The North face Mens Vest is your ideal option for outdoor activities. This North Face Mens Nuptse Down Vest Navy will be your excellent companion in your Climbing,north face jackets women Skiing, Snowboarding or Winter Camping activities, they protect you from the snow water enviroment, keep you warm and dry, enjoy your entertainment, show your good taste, North Face Mens Jacketsand your quality life. This mens vest is your best choice for chilly winter!

UGG classic short boots are a sensation the earth over. UGG Bailey Button Boots ,People of all professions and age groups are getting fans of the sheepskin styled ugg boots from Australia.classic ugg boots Historically, shepherds have been the 1st people to wear sheepskin boots to force-shield their feet from the harsh weather.ugg boots sale It is stated that these fur lined flat soled dicoutnt ugg boots are now a part of the ever changing world of fashion considering that pilots throughout the times of war wore them in purchase to offer their ft with warmth at increased altitudes and surfers wore them after a frosty dip in the sea to warm their feet.cheap ugg boots one cannot deny the actuality that classic ugg boots relive the unidentified passions of people for the ultimate in casual design and comfort the earth over.cheap uggs,
like the traditional Short,ugg boots on sale the UGG Bailey Button Boots may be a calf-height boot produced from genuine Twinface sheepskin. cheap ugg bootsWe've updated this conventional design using a wooden UGG logo key and elastic band closure.ugg boots for sale
a one wooden buttons etched with the signature UGG logo allow this boot to be a one of our most warm sale styles.bailey button uggs boots The Bailey key can either beworn up or cuffed along adding only a little selection depending in your style. All ugg boots in our traditional Collection feature a gentle foam insole covered with genuine sheepskin. Now ugg boots on sale,ugh boots for sale high quality, discount ugg boots, free shipping!

Ben (not verified) says: Thank you!

Thank you!

Post new comment

The content of this field is kept private and will not be shown publicly.