this is one of my very first posts. I’ve made great use of the forum to learn the basics, I now have a problem I can’t understand and can’t solve, so some help would be appreciated.
I have an action that accepts the upload of an image file, along with a few other model fields. It works fine if I upload a file, but if the (non-required) image field is not filled out, I get an error:
Trying to get property of non-object
This occurs where I try to use the uploaded file extension in forming the new filename:
OK - so there’s nothing in $uploadedFile, so there’s no extensionName property.
It response, I’ve put in some tests, but the form then complains no file was uploaded.
The code is:
public function actionCreate()
{
$model=new Labels;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Labels']))
{
$model->attributes=$_POST['Labels'];
$uploadedFile = CUploadedFile::getInstance($model,'image');
$label=$model->name;
if(isset($uploadedFile)){
$extension = strtolower($uploadedFile->extensionName);
$randomNum = rand(0000, 9999);
$filename = "{$label}-{$randomNum}.{$extension}";
$fullpath=Yii::app()->basePath.'/../uploads/'.$filename;
$model->image=$filename;
}
if($model->save())
{
if(isset($uploadedFile)){
$uploadedFile->saveAs($fullpath);
}
$this->redirect(array('view','id'=>$model->id));
}
}
if(isset($_GET['id']))
{
$id=$_GET['id'];
$this->render('minicreate',array(
'model'=>$model,
'winid'=>$id));
}
ELSE
{
$this->render('create',array('model'=>$model,));
}
}
Any pointers would be very welcome. I have found the file upload to be very delicate and not very informative when it goes wrong, but I expect that this is caused by my implementation.
OK I tried that, but now it redirects to the ‘view’ happily, without having saved the model, and the $model->id is blank so I get a 404 error as the id in the URL is empty.
Can you post your model rules? It sounds like one of your rules is not being met.
You should ideally only redirect if the save is successful. Otherwise, you should render the original form again with the errors displayed.
Have a look here for information on how to handle uploads. That example is for when the file is required, which I’m assuming yours isn’t because of the way you’re handling it.
Edit:
In answer to your question, $model->save(false) is saving the model without performing any validation, which is generally a very bad idea.
Thanks for the feedback - yes I’ve been testing without validation, and its not really the solution.
My Labels model rules are:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('winery_id, name', 'required'),
array('rating_5, price_range_id, retail_category_id', 'numerical', 'integerOnly'=>true),
array('winery_id', 'length', 'max'=>11),
array('name', 'length', 'max'=>80),
array('image', 'file', 'types'=>'jpg, gif, png'),
array('thumbnail', 'length', 'max'=>50),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, winery_id, sub_label, name, rating_5, image, thumbnail, price_range_id, retail_category_id', 'safe', 'on'=>'search'),
);
}
So as far as I can see there’s no need to have an image.
OK ! that nailed it. Thanks a million. I also had to change the order of testing with the saving/redirecting. When there was no file it failed with the old setup of testing both the save and the file together.
if($model->save())
{
if ($uploadedFile)
{
$uploadedFile->saveAs($fullpath);
}
$this->redirect(array('view','id'=>$model->id));
}