Вы создали форму с полем типа file, и хотите сохранять файл как сущность друпала при отправке данных формы.
1 2 3 4 5 6 |
$form['file'] = [ '#type' => 'file', '#title' => t('File'), '#description' => t('File to upload.'), '#attributes' => ['accept' => '.csv'], ]; |
Обычно объявления форм в Drupal 8+ размещаются в виде расширений класса FormBase в каталоге модуля /scr/Form/*.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; /** * @see \Drupal\Core\Form\FormBase */ class FileSaveForm extends FormBase { /** * */ public function buildForm(array $form, FormStateInterface $form_state) { $form['file'] = [ '#type' => 'file', '#title' => t('File'), '#description' => t('File to upload.'), '#attributes' => ['accept' => '.csv'], ]; // Save action. $form['actions']['saveFile'] = [ '#type' => 'submit', '#value' => t('Save File'), '#submit' => ['::saveFile'], ]; return $form; } /** * @inherited. */ public function getFormId() { return 'save_file_form'; } /** * Обработчик сабмита формы */ public function saveFile(array &$form, FormStateInterface $form_state) { $filefield_name = 'file'; $all_files = \Drupal::request()->files; $file = $all_files->get('files')[$filefield_name]; if ($file && $file->isValid()) { // Подготовим папку в паблик файлах, // пусть это будет upload_dir. \Drupal::service('file_system') ->mkdir("public://upload_dir", 0777, TRUE); // создание файла if ($drupalFile = file_save_upload( 'file', [], 'public://upload_dir', 0) ) { // если всё прошло успешно, можно вывести сообщение Drupal::messenger()->addStatus(t('File has been created.')); } } } /** * @inherited. */ public function submitForm(array &$form, FormStateInterface $form_state) { // это штатный обработчик, он требуется в любом случае, т.к. // мы должны имплементировать FormInterface } } |
Этот пример содержит две проблемы.
Разрешаем нужные расширения
Первая связана с тем, что я намеренно разрешил загрузку только csv файлов, которых нет в «стандартном» списке разрешенных для функции file_save_upload.
Поэтому требуется задать нужный нам валидатор.
1 2 3 4 5 |
if ($drupalFile = file_save_upload( 'file', ['file_validate_extensions' => ['csv']], 'public://migrations', 0) ) ... |
Временные файлы
Вторая проблема более серьёзная, она заключается в том, что файл сохраняется как временный. И через какое то время (типично — 8 часов) он может быть удален сборщиком мусора в друпал.
Чтобы избежать этого есть как минимум два пути:
Первый — это использование созданного файла в какой то другой сущности, через регистрацию связи сервисом ‘file.usage’.
Второй путь — это напрямую установить флаг permanent для только созданной сущности.
1 2 3 |
$drupalFile->setPermanent(); $drupalFile->save(); |