I ended up using a function that creates the folders if needed. I copied what Patrick had here.
/**
* Download external file.
*
* param@param string $url
* Full url to file to download.
* param@param string $uri
* Drupal uri of where to save file
* public://archive/test.pdf.
* param@param int $save_mode
* File save mode from drupal core,
ex* Ex: FILE_EXISTS_REPLACE.
*
* @return mixed $new_file The file object.
*/
function xcms_import_download_external_file($url, $uri, $save_mode = FILE_EXISTS_RENAME, $manage_file = TRUE) {
$url_info = parse_url($url);
$url_path_info = pathinfo($url_info['path']);
// This helps with filenames with spaces
$url = $url_info['scheme'] . '://' . $url_info['host'] . $url_path_info['dirname'] .'/'. rawurlencode($url_path_info['basename']);
// Need to remove the filename from the uri
$uri_target = file_uri_target($uri);
$uri_scheme = file_uri_scheme($uri);
$uri_path_info = pathinfo($uri_target);
$directory = file_stream_wrapper_uri_normalize($uri_scheme . "://" . $uri_path_info['dirname']);
if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
$drupal_result = drupal_http_request($url);
if (!empty($drupal_result->data)) {
$path = file_stream_wrapper_uri_normalize($uri);
if ($manage_file) {
$new_file = file_save_data($drupal_result->data, $path, $save_mode);
}
else {
return file_unmanaged_save_data($drupal_result->data, $path, $save_mode);
}
}
else {
drupal_set_message("Error downloading file, no data recieved for " . $url);
return FALSE;
}
$new_file->display = 1;
return (array)$new_file;
}
else {
return FALSE;
}
}