D7 Upload de vários arquivos

O Drupal 7 e a API de formulário não suportam upload de vários arquivos como um tipo de campo na API de formulário. Foi assim que contornei isso e fiz o upload de vários arquivos funcionar como parte do meu próprio formulário personalizado.

function photos_upload_form($form, &$form_state) {
$form
= array();

$form
['file'] = array(
'#type' => 'file',
'#name' => 'files[]',
'#title' => t('Upload some photos'),
'#description' => t('JPG's, GIF's, and PNG's only, 10MB Max Size'),
'#attributes' => array('multiple' => 'multiple'),
);

//The nid of the node to upload the photos to
$form
['nid'] = array(
'#type' => 'hidden',
'#value' => $nid,
);

$form
['submit'] = array(
'#type' => 'submit',
'#value' => t('Upload'),
);

return $form;
}

O campo ‘#attributies’ no campo do arquivo é o que permite que a maioria dos navegadores reconheçam que este campo permitirá o upload de vários arquivos de uma vez.

Observe também que o #nome do campo do arquivo está listado como uma matriz (arquivos []) em vez de apenas um nome normal. Isso agrupará todos os seus arquivos na variável $ _FILES no envio do formulário para que você possa referenciá-los como verá abaixo.

function photos_upload_form_validate($form, &$form_state) {
//Save multiple files
$num_files
= count($_FILES['files']['name']);
for ($i = 0; $i < $num_files; $i++) {
$file
= file_save_upload($i, array(
'file_validate_is_image' => array(),
'file_validate_extensions' => array('png gif jpg jpeg'),
));
if ($file) {
if ($file = file_move($file, 'public://')) {
$form_state
['values']['file'][$i] = $file;
}
else {
form_set_error
('file', t('Failed to write the uploaded file the site's file folder.'));
}
}
else {
form_set_error
('file', t('No file was uploaded.'));
}
}
}

Esta função de formulário valida se cada arquivo corresponde aos critérios de validação (se é uma imagem e se tem extensões de arquivo válidas).

Observe que estou usando $ i em arquivo salvar carga em vez do campo de arquivo de formulário mostrado na primeira função de formulário. Isso ocorre porque quando você especifica o ‘#nome’ do campo do arquivo como uma matriz, ele fará referência a todos os arquivos carregados na variável $ FILES como índices numerados (de zero) em vez de nomes de strings. Isso é o que nos permite salvar cada arquivo no array $ FILES.

function photos_upload_form_submit($form, &$form_state) {
$nid
= $form_state['values']['nid'];
$node
= node_load($nid);
if (is_array($form_state['values']['file'])) {
//Make sure we keep our previously uploaded images
$i
= empty($node->field_image) ? 0 : count($node->field_image['und']);
foreach ($form_state['values']['file'] as $file) {
$new_file
= file_load($file->fid);
$file_info
= image_get_info($file->uri);
$node
->field_image[LANGUAGE_NONE][$i]['fid'] = $file->fid;
$node
->field_image[LANGUAGE_NONE][$i]['alt'] = '';
$node
->field_image[LANGUAGE_NONE][$i]['title'] = '';
$node
->field_image[LANGUAGE_NONE][$i]['width'] = $file_info['width'];
$node
->field_image[LANGUAGE_NONE][$i]['height'] = $file_info['height'];
$node
->field_image[LANGUAGE_NONE][$i]['uid'] = $file->uid;
$node
->field_image[LANGUAGE_NONE][$i]['filename'] = $file->filename;
$node
->field_image[LANGUAGE_NONE][$i]['uri'] = $file->uri;
$node
->field_image[LANGUAGE_NONE][$i]['filemime'] = $file->filemime;
$node
->field_image[LANGUAGE_NONE][$i]['filesize'] = $file->filesize;
$node
->field_image[LANGUAGE_NONE][$i]['status'] = '1';
$node
->field_image[LANGUAGE_NONE][$i]['timestamp'] = $file->timestamp;
$node
->field_image[LANGUAGE_NONE][$i]['rdf_mapping'] = array();
$i
++;
}
}
node_save
($node);
drupal_set_message
(t('Upload successful'));
}

A função de formulário acima está simplesmente pronta para salvar os arquivos recém-carregados no nó apropriado que especificamos na primeira função de formulário anteriormente. É importante observar a declaração de $ i nesta última função porque isso garante que não substituamos nenhum arquivo carregado anteriormente no nó.