I have found some very detailed tutorials about Services 3. I appreciate them very much here is a small list.

http://drupal.org/node/1354202

How to add multiple images to a node using node.save service?

http://drupal.org/node/1699354

But i cant find a way to upload images from the mobile app to the server. Is that possible ? Where can i get some example ?

Is there in Services core to accomplish this ? Every solution looks like i need o code something to get it work.

I had a requirement once like this where, using web service I have to create a node that will also save image. The following code uploads and saves image using web service.

// File validator.
$validators = array(
  /**
   * Defaults already allow png, jpg etc. If more needed to be supported,
   * edit here.
   */
  'file_validate_extensions' => array(),
  'file_validate_size' => array(),
);


foreach ($_FILES['files']['name'] as $field_name => $file_name) {
  // Save the file and get file object.
    $file = file_save_upload($field_name, $validators, file_default_scheme() . "://");

  // Check whether image is uploaded.
  if ($file->fid) {
    $node = new stdClass();
    $node->type = 'CONTENT_TYPE';
    $node->title = 'TITLE';
    $node->language = LANGUAGE_NONE;
    $node->uid = 'USER_UID';
    node_object_prepare($node);

    $node->field_custom[$node->language][0]['value'] = 'SOME_VALUE';
    // File upload here..
    $node->field_image[$node->language][0] = (array)$file;

    $node = node_submit($node);
    node_save($node);
  }
  else {                                                                      
    return services_error(t('File upload failed'), 406, t('File upload failed'));
  }
}

NOTE: Following code was tested using services 3. Also it was an iOS app that was consuming this web service, and it worked there.

NOTE: File uploaded with POST request.

I tested the above code using a Google Chrome plugin called REST Console. To install the plugin search for "rest console" in Chrome Web Store and install the first plugin you get in result (with up green and down blue arrow)

Hope this helps!

  • 1
    Thanks, and you mean there is nothing in Services core to achieve this ? – niksmac Jan 28 '13 at 5:28
  • Haven't seen.. you may see the api.php files of services module – subhojit777 Jan 28 '13 at 5:33
  • drupal.org/files/endpoint_resources.png here is something like "files" in resource type. – niksmac Jan 28 '13 at 5:34
  • sorry.. I took the help of the coding in resources/file_resource.inc to upload image using web service.. I forgot to mention that its been a long time since I created the web service – subhojit777 Jan 28 '13 at 5:40
  • One thing I can suggest is you can call the web service programmatically from your web service callback and obtain the $file array.. but will not that be an overload? calling another web service inside a web serice – subhojit777 Jan 28 '13 at 5:42

First of all, make sure to in your endpoint is enable the File --> Create resource.

And in the "client side" i did something like this:

/**
 * Upload a file using services 3.X
 * 
 * @param the path of the local file
 * @return bool|int the fid of the file.
 *
 * 
 * With the fid you can attach this file in the node object before to be send.
 * ej.
 * $node->title = 'My remote node';
 * $fid = node_upload_image('/The_path/to_the/local_file.jpg');
 * $node->file_field[0] = array( 
 *    'fid' => $fid,
 *    'list' => 1,
 *    'data' => array()
 * );
 * // Other fields related with the node.
 * ...
 * 
 * // Sending the node.
 * $data = http_build_query($node, '', '&');
 * $response = drupal_http_request('myremotesite.com'. '/node', array(
 *   'Accept' => 'application/json', 
 *   'Cookie' => 'auth_cookie_info'
 * ), 'POST', $data);
 *
 * Done. 
 */
function node_upload_image($image_path) {
  $file = array(
    'filesize' => filesize($image_path),
    'filename' => basename($image_path),
    'file' => base64_encode(file_get_contents($image_path)),
    'uid'  => 1  // This should change it by the user who use the service.
  );

  $data = http_build_query($file, '', '&');
  $response = drupal_http_request('myremotesite.com/myservice-endpoint' . "/file", array('Accept' => 'application/json', 'Cookie' => 'auth_cookie_info'), "POST", $data);


  if ($response->code == 200) {
    return json_decode($response->data)->fid;
  }


  $this->error =  $response->status_message; 
  return false;
}

I did this from another Drupal, and is for Drupal 6, port the code to D7 should be easy, and i think you get the general idea about how do it.

The regular services 3 has a 'file' endpoint. You can just enable file creation and post something like this; the file itself is base-64 encoded:

{
    "filename": "user993.jpg",
    "target_uri": "pictures/user993.jpg",
    "filemime": "image/jpeg",
    "file": "/9j/4AAQSkZJRgABAQELIiyoy0pUQRoFjAVVGAAMACiigBaKKKAP/2Q==...",
    "filesize": "5356"
}

For uploading an image you would need only a filename and a file - which would be base64 encoded.

You could check my repo here, where you could find a simple class for working with Drupal 7 Rest Services and an examples.php file where there are some examples on how to use the class. There you could find also an example on how to upload an image, which I added recently.

https://github.com/flesheater/drupal_rest_server_class

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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