Example #1
0
/**
 * 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 nxt_handle_upload_error
 * @uses apply_filters
 * @uses nxt_check_filetype_and_ext
 * @uses current_user_can
 * @uses nxt_upload_dir
 * @uses nxt_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 ).
 * @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 nxt_handle_sideload(&$file, $overrides = false)
{
    // The default error handler.
    if (!function_exists('nxt_handle_upload_error')) {
        function nxt_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 = 'nxt_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 = 'nxt_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) {
        $nxt_filetype = nxt_check_filetype_and_ext($file['tmp_name'], $file['name'], $mimes);
        extract($nxt_filetype);
        // Check to see if nxt_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 = nxt_upload_dir()) && false === $uploads['error'])) {
        return $upload_error_handler($file, $uploads['error']);
    }
    $filename = nxt_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)) {
        return $upload_error_handler($file, sprintf(__('The uploaded file could not be moved to %s.'), $uploads['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}";
    $return = apply_filters('nxt_handle_upload', array('file' => $new_file, 'url' => $url, 'type' => $type), 'sideload');
    return $return;
}
Example #2
0
/**
 * Create a file in the upload folder with given content.
 *
 * If there is an error, then the key 'error' will exist with the error message.
 * If success, then the key 'file' will have the unique file path, the 'url' key
 * will have the link to the new file. and the 'error' key will be set to false.
 *
 * This function will not move an uploaded file to the upload folder. It will
 * create a new file with the content in $bits parameter. If you move the upload
 * file, read the content of the uploaded file, and then you can give the
 * filename and content to this function, which will add it to the upload
 * folder.
 *
 * The permissions will be set on the new file automatically by this function.
 *
 * @since 2.0.0
 *
 * @param string $name
 * @param null $deprecated Never used. Set to null.
 * @param mixed $bits File content
 * @param string $time Optional. Time formatted in 'yyyy/mm'.
 * @return array
 */
function nxt_upload_bits($name, $deprecated, $bits, $time = null)
{
    if (!empty($deprecated)) {
        _deprecated_argument(__FUNCTION__, '2.0');
    }
    if (empty($name)) {
        return array('error' => __('Empty filename'));
    }
    $nxt_filetype = nxt_check_filetype($name);
    if (!$nxt_filetype['ext']) {
        return array('error' => __('Invalid file type'));
    }
    $upload = nxt_upload_dir($time);
    if ($upload['error'] !== false) {
        return $upload;
    }
    $upload_bits_error = apply_filters('nxt_upload_bits', array('name' => $name, 'bits' => $bits, 'time' => $time));
    if (!is_array($upload_bits_error)) {
        $upload['error'] = $upload_bits_error;
        return $upload;
    }
    $filename = nxt_unique_filename($upload['path'], $name);
    $new_file = $upload['path'] . "/{$filename}";
    if (!nxt_mkdir_p(dirname($new_file))) {
        $message = sprintf(__('Unable to create directory %s. Is its parent directory writable by the server?'), dirname($new_file));
        return array('error' => $message);
    }
    $ifp = @fopen($new_file, 'wb');
    if (!$ifp) {
        return array('error' => sprintf(__('Could not write file %s'), $new_file));
    }
    @fwrite($ifp, $bits);
    fclose($ifp);
    clearstatcache();
    // Set correct file permissions
    $stat = @stat(dirname($new_file));
    $perms = $stat['mode'] & 07777;
    $perms = $perms & 0666;
    @chmod($new_file, $perms);
    clearstatcache();
    // Compute the URL
    $url = $upload['url'] . "/{$filename}";
    return array('file' => $new_file, 'url' => $url, 'error' => false);
}