A simple example of a method to upload and save images. In this example, I created a "Photo" model that saves caption & alt text info to be displayed with the images. If you create a similar model using Gii and then apply these changes.
Firstly, you will need to install the image extension (cImageComponent) available from the YiiFrameworks extension library and this extension requires either GD or ImageMagick libraries. Controller: Here, I'm just showing you the create action. obviously, you will also need to code the Update and Delete actions as well.
When uploading photos, I prefer to rename the photo with a randomly generated name and this is included in the UpdatePhoto function below. Also, I crunch photos to a maximum size, this stops users trying to upload their 2500px 21Mb photo! The UpdatePhoto function will also create a thumbnail and store that in a "thumbs" sub-directory.
public function actionCreate()
{
$model=new Photos;
if(isset($_POST['Photos']))
{
$model->attributes=$_POST['Photos'];
$myfile = CUploadedFile::getInstance($model,'image');
$model->image=$myfile;
if($model->save())
$this->updatePhoto($model, $myfile);
$this->redirect('view'.'id'=>$model->id);
}
$this->render('create',array(
'model'=>$model,
));
}
/*--------------
* Upload and crunch an image
----------------*/
public function updatePhoto($model, $myfile ) {
if (is_object($myfile) && get_class($myfile)==='CUploadedFile') {
$ext = $model->image->getExtensionName();
//generate a filename for the uploaded image based on a random number
// but check that the random number has not already been used
if ($model->filename=='' or is_null($model->filename)) {
$model->filename = uniqid(rand(), true) . \'.\' . $ext;
$model->filename=$filename;
}
$model->save();
$model->image->saveAs($model->getPath()); //model->getPath see below
$image = Yii::app()->image->load($model->getPath());
//Crunch the photo to a size set in my System Options Table
//I hold the max size as 800 meaning to fit in an 800px x 800px square
$size=$this->getOption('PhotoLarge');
$image->resize($size[0], $size[0])->quality(75)->sharpen(20);
$image->save();
// Now create a thumb - again the thumb size is held in System Options Table
$size=$this->getOption('PhotoThumb');
$image->resize($size[0], $size[0])->quality(75)->sharpen(20);
$image->save($model->getThumbnail()); // or $image->save('images/small.jpg');
return true;
} else return false;
}
View: The view is pretty standard, note the enctype has been changed to multipart. Note also, the function getThumbnail from the photo model which returns the thumbnail image. the code for this is given below.
$form=$this->beginWidget('CActiveForm', array( 'enableAjaxValidation'=>true, 'id'=>'formPhoto', 'htmlOptions'=>array('enctype'=>'multipart/form-data', ), )); Fields with * are required.
echo $model->getThumbnail();
echo $form->labelEx($model,'filename');
echo $form->hiddenField($model, 'id');
echo $form->hiddenField($model, 'property_id');
echo CHtml::activeFileField($model, 'image'); // see comments below ?-->
echo $form->labelEx($model,'caption');
echo $form->textArea($model,'caption',array('rows'=>6, 'cols'=>50));
echo $form->labelEx($model,'alt_text');
echo $form->textField($model,'alt_text',array('rows'=>6, 'cols'=>50));
echo $form->labelEx($model,'sort_order');
echo $form->textField($model,'sort_order');
echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save');
echo CHtml::button('Cancel',array('onclick'=-->"window.parent.$('#cru-dialog').dialog('close');window.parent.$('#cru-frame').attr('src','');"));
$this->endWidget();
<!-- form -->
Model :
public function getThumbnail(){
// here i return the image
if (!empty($this->filename) && $this->filename!='')
return CHtml::image($this->getPath(),$this->alt_text,array('width'=>options::model()->getOption('PhotoThumb').'px','max-height'=>options::model()->getOption('PhotoThumb').'px'
));
}
public function getPath($all=true){
if (is_null($this->_PhotoPath)) {
// I hold the image path and system directory separator in the config/main.php
// this is because I develop on a windows server and normally deploy on Linux
$this->_PhotoPath=Yii::app()->params['imagePATH'];
$this->_PathSep=Yii::app()->params['pathSep'];
}
$path=$this->_PhotoPath.$this->_PathSep;
if ($all) $path.=$this->filename;
return $path;
}
edit: I should have mentioned before that the model has a dummy field to store the bitmap image. Use a variable definition 'Public $image' and add a validation rule as safe. This will enable the digital image to be saved in the model by the controller using the line
$model->attributes=$_POST['Photos'];
0 comments: