I'm creating a plugin FileManager
where all uploads are stored in a single table. This plugin has an AttachmentBehavior
that attaches a hasMany
association.
I use multi-files input in templates Articles/add.php and Articles/edit.php to upload files that will be linked to an article :
// Example in Articles/edit.php
echo $this->Form->create($article, ['type' => 'file']);
echo $this->Form->control('title', /*[...]*/);
echo $this->Form->control('body', /*[...]*/);
echo $this->Form->control('pieces_jointes', ['type' => 'file', 'multiple' => true, 'name' => 'pieces_jointes[]']);
I can add new article with files, there's no problem.
I can edit an article that doesn't not have file to add files, there's no problem.
But when I edit an article that already have files to add some more files, I have an error "Cannot use object of type Laminas\Diactoros\UploadedFile as array"
This error appears when the entity Article
is patched.
Here's my controller :
// in ArticlesController.php
public function edit($id)
{
$article = $this->Articles->findById($id)->firstOrFail();
if ($this->request->is(['post', 'put'])) {
debug($article); // $article->pieces_jointes is an array of entities of my files table.
debug($this->request->getData()); // $this->request->getData()->pieces_jointes is an array of UplaodedFile objects
$article = $this->Articles->patchEntity($article, $this->request->getData()); // The error occurs here
if ($this->Articles->save($article)) {
return $this->redirect(/*[...]*/);
}
}
$this->set(compact('item'));
}
It's not really clear for me about what is going on. Does anyone can explain me and help me to solve this problem ?
CodePudding user response:
Removing associated file Model in AttachmentBehavior::beforeMarshal
seems to fix the Error :
// in AttachmentBehavior
public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
foreach ($this->_fields as $field => $value) {
// Remove associated file Model (PiecesJointes, ...) in $options['associated']
$options['associated'] = collection($options['associated'])
->reject(function ($modelAssociated, $key) use ($value) {
return $modelAssociated == $value['alias'];
})
->toArray();
// [...]
}
}
But I would need the confirmation that I'm right (?)
CodePudding user response:
You shouldn't use the same name for the upload field and the association property, that's a clash waiting to happen in various places of the framework.
Rename the fields in your forms, etc, so that it's using a name that neither matches any association property, nor any column name, and then let your behavior and stuff process the input using the "external" name, and convert it to the "internal" name after transforming the input into the structure required for saving the data.