public static function ManagedFile::processManagedFile in Zircon Profile 8
Same name and namespace in other branches
- 8.0 core/modules/file/src/Element/ManagedFile.php \Drupal\file\Element\ManagedFile::processManagedFile()
Render API callback: Expands the managed_file element type.
Expands the file type to include Upload and Remove buttons, as well as support for a default value.
File
- core/
modules/ file/ src/ Element/ ManagedFile.php, line 184 - Contains \Drupal\file\Element\ManagedFile.
Class
- ManagedFile
- Provides an AJAX/progress aware widget for uploading and saving a file.
Namespace
Drupal\file\ElementCode
public static function processManagedFile(&$element, FormStateInterface $form_state, &$complete_form) {
// This is used sometimes so let's implode it just once.
$parents_prefix = implode('_', $element['#parents']);
$fids = isset($element['#value']['fids']) ? $element['#value']['fids'] : [];
// Set some default element properties.
$element['#progress_indicator'] = empty($element['#progress_indicator']) ? 'none' : $element['#progress_indicator'];
$element['#files'] = !empty($fids) ? File::loadMultiple($fids) : FALSE;
$element['#tree'] = TRUE;
// Generate a unique wrapper HTML ID.
$ajax_wrapper_id = Html::getUniqueId('ajax-wrapper');
$ajax_settings = [
'callback' => [
get_called_class(),
'uploadAjaxCallback',
],
'options' => [
'query' => [
'element_parents' => implode('/', $element['#array_parents']),
],
],
'wrapper' => $ajax_wrapper_id,
'effect' => 'fade',
'progress' => [
'type' => $element['#progress_indicator'],
'message' => $element['#progress_message'],
],
];
// Set up the buttons first since we need to check if they were clicked.
$element['upload_button'] = [
'#name' => $parents_prefix . '_upload_button',
'#type' => 'submit',
'#value' => t('Upload'),
'#attributes' => [
'class' => [
'js-hide',
],
],
'#validate' => [],
'#submit' => [
'file_managed_file_submit',
],
'#limit_validation_errors' => [
$element['#parents'],
],
'#ajax' => $ajax_settings,
'#weight' => -5,
];
// Force the progress indicator for the remove button to be either 'none' or
// 'throbber', even if the upload button is using something else.
$ajax_settings['progress']['type'] = $element['#progress_indicator'] == 'none' ? 'none' : 'throbber';
$ajax_settings['progress']['message'] = NULL;
$ajax_settings['effect'] = 'none';
$element['remove_button'] = [
'#name' => $parents_prefix . '_remove_button',
'#type' => 'submit',
'#value' => $element['#multiple'] ? t('Remove selected') : t('Remove'),
'#validate' => [],
'#submit' => [
'file_managed_file_submit',
],
'#limit_validation_errors' => [
$element['#parents'],
],
'#ajax' => $ajax_settings,
'#weight' => 1,
];
$element['fids'] = [
'#type' => 'hidden',
'#value' => $fids,
];
// Add progress bar support to the upload if possible.
if ($element['#progress_indicator'] == 'bar' && ($implementation = file_progress_implementation())) {
$upload_progress_key = mt_rand();
if ($implementation == 'uploadprogress') {
$element['UPLOAD_IDENTIFIER'] = [
'#type' => 'hidden',
'#value' => $upload_progress_key,
'#attributes' => [
'class' => [
'file-progress',
],
],
// Uploadprogress extension requires this field to be at the top of
// the form.
'#weight' => -20,
];
}
elseif ($implementation == 'apc') {
$element['APC_UPLOAD_PROGRESS'] = [
'#type' => 'hidden',
'#value' => $upload_progress_key,
'#attributes' => [
'class' => [
'file-progress',
],
],
// Uploadprogress extension requires this field to be at the top of
// the form.
'#weight' => -20,
];
}
// Add the upload progress callback.
$element['upload_button']['#ajax']['progress']['url'] = Url::fromRoute('file.ajax_progress');
}
// The file upload field itself.
$element['upload'] = [
'#name' => 'files[' . $parents_prefix . ']',
'#type' => 'file',
'#title' => t('Choose a file'),
'#title_display' => 'invisible',
'#size' => $element['#size'],
'#multiple' => $element['#multiple'],
'#theme_wrappers' => [],
'#weight' => -10,
'#error_no_message' => TRUE,
];
if (!empty($fids) && $element['#files']) {
foreach ($element['#files'] as $delta => $file) {
$file_link = [
'#theme' => 'file_link',
'#file' => $file,
];
if ($element['#multiple']) {
$element['file_' . $delta]['selected'] = [
'#type' => 'checkbox',
'#title' => \Drupal::service('renderer')
->renderPlain($file_link),
];
}
else {
$element['file_' . $delta]['filename'] = $file_link + [
'#weight' => -10,
];
}
}
}
// Add the extension list to the page as JavaScript settings.
if (isset($element['#upload_validators']['file_validate_extensions'][0])) {
$extension_list = implode(',', array_filter(explode(' ', $element['#upload_validators']['file_validate_extensions'][0])));
$element['upload']['#attached']['drupalSettings']['file']['elements']['#' . $element['#id']] = $extension_list;
}
// Let #id point to the file element, so the field label's 'for' corresponds
// with it.
$element['#id'] =& $element['upload']['#id'];
// Prefix and suffix used for Ajax replacement.
$element['#prefix'] = '<div id="' . $ajax_wrapper_id . '">';
$element['#suffix'] = '</div>';
return $element;
}