Have to upload the image twice because the edit template doesn't show the image that was uploaded at the add page

In my edit function I have an image upload but when I go to the edit page, the file from the add page doesn’t stick and the image has to be uploaded again. I want the image to show up in the edit page so it can be submitted without having to upload the image again. I have no idea how to accomplish this.


public function edit($id = null) {
  $bio = $this->Bios->get($id, [
  'contain' => [],
  ]);
  if ($this->request->is(['patch', 'post', 'put'])) {
    $bio = $this->Bios->patchEntity($bio, $this->request->getData());
	
    if(!$bio->getErrors()) {
      if (!empty($this->request->getData('resize_to_thumb'))) {
        $resize_to_thumb=$this->request->getUploadedFile('resize_to_thumb'); 

        if ($resize_to_thumb->getError() == 0) {
        $destination = WWW_ROOT.'img'.DS.'bio_images'.DS.$resize_to_thumb->getClientFilename();
        $fileName = $resize_to_thumb->getClientFilename();
        $fileName = 'img/bio_images/' . $fileName;
        $bio->resize_to_thumb=$fileName;
        $resize_to_thumb->moveTo($destination);
       }
	 }

  if ($this->Bios->save($bio)) {
		
    $this->Flash->success(__('The bio has been saved.'));

    return $this->redirect(['action' => 'index']);
   }
     $this->Flash->error(__('The bio could not be saved. Please, try again.'));
   }
   $users = $this->Bios->Users->find('list', ['limit' => 200]);
   $this->set(compact('bio', 'users'));
}

In my template:


<p>Add a thumb-size avatar</p> 
<?php echo $this->Form->file('resize_to_thumb');?>

I just added this to the template and it worked
echo $bio -> resize_to_thumb;

You can’t pre-populate a file input.

Best you can do is, once the upload is complete, show a thumbnail and allow the user to “change” the uploaded file. (by upload another file and replace it)

Also this allows to not upload the same file many times.

I still haven’t gotten the added file to upload again after edit is executed. I don’t understand raul338’s reply.

If sounds like you’re thinking that a file will be uploaded in one post, and then you create a second form from that and the file will magically be added to that post data as well? That’s not how it works. You’ll need to save the file from the first post somewhere to work with later on. (And presumably have some periodic cleanup of any such temp files that people don’t complete the process with.)

I added an else condition to my controller and it still doesn’t work. I added

         } else {
			  $bio -> home_page_image;
		  }

The entire code looks like this:


if (!empty($this->request->getData('home_page_image'))) {
		    $home_page_image = $this->request->getUploadedFile('home_page_image');   
              if ($home_page_image->getError() == 0) {
				$fileName2 = $home_page_image->getClientFilename();
			    $destination2 = WWW_ROOT.'img'.DS.'bio_images'. DS . $fileName2;
			    $fileName2 = 'img/bio_images/' . $fileName2;
				$bio->home_page_image=$fileName2;
                $home_page_image->moveTo($destination2);
            }
          } else {
			  $bio -> home_page_image;
		  }
        }

If the file upload is empty it’s supposed to grab the image that already exists in the database but this doesn’t work.

Your line $bio -> home_page_image; does nothing at all. Is there supposed to be an assignment in there somewhere?

Maybe it should be assigned to a variable like this:

else {
$home_page_image = $bio -> home_page_image;
}

and then save it to the database on the next line:

if ($this->Bios->save($bio) && $this->Bios->save($home_page_image)) {
$this->Flash->success(__('The bio has been saved.'));
return $this->redirect(['action' => 'index']);
}

This might work:


if ($this->Bios->save($bio) && if (isset($home_page_image) $this->Bios->save($home_page_image)))

