function s3fs_cors_field_widget_form in S3 File System CORS Upload 7
Implements hook_field_widget_form().
File
- ./
s3fs_cors.module, line 112 - Allow uploading of files directly to AmazonS3 via the browser using CORS.
Code
function s3fs_cors_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
// A lot of this is borrowed from file_field_widget_form().
$defaults = array(
'fid' => 0,
'display' => !empty($field['settings']['display_default']),
'description' => '',
);
// Load the items for form rebuilds from the field state as they might not be
// in $form_state['values'] because of validation limitations. Also, they are
// only passed in as $items when editing existing entities.
$field_state = field_form_get_state($element['#field_parents'], $field['field_name'], $langcode, $form_state);
if (isset($field_state['items'])) {
$items = $field_state['items'];
}
// Since the upload isn't going through PHP, it is limited only by S3's max
// filesize for single-part uploads, which is 5GB.
$validators = file_field_widget_upload_validators($field, $instance);
$max_filesize = parse_size('5G');
// If the user is on IE8 or 9, they can't do CORS uploads, so PHP's upload
// size limit matters.
if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/MSIE [8-9]\\.0/', $_SERVER['HTTP_USER_AGENT'])) {
$max_filesize = parse_size(file_upload_max_size());
}
// If the admin has specified a smaller max size, use that.
if (!empty($instance['settings']['max_filesize']) && parse_size($instance['settings']['max_filesize']) < $max_filesize) {
$max_filesize = parse_size($instance['settings']['max_filesize']);
}
$validators['file_validate_size'] = array(
$max_filesize,
);
// We use the s3fs_cors_upload type, which is based of of the managed_file type,
// extended with some enhancements for CORS.
$element_info = element_info('s3fs_cors_upload');
$element += array(
'#type' => 's3fs_cors_upload',
'#upload_location' => file_field_widget_uri($field, $instance),
// TODO: See https://www.drupal.org/node/2185925 for ideas on how to
// deal with file_field_widget_upload_validators() being too restrictive on file size.
'#upload_validators' => $validators,
'#value_callback' => 's3fs_cors_field_widget_value',
'#process' => array_merge($element_info['#process'], array(
'file_field_widget_process',
)),
// Allows this field to return an array instead of a single value.
'#extended' => TRUE,
);
if ($field['cardinality'] == 1) {
// Set the default value.
$element['#default_value'] = !empty($items) ? $items[0] : $defaults;
// If there's only one field, return it as delta 0.
if (empty($element['#default_value']['fid'])) {
$element['#description'] = theme('file_upload_help', array(
'description' => $element['#description'],
'upload_validators' => $element['#upload_validators'],
));
}
$elements = array(
$element,
);
}
else {
// If there are multiple values, add an element for each existing one.
foreach ($items as $item) {
$elements[$delta] = $element;
$elements[$delta]['#default_value'] = $item;
$elements[$delta]['#weight'] = $delta;
$delta++;
}
// And then add one more empty row for new uploads except when this is a
// programmed form as it is not necessary.
if (($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) && empty($form_state['programmed'])) {
$elements[$delta] = $element;
$elements[$delta]['#default_value'] = $defaults;
$elements[$delta]['#weight'] = $delta;
$elements[$delta]['#required'] = $element['#required'] && $delta == 0;
}
// The group of elements all-together need some extra functionality
// after building up the full list (like draggable table rows).
$elements['#file_upload_delta'] = $delta;
$elements['#theme'] = 'file_widget_multiple';
$elements['#theme_wrappers'] = array(
'fieldset',
);
$elements['#process'] = array(
'file_field_widget_process_multiple',
);
$elements['#title'] = $element['#title'];
$elements['#description'] = $element['#description'];
$elements['#field_name'] = $element['#field_name'];
$elements['#language'] = $element['#language'];
$elements['#display_field'] = !empty($field['settings']['display_field']) ? $field['settings']['display_field'] : 0;
// Add some properties that will eventually be added to the file upload
// field. These are added here so that they may be referenced easily through
// a hook_form_alter().
$elements['#file_upload_title'] = t('Add a new file');
$elements['#file_upload_description'] = theme('file_upload_help', array(
'description' => '',
'upload_validators' => $elements[0]['#upload_validators'],
));
}
return $elements;
}