In my model BaseImage i’ve got a setter setFile():
// Set file.
public function setFile($file)
{
if($file instanceof CUploadedFile)
$this->file = $file;
else
throw new Exception("file has to be an instance of CUploadedFile", 1);
}
Works great. But now I have a situation that I don’t want to store an uploaded image, but a file created with GDlib imagejpeg() function.
But I can’t create a file and then load it into a CUploadedFile object right? That would be bad coding I guess.
What options do I have? I can’t find a class like CUploadedFile in Yii to use for this.
No ideas I guess. Maybe it’s not possible what I want. I’m working with a workaround now. So it’s possible to set an uploaded image and it’s possible to work without it. Then I store the image manually and after that I call the create thumbnails method again. It’s not pretty, but I don’t know how else to do.
You can rewrite BaseImage for processing other parameters not only CUploadedFile and resize images outside the model.
$newBaseImage = new BaseImage();
$tmp = tempnam(sys_get_temp_dir(), 'xxx_');
$image->saveAs($tmp);
BaseImage::resizeFile($tmp); //resize $tmp file via GD or Imagick
$newBaseImage->setFile($tmp);
$newBaseImage->save();
public function setFile($file)
{
$this->file = $file;
if ($file instanceof CUploadedFile) {
$this->mimetype = $file->getType();
$this->size = $file->getSize();
} else {
$this->mimetype = CFileHelper::getMimeType($file);
$this->size = filesize($file);
}
}
public function afterSave() { //or special method called manually
if ($this->file instanceof CUploadedFile) {
$this->file->saveAs($this->getFileName());
} else {
rename($this->file, $this->getFileName());
}
}
Or you can resize CUploadedFile inside the model.
$newBaseImage = new BaseImage();
$newBaseImage->setFile($image);
$newBaseImage->save();
public function afterSave() { //or special method called manually
$this->file->saveAs($this->getFileName());
BaseImage::resizeFile($this->getFileName()); //resize $tmp file via GD or Imagick
}
Other approach:
You can always save original uploaded image and resize it on request only.
Then you will generate thumbails on fly and cache it (manually or via nginc)
Thanks a lot for taking the effort to explain this. I think this is the best solution to modify my models setFile() method for accepting a CUploadedFile object or just an array with (name,location,extension, etc.). And also I’ve added a flag
private generateThumbnails = true;
which can be set to false in the case of a non CUploadedFile. Also the storeImage() method I’m not using the saveAs() option of the CUploadedFile anymore, but just the moveuploadedfile() function.
// After save.
public function afterSave()
{
// Store image if set.
if(isset($this->file))
$this->storeImage();
// Generate thumbnails.
if($this->generateThumbnails == true)
$this->generateThumbnails();
return true;
}
Still it feels a little messy, but I have that a lot when I create my classes. Maybe I want them to be to perfect. Or I’ve got to learn a lot more about OOP to make it more slick and clean.