1 file.module | file_ajax_upload() |
Ajax callback: Processes file uploads and deletions.
This rebuilds the form element for a particular field item. As long as the form processing is properly encapsulated in the widget element the form should rebuild correctly using FAPI without the need for additional callbacks or processing.
See also
File
- core/
modules/ file/ file.module, line 1119 - Defines a "managed_file" Form API field and a "file" field for Field module.
Code
function file_ajax_upload() {
$args = func_get_args();
// Token used to validate that the path values are unmodified.
$token = (string) array_pop($args);
// Form build key to pull from the form cache.
$form_build_id = (string) array_pop($args);
// All remaining arguments are the path to the form element in the form tree.
$form_parents = $args;
// Reassemble the #ajax['path'] property so we can validate the token.
$original_path = 'file/ajax/' . implode('/', $form_parents) . '/' . $form_build_id;
$original_token = backdrop_hmac_base64($original_path, backdrop_get_private_key() . backdrop_get_hash_salt());
if ($original_token !== $token) {
// Path has been tampered with. Reject the request.
backdrop_set_message(t('Invalid upload token.'), 'error');
$commands = array();
$commands[] = ajax_command_remove('.file-ajax-messages');
$commands[] = ajax_command_prepend(NULL, '<div class="file-ajax-messages">' . theme('status_messages') . '</div>');
return array('#type' => 'ajax', '#commands' => $commands);
}
// Sanitize form parents before using them.
$form_parents = array_filter($form_parents, 'element_child');
if (empty($_POST['form_build_id']) || $form_build_id != $_POST['form_build_id']) {
// Invalid request.
backdrop_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
$commands = array();
$commands[] = ajax_command_remove('.file-ajax-messages');
$commands[] = ajax_command_prepend(NULL, '<div class="file-ajax-messages">' . theme('status_messages') . '</div>');
$field_name = (string) reset($form_parents);
$wrapper_id = backdrop_html_id('edit-' . $field_name);
$commands[] = ajax_command_invoke('#' . $wrapper_id . ' .form-type-managed-file input[type="file"]', 'val', array(''));
return array('#type' => 'ajax', '#commands' => $commands);
}
list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
if (!$form) {
// Invalid form_build_id.
backdrop_set_message(t('An unrecoverable error occurred. Use of this form has expired. Try reloading the page and submitting again.'), 'error');
$commands = array();
$commands[] = ajax_command_remove('.file-ajax-messages');
$commands[] = ajax_command_prepend(NULL, '<div class="file-ajax-messages">' . theme('status_messages') . '</div>');
return array('#type' => 'ajax', '#commands' => $commands);
}
// Process user input. $form and $form_state are modified in the process.
backdrop_process_form($form['#form_id'], $form, $form_state);
// Retrieve the element to be rendered.
foreach ($form_parents as $parent) {
$form = $form[$parent];
}
$form['#prefix'] .= '<div class="file-ajax-messages">' . theme('status_messages') . '</div>';
$output = backdrop_render($form);
$js = backdrop_add_js();
$settings = backdrop_array_merge_deep_array($js['settings']['data']);
$commands[] = ajax_command_replace(NULL, $output, $settings);
return array('#type' => 'ajax', '#commands' => $commands);
}