Closed (fixed)
Project:
Services
Version:
7.x-3.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
16 Mar 2012 at 08:26 UTC
Updated:
17 Jul 2015 at 12:14 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
32i commentedHi there, don't see patch file attached - however I'm interested in it and would like to see it. Would you be so kind to attach the patch?
Comment #2
kylebrowning commentedComment #3
kylebrowning commentedComment #4
wedge commentedMini review, I haven't had time to actually test it yet.
1. Spelling in the field_name description.
2. Is the file_usage_add necessary? (See #1490552: File resource should not count itself to file usage)
Thanks for posting this. It could be useful.
Comment #5
32i commentedThanks a million, Kyle.
Comment #6
32i commentedHi there Kyle, when you define args to the action, you mention type = 'array'
and then, in _node_resource_attach_file you're receiving field name as array - why don't change type to 'string' so $node->{$field_name[0]}['und'][0] = (array)$file; will be $node->{$field_name}['und'][0] = (array)$file; ?
It's confused me a bit, however I might miss your point here - that's why I'm asking.
Kind Regards, Slava.
Comment #7
kylebrowning commentedWhat if you want to supply the file path, how do you that with your code?
What if there are multiple files?
Its an array b/c you need to pass in all the elements of a file object so that it can be created successfully.
Comment #8
ygerasimov commentedKyle, in terms of #1060362: Remove resources in Services 4.x I would not like to add this action to core of services. Lets create separate module for it and gather all useful resources there.
Regarding patch. Can we use standard file_save_upload() to save the files and gather errors with form_get_errors()? Also I believe file validators should be taken from field settings.
Tests are must for this case.
Comment #9
kylebrowning commentedid prefer not to wait for that patch to land unless you are going to do it very soon.
Comment #10
henrikakselsen commentedEDIT: nevermind, I redownloaded services, and then it worked. Must have messed up something myself.
Is the #2 patch working? I'm getting a lot of errors.
Comment #11
kylebrowning commentedpatch two probably needs to be remade since schanges have happened since i wrote it. One sec ill get a new one up.
Comment #12
kylebrowning commentedPatch in #2 aplies cleanly for me, not sure what errors you are getting?
Comment #13
kylebrowning commented#2: 0001-Attach-files-to-a-node.patch queued for re-testing.
Comment #14
drewish commentedYeah I think we should probably try to let file_save_upload() do more of the work here. Did you really mean to change servers/rest_server/includes/RESTServer.inc? It seems like that would break multipart form handling.
Comment #15
drewish commentedAlso the error messages spell unknown as 'unkown'. You might want to check $file->fid after the first file_save() because if it's not set by then all the subsequent stuff will explode... though that makes me wonder why you're calling file_move()? Why not just put it into the final destination?
Actually I think the real solution is, as ygerasimov also suggested, just to use file_save_upload().
Comment #16
kylebrowning commentedYes I really meant to change RESTServer, it doesn't break multipart the tests still pass.
However it'd be a really big help if someone else could get this patch up to snuff, I think Ive brought it pretty far along but I need to focus on a few other backports.
Comment #17
7wonders commentedIm trying this out from a java (android) app by posting to endpoint/node/999/attach_file and passing in the params using params.put with a library called loopj:
Strangely its getting added to the file_managed table but with a status 0 and wrong filepath. Its not attaching to the node at all. Whats the expected parameters for this to work?
Comment #18
jhr commented@7 wonders,
I got it to work posting a form input type=file to: site.com/endpoint/node/22/attach_file.json?field_name=field_log_file
This patch:
- rerolls against the latest dev
- fixes the above misspellings
- fixes the services_error( t('text,500 ));
- clears some whitespace at end of line
node_save, adds an entry to {file_usage}
File_usage_add adds a second entry to {file_usage}
file_usage_add($file, 'services', 'files', $file->fid);I don't think services needs to add an entry with file_usage_add, because it blocks Drupal from deleting that file. ex. Upload a file with this patch, then edit node and remove/replace that file and save and the file will still exist.
File usage functions:
http://drupal.org/node/1017800
Also, attach_file doesn't apply the file field's directory as if you uploaded within Drupal.
Comment #19
awm commentedcan someone please add some documentation as how to use this patch. I have enabled the attach file method on the node resource. Then I am using xhr poster to test the end point and I keep getting 404 Not found: Could not find the controller.
It would be helpful if someone can give an example of how to use this patch.
Thank you.
Comment #20
kylebrowning commentedComment #21
jhr commentedTo get this to work I'm posting a multipart/form-data to endpoint/node/123/attach_file?file_field=field_machine_name. <input type=file name=files[anything]>
This is a major rewrite/simplification. There's no need to duplicate the fine work already provided by file_save_upload. Especially since the only thing to change was the name attribute of the input element.
Has $nid & $field_name been sanitized/made safe by the time they reach _node_resource_attach_file()?
@todo
-Right now, this overwrites a file already on the node... if N files are uploaded it overwrites the first N files. As a targeted action 'attach_file'... should it error if a file is already attached, and only 1 file can be attached? Give options, and default behavior?
-The querystring ?field_name=etc needs to be changed to a posted variable.
-This doesn't trigger the image field's style(thumbnail, small, medium,etc) generator. Thoughts on how this is implemented?
-A nice feature might be to allowing changing of the filename when the file.
Comment #22
jhr commentedOops
Comment #23
ygerasimov commentedWe define 'field_name' argument as array but use only first element (a machine name). Maybe we should change argument to string?
Should be added check whether field really exists and attached to this node type.
Test should be added.
Comment #24
jhr commented:)
I really wanted a way to upload a picture, while the user was entering information. I saw this in one of the videos from Drupalcon. So the flow would be to upload to presave/presavedata, store the fid, then attach to the node on node/create. Doing it this way, let's it work similar to how file upload works on a new node.
Action:
node/file_presave
**I can post file to and get back the fid
node/file_presavedata
** there's code but it needs work, compare/borrow from file_create
Targeted Action
node/123/attach_file
* fixed the array param to data
* I'm unsure whether to use array(data=>field_name) or just 'data'
Should it be broken up into separate issues?
Comment #25
jhr commented3am posts w/o attachments, mmmm.
Comment #26
marcingy commentedThis is not a functional review just a code strandards review
Please remove commented out lines
Why is user declared as a global it is not used
Missing space after // and missing period at the end of the line
Missing space after $counter and before 0
let should be Let and missing space after //
Missing space after // and missing period at the end of the line
Missing space after // and missing period at the end of the line
Duplicate function
Why is user declared as a global it is not used
Missing space after // and missing period at the end of the line
Extra spaces after ( and before )
Extra space after =>
Missing space after // and missing period at the end of the line
Missing space after $counter and before 0
let should be Let and missing space after //
Most of the code in _node_resource_file_presave and _node_resource_attach_file is the same lets have a helper function for those elements.
Missing space after // and missing period at the end of the line
Remove commented out code
No need for this services has a generalise callback that does this already, and if the intent is additional permissions then the callback needs to do that and not return true.
Comment #27
jhr commentedYea, it's a little rough still. ;)
Comment #28
awm commentedI am posting some thing like this
I keep getting the 406 not acceptable.
In my logs Services report the following
I this a bug or something is wrong with what I am posting?
Comment #29
metow commentedI'm guessing some of you are able to upload at least a file using the services, can someone please give a code sample of his to do this?
I want to upload an image file in android to my drupal website?. I've lost 2 weeks so far.
I have most probably very easy questions for you all:
Comment #30
7wonders commented@metow - Ive been using the loopj (just google loopj android) library which works nicely with something like this:
The Base64 is another custom jar I picked up from somewhere so I could use earlier versions of android, just google base64 android earlier versions or similar and you will find it.
This will upload the file to the server into the directory you specify (public/private). If you want it to be attached to a node you will have to use the fid that you get back in the json in onSuccess to send a subsequent request to create a node (or figure out the targeted action in this issue). FILE_URI is "http://yourdomain.com/your_endpoint/file" which can all be set up in the services settings.
Comment #31
Chewedon commentedWhat is the status of the patch?
Which version should I be using?
I am currently using the 0001-Attach-files-to-a-node.patch , my app says it successfully uploaded the photo but when I go to check my Drupal node, the photo doesn't seem to be uploaded.
I am currently setting the name, fileName, fileData, mimetype, field_name and nid when I upload my photo dictionary, am I doing something wrong ?
Anyone able to shed some light would be great.
EDIT
------------
After finally take a good read through some of these comments, I manage to get it working with patch 0002.
I also had to change from "fileName" to "filename" although my final image file name on Drupal came out as "null" = /
EDIT 2
------------
OK, have fixed the file name. Forgot that Kyle's Drupal IOS SDK uses "fileName" rather than "filename" and because patch 0002 uses "filename", I had to modify Kyle's Drupa IOS SDK class to use "filename" rather than "fileName".
I'm a happy fella again :)
Comment #32
jhr commentedI took out the part that changed $_POST to $_FILES from the first patch. Having the $_FILES returned meant that all multipart posts would only return the $_FILES variable, and any other post data wouldn't be passed to the resource functions. (ie it allows you to post data, rather than attach it to the url as a param).
And obviously still needs tests.
Comment #33
ygerasimov commented@jhr, thank you for your work on the patch.
Regarding #24, yes lets have this issue only for targeted_action. Can you split the patch? I believe blocker here is only absence of the test. Will you take care about it or shall I work on it?
Comment #34
ygerasimov commentedHere is patch with the test. I have kept only attach_file targeted action.
Also I have changed a logic a bit. We now do validation on cardinality and number of incoming files before starting uploading files.
Comment #35
ygerasimov commentedAs agreed with kylebrowning on IRC comitting #34. Needs to have backport.
Comment #36
7wonders commentedIs this supposed to be working?? I just get:
POST http://test.dev/test/node/1/attach_file?field_name=field_log_file
Content-Type: multipart/form-data
Filename: /home/me/logs/test.txt
-- response --
401 Unauthorized: Missing required argument field_name
Comment #37
awm commentedI am getting 500
Comment #38
awm commentedThe following change worked for me when attempting to address the issue in #37.
I changed the following code in _node_resource_attach_file (line 626) of node_resource
From
To
I know this is not a proper solution but I hope this helps in identifying the problem and providing a better solution.
Also, I think the original patch works for image field without any changes but not for any file.
(I am not sure if this should be switched back to 7.x)
Comment #39
awm commentedNeeds review as per #37.
Comment #40
wedge commented@awm086 I get the same thing if I try to attach the file to a file field. If I attach the file to an image field, it works as expected. Your solution fixed this for me. I have rolled a patch for this.
Comment #42
wedge commented#40: services-1484992-40.patch queued for re-testing.
Comment #44
wedge commentedI also have a question about upload destinations (file paths). This was possible to set with file_resource_create, can this be done now?I have a filefield_path setting that should take care of this but it isn't respected by the file_field_widget_uri method. Perhaps some kind hook or alter call could be added after this:$destination = file_field_widget_uri($field, $instance);so that I can modify the destination from my module? Any thoughts about this?It turns out that filefield_path actually took care of this.
Comment #45
awm commentedThere also seems to be race conditions when trying to post multiple files from mobile device, ios, in my case.
Everything works fine when I hit the endpoint once per file but when I do multiple multiple files the node is not updated properly.
I tested with 3 files and, although, all the files were uploaded to the proper directory, only one file was attached to the node, namely the 3rd file.
In the case of trying 11 files, Only 8 files were attached.
I am not sure if this is a race condition related to node save (http://drupal.org/node/1679344) but I may be the case.
Comment #46
kylebrowning commented#40: services-1484992-40.patch queued for re-testing.
Comment #48
awm commentedI re-rolled the patch to check for field settings. The current one will fail in case of field_image.
Comment #49
dolphinonmobile commentedCan there be added support for submitting optional extra file field information, (alt, description etc) on this endpoint? Rather than a required extra /node update to add them.
Comment #50
awm commented#49 : It is possible but I believe, if I'm not mistaken, that this will have to be a feature request.
Comment #51
dolphinonmobile commentedI'v put up a feature request #1823908: Attach file to node targeted_action extra field information with an example.
Comment #52
wildermuthn commentedI can't get this to work, unfortunately.
When I upload a file through the endpoint, I get the following errors with no change in content on my server:
Here's the request and response:
Comment #53
awm commented@wildermuthn , as you may already know, 200 means the call succeeded. Can you verify the no file is actually uploaded to the target folder?
Comment #54
kylebrowning commented#48 has been commited.
Comment #55
tmctighe commentedI know it's a 2 year old post, but I had the same problem as @wildermuthn
It came down to the curl I was using to send the data wasn't structured right (and I couldn't really find good documentation on what I was doing wrong.
You want it to look like:
curl POST -H "Content-Type: multipart/form-data" --form "field_name=field_image" --form "files[files]=@testimage.jpg" --form "attach=1" "example.com/api/node/[NID]/attach_file"
The key here being files[files]=image.
Comment #56
lisa.rae commentedCorrection to above comment (#55) -- curl format is:
Comment #57
abbasl7 commentedI'm trying to get this work using json formatted data.
Can someone help with sample format? Following looks correct?
Comment #58
ajoboe commentedDoes anyone know of an example of using attach_file in Java (not Android)?