xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Загрузка файлов средствами Form API

Опубликовано в

Пример загрузки картинки с помощью Form API:

/**
 * Form builder.
 */
function mymodule_myform() {
  $form['file'] = array(
    '#type' => 'file',
    '#title' => 'Картинка',
    '#description' => 'Выберите файл с расширением jpg, jpeg, png или gif',
  );
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Отправить',
  );
 
  return $form;
}
 
/**
 * Form validate callback.
 */
function mymodule_myform_validate($form, &$form_state) {
  $validators = array(
    'file_validate_is_image' => array(), // Проверка, действительно ли файл является изображением
    'file_validate_extensions' => array('png gif jpg jpeg'), // Проверка на расширения
    'file_validate_size' => array(1 * 1024 * 1024), // Проверка на размер файла (максимум 1mb)
  );
  // Загружаем файл в sites/default/files (по умолчанию)
  if ($file = file_save_upload('file', $validators, 'public://')) {
    $form_state['values']['file'] = $file; // передаём информацию о файле в ф-ю mymodule_form_submit()
  }
  else {
    form_set_error('file', 'Файл не был загружен');
  }
}
 
/**
 * Form submit callback.
 */
function mymodule_myform_submit($form, &$form_state) {
  $file = $form_state['values']['file'];
  $file->status = FILE_STATUS_PERMANENT; // Изменяем статус файла на "Постоянный"
  file_save($file); // Сохраняем новый статус
  drupal_set_message('Картинка загружена');
}

Важно помнить, что ф-я file_save_upload() загружает файл на сервер, добавляет информацию о нём в таблицу file_managed и помечает его как "Временный", поэтому если вам необходимо пользоваться файлом в дальнейшем, то нужно в submit-е формы изменять статус файла на "Постоянный" (FILE_STATUS_PERMANENT) и вызывать file_save(), чтобы файл автоматически не удалился по прошествии времени .

Полезное дополнение к статье — Использование виджета AJAX загрузки файлов в своих формах.

Написанное актуально для Drupal 7
Похожие записи

Комментарии RSS

Добрый день!
file_save_upload(), как и move_uploaded_file() некорректно загружают файлы с русскими именами, нашел вот это решение, из него два вопроса:
1. Это правильное решение или у вас свой взгляд на решение этой проблемы?
2. Если все же правильное, то в какой из .htaccess вносить изменения? Их у меня два (в корне сайта и в sites\default\files)?

Второй день бьюсь. Помогите пожалуйста!

PS: пробовал вносить во все свои .htaccess, ничего не помогает.

Пока ждал ответа докопался, что проблема не в этом. Нужно было сохранять файл из GET запроса, сохранялся криво, пока не попробовал iconv().
Спасибо )

Если у меня несколько полей для загрузки файлов вида:

$form['file'][0] = array(
    '#type' => 'file',
  );
 
$form['file'][1] = array(
    '#type' => 'file',
  );
 
...

Как в этом случае будет выглядеть сохранение файлов?
В частности, интересует вид первого параметра в file_save_upload()

'file[0]'

А если индексы тройные?

$form['attachment'][$i]['file'] = array(
     '#type' => 'file',
);

'attachment[' . $i . '][file]'

А вы сами пробовали так сделать? У меня не работает ни с двойными, ни с тройными индексами.

Возможно, вам интересно будет почитать:
http://drupal.org/node/83698

Я просто оставлю это здесь:
file_validate_extensions() Check that the filename ends with an allowed extension. This check is not enforced for the user #1.

Создал страницу, на странице добавил форму на форме:

$form = array(
    '#attributes' => array('enctype' => 'multipart/form-data'),
  );
 
  $form['upload'] = array(
    '#type' => 'file',
    '#description' => t('Upload only .xls files'),
  );
 
  $form['submit'] = array(
    '#type'  => 'submit', 
    '#value' => t('Import'),
  );
 
  return $form;

Вот функция валидации:

if (isset($form['upload'])) {
    $validators = array(
      'file_validate_extensions' => array('xls'),
    );
    $dir = 'public://';
    $file = file_save_upload('upload', $validators, $dir);
    if ($file) {
      $form_state['values']['upload'] = $file;
    }
    else {
      form_set_error('upload', t('Error. File is not .xls'));
    }
  }

На сабмите:

$file = $form_state['values']['upload'];
$file->status = FILE_STATUS_PERMANENT;
file_save($file);

Нужно мне загружать файлы екселя и с нами уже работать. Выбивает ошибка вот на этой строчке $file = file_save_upload('upload', $validators, $dir);