I added:
if ($this->Bios->save($bio) && (isset($home_page_image)) {$this->Bios->save($home_page_image)}){
And when I submitted the form, I got the following error:
Argument 1 passed to Cake\ORM\Table::save() must implement interface Cake\Datasource\EntityInterface, instance of Laminas\Diactoros\UploadedFile given, called in C:\xampp\htdocs\pp\src\Controller\BiosController.php on line 224

Line 224, the line that the error message is referring to, is this line:

if ($this->Bios->save($bio) && (isset($home_page_image)) {$this->Bios->save($home_page_image)}){

When I run debug on $bio, it shows ‘home_page_image’ => null
even though an image file has been uploaded.

if ($this->request->is(['patch', 'post', 'put'])) {
$bio = $this->Bios->patchEntity($bio, $this->request->getData());
debug($bio);

object(App\Model\Entity\Bio) id:0 {
‘id’ => (int) 35
‘user_id’ => (int) 35
‘contributor’ => ‘David’
‘resize_to_thumb’ => null
‘home_page_image’ => null
‘body’ => ‘

Does it save the images when you press submit?


‘gender’ => ‘’

Assuming, that this Code is from the “add” Action, you need to do

debug($this->request->getData()

to See all the data, that is sent from your form to the controller. There should be a variable of type "object(Laminas\Diactoros\UploadedFile)"

For example, I named the variable “recipeimage_file”

To access the variable you could do:
$uploaded_file = $this->request->getUploadedFile('recipeimage_file');

Then check if the variable os not null or empty and save the uploaded file to disk.

if ($uploaded_file !== null && $uploaded_file->getError() !== \UPLOAD_ERR_NO_FILE)
{
$fileName =$uploaded_file->getClientFilename();
$destination = WWW_ROOT.‘img’.DS;
$uploaded_file->moveTo($destination.$fileName);
}

If upload was successful, you need to attach the filename to your “bio” entity and the save the “bio” entity.

And if you need a preview in your add form it could be like this (please ignore the CSS-Classes, it is from one of my projects styled with tailwinds):

                    <div class="flex flex-col mt-2">
                      <label class="input-label"><?= __('ImagePreview') ?></label>
                      <div>
                        <img id="preview" class="rounded-md" width="300" height="auto" />
                      </div>
                      <div class="mt-2">
                        <label for='submittedfile' class="bg-blue-500 hover:bg-blue-400 rounded text-sm font-medium text-white max-w-min h-4 p-2 "><?= __('Search Image')?></label>
                        <?php echo $this->Form->file('recipeimage_file',['class'=>'hidden','id'=>'submittedfile','type'=>'file','onchange'=>'document.getElementById("preview").src = window.URL.createObjectURL(this.files[0])','required'=>'false']);?>
                      </div>
                    </div>

Thanks dirk. The code that I submitted here was from my edit method in the controller. The add method works, it’s the edit method that doesn’t re-submit the original image. The user has to upload the image file again in the edit interface. I have a test on Wednesday morning so I am going to leave this until after the test. I have to study now.

I took the test so I can work on this now.

I added a hidden input for the home page image but it still didn’t save the image after editting the post.

I tried

if ($this->Bios->save($bio, $home_page_image)) {

and
if ($this->Bios->save($bio, 'home_page_image')) {

in my edit method and there were no errors this time upon submission but the image still wasn’t saved. It disappeared when I editted the form again.

It saved the image file to the database after the first edit and then the image file was deleted from the database for the second edit.

In the model I have

        $validator
            //->scalar('home_page_image')
            //->maxLength('home_page_image', 180)
            //->allowEmptyFile('home_page_image');
			->isArray('home_page_image')
			->allowEmptyArray('home_page_image');

When I debug here:


if ($this->request->is(['patch', 'post', 'put'])) {
  $home_page_image = $this->request->getData('home_page_image');
  debug($home_page_image);

I get

[
‘tmp_name’ => ‘C:\xampp\tmp\php6C59.tmp’,
‘error’ => (int) 0,
‘name’ => ‘WIN_20210418_20_07_26_Pro.jpg’,
‘type’ => ‘image/jpeg’,
‘size’ => (int) 118087,
]

Maybe the size is too big. I don’t know where the size is set.