WordPress Version: 3.9
/**
* Handle sideloads, which is the process of retrieving a media item from another server instead of
* a traditional media upload. This process involves sanitizing the filename, checking extensions
* for mime type, and moving the file to the appropriate directory within the uploads directory.
*
* @since 2.6.0
*
* @uses wp_handle_upload_error
* @uses wp_check_filetype_and_ext
* @uses current_user_can
* @uses wp_upload_dir
* @uses wp_unique_filename
* @param array $file an array similar to that of a PHP $_FILES POST array
* @param array $overrides Optional. An associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ).
* @param string $time Optional. Time formatted in 'yyyy/mm'.
* @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
*/
function wp_handle_sideload(&$file, $overrides = false, $time = null)
{
// The default error handler.
if (!function_exists('wp_handle_upload_error')) {
function wp_handle_upload_error(&$file, $message)
{
return array('error' => $message);
}
}
// You may define your own function and pass the name in $overrides['upload_error_handler']
$upload_error_handler = 'wp_handle_upload_error';
// You may define your own function and pass the name in $overrides['unique_filename_callback']
$unique_filename_callback = null;
// $_POST['action'] must be set and its value must equal $overrides['action'] or this:
$action = 'wp_handle_sideload';
// Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
$upload_error_strings = array(false, __("The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>."), __("The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form."), __("The uploaded file was only partially uploaded."), __("No file was uploaded."), '', __("Missing a temporary folder."), __("Failed to write file to disk."), __("File upload stopped by extension."));
// All tests are on by default. Most can be turned off by $overrides[{test_name}] = false;
$test_form = true;
$test_size = true;
// If you override this, you must provide $ext and $type!!!!
$test_type = true;
$mimes = false;
// Install user overrides. Did we mention that this voids your warranty?
if (is_array($overrides)) {
extract($overrides, EXTR_OVERWRITE);
}
// A correct form post will pass this test.
if ($test_form && (!isset($_POST['action']) || $_POST['action'] != $action)) {
return $upload_error_handler($file, __('Invalid form submission.'));
}
// A successful upload will pass this test. It makes no sense to override this one.
if (!empty($file['error'])) {
return $upload_error_handler($file, $upload_error_strings[$file['error']]);
}
// A non-empty file will pass this test.
if ($test_size && !(filesize($file['tmp_name']) > 0)) {
return $upload_error_handler($file, __('File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.'));
}
// A properly uploaded file will pass this test. There should be no reason to override this one.
if (!@is_file($file['tmp_name'])) {
return $upload_error_handler($file, __('Specified file does not exist.'));
}
// A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
if ($test_type) {
$wp_filetype = wp_check_filetype_and_ext($file['tmp_name'], $file['name'], $mimes);
extract($wp_filetype);
// Check to see if wp_check_filetype_and_ext() determined the filename was incorrect
if ($proper_filename) {
$file['name'] = $proper_filename;
}
if ((!$type || !$ext) && !current_user_can('unfiltered_upload')) {
return $upload_error_handler($file, __('Sorry, this file type is not permitted for security reasons.'));
}
if (!$ext) {
$ext = ltrim(strrchr($file['name'], '.'), '.');
}
if (!$type) {
$type = $file['type'];
}
}
// A writable uploads dir will pass this test. Again, there's no point overriding this one.
if (!(($uploads = wp_upload_dir($time)) && false === $uploads['error'])) {
return $upload_error_handler($file, $uploads['error']);
}
$filename = wp_unique_filename($uploads['path'], $file['name'], $unique_filename_callback);
// Strip the query strings.
$filename = str_replace('?', '-', $filename);
$filename = str_replace('&', '-', $filename);
// Move the file to the uploads dir
$new_file = $uploads['path'] . "/{$filename}";
if (false === @rename($file['tmp_name'], $new_file)) {
if (0 === strpos($uploads['basedir'], ABSPATH)) {
$error_path = str_replace(ABSPATH, '', $uploads['basedir']) . $uploads['subdir'];
} else {
$error_path = basename($uploads['basedir']) . $uploads['subdir'];
}
return $upload_error_handler($file, sprintf(__('The uploaded file could not be moved to %s.'), $error_path));
}
// Set correct file permissions
$stat = stat(dirname($new_file));
$perms = $stat['mode'] & 0666;
@chmod($new_file, $perms);
// Compute the URL
$url = $uploads['url'] . "/{$filename}";
/** This filter is documented in wp-admin/includes/file.php */
$return = apply_filters('wp_handle_upload', array('file' => $new_file, 'url' => $url, 'type' => $type), 'sideload');
return $return;
}