I’ve needed to upload and resize an image on a Zend Framework. Not especially difficult but it does take a little setting up.
First, I need to set up some upload locations for the final files. This was in my application.ini file like this:
paths.images.thumbs=APPLICATION_PATH "/../public/photos/thumbs"
paths.images.web=APPLICATION_PATH "/../public/photos/web"
paths.images.original=APPLICATION_PATH "/../public/photos/original"
Then I needed to set up the form
class Application_Form_Photos extends Zend_Form
{
public function init()
{
$decorator = new Decorators_Inputs();
// Add a name element
$this->addElement('text', 'name', array(
'label' => 'Photo Name:',
'required' => true,
'style' => 'width:200px;',
'filters' => array('StringTrim'),
'validators' => array(
'NotEmpty'
),
'decorators' => array($decorator)
));
$photo = new Zend_Form_Element_File('photo');
$photo->setLabel('Photo (jpg only)')
->setDestination(Zend_Registry::get('config')->paths->images->original);
// ensure only one file
$photo->addValidator('Count', false, 1);
// max 10MB
$photo->addValidator('Size', false, 10097152)
->setMaxFileSize(10097152);
// only JPEG, PNG, or GIF
$photo->addValidator('Extension', false, 'jpg,png,gif');
$photo->setValueDisabled(true);
$photo->setDecorators(array('File', new Decorators_Files()));
$this->addElement($photo, 'photo');
$submit = new Zend_Form_Element_Submit('submit');
$submit->setValue('Upload');
$submit->setName('Upload');
$submit->setDecorators(array(new Decorators_Submit()));
$this->addElement($submit);
}
}
The Decorators_Files class is a decorator (See here for how to set that up)
class Decorators_Files extends Zend_Form_Decorator_Abstract
{
protected $_format = '
';
public function render($content)
{
$element = $this->getElement();
$name = htmlentities($element->getFullyQualifiedName());
$label = htmlentities($element->getLabel());
$id = htmlentities($element->getId());
$value = htmlentities($element->getValue());
$style = htmlentities($element->getAttrib('style'));
$class = htmlentities($element->getAttrib('class'));
$error = "";
$errors = $element->getErrors();
if($errors){
$error = 'Please enter a value';
$class = 'error';
}
$markup = sprintf($this->_format, $name, $label, $id, $name, $value,$class, $style,$error);
return $markup;
}
}
Now, I need the code to handle the upload
/**
* Handle the image upload
* @param Application_Form_Photos $form, the form that contains the image
* @param Zend_Controller_Request_Abstract $request, the request
* @param Application_Model_MediaMapper $media_mapper, the Model class which handles saving the file details
*/
private function handle_image_upload(Application_Form_Photos $form, Zend_Controller_Request_Abstract $request, Application_Model_MediaMapper $media_mapper)
{
//Create an entry in the DB
$extension = pathinfo($form->getElement('photo')->getValue(), PATHINFO_EXTENSION);
$media_model = new Application_Model_Media();
$media_model->setName($request->getParam('name'))
->setThumb('')
->setWeb('')
->setOriginal('');
$media_mapper->save($media_model);
//Rename the file
$form->getElement('photo')->addFilter('Rename', array(
'target' => $media_model->getId() . '.' . $extension,
'overwrite' => true
));
//Add the filter to resize to web image
$form->getElement('photo')->addFilter(new Filters_File_Resize(array(
'width' => 800,
'height' => 600,
'keepRatio' => true,
'directory' => Zend_Registry::get('config')->paths->images->web
)));
//Add the filter to resize to thumb, note it can't be the same filter as above or the web image action will fail
$form->getElement('photo')->addFilter(new Filters_File_Thumb(array(
'width' => 200,
'height' => 133,
'keepRatio' => false,
'directory' => Zend_Registry::get('config')->paths->images->thumbs
)));
//Upload the photo
if ($form->getElement('photo')->receive()) {
$media_model->setThumb('photos/thumbs/' . $media_model->getId() . '.' . $extension);
$media_model->setWeb('photos/web/' . $media_model->getId() . '.' . $extension);
$media_model->setOriginal('photos/original/' . $media_model->getId() . '.' . $extension);
$media_mapper->save($media_model);
}
}
Finally, I need some filters that will handle the image resize.
I initially used the filter written by Stefan Koch. See
http://eliteinformatiker.de/2011/09/02/thumbnails-upload-and-resize-images-with-zend_form_element_file/