Ошибка:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'public://import_1.xls' for key 'uri': INSERT INTO {file_managed} (uid, filename, uri, filemime, filesize, status, timestamp) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6); Array ( [:db_insert_placeholder_0] => 1 [:db_insert_placeholder_1] => import.xls [:db_insert_placeholder_2] => public://import_1.xls [:db_insert_placeholder_3] => application/vnd.ms-excel [:db_insert_placeholder_4] => 28160 [:db_insert_placeholder_5] => 0 [:db_insert_placeholder_6] => 1324291479 ) в функции drupal_write_record()

Что не так я написал? Спасибо.

Спасибо!

вставил скрипт в, но у меня выдает ошибку. В чем может быть проблема?
Call to undefined function file_save() in C:\xampp\htdocs\dp\sites\all\modules\object\object.inc on line 211

наверное в том, что у вас drupal 6

понятно, а как можно реализовать загрузку файлов в 6 версии?

Спасибо, но,у меня еще вопросы:

 $dest_path = 'upload_directory/file';
    $result = file_copy($file, $dest_path, FILE_EXISTS_RENAME);

upload_directory/file Эту директорию надо где то создавать?

я создаю при установке/включении своего модуля в hook_install/hook_enable:

  $path = file_create_path(file_directory_path() .'/upload/dir1');
  file_check_directory($path, FILE_CREATE_DIRECTORY); 

это путь к файлу. если директории нет, то её естественно нужно создать и дать соответствующие права

Спасибо, скрипт написал -он копирует файл в папку files, но у меня еще 1 вопрос: что бы
получить ссылку на скачивание файла (для занесения её в бд), в хуке в submit, в функцию file_create_url какой параметр можно передать?

путь к файлу относительно папки drupal

а как можно получить путь к файлу? Можно ли как то использовать объект $file, который только загрузили?

А как реализовать, что бы в - drupal_set_message('Картинка загружена') - выводилось еще
и название загруженной картинки?

А можно ли как-то аналогично с помощью Form API реализовать мульти-загрузку нескольких файлов? Просто в этом примере стандартный элемент формы типа file берёт только один файл за раз. Пытался по-всякому дописывать к полю атрибут multiple, но что-то безрезультатно. И не очень понятно, что в этом случае передовать первым аргументом в функцию file_save_upload.

Потом попробовал вместо '#type' => 'file' вставить загрузчик plupload ('#type' => 'plupload'), но тут опять-таки непонятно, как передать то, что он подгружает, в file_save_upload

function staff_form_submit($form, &$form_state) {
  $file = $form_state['values']['file'];
  $file->status = FILE_STATUS_PERMANENT; // Изменяем статус файла на "Постоянный"
  file_save($file); // Сохраняем новый статус
  drupal_set_message('Картинка загружена');
 
  $staff = entity_ui_form_submit_build_entity($form, $form_state);
  $staff->save();
  $form_state['redirect'] = 'admin/structure/staffs';
 
}

ошибка:
Картинка загружена
Error messageRecoverable fatal error: Object of class stdClass could not be converted to string in drupal_write_record() (line 6938 of C:\xampp\htdocs\corjeque\includes\common.inc).

вот в контексте

http://pastebin.com/eB4YM38W

перед entity_ui_form_submit_build_entity() сделайте unset($form_state['values']['file'])

Благодарю) Картинка загружается. По моему мнению - это самый полезный блог/ресурс по CMS Drupal.

Скажите, картинка которую я загрузил в форму, кидается в каталог,
А если создать для нее специальное поле в .install - blob и прописать его в форме, я смогу отобразить его черз theme('table'....)

нет

а как при выводе информации обратится к файлу

foreach ($query as $staffs) 
		{
		$rows[] = array(
			check_plain($staffs->hid),
			check_plain($staffs->name),
			check_plain($staffs->post),
			check_plain($staffs->rank),
			check_plain($staffs->exp),
			check_plain($staffs->salary),
			$staffs->file,
 
	);
}

что значит "обратится"?

*обратиться
я имел ввиду: как вызвать файл из каталога друпал, для того чтобы отобразить его в конкретном материале. Мы же зачем то заполняли эту форму

куда вызвать? если показать в браузере, то — http://htmlbook.ru/html/img

а если отображать в друпале, то http://xandeadx.ru/blog/drupal/538?

я вас не понимаю

Привет. Как можно поменять название файла при с помощью Form API ?

* при загрузке с помощью Form API

Спасибо! ты мастер!

спасибки за пост

У меня у одного чтоле не работает?
Основная суть в том что в $_FILES имеем:

array(
  'file' => array(
    'name' => '13091023-short.txt',
    'type' => 'text/plain',
    'tmp_name' => '/tmp/phpME50PG',
    'error' => 0,
    'size' => 7642,
  ),
)

в то время как в теле file_save_upload имеем:

  if (empty($_FILES['files']['name'][$source])) {
    return NULL;
  }

в итоге не работает ну ваще никак...
можно вручную конечно обработать, но хотелось бы друпалвэй

upd.

низя писать '#name', в этом все дело.

Добрый вечер! Подскажите как добраться до загруженного файла в модуле, чтобы изменить его. Например чтобы наложить водяные знаки на картинку.

Скажите, а есть ли полная версия модуля, не могу разобраться что и как подключать?

Скажите, а если я не просто хочу добавить файл, а хочу чтобы он сохранился в форме. Т.е. чтобы при следующем открытии страницы с формой в данном поле был указан этот файл и у меня была возможность его удалить и загрузить другой.

Не подскажете, почему виджет загрузки файла меняет расширение загружаемого файла с расширением .js на .js.txt?

защита от заливки вредоносных файлов

Спасибо. Это настраивается или только программно? Направьте, куда копать?

Спасибо. Нашел обсуждение именно по моему вопросу http://stackoverflow.com/questions/1378246/drupal-filefield-wont-upload-javascript-files

Как получить полный путь к загруженному файлу?

путь к файлу
$path = file_create_url($file->uri);
P.S.
file_create_url - формирует путь для скачивания файла.

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании