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!
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | patchServicesNodeSaveForUpload2010-10-14.txt | 701 bytes | grdrupal |
Comments
Comment #1
marcingy commentedSupport requests can't be critical
Comment #2
grdrupal commentedI 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).
Comment #3
grdrupal commentedSince 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;
}
}
}
Comment #4
pwaterz commentedthis 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,
);
}
?>
Comment #5
voxpelli commentedChanging to correct status - there's a patch needing testing and supporting Upload.module seems to be a feature request (or bug?)
Comment #6
kylebrowning commentedIm 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
Comment #7
kylebrowning commentedIm 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
Comment #8
marcingy commentedMoving to current version and setting as postponed for consideration in 7.4
Comment #9
longwaveA 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.
Comment #10
ygerasimov commentedI marked issue #1094584: node resource not saving some provided fields as duplicate of this one.
Comment #11
marcingy commentedThis should be 6-3 as upload does not exist in d7.
Comment #12
kylebrowning commentedDoes this patch actually do anything? Can someone write a test to verify this, otherwise I'm going to close this issue in 2 weeks.
Comment #13
kylebrowning commented