File upload frontend - toFiles Array?

A user can upload files on the subpage /upload.
I have built the page with help from the cookbook.



I’m mixing both together. A user can create a page and upload files in those.

The page structure (stripped-down):

Form:

<form action="" method="post" enctype="multipart/form-data">
 <div class="form-element">
  <label for="name">Name</label>
  <input type="text" id="name" name="name" value="<?= $data['name'] ?? null ?>" required/>
 </div>
 <div class="form-fields">
  <label for="file">Select files</label>
  <input name="file[]" type="file" id="file" multiple>
 </div>

<input class="registration-button" type="submit" name="upload" value="Upload" />
</form>

controller:

<?php
return function ($kirby, $page, $site) {
 if ($kirby->request()->is('post') === true && get('upload')) {

  $user = $kirby->user(get('email'));

  $data = [
    'name'    => get('name'),
    'author'  => $user->id()
  ]
  $uploads = $kirby->request()->files()->get('file');
  $kirby->impersonate('kirby');
  try {
   //creating a page right here
   $registration = $site->find('projects')->createChild([
    'slug'     => $data['name'],
    'template' => 'basic_template',
    'draft'    => false,
    'content'  => $data
   ])->sort(1);

   //uploading files right here
   //they will be arranged in the new project
   foreach ($uploads as $upload) {
    try {
     $name = $upload['name'];
     $file = $registration->createFile([
       'source'   => $upload['tmp_name'],
       'filename' => $name,
       'template' => 'upload',
       'content' => [
       'date' => date('Y-m-d h:m')
      ]
     ]);
    } 
    catch (Exception $e) {
     $alerts[$upload['name']] = $e->getMessage();
    }
   }
  }

This is working fine.
How can I pass the uploaded files to the page?
It currently passes the name to the project.txt file, but I need an array, right? To make an ->toFile() command in the template.

current project.txt:

important_file: image.jpg

What I want the project.txt to be:

important_file:
- image.jpg

Is there a command to turn a normal string to an array string?

1 Like

Yes, you need an array and yaml-encode that if you want to later show it in a files field in the Panel. If not, you might as well leave it as is, and can still call the toFile() method on the field.

Why do you want to store that file in the content file? Or are there multiple files and one should be the hero file?

Yes, a user can upload multiple files and then select one.

e.g. 10 images, one of them will be the thumbnail.

I want to convert it to an array. If I edit it in the panel, it makes this array dash. But how can I add this dash?

1 Like
$fileArray = A::wrap($file->filename());

$page = $page->update([
  'important_file' => Data::encode($fileArray, 'yaml')
  ]);
1 Like

Ah very cool! It seems to work. I always thought wrap is something to eat.

1 Like

That depends, enjoy:

$edible = A::wrap('pasta');
4 Likes