bolt / forms

MIT License
21 stars 27 forks source link

Question about file upload and config option (missing feat or need doc ?) #77

Open Virprince opened 3 years ago

Virprince commented 3 years ago

Using Bolt 4, I want to be able to get the path of an uploaded file and store it in a contenttype but could'nt find how. $event->getAttachments() was always empty and $form->getData() show me original file in tmp and without suffix.

I dig a bit in extension code and config option and have some questions

are base_directory, subdirectory and management_controller working ?

in bolt-boltforms.yaml you can set options for uploads:

uploads:
  enabled: true                                 # The global on/off switch for upload handling
  base_directory: /home/[user]/[foo]/uploads # Outside web root and writable by the web server's 
  filename_handling: suffix                      # Can be either "prefix", "suffix", or "keep"
  management_controller: true                   # Enable a controller to handle browsing and downloading of uploaded files

An uploads folder is created in bolt root project and files are uploaded in it, ignoring your base_directory option. If you set a subdirectory option in your form config, it is ignored too

there is no controller in extension so.... management_controller option does something ?

my_form:
  uploads:
    subdirectory: candidatures  # Optional subdirectory

Upload config is in field level config ?

in src/EventSubscriber/FileUploadHandler.php, you find no use of base_directory option or subdirectory.

// src/EventSubscriber/FileUploadHandler.php
private function processFileField(Form $field, Collection $fieldConfig, PostSubmitEvent $event): void
    {

        $file = $field->getData();
        $form = $event->getForm();
        $formConfig = $event->getFormConfig();

        $filename = $this->getFilename($field->getName(), $form, $formConfig);
        $path = $fieldConfig['directory'] ?? '/uploads/';
        Str::ensureStartsWith($path, \DIRECTORY_SEPARATOR);
        $files = $this->uploadFiles($filename, $file, $path);

        if (isset($fieldConfig['attach']) && $fieldConfig['attach']) {
            $event->addAttachments([$field->getName() => $files]);
        }

    }

In this function we see $fieldConfig is used with directory and attach key

So if i put those key in my formfield config

f_avatar_upload:
      type: file
      directory: /uploads/avatar/  #add
      attach: true                         # add
      options:
        required: false
        label: Image représentant le personnage
        constraints:
          - Image:
              mimeTypes: [ 'image/png', 'image/jpeg' ]
              mimeTypesMessage: 'Le document doit être au format png ou jpg'
        help: "Cette information sera visible par tous"

Boom, my file is uploaded in the subdirectory , i finaly see attachement in $event->getAttachments() and it's sort of what i needed... filepath with suffix

array:5 [▼
  "ip" => "127.0.0.1"
  "timestamp" => Carbon\Carbon @1625135286 {#4318 ▶}
  "path" => "/inscription/creation-de-son-personnage?code=ij6HYzYGYKDRQlTJyMdDp0JfejxoBY"
  "url" => "http://127.0.0.1:8000/inscription/creation-de-son-personnage?code=ij6HYzYGYKDRQlTJyMdDp0JfejxoBY"
  "attachments" => array:1 [▼
    "f_avatar_upload" => array:1 [▼
      0 => "/home/[user]/[foo]/[bla]/[my_bolt_project]/uploads/avatar/75a4a196_Uploaded file60dd98b6bded220190212223454-1.jpg"
    ]
  ]
]

Maybe i missed something but if it's the way it means to work, a bit of documentation can be added to config.yaml in the file example

#        upload:
#            type: file
#            attach: true  # attach your file if you need to send it or save it 
#            directory: /uploads/pet/  #path to directory where file is uploaded
#            options:
#                required: false
#                label: Picture of your pet that you want us to add to our site

edit: Add management_controller in first question.