Загрузка нескольких файлов в своём модуле Drupal 7

Как известно, Drupal 7 со своим Form API не поддерживает загрузку нескольких файлов. В статье я покажу как добавить эту возможность загрузки нескольких файлов в своём модуле Drupal 7 с помощью стандартного Form API компонента типа file '#type' => 'file'.

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;
}

Здесь, в атрибуты компонента file мы добавляем новый '#attributes' => array('multiple' => 'multiple'). Это позволит выбирать этим компонентов несколько файлов (Для справки: http://htmlbook.ru/samhtml5/formy/zagruzka-failov). Так же, задаём имя компонента как files[], что позволит получить все выбранные файлы в одном массиве глобального массива $_FILES.

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.'));
        }   
    }
}

В этой функции проверяем, чтобы каждый файл соответствовал критериям проверки (если это изображение, то чтобы оно имеело допустимые расширения файлов и т.д.).

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'));
}