1

I have a question about handling file uploads. I am trying to implement a form that will allow the user to upload a file. I do not need to store the file, though. I just need to take the uploaded file, where its location happens to be, and pass it to an outside API, which uploads it to its server (its Jira). Is there a way to do this? The file has to be publicly available to be consumed by Jira's API (in other words, Jira won't be able to provide a username/password to validate against drupal). This is what I have, so far:

in my _add_form hook:

$form['file'] = array(
                '#type' => 'file',
                '#title' => t('Document'),
                '#description' => t('Upload a file, allowed file types: pdf, images, documents'),
            );

in my _add_form_validate hook:

$validators =  array(
                'file_validate_extensions' => array( 'jpg jpeg gif png bmp txt doc docx xls xlsx pdf ppt pptx ' )
            );

            $file = file_save_upload('file', $validators);

            if (isset($file->filename)) {
                $form_state['storage']['file'] = $file;
            }

in my _add_form_submit hook:

i can see the object form_state->storage->file but I don't see the full path to where the file is residing. All i see, thats close, is:

 file_name = "myfile.jpeg"
 file_path = "/tmp/myfile.jpeg"
 destination = "/tmp/myfile.jpeg"

but, as I mentioned, I need to full path to pass to another, external, API so that the file can be consumed. I do not need to store or save the file afterwards.

admin/settings/file-system settings:

File System Path:  sites/mySite.net/files 
Temporary Dir: /tmp
Download Method: Private
3
  • I think you would have to actually save the file and then delete it on the success to the API call to Jira since the /tmp area is probably not going to be publicly available. Well at least I would think it wouldn't be. Either way I think setting it up as a normal file upload into the public directory (and setting a proper directory for the image) running through the API calls on the submit success and then deleting the file on the API success would work out. If you would like an overview in code I can post an answer or maybe I am misunderstanding what you are trying to accomplish? Commented Jan 18, 2015 at 21:27
  • Thanks for your response. That might be a way to do it. Can you explain how to upload to a public directory? I'm new to working in drupal.
    – jason
    Commented Jan 18, 2015 at 21:34
  • Yes I will add an answer shortly stepping through a high-level solution for this. Commented Jan 18, 2015 at 21:36

1 Answer 1

0

Ok here is high level overview of the file uploading. I took most of this from the Drupal 6 Developer modules but made some changes that should get you started on how to achieve your final goal here. I left all the original comments and denoted any new comments with // ** Comment Text so you should be able to skim through this and get the general idea.

<?php

//////////////// Tutorial Example 11 //////////////////////

// ** Will denote any changes or anything that I am pointing out below.

/**
 * Example 11: A form with a file upload field.
 *
 * This example allows the user to upload a file to Drupal which is stored
 * physically and with a reference in the database. In this example, only
 * png, gif, jpg, and jpeg files are allowed.
 *
 * @see form_example_tutorial_11_validate()
 * @see form_example_tutorial_11_submit()
 * @ingroup form_example
 *
 */
