Object of class Laminas\Diactoros\UploadedFile could not be converted to string

I have a form that allows an image file to be uploaded. When I upload an image, it successfully submits it to the database but when no image is uploaded, I get the error “Object of class Laminas\Diactoros\UploadedFile could not be converted to string”

public function add($user_id = null)
	{
$recipe = $this->Recipes->newEmptyEntity();
$this->set(compact('recipe'));
$image1 = $this->request->getUploadedFile('image1'); 
if ($image1 !== null ){
$destination2 = "img/recipe_images/" . $image1->getClientFilename();
$image1->moveTo($destination2);
$recipe -> image1 = $destination2;
} 
if ($this->Recipes->save($recipe)) {
$this->Flash->success(__('The recipe has been saved.'));
return $this->redirect(['action' => 'view', $recipe->id]);
}
$this->Flash->error(__('The recipe could not be saved. Please, try again.'));
}
}

You better check if $image1 got errors. As far as i remember.it will never be NULL.
Tomorrow i can give you more details, when im home at my computer

I should have included my entire code. This is what it looks like now:

public function add($user_id = null)
    {
$recipe = $this->Recipes->newEmptyEntity();
$this->set(compact('recipe'));
if ($this->request->is('post')) {
$recipe = $this->Recipes->patchEntity($recipe, $this->request->getData());
if ($this->Recipes->save($recipe)) {
$image1 = $this->request->getUploadedFile('image1'); 
if ($image1 !== 0){						$destination2 = "img/recipe_images/" . $image1->getClientFilename();
if (file_exists($destination2)){
$image1->moveTo($destination2);
$recipe -> image1 = $destination2;
}}

If I comment out

$recipe = $this->Recipes->patchEntity($recipe, $this->request->getData());

it doesn’t throw an error but no data is saved to the database.

when you assign $destination2 to $recipe is to late. at this moment $recipe is already saved.
tomorrow i will send you more details

I changed the order as you pointed out so it saves at the right time. I added the following and now it works:

if ($image1 !== null && $image1->getError() !== UPLOAD_ERR_NO_FILE)

It was ‘uploadedFilesAsObjects’ => false, saved to config/app.php that solved the problem but now I have to click on the submit button twice before it saves to the database.

Now if the image file isn’t empty, I have to click the submit button twice. I think I am closing the curly bracket in the wrong place.

Where should my curly brackets be? I have to submit twice for the following code:

public function add($user_id = null)
    {
$recipe = $this->Recipes->newEmptyEntity();
$this->set(compact('recipe'));
if ($this->request->is('post')) {
$recipe = $this->Recipes->patchEntity($recipe, $this->request->getData());
$image1=$this->request->getUploadedFile('image1'); 
if
($image1 !== null && $image1->getError() !== UPLOAD_ERR_NO_FILE){ 
$destination2 = "img/recipe_images/" . $image1->getClientFilename();
$image1->moveTo($destination2);
$recipe -> image1 = $destination2;
}
if ($this->Recipes->save($recipe)) {
$this->Flash->success(__('The recipe has been saved.'));
return $this->redirect(['action' => 'view', $recipe->id]);
}
$this->Flash->error(__('The recipe could not be saved. Please, try again.'));
        }

    }

It’s not saving the image to the database any more. I thought it was submitting it at one time but maybe I’m wrong.

I need both ($image1 !== null && $image1->getError() !== UPLOAD_ERR_NO_FILE) in the function and ‘uploadedFilesAsObjects’ => false, saved to config/app.php in order for it to not submit an error but it doesn’t save the image to the database.

The following saves the image but it doesn’t save it to the target path. I’ve tried two separate ways to configure the target path and neither one works.

$image1 = $this->request->getUploadedFile('image1');
$fileName = $image1->getClientFilename();
//$targetPath = WWW_ROOT . 'img'. DS . 'recipe_images' .DS. $fileName;
$targetPath = 'img/recipe_images/' . $fileName;
$image1->moveTo($targetPath);
$recipe = $this->Recipes->patchEntity($recipe, $this->request->getData());  
$recipe->image1 = $fileName;

I tried the following as well but it still didn’t save my image to the target path: move_uploaded_file($fileName , $targetPath);

It turns out that the image is actually being saved to the target path directory and it just doesn’t show the target path directory in the database so this is working now.

It is saving the image but now the problem is that I can’t display the image on the template page because my earlier saves included the directory. I can do a str_replace() to filter out the directory saved and then concatenate the directory name to the image but this isn’t working for me for some reason.

I just added $fileName = 'img/recipe_images/' . $fileName; and now the directory name is in the database.

I’m back to square one. It only works when a file is uploaded. If no file is uploaded, I get the error: Cannot retrieve stream due to upload error: No file was uploaded

I’m sorry if I’m not clearer about what is happening. I keep changing the code and then I don’t add it to the replies that I make.

public function add($user_id = null)  {
  $recipe = $this->Recipes->newEmptyEntity();
  $this->set(compact('recipe'));
  if ($this->request->is('post')) 
  {
      $recipe = $this->Recipes->patchEntity($recipe, $this->request->getData());
      if(!$recipe->getErrors()) {

          if (!empty($this->request->getData('image1'))) {
          $image1 = $this->request->getData('image_file');
              if ($image1->getError() == 0) {
                $destination2 = WWW_ROOT.'img'.DS.'recipe_images'.DS.$image1->getClientFilename();
                $recipe->image1=$image1->getClientFilename(); //here i save only the filename, not the whole path
                $image->moveTo($destination);
              }
              else {
                  $recipe->image1=NULL; //remove this for the edit method, otherwise, it could happen that the filename will be overwritten with NULL
              }
          }
        }
      if ($this->Recipes->save($recipe)) 
      {
        $this->Flash->success(__('The recipe has been saved.'));
        return $this->redirect(['action' => 'view', $recipe->id]);
      }
      $this->Flash->error(__('The recipe could not be saved. Please, try again.'));
  }
}

Will there be a problem with that code when set’ing it before changes are made to it?
Admittedly the changes are applied from a post call, therefore the var won’t be going back to the client, it just may not be future-proof in case that is changed (or copy/pasted for a template elsewhere).

Thanks for the code, dirk.
I corrected the typos so that the code includes the line
$image1 = $this->request->getData('image1');
instead of
$image1 = $this->request->getData('image_file');
and
$image1->moveTo($destination2);
instead of
$image->moveTo($destination);

When I didn’t upload an image, I got the error: Call to a member function getError() on array

and when I did upload a file it stayed on the same page after clicking the submit button.
So I changed
$image1 = $this->request->getData('image1');
to
$image1 = $this->request->getUploadedFile('image1');
but it still stayed on the same page after I clicked on the submit button and nothing was saved to the database.