Form fileField - hidden field empty

There is no useful need to preserve value in that hidden field.

when you upload fill input field filled something as , C:\Users\kiran.sharma\Desktop\photo.png

and on update/edit page you can get value as in my above post and there are various ways to remain field blank on update/edit (one posted by vibhaJadwani) page and no reflection on particular file field in db and folder.

so i thing it makes no sense to preserve value.

can i ask for which purpose you require that?

Perhaps then you can enlighten the World as to what useful purpose the hidden field serves? There is no useful need for a hidden field that is always blank. It is nothing other than a nuisance.

Sure! This is the CRUD generated by Gii:




if(isset($_POST['Labels']))

		{

			$model->attributes=$_POST['Labels'];



Now, on update, since we are posting a hidden field that has no value for “Labels[label_logo]”, that attribute will be blank and we will lose the value in our database. If on the other hand the hidden field (which by default serves NO useful purpose) does in fact hold the value we have in our database, then we don’t need to worry about a workaround for this stupidity. The hidden field will serve a useful purpose in the same way it does in thousands of PHP applications that have file upload, that is, if no new file is uploaded the existing filename is preserved in our database without the need for silly workarounds.

@Backslider please moderate your posts, there is really no need to use such tone.

You are constantly asking why is there a hidden field… but the reason is explained just above it in the comments… you even did copy/paste that code above in the 3rd post. Do that comment answer your question?


On update:

My thinking is that I want to know if the user had uploaded a picture or not. So for that I can check the value of the model attribute. If there would be a previous value that would not be the case. That is the main reason why we should not change this as you suggested because it would possibly break current code and would not be BC. (BC == backward compatibility)

I cannot comprehend why you cannot see the flaw in your own thinking.

"I want to know if the user had uploaded a picture or not. So for that I can check the value of the model attribute"

The attribute will always be blank, it will not tell you anything about a file upload. The only way to tell if there is a file upload is to check $_FILES:




    $logo=CUploadedFile::getInstance($model,'label_logo');

    

    if(!empty($logo)) $model->label_logo = $logo;



I have no idea what post you are referring to. Please explain yourself the useful purpose of the hidden field that always remains blank.

The post I’m referring is the 3rd post in this thread.

The comment is:

Problem is that if there is no hidden INPUT, when the user does not choose a file

to be uploaded in POST you don’t get the model attribute at all, i.e. There is no $_POST[‘yourmodel’][‘fileattribute’]

That’s the reason why the hidden field is there…

Edit:

Ops… actually the field is never there even if the user selects a file. So the usual check if the form was submited as mentioned in the comments would fail.

So you are telling me that the only useful purpose this hidden field serves is a fudge for the rare possibility that a form only has a single file input?

If that is the case, then the input will still serve exactly the same purpose, while serving the more useful and logical purpose of preserving the existing filename in case there is no new upload, if it is in fact populated with the existing value for an update. This will not break BC at all.

I just did a dump of my $_POST and it contains:




 [yt0] => Save



So, you do not need the hidden field at all to check if the form has been posted, since $_POST will not be empty even if you have a single file input and no hidden field.

You cannot relay on if(isset($_POST))… you need to check for the model so it should be if(isset($_POST[‘yourmodel’]))

What you are essentially telling me is that rather than have the logical thing and populate the hidden field, we should have something like this:




	public function actionUpdate($id)

	{

		$model=$this->loadModel($id);

                $myfile = $model->myfile; // need this because silly hidden field is always empty




		if(isset($_POST['MyModel']))

		{

			$model->attributes=$_POST['MyModel'];

			$model->myfile = $myfile;  // need this because silly hidden field is always empty

			

			$file=CUploadedFile::getInstance($model,'myfile');

			

			if(!empty($file)) $model->myfile = $file; 	               




Thats just ugly… :-X

With a populated hidden field:




	public function actionUpdate($id)

	{

		$model=$this->loadModel($id);


		if(isset($_POST['MyModel']))

		{

			$model->attributes=$_POST['MyModel'];

			

			$file=CUploadedFile::getInstance($model,'myfile');

			

			if(!empty($file)) $model->myfile = $file; 



That makes sense…

I understand your point of view and your passion for this issue… but there is really no need to make a post on every few minutes…

What happens if some user has a required file upload even on update like forced picture change (can’t think of better need, but I think you can agree on that, that someone needs to have a required file upload on update too)

In that case if a user did not select a file the old filename would be in the file attribute.

In general when a user uploads a new file… the old one has to be deleted… and that can be done only after the record has been updated and the new file saved… so you again need to keep somewhere the old file name.

That’s why you should validate files with $_FILES, not $_POST.

And guess what? I just set my file upload to ‘allowEmpty’ => false and it validates perfectly with my populated hidden field:




<label class="error" for="Labels_label_logo">Label Logo</label>

<input id="ytLabels_label_logo" class="error" type="hidden" value="201207252046181417678878_likkethis.jpg" name="Labels[label_logo]">

<input id="Labels_label_logo" class="error" type="file" name="Labels[label_logo]">

<div id="Labels_label_logo_em_" class="errorMessage">Label Logo cannot be blank.</div>



I agree that the old file(s) should be deleted, so ignore my simple example of assigning the new filename to the model attribute. I actually do something like this:




if(!empty($logo)) {

	$logo->saveAs(Yii::getPathOfAlias('webroot') . '/uploads/labels/' . $logo);

	Labels::model()->processLabelImage($logo, $model->id);

}



The processLabelImage() function will crop and resize the image into three different size images, move the four images to their final directory, delete the old files if any exist and update the record.

If however no new file is uploaded, then my populated hidden field will preserve the current filename.

I reiterate that if the hidden field is populated, it will still do exactly as you think it should, while negating the need for funky code.

This should be done in any case…

I don’t see your point here… if the file field is required and the user does not select a file to be uploaded the validation should not pass… it did validate because the file attribute holds the old filename…

This works for you because you use a simple way of generating the picute names, but it’s not so unusual that the filename is generated/calculated on upload and cannot be generated/calculated at a later time when a new one is uploaded… that’s why I wrote before that for deleting the old file you need to preserve the current filename.

I really don’t see what is so “funky” in preserving the old filename… it just adds two code lines… what does those 2 lines means in the whole upload action that in any case is never so simple as in your previous examples… because it has to check for $_FILES, has to validate the model, has to deal with situations in the case there is a required file missing or model validations errors… upload the new file, delete the old one, save the model… deal with possible errors during upload of new file or delete of old file, deal with possible errors on model save…

Oh puhleese… it validated as in it threw an error because the FILE was missing. Please look at what I posted.

Again, it only proves that a populated hidden field is far more useful than an empty one and DOES NOT break BC.

How do you know this? The fact is that my processLabelImage() function in fact renames the files so we are sure we do not get duplicate filenames:




    value="201207252046181417678878_likkethis.jpg"



You talk about "preserving the old filename" while insisting that the hidden field should be blank without giving any valid reason as to WHY it should be blank… it most logically should hold the old filename… sheesh!

We are going in a circle here…

What I’m saying is that you need the old filename after the model is saved so in the case that the hidden field is populated and the user did select a new file to be uploaded… After you saved the model and saved the new file… you need to delete the old file but at that time the old filename is not available if you did not remember it somewhere.

We are only going in circles because you are so stubborn and don’t bother to comprehend what I am telling you. You now want to continue with this tangent on how replacement files should be processed. Let me tell you: I am doing it and I am doing it with a populated hidden field because that is the simplest and most logical way to do it. Not only is it not a problem with new file uploads, it negates any need whatsoever to worry about the old file name if no new file is uploaded.

I have also proven to you that populating the field DOES NOT break BC and if the attribute is set to required it will throw an error if a file is not uploaded, whether the hidden field is populated or not.

You have in a number of posts both here and in the bug section displayed your own lack of understanding of how Yii handles and validates file uploads…