public static function PlUploadFile::valueCallback in Plupload integration 8
Same name and namespace in other branches
- 2.0.x src/Element/PlUploadFile.php \Drupal\plupload\Element\PlUploadFile::valueCallback()
Overrides FormElement::valueCallback
See also
ManagedFile::valueCallback
file_managed_file_save_upload()
File
- src/
Element/ PlUploadFile.php, line 52
Class
- PlUploadFile
- Provides a PLUpload widget for uploading and saving files.
Namespace
Drupal\plupload\ElementCode
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
$id = $element['#id'];
// If a unique identifier added with '--', we need to exclude it.
if (preg_match('/(.*)(--[0-9A-Za-z]+)$/', $id, $reg)) {
$id = $reg[1];
}
// Seems cleaner to use something like this, but it's empty.
// $request_files = \Drupal::request()->files;
$input = $form_state
->getUserInput();
$files = [];
foreach ($input as $key => $value) {
if (preg_match('/' . $id . '(--([0-9A-Za-z_-]+))?_([0-9]+)_(tmpname|name|status)/', $key, $reg)) {
$i = $reg[3];
$key = $reg[4];
// Only add the keys we expect.
if (!in_array($key, [
'tmpname',
'name',
'status',
])) {
continue;
}
// Munge the submitted file names for security.
//
// Similar munging is normally done by file_save_upload(), but submit
// handlers for forms containing plupload elements can't use
// file_save_upload(), for reasons discussed in plupload_test_submit().
// So we have to do this for them.
//
// Note that we do the munging here in the value callback function
// (rather than during form validation or elsewhere) because we want to
// actually modify the submitted values rather than reject them
// outright; file names that require munging can be innocent and do
// not necessarily indicate an attempted exploit. Actual validation of
// the file names is performed later, in plupload_element_validate().
if (in_array($key, [
'tmpname',
'name',
])) {
// Find the whitelist of extensions to use when munging. If there are
// none, we'll be adding default ones in plupload_element_process(),
// so use those here.
if (isset($element['#upload_validators']['file_validate_extensions'][0])) {
$extensions = $element['#upload_validators']['file_validate_extensions'][0];
}
else {
$validators = _plupload_default_upload_validators();
$extensions = $validators['file_validate_extensions'][0];
}
$value = file_munge_filename($value, $extensions, FALSE);
// To prevent directory traversal issues, make sure the file name does
// not contain any directory components in it. (This more properly
// belongs in the form validation step, but it's simpler to do here so
// that we don't have to deal with the temporary file names during
// form validation and can just focus on the final file name.)
//
// This step is necessary since this module allows a large amount of
// flexibility in where its files are placed (for example, they could
// be intended for public://subdirectory rather than public://, and we
// don't want an attacker to be able to get them back into the top
// level of public:// in that case).
$value = rtrim(\Drupal::service('file_system')
->basename($value), '.');
// Based on the same feture from file_save_upload().
if (!\Drupal::config('system.file')
->get('allow_insecure_uploads') && preg_match('/\\.(php|pl|py|cgi|asp|js)(\\.|$)/i', $value) && substr($value, -4) != '.txt') {
$value .= '.txt';
// The .txt extension may not be in the allowed list of extensions.
// We have to add it here or else the file upload will fail.
if (!empty($extensions)) {
$element['#upload_validators']['file_validate_extensions'][0] .= ' txt';
\Drupal::messenger()
->addMessage(t('For security reasons, your upload has been renamed to %filename.', [
'%filename' => $value,
]));
}
}
}
// The temporary file name has to be processed further so it matches
// what was used when the file was written; see
// plupload_handle_uploads().
if ($key == 'tmpname') {
$value = _plupload_fix_temporary_filename($value);
// We also define an extra key 'tmppath' which is useful so that
// submit handlers do not need to know which directory plupload
// stored the temporary files in before trying to copy them.
$files[$i]['tmppath'] = \Drupal::config('plupload.settings')
->get('temporary_uri') . $value;
}
elseif ($key == 'name') {
$value = \Drupal::service('transliteration')
->transliterate($value);
}
// Store the final value in the array we will return.
$files[$i][$key] = $value;
}
}
return $files;
}