function form_example_tutorial_11($form_state) {
  // This is required to upload files.
  // enctype="multipart/form-data" required by browsers to handle files.
  $form = array(
    '#attributes' => array('enctype' => "multipart/form-data"),
  );

  $form['file'] = array(
    '#type' => 'file',
    '#title' => t('Image'),
    '#description' => t('Upload a file, allowed extensions: jpg, jpeg, png, gif'),
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

/**
 * Validate handler for form_example_tutorial_11().
 * Verify the valid extensions, and verify content is an image also.
 */
function form_example_tutorial_11_validate($form, &$form_state) {

  // ** I just left this as image but you can change the ext array if needed.
  $file = file_save_upload('file', array(
    'file_validate_extensions' => array('png gif jpg jpeg'),
    'file_validate_is_image' => array(),
  ));

  // If the file passed validation: ** File is in /tmp folder now
  if (isset($file->filename)) {
    // Move the file, into the Drupal file system
    // ** Notice the 'jira-upload/', this would be where your file is placed,
    // ** It will be in your /files folder, but you need to make this directory,
    // ** You can do it in code but for simplicity I just left it as is for now.
    if (file_move($file, 'jira-upload/' . $file->filename)) {
      // Update the new file location in the database.
      // ** Change from /tmp/filename.ext to, 
      // ** /sites/default/files/jira-upload/filename.ext in database. 
      // ** This will be important for Drupal later.
      drupal_write_record('files', $file, 'fid');
      // Save the file for use in the submit handler.
      $form_state['storage']['file'] = $file;
    }
    else {
      form_set_error('file', t('Failed to write the uploaded file the site\'s file folder.'));
    }
  }
  else {
    form_set_error('file', t('Invalid file, only images with the extension png, gif, jpg, jpeg are allowed'));
  }
}

/**
 * Submit handler for form_example_tutorial_11().
 */
function form_example_tutorial_11_submit($form, &$form_state) {
  $file = $form_state['storage']['file'];
  // We are done with the file, remove it from storage.
  unset($form_state['storage']['file']);
  // Make the storage of the file permanent/temp
  // ** This will actually make it where you don't have to delete,
  // ** You can let Drupal clean it up later on cron runs after a certain,
  // ** Amount of time. This will be done automatically.
  file_set_status($file, FILE_STATUS_TEMPORARY);
  // ** This is what you wanted, was the public file that can be navigated to,
  // ** This should work pretty well, but there are other ways. 
  // ** Since validation is already passed I would run the API call here as,
  // ** Well. You could pass the $file object to another function or your pref.
  $fileurl = file_create_url($file->filepath);
  // Set a response to the user.
  // ** I added the $fileurl so you could see it on the frontend,
  // ** Without having to know if devel is there. 
  drupal_set_message(t('The form has been submitted and the image has been saved, fileurl: @fileurl. filename: @filename.', array('@filename' => $file->filename, '@fileurl' => $fileurl)));
}

?>

Note: For this to work with the way you are wanting to curl the image and send it you will need to set your file system to public. I'm placing a screenshot of that page with configuration. File System Configuration Page

Additional Hook:

If your file system is private you will have to run an additional hook in order to allow access to the file through Drupal without having it attached to a node or anything. I tested this with making my file-system private and clearing out all previous images, then along with the code that I edited from the Drupal 6 Examples module I placed the code below in the main module file (just incase anyone needs to know how to test this out without knowing all the code). This should give you the functionality that you need without having to change the file-system.

<?php

/**
 * Implements hook_file_download().
 */
function form_example_file_download($file) {
  //dpm($file);
  // Used jira- as indicator but it needs to match your folder where you are storing your files.
  if (strpos($file, 'jira-') === 0) {
    $info = image_get_info(file_create_path($file));
    return array('Content-type: ' . $info['mime_type']);
  }
}

?> 
13
  • Thank you for your very in depth response. The problem, though, is that when my Curl object tries to open the file, I get this error :couldn't open file "localhost/mySite/web/system/files/jira_attachments/…"
    – jason
    Commented Jan 19, 2015 at 17:37
  • Is this due to Drupal permissions or something with Curl?
    – jason
    Commented Jan 19, 2015 at 17:37
  • oh, and if it helps for context, the reason I need to get this to work is for another issue I'm having, here : stackoverflow.com/questions/28030564/…
    – jason
    Commented Jan 19, 2015 at 17:43
  • So when you submit your form you are actually getting the mySite/web/system/files...? Is that where you setup your public files for Drupal to be served from? You can check that config by going to this page /admin/settings/file-system Also can you get to the image in the browser? Commented Jan 19, 2015 at 17:47
  • Yes, I can see the file in my folder explorer being uploaded. I can then navigate in my browser to that file, using the url that's created by file_create_url. As for permissions in admin/settings/file-system, all I see are: the option is Download Method: private. Also, if I use the absolute path (*id: c:/windows/wamp/...") it works fine
    – jason
    Commented Jan 19, 2015 at 17:55

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.