I'm currently working on a Flash application that needs to save files to Drupal. I already saved the file to the Drupal site with the File service, but I can't get to attach the file to the node with the node.save service (Core Upload module, not CCK file field).

The object that I will transfer with node.save looks like this in AS3 :

var node:Object;
// all the other required node fields : nid, type, language, uid, name,
// status, title, changed, created, format, taxonomy, picture
node.files = new Array();

var aFile:Array = new Array;
aFile['list']=1;
aFile['weight']=0;
aFile['remove']=0;
aFile['description']="test.txt";

// id = id of the previously saved file
node.files[id] = aFile;

I guess there's some fields missing or something like that, or maybe it just doesn't work...

I'm currently debugging the process in the drupal_execute call that the services module use... but I found out it's not easy to find the answer, a bit of help would be more than welcome!

Comments

marcingy’s picture

Priority: Critical » Normal

Support requests can't be critical

grdrupal’s picture

Category: support » task

I found it actually concerns only modules who modify data directly in the object loaded with node_load() before saving it with node_save(). Other modules (like CCK) act on the [#post] data of the form.

The service module needs a patch to be able to handle the upload module (or any module like this one). I'll make one and post it here as soon as I can.

The patch will modify the services module, in the node_service.inc file - node_service_save function. I will scan the $edit data to find a flag. If the flag exist, I will replace the data of the flagged structure directly in the $node structure (to reproduce the upload module behavior).

grdrupal’s picture

StatusFileSize
new701 bytes

Since it was requested by someone, I uploaded the patch for the Upload Module. This patch will not work with other modules using Services. Although you can probably make a tweak for your purposes (it is quite a simple patch...)

You then feed the [files] structure with extended data. The next snippet of code was taken from the project I am working on, that will be release as a module for Drupal really soon, called "abCparti" it replicates the Drupal behavior but on a Flash app. :

if(this.files != null){
unObjet.files = new Array();
for(i = 0; i < this.files.length; i++){
if(this.files[i] != null && this.files[i].nid == 0){
var unFichier:Array = new Array();
unFichier['filename'] = this.files[i].filename;
unFichier['filepath'] = this.files[i].filepath;
unFichier['filemime'] = this.files[i].filemime;
unFichier['source'] = "upload"; // On utilise le module upload
unFichier['destination'] = this.files[i].filepath;
unFichier['filesize'] = this.files[i].filesize;
unFichier['uid'] = this.uid;
unFichier['timestamp'] = this.files[i].timestamp;
unFichier['fid'] = this.files[i].fid;
unFichier['list'] = 1; // 1 car on veux qu'il apparaisse avec un node.get
unFichier['description'] = this.files[i].filename;
unFichier['weight'] = 0; // Poid entre les attachements, ordre d'apparence
unFichier['new'] = 1;
unObjet.files[this.files[i].fid] = unFichier;
}else if(this.files[i] != null && this.files[i].nid != 0){
var unFichier:Array = new Array();
unFichier['fid'] = this.files[i].fid;
unFichier['uid'] = this.uid;
unFichier['filename'] = this.files[i].filename;
unFichier['filepath'] = this.files[i].filepath;
unFichier['filemime'] = this.files[i].filemime;
unFichier['filesize'] = this.files[i].filesize;
unFichier['status'] = this.status;
unFichier['timestamp'] = this.files[i].timestamp;
unFichier['vid'] = this.vid;
unFichier['list'] = 1; // 1 car on veux qu'il apparaisse avec un node.get
unFichier['description'] = this.files[i].filename;
//unFichier['nid'] = this.nid;
unFichier['weight'] = 0; // Poid entre les attachements, ordre d'apparence
unObjet.files[this.files[i].fid] = unFichier;
}
}
}

pwaterz’s picture

this is how I save a file with node save, I have never used the services module, but this code should work regardless
<?
//Get-Create the path where you want to store that file
$filename = file_save_data(file_get_contents($path, FILE_EXISTS_RENAME);

$mime = 'image/jpeg'; // Standard mine

$file_drupal_path = $filename;

$file = new stdClass();
$file->filename = basename($file_drupal_path);
$file->filepath = $file_drupal_path;
$file->filemime = $mime;
$file->filesize = filesize($file_drupal_path);

$file->uid = $uid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$file->fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $file->filepath));

//Store title text, alt text, descrition
$data= array(
'fid' => $file->fid,
'title' => $text,
'alt' => $alt,
'description' => $description

);

$node->field_story_photo[] =
array(
'fid' => $file->fid,
'title' => basename($file->filename),
'data' => $data,
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'description' => basename($file->filename),
'list' => 1,
);

}
?>

voxpelli’s picture

Category: task » feature
Status: Active » Needs review

Changing to correct status - there's a patch needing testing and supporting Upload.module seems to be a feature request (or bug?)

kylebrowning’s picture

Version: 6.x-2.x-dev » 6.x-3.x-dev
Assigned: Unassigned » kylebrowning

Im not certain on this one but as its an API change we cant really doing anything about it in 2.x.

Changing the 3.x and Ill doo some looking into this issue on Monday

kylebrowning’s picture

Im not certain on this one but as its an API change we cant really doing anything about it in 2.x.

Changing the 3.x and Ill doo some looking into this issue on Monday

marcingy’s picture

Version: 6.x-3.x-dev » 7.x-3.x-dev
Status: Needs review » Postponed

Moving to current version and setting as postponed for consideration in 7.4

longwave’s picture

A possible workaround for this in 6.x is provided in #459192-14: Deploy module doesn't work with upload module which adds a new node.saveUploads service that can attach file uploads to an existing node (after sending the files themselves with file.save). This was developed for use with Deploy but could work equally well as a standalone service.

ygerasimov’s picture

I marked issue #1094584: node resource not saving some provided fields as duplicate of this one.

marcingy’s picture

Version: 7.x-3.x-dev » 6.x-3.x-dev

This should be 6-3 as upload does not exist in d7.

kylebrowning’s picture

Issue tags: +closeintwoweeks

Does this patch actually do anything? Can someone write a test to verify this, otherwise I'm going to close this issue in 2 weeks.

kylebrowning’s picture

Status: Postponed » Closed (won't fix)