Skip to content

Nahrávání souborů

Nahrávání v administraci je dnes postavené hlavně na jednom zjednodušeném prvku:

  • element.type: dropzone

Starší větvení na více speciálních upload typů už není hlavní doporučený model dokumentace.

Co se změnilo

Dřív dokumentace popisovala více variant jako files, cFiles, různé speciální factory metody a pevné DOM identifikátory typu id: 101.

Současný stav je jednodušší:

  • renderer generuje .dropzone element
  • JS inicializuje všechny .dropzone[data-url]
  • konfigurace se čte z data-* atributů
  • backend upload řeší DropzoneHandler

id: 101 není obecné pravidlo. Je to jen historický nebo konkrétní příklad z některých YAML definic.

YAML definice

Typický zápis dnes vypadá takto:

- name: pdf_file
  label: Upload PDF
  hideOnNew: true
  multilingual: true
  element:
    type: dropzone
    action: uploadPdf
    accept: .pdf

Nebo pro více souborů:

- name: file1
  label: Photos
  text:
  element:
    type: dropzone
    multiple: true
    chunked: true
    accept: image/webp,image/jpeg,image/png

Používané klíče:

  • element.type: dropzone
  • element.action volitelná upload route přípona
  • element.accept accepted mime/ext seznam pro browser
  • element.multiple: true povolí víc souborů
  • element.chunked: true zapne chunked upload
  • text vlastní zpráva pro Dropzone
  • id je volitelné; pokud chybí, použije se name

Jak se skládá upload URL

FormFieldFactory::createDropzone() bere základ z aktuálního request URI a případně přidá element.action.

Prakticky:

  • bez action se upload posílá na aktuální URL
  • s action: uploadPdf se přidá /uploadPdf
  • u vícejazyčných polí se může přidat i /{lang}

Render výsledného prvku

Dropzone renderer negeneruje složitou vlastní strukturu. Výstup je jednoduchý:

<div id="dropzonepdf_file" class="dropzone" data-url="..." data-accept=".pdf"></div>

JS pak inicializuje všechny:

document.querySelectorAll('.dropzone[data-url]')

To je důvod, proč pevné ruční DOM ID typu dropzone101 už není důležité pro pochopení systému.

Admin JavaScript

Inicializace je v:

  • src/admin/js/dropzone/files.js

Sdílené chování:

  • čte data-url
  • čte data-accept
  • čte data-message
  • čte data-chunked
  • čte data-multiple
  • posílá X-CSRF-Token
  • používá společné i18n hlášky

Chunked konfigurace je dnes jednotná:

  • chunkSize: 1048576
  • retryChunks: true
  • retryChunksLimit: 3
  • parallelUploads: 1

Pokud data-chunked="1" chybí, použije se nechunkovaný režim.

Backend handler

Upload backend řeší:

  • core/Upload/DropzoneHandler.php

Použití:

$result = DropzoneHandler::upload();

Nebo s omezením:

$result = DropzoneHandler::upload([
    'allowedExtensions' => ['pdf'],
    'maxFileSizeMB' => 20,
]);

Při uploadu handler vrací typicky:

['status' => DropzoneHandler::STATUS_CHUNK]

nebo po dokončení:

[
    'path' => '/abs/path/to/file',
    'name' => 'soubor.pdf',
    'status' => DropzoneHandler::STATUS_COMPLETE,
]

nebo:

['error' => '...']

Bezpečnost a omezení

DropzoneHandler vždy blokuje:

  • php*
  • html
  • js

Navíc můžeš povolit explicitní allowlist přes allowedExtensions.

Velikost se hlídá přes:

  • maxFileSizeMB

Dočasné soubory se ukládají do adresáře nastaveného přes:

  • DropzoneHandler::setPath(...)

v projektu standardně do var/tmp.

Příklady v projektu

Aktuální reálné příklady:

  • app/Modules/News/data.yaml upload PDF přes action: uploadPdf

  • app/Modules/Gallery/Photo/data.yaml upload více fotek přes multiple: true, chunked: true

Co už nebrat jako zdroj pravdy

Za zastaralé považuj hlavně:

  • dokumentaci založenou na src/backend/...
  • popis více historických upload typů jako hlavního modelu
  • představu, že každý dropzone musí mít ručně významné id: 101

Současný doporučený model je prostě type: dropzone s jednoduchou konfigurací v element.