Behavior to handle file uploads. More info on Github project page.
Requirements ¶
Yii 1.1 above
Usage ¶
[https://github.com/gregmolnar/yii-attachment-behavior#usage]( https://github.com/gregmolnar/yii-attachment-behavior#usage)
Behavior to handle file uploads. More info on Github project page.
Yii 1.1 above
[https://github.com/gregmolnar/yii-attachment-behavior#usage]( https://github.com/gregmolnar/yii-attachment-behavior#usage)
Processors
You can ignore the processors part of this extension. Only use it if you know you have the PHP extension install and enabled.
Its only required if you want to resize an image or do some sort of processing.
EDIT RE:errors
EDIT:
Make sure your your database table is text or something other than blob or you will have to use another way to retrieve it (from what I read). Also, read below to make sure you have the proper extensions installed in your php. Try using 'class' => 'GDProcessor', if your getting errors or just leave it out as mentioned below.
Also make sure you call your yii base path by addiing ../ when you echo the image in your view file. This will call your images file under your root.
So I swithced:
<?php echo '<img src="'.$model->getAttachment('thumb').'" />'; ?> //thumbnail <?php echo '<img src="'.$model->Attachment.'" />'; ?> //base image
TO:
<?php echo '<img src="../'.$model->filename.'" />'; ?> //FULL SIZE IMAGE <?php echo '<img src="../'.$model->Attachment.'" />';?> // EXTENSION SIZED IMAGE (WHATEVER SIZE YOU SPECIFIED IN YOUR MODEL) <?php echo '<img src="../'.$model->getAttachment('thumb').'" />'; ?> EXTENSION SIZED THUMBNAIL (WHATEVER YOU SPECIFIED IN YOUR MODEL)
So my images are stored in:
yiibasepath/images/mymodelname/thefile.jpg so if you wanted to put them in images/uploads/modelname/ use
<?php echo '<img src="../uploads/.$model->Attachment or filename.'"
Great extension
Just a couple things i can't figure out.
The only thing i cant get to work is the 'fallback' image :( any ideas. i have the right path specified.
Also, on update it dumps the image if you don't upload a new one when your updating.
Re
You need to make sure that the filename doesn't have any rules set in the model. Also set it to unsafe. Check the github repo read me for an example.
As for the fallback image,
Did you uncomment that line? Have you checked what the output is on the front end?
Re
Thanks for your help. I missed putting it to unsafe when i redid it. that fixed the dumping portion.
I have it uncommented and didn't work. I haven't checked the front end output yet going to do that now.
Make image link
Anther thing that relates to my previous post:
I have been using this and just figured I'd share how to make your image a link. I use this in my _view file because my index file uses it's data. I wanted to click on the image and it take you to the item in my case products. So product_id would be your id name.
<?php echo CHtml::link('<img src="../'.$data->getAttachment('thumb').'" />', array('view', 'id'=>$data->product_id)); ?>
my example uses thumb but if you wanted to use base image then it would be something like this.
<?php echo CHtml::link('<img src="'.$model->Attachment.'" />', array('view', 'id'=>$data->product_id)); ?>
Dosen't delete thumbs
Hello again,
I have my images saving dynamically as the name instead of the id. The problem is that when you delete the item the thumb won't delete with it. The main image does delete.
It will remove the name and leave the image and it would be titled i.e. -thumb.png
Instead of this
'path'=> "images/:model/:id.:ext",
I had this
'path' => "images/:model/$this->name.:ext",
do you know a way to have this work?
path
@skworden
Sorry for the late reply. Your path config is wrong and that causes the issue probably. It should be this:
'path' => "images/:model/:name.:ext",
Fork where you can reference the owners attributes in the path
I created a fork in wich you can reference the atttribute values of the extended object like this:
public function behaviors() { return array( 'image' => array( //... 'path' => ":folder/:{attributeName}/:id.:ext", //... }
I allready sent a Pull Request to @Greg Molnar for his consideration of my changes.
@skworden I think this could solve your problem ;)
re
@Bravoman I'll review the changes when I got some time and will merge.
Set model
It would be nice if you could set the model in the model if not then it would default to what model it is in. I only say this because I am using it in a module and it throws an
Undefined index: User error every time you log in.
It throws it because you set your model in the user module and it is not the same as the module's model. i.e. User module uses user model with a name alias of users.
public function behaviors() { return array( 'image' => array( ...other settings 'model'=>'users',//set it here. ...other settings
re
@skworden
I am not sure I got what you mean. If you mean the :model token in the filename that's coming from the owner of the behaviour(get_class($this->Owner)).
Next time could you please open a ticket on github as a I am using that for issue management. Thanks.
RE
Added issue to GIT
File processing in
afterSave()
Be careful, that all file processing and handling of uploaded file is handled in
afterSave()
, not inbeforeSave()
in this extension!This means, that if you have any error on upload (not necessarily connected to a file, it can be PHP error, this behavior incorrect configuration and many more), you'll end up with entry in database, that don't belongs to any physically existing file!
re
@Trejder
I that is a very rare case. I could change the extension to process the upload on beforeSave but there are other behaviors attached to the model and those are blocking the save method for any reason there will be a file on the server with no associated record in the database. I am not sure how Yii generates the model's primary key before save but since the key is usually an incrementing value you might hit an issue when saving a model fails and the file is uploaded to the server with the ID but someone else saves a record without an attachment before you do it again and that file will be attached to the other model. If you see what I mean.
Feel free to let me know if you have an idea to do this better. Also if you have an issue in the future pleas use github as I am looking at that more often.
Thanks
re
@Trejder
I that is a very rare case. I could change the extension to process the upload on beforeSave but there are other behaviors attached to the model and those are blocking the save method for any reason there will be a file on the server with no associated record in the database. I am not sure how Yii generates the model's primary key before save but since the key is usually an incrementing value you might hit an issue when saving a model fails and the file is uploaded to the server with the ID but someone else saves a record without an attachment before you do it again and that file will be attached to the other model. If you see what I mean.
Feel free to let me know if you have an idea to do this better. Also if you have an issue in the future pleas use github as I am looking at that more often.
Thanks
Upload more than 1 file
Hi Greg!
How I can I use this extension to upload several files at a time?
Do I have to add something to the behaviors() function?
Thank you.
Mário
re multiple images
Hi Mario,
The best to do is to use another model. For instance if you have a Post model you would create a PostImages model and Post has_many PostImages and the behavior is attached to the PostImages model.
Let me know if this doesn't make sense.
Greg
Hi Greg
Being a newbie in Yii I have read some on has_many but haven't got to that point in using it yet.
Could you please provide an example?
Thanks in advance.
re
I will create an example app for you when I got some time.
re
Thanks a lot Greg!
That would be very helpfull.
Just one thing, that I don't know if it will affect the way the model will be modified: I save my images (names) in the same table as my posts, this is I don't have a tbl Post and another tbl PostImages. Does that affect it?
Mário
re
You will need to change that. Basically you need another model and just need to setup the relation between those like this. You will see how I mean from the sample app.
jquery file uploader
hi Greg. does this extension work with the jquery file uploader while uploading multiple images? thanks
re: jquery file uploader
Hi,
I never used that file uploader but I used this plugin with plupload and I guess that is similar to the jquery one so it should be ok. Give it a try and let me know if you hit any error.
Greg
Image column in grid view using this extenstion.
This will add an image column to grid view using this extension and will look like this (minus styling that is custom)
<?php /** * EImageColumn class file. * * This column assumes that the filename is saved as a path to the * image that is to be rendered. If no pathPrefix is given, it * assumes Yii::app()->baseUrl as a prefix for the image. This is * designed to work with the Attachment Behavior extension for YII. * * Example Usage: * SAVE THIS FILE AS EImageColumn.php under extenstions/AttachmentBehavior or where you have the extension AttachmentBehavior Saved. If it's different from above change the next line accordingly. in config/main.php 'import'=>array( 'application.extensions.AttachmentBehavior.*', ), Then you can call it in a grid view like so $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'photo-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( array( 'class'=>'EImageColumn', 'name' => 'filename', 'htmlOptions' => array('style' => 'width: 60px; height: 60px; !important; margin: 5px;'), 'headerHtmlOptions' => array('style'=>'text-align:center; vertical-align;'), ), )); ?> * * skworden */ Yii::import('zii.widgets.grid.CGridColumn'); /** * CImageColumn represents a grid view column that displays an image, and optional, a link * */ class EImageColumn extends CGridColumn { public $name; public $value; public $sortable; // Path to the image. public $pathPrefix = null; public $pathSuffix = null; // wraps htmlOptions for the image/for the link public $htmlOptions = array(); public $linkHtmlOptions = array(); // alt attribute for the <image> tag public $alt = ''; // optional: link public $link = false; public $filter = false; public function init() { parent::init(); if($this->pathPrefix === null) $this->pathPrefix = Yii::app()->baseUrl . '/'; if($this->name===null) throw new CException(Yii::t('zii','Please specify a name for AImageColumn.')); } protected function renderHeaderCellContent() { if($this->grid->enableSorting && $this->sortable && $this->name!==null) echo $this->grid->dataProvider->getSort()->link($this->name,$this->header); else if($this->name!==null && $this->header===null) { if($this->grid->dataProvider instanceof CActiveDataProvider) echo CHtml::encode($this->grid->dataProvider->model->getAttributeLabel($this->name)); else echo CHtml::encode($this->name); } else parent::renderHeaderCellContent(); } protected function renderDataCellContent($row,$data) { if (empty($data->{$this->name})) //if image column in your database is empty { //if db filepath is empty render the default image from Attachment behavior $image = CHtml::image($this->pathPrefix . $data->Attachment, $this->alt, $this->htmlOptions); } //render db filepath is null render the default image from Attachment behavior elseif ($data->{$this->name}==null) { $image = CHtml::image($this->pathPrefix . $data->Attachment, $this->alt, $this->htmlOptions); } //if file path exist and is not valid render default image elseif (!file_exists(Yii::app()->baseUrl.'/'.$this->name)) { $image = CHtml::image($this->pathPrefix . $data->Attachment, $this->alt, $this->htmlOptions); } else { $image = CHtml::image($this->pathPrefix . $data->{$this->name}, $this->alt, $this->htmlOptions); } echo $image; } }class EImageColumn extends CGridColumn { public $name; public $value; public $sortable; // Path to the image. public $pathPrefix = null; public $pathSuffix = null; // wraps htmlOptions for the image/for the link public $htmlOptions = array(); public $linkHtmlOptions = array(); // alt attribute for the <image> tag public $alt = ''; // optional: link public $link = false; public $filter = false; public function init() { parent::init(); if($this->pathPrefix === null) $this->pathPrefix = Yii::app()->baseUrl . '/'; if($this->name===null) throw new CException(Yii::t('zii','Please specify a name for AImageColumn.')); } protected function renderHeaderCellContent() { if($this->grid->enableSorting && $this->sortable && $this->name!==null) echo $this->grid->dataProvider->getSort()->link($this->name,$this->header); else if($this->name!==null && $this->header===null) { if($this->grid->dataProvider instanceof CActiveDataProvider) echo CHtml::encode($this->grid->dataProvider->model->getAttributeLabel($this->name)); else echo CHtml::encode($this->name); } else parent::renderHeaderCellContent(); } protected function renderDataCellContent($row,$data) { if (empty($data->{$this->name})) //if image column in your database is empty { //if db filepath is empty render the default image from attachment behavior $image = CHtml::image($this->pathPrefix . $data->attachment, $this->alt, $this->htmlOptions); } //render db filepath is null render the default image from attachment behavior elseif ($data->{$this->name}==null) { $image = CHtml::image($this->pathPrefix . $data->attachment, $this->alt, $this->htmlOptions); } else { $image = CHtml::image($this->pathPrefix . $data->{$this->name}, $this->alt, $this->htmlOptions); } echo $image; } }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.