Closed (works as designed)
Project:
Services
Version:
6.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
26 Jun 2008 at 00:50 UTC
Updated:
2 Nov 2011 at 10:08 UTC
I'm attempting to create a service in Python over XML-RPC for creating nodes that have taxonomy terms and CCK node reference fields. When the taxonomy is set to be "required," I get back a validation error like, " field is required." The node reference field throws a validation error, as well: ": This post can't be referenced."
Any thoughts? Sample code below:
import pprint, sys, time, xmlrpclib;
from config import config;
pp = pprint.PrettyPrinter(indent=2);
def createNode(node):
return server.node.save(config['key'], sessid, node);
# Make initial connection to service, then login as admin
server = xmlrpclib.Server(config['url']);
connection = server.system.connect(config['key']);
session = server.user.login(config['key'], connection['sessid'], config['username'], config['password']);
sessid = session['sessid'];
user = session['user'];
node = {
'type': config['node_type'],
'title': 'python test',
'body': 'lorem ipsum',
'uid': user['uid'],
'name': user['name'],
'changed': int(time.time()),
'taxonomy': {
'1': {'1': 1}
},
'field_author': [
{'value': 'John Doe'},
],
'field_provider': [
{'nid': 56},
],
}
createNode(node);
Comments
Comment #1
jrbeemanI've figured out the taxonomy issue (seems to have been caused by another incompatible module), but the CCK node reference issue is still giving me problems.
Comment #2
snelson commentedAny luck on this? The node array is passed straight to drupal_execute, so you're probably just not putting the noderef field in a format drupal_execute likes. You should look at what the $form_values array looks like when the node form is submitted within Drupal, and then match it in your node dict in Python, thought what you posted does look pretty good. You can do this with a hook_form_alter in a custom module.
Scott
Comment #3
jrbeemanAh - yep, I was just looking at the wrong point in time of the node submission execution. The correct format is:
It's just an objects with a property
nids(note the plural). Thanks!Comment #4
Anonymous (not verified) commentedAutomatically closed -- issue fixed for two weeks with no activity.
Comment #5
liquidcms commentedsetting this back to active and up-revving to the release i am using.
I get this same errors when trying to save a node that uses a noderef field. I will go through and check format that you are mentioning here; but even then this should be a bug since i simply do a node_load at master and then send a node.save to slave site with the same node object. Would seem wrong that the format i load isn't valid to be saved.
although maybe this is a core bug and not a services bug - although i coulda swore i do this locally (just load, save with no services involved) all the time; but perhaps not - that will be next test.
Comment #6
liquidcms commentedyup, i think a services bug
this works:
and this doesn't
which is basically saying node_save($node) works but node.save($node) doesn't for noderef fields.
Comment #7
gddNote that on the receiving end, the node service uses drupal_execute() to process node saves, not the node_save() function. drupal_execute() mimics a submission of the node/add or node/edit form and there are some cases wherein this data is passed differently than the data you get via a node_load(). Nodereference fields are one instance of this (and these can also depend on which widget is in use.) Taxonomy is another place where this is a problem. There are very good reasons why this is the case and node_save() is not used, although they are kind of obscure and outside the realm of a comment in an issue like this.
Comment #8
gddAlso if you are pushing nodes around between sites you may want to check out the deploy module
http://drupal.org/project/deploy
(sorry for the shameless self-promotion)
Comment #9
liquidcms commentedwow.. pretty fast reply.. ok, i'll look at doing node object massaging prior to node.save, to bad that has to occur; but oh well.
btw, i also have taxonomy on this node; and didnt get an error from that; but maybe once i sort uot cleaning noderef fields i will
Comment #10
liquidcms commentedyea, one of the guys on our team has looked at deploy.. don't think it can quite handle all of what we are doing.. which is a very large editorial system that uses workflow and "delivery vehicles" to deliver content to different sites... currently we have email and ftp as delivery vehicle types and i am adding the xmlrpc del veh type to the mix.
perhaps i'll take another look at deploy this evening.. thanks.
Comment #11
liquidcms commentedahh, and sadly Deploy is only Drupal6 (and we're still on 5)
Comment #12
liquidcms commentedah, i see.. from #3 above, jrbeeman is only correct if the field is not set to multiple. if it is the format is:
annoying that this isn't consistent.
Comment #13
liquidcms commentedseems like i keep having to write custom field handlers every time i get a bit further on this - first noderef, then taxonomy, then workflow...
then, decided going about this the wrong way.. fix the source rather than each field.. so i made a new node.save service that uses node_save() rather than drupal_execute() and now everything seems much easier.
heyrocker mentions there are reasons for using drupal_execute(); but for my application; haven't seen it yet.
Comment #14
marcingy commentedThe simple answer is node_save does not invoke any FAPI based validation while drupal_excute does - and that is why heyrocker correctly says use drupal_excute.
Comment #15
gddThe other problem is that if you are using modules that extend the node form through hook_form_alter(), then these additions will get lost when you node save (since typically these are managed through additional submit[] handlers in the form definition.) So for any individual situation where you know what you're dealing with, node_save() will be an option, but for a situation like ours, where we have to worry about a lot of edge cases and dealing with a lot of unkowns, drupal_execute() is the only way to go because it handles things just like Drupal does.
This is in the end a Drupal problem, because the front end (FAPI) is so tightly integrated with backend processing. There are not a lot of clear APIs to bridge the two. There has been a lot of talk over the years about how to address this but nothing has ever really come to light.
Comment #16
liquidcms commentedbut still, even with drupal_execute().. special field handlers need to be done for all these "edge cases".
so far, in my app, it is a bit of a toss up:
drupal_execute:
- handles file fields better
- need sep code for taxonomy, noderefs, workflow
node_save:
- need to set fid to 'upload' in file fields
- workflow has to be cleaned up, but easier than with d_execute, just change keys from _workflow to workflow
- taxonomy and noderefs work as is
Comment #17
gddI would argue that the fact that Date and Nodereference need special field handlers that are widget dependent is a bug in those modules, but Karen has made it plain on many occasions that she does not support the drupal_execute() method of saving nodes and that if you want to go that route you are on your own.
You're completely correct that either way you're just choosing your poison.
I had an idea recently that we should supply both options in services, a node_save() version and a drupal_execute() version, and the user can choose which one they want to use. Any comments on this idea? (note that in order to maintain API consistency, I would argue that the exisisting node.save continue to use drupal_execute(), which could be confusing.)
Comment #18
liquidcms commentedwell that was the approach i took; so maybe i am biased - but took me about 10 minutes (gotta love drupal) to add a new service that uses node_save().
i guess we'd need to have different method names if both were available; for my app was a no brainer since the service is just part of a much bigger editing and delivery system called CAPSA, so i now have a capsa.node.save and original node.save. Perhaps node.execute (but sadly not very backward compatible)
Comment #19
ray007 commented@liquidcms: You may not only want to call node_save(), but maybe do a bit more:
That should call some of the hooks drupal_execute() also calls, not sure if I missed something.
Would you share the service you've written with us (or me) ?
Comment #20
liquidcms commentedmy service is simply a copy of the existing node.save, except it uses node_save():
also, i am using Dr5.
I might get a chance later this week to try out your additions..
thanks.
Comment #21
garrizaldy commentedI was able to save and update regular node fields like titles but was unable to save and update on CCK Field on the nodes.
here is my xml request for a node.save after a successful system.connect and user.login http://pastebin.com/m5ceca16
here's an example how I build my node array:
Comment #22
gddI believe this is a problem with how you are constructing your nodes, and is not a Services issue at all. Please refer to
http://drupal.org/node/439090
for some guidance on how to format nodes for saving thorugh drupal_execute() which the node.save service uses.
Is there still a bug somewhere in this isssue? Because I don't see one. If someone wants to report one then feel free to reopen.
Comment #23
houdelou commentedI had the same problem. As mentioned in this post http://drupal.org/node/711604, it works with a list field instead of autocomplete. And as mentioned in comment #21 of the present post, I doubled the array like this
$node['field_content'] = array(array("nid" => "21"));Comment #24
sanjith commentedHi,
Any one suggest a better way for handling multi dimensional array using xmlrpc via services module.
using node.save, I could not save the node with taxonomy tags !
So I written my own method to catch the node object and taxonomy terms and joined as needed for node_save.
But this is not the correct way I think ...
I want to pass a array(array) using xmlrpc and need to get and access in hook_services() ?
Thanks in Advance,
SVN
Comment #25
sanjith commentedI passed the array(array) to the services
serialize the array in client.php, and in my drupal service method , unserialized.
My next question is how to attach a file to a node - cck field ?
Comment #26
kylebrowning commentedlook at the tests.
Comment #27
epiphanydigital commentedHi all, I'm fairly new to the services module and am doing all of my interaction with it using the JSON_SERVER and Sencha Touch as for the client side framework. I had no problem saving a custom content type to Drupal, but when I started adding the additional fields shown below, I started having issues.
The
field_pidis one I've tried both sendingnidsa number and an object of indexed numbers (like below), after reading through the above conversation about plural "nids" vs singular "nids".Does anyone have any idea if there is something wrong with the following data or why I could be getting the following error back?
Getting error:
GET http://mydomain.com/services/json?method=%22node.save%22&node=%7B%22titl...(s)%22%7D%5D%2C%22field_frequency%22%3A%5B%7B%22value%22%3A%221x%22%7D%5D%2C%22field_frequencyunit%22%3A%5B%7B%22value%22%3A%22Hourly%22%7D%5D%2C%22field_pid%22%3A%7B%22nids%22%3A%7B%220%22%3A48%7D%7D%7D&callback=Ext.util.JSONP.callback 500 (Internal Server Error)
Comment #28
greg.harveyAnyone struggling with this or any other problem with node creation in Services 3.x, install the Devel module and add
dpm($form_state);to the core node_form_submit() function. The data in$form_state['values']is the form the Services node save expects to receive data in. Anything else will fail in one way or another...