This question has been asked lots of other places and I was quite determined to make it happen. The use case is copy and paste a URL for an image on the web into the Media Module file browser. The Remote Stream Wrapper module does something similar except the images are not stored on the local server. Instead the metadata about the image is stored in the database while Image Cache stores images locally. I really wanted to import images I have access to onto my server.

1 Answer 1


First, a form is built. Then the elements in the form array are expanded during drupal_process_form(). The default value of each element is set during this stage. The file.module has a callback hook added during the set element value stage which other form elements do not have, '#file_value_callbacks`.

I simply added a textfield element to the upload form for the media browser and registered a callback. If there is an URL in the textfield, drupal_http_request() is used to pull the data / image and save it passing the file ID as the value of the upload widget element to finish processing the image.

It seems to work as expected. There are some gaping security holes which need to be cleaned up. Nonetheless, this implementation will greatly increase the efficiency of workflow for my next project.

enter image description here

Here is my solution:

 * Implements hook_form_FORM_ID_alter()

function helper_form_file_entity_add_upload_alter (&$form, &$form_state, $form_id) {
  // Keep the textfield clear if there is a file ID
  // We only have to upload the image once then who cares?
  if (!empty($form['upload'])){
    $form['upload']['#file_value_callbacks'][] = 'helper_file_value_callback';
    $form['url'] = array(
      '#type' => 'textfield',
      '#title' => 'Enter image URL',

function helper_file_value_callback (&$element, &$input, &$form_state) {
  global $user;

  // Make sure that there is a $url
  if (empty($input['fid']) && valid_url($url = $form_state['input']['url'])) {

    $upload_name = implode('_', $element['#parents']);
    $destination = $element['#upload_location'];
    $parsed_url = parse_url($url);
    $path = str_replace('///', '//', "$destination/") . drupal_basename($parsed_url['path']);

    // Make sure that there is a directory.
    if (isset($destination) && !file_prepare_directory($destination, FILE_CREATE_DIRECTORY)) {
      watchdog('file', 'The upload directory %directory for the file field !name could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.',
          array('%directory' => $destination, '!name' => $element['#field_name']));
      form_set_error($upload_name, t('The file could not be uploaded.'));
      return FALSE;

    // Download file and make sure that return code is 200 or else abort!
    $result = drupal_http_request($url);
    if ($result->code != 200) {
      drupal_set_message(t('HTTP error @errorcode occurred when trying to fetch @remote.',
          array('@errorcode' => $result->code, '@remote' => $url)), 'error');
      return FALSE;

    // Construct the $file object
    // file_save() adds the timestamp and filesize on save
    // file_unmanaged_save_data posts message on error
    if ($uri = file_unmanaged_save_data($result->data, $path, FILE_EXISTS_RENAME)){
      // Create a file object
      $file = new stdClass();
      $file->fid = NULL;
      $file->uri = $uri;
      $file->filename = trim(drupal_basename($parsed_url['path']));
      $file->filemime = file_get_mimetype($file->uri);
      $file->uid = $user->uid;
      $file->status = 0;

      if (file_save($file)){
        $input['fid'] = $file->fid;


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.