The code in node_resource.inc
drupal_form_submit($node->type . '_node_form', $form_state, $old_node);
makes the assumption that $node->type is allways set.

If not, the absence of type results in the following notices/warnings:

    Notice: Undefined index: type in _node_resource_update() (line 282 of /services/sites/all/modules/contrib/services/resources/node_resource.inc).
    Notice: Undefined index: _node_form in drupal_retrieve_form() (line 735 of /services/includes/form.inc).
    Warning: call_user_func_array() expects parameter 1 to be a valid callback, function '_node_form' not found or invalid function name in drupal_retrieve_form() (line 770 of /services/includes/form.inc).

From my point of view it's not desireable to force the client to PUT the node type for an update.
We could just take it from the $old_node object, if not set in the PUT request.

Files: 
CommentFileSizeAuthor
#24 services-1191786-node-update-type-optional-D6.patch5.83 KBmarcingy
#21 services-1191786-node-update-type-optional-D7.patch5.46 KBygerasimov
#20 allow-no-node-type-2.patch4.04 KBmarcingy
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch allow-no-node-type-2.patch. This may be a -p0 (old style) patch, which is no longer supported by the testbots.
[ View ]
#18 allow-no-node-type.patch3.89 KBmarcingy
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch allow-no-node-type.patch. This may be a -p0 (old style) patch, which is no longer supported by the testbots.
[ View ]
#10 make_type_attribute_optional-1191786-10.patch4.7 KBsanduhrs
FAILED: [[SimpleTest]]: [MySQL] 1,860 pass(es), 12 fail(s), and 8 exception(es).
[ View ]
#8 make_type_attribute_optional-1191786-8.patch5 KBsanduhrs
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch make_type_attribute_optional-1191786-8.patch. This may be a -p0 (old style) patch, which is no longer supported by the testbots.
[ View ]
#5 make_type_attribute_optional-1191786-4.patch4.76 KBsanduhrs
FAILED: [[SimpleTest]]: [MySQL] 1,858 pass(es), 18 fail(s), and 12 exception(es).
[ View ]
#1 make_type_attribute_optional-1191786-1.patch561 bytessanduhrs
PASSED: [[SimpleTest]]: [MySQL] 1,750 pass(es).
[ View ]

Comments

sanduhrs’s picture

Status:Active» Needs review
StatusFileSize
new561 bytes
PASSED: [[SimpleTest]]: [MySQL] 1,750 pass(es).
[ View ]

Patch attached, please review.

kylebrowning’s picture

Category:bug» feature
marcingy’s picture

Status:Needs review» Needs work

This seems like a good feature however as it stands I can set $node['type'] to be an empty string and it will try to use that value an !empty check would be more appropriate than isset. Also as this is a new feature can you add a test for this?

sanduhrs’s picture

Still, I think a method that throws notices and warnings instead of returning a meaningful response should be considered a bug.
By the way, the generated response for a request like

PUT http://example.org/rest/node/1

node[title]=New Title Here

is

Status: 200 OK

<?xml version="1.0" encoding="utf-8"?>
<result>
  <nid>1</nid>
  <uri>http://example.org/rest/node/1</uri>
</result>

Which implies to me, that all went well while it didn't.
Bug?

sanduhrs’s picture

StatusFileSize
new4.76 KB
FAILED: [[SimpleTest]]: [MySQL] 1,858 pass(es), 18 fail(s), and 12 exception(es).
[ View ]

The new patch checks whether the type attribute ist set and if it's a valid node type.
If not set or invalid it will keep the old value.
The patch inludes three test cases to check for missing, empty and invalid type attribute.

marcingy’s picture

This still does not take into account that node type can be empty with the isset check. Plus there is no need to do an !array_key_exists($node['type'], $node_types)) check instead you can do an isset for this. This should be used as it is more performant.

sanduhrs’s picture

Well, if the node type doesn't exist, the same error occurs, as if none or empty is given.
So to be sure, we need to check if the node type is valid array_key_exists($node['type'], $node_types))
This also takes into account when type is empty.

Can we assume that the $old_node->type is valid per se as I do in that patch?
Probably not, because some administrator could have deleted it.
I'm not sure what to do in that case.

sanduhrs’s picture

Status:Needs work» Needs review
StatusFileSize
new5 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch make_type_attribute_optional-1191786-8.patch. This may be a -p0 (old style) patch, which is no longer supported by the testbots.
[ View ]

To prevent the error from occuring, we need to check for a valid node type parameter in any case.
Whether it has been submitted or not doesn't make a difference.

I tried to check for validity with a simple function_exists($node['type'] . '_node_form'), but that didn't work out.
Any other ideas for a better performing solution?

Attached is a patch that checks for isset, empty and validity.
It returns 406 in case of invalidity.

marcingy’s picture

Status:Needs review» Needs work

This can simplified

<?php
   
// Make submission of node type optional
   
if (!isset($node['type']) || empty($node['type'])) {
     
$node['type'] = $old_node->type;
    }
>

to

<?php
   
// Make submission of node type optional.
   
if (empty($node['type'])) {
     
$node['type'] = $old_node->type;
    }
?>

as empty will return false if the item does not exist or is ''.

Also you need to add periods after your comments.

The approach of making sure the node type is valid is a really good idea, once the above is done this should be good to go. I haven't run the tests yet but they look sane from an eyeball.

sanduhrs’s picture

StatusFileSize
new4.7 KB
FAILED: [[SimpleTest]]: [MySQL] 1,860 pass(es), 12 fail(s), and 8 exception(es).
[ View ]

Changed, as you suggested.

sanduhrs’s picture

Assigned:Unassigned» sanduhrs
Status:Needs work» Needs review

Please review.

marcingy’s picture

Status:Needs review» Reviewed & tested by the community

Thanks looks good.

kylebrowning’s picture

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

if we can get a 6.x version that would be great.

kylebrowning’s picture

Status:Reviewed & tested by the community» Needs work
killua99’s picture

I don't know where to put this notice:

Notice: Undefined variable: final_resource en services_edit_form_endpoint_resources_submit() (línea 396 de ~/sites/all/modules/services/plugins/export_ui/services_ctools_export_ui.class.php).

marcingy’s picture

Version:6.x-3.x-dev» 7.x-3.x-dev
Assigned:sanduhrs» marcingy

Grabbing to reroll this weekend

@Killua99 please raise a new issue as your post is not related to this issue at all thanks.

killua99’s picture

Ok then.

marcingy’s picture

Status:Needs work» Needs review
StatusFileSize
new3.89 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch allow-no-node-type.patch. This may be a -p0 (old style) patch, which is no longer supported by the testbots.
[ View ]

New version of the patch to allow updates to ignore type. As per normally I'll backport after d7 version is rtbc.

ygerasimov’s picture

Status:Needs review» Needs work
+++ b/resources/node_resource.incundefined
@@ -313,13 +313,18 @@ function _node_resource_update($nid, $node) {
+  // If no type is provided use the existing node type.
+  if (empty($node['type']) && isset($old_node->type)) {
+    $node['type'] = $old_node->type;
+  }
+
   // Validate the node. If there is validation error Exception will be thrown
   // so code below won't be executed.

I think there is no need to check whether $old_node->type is available as we did node_load before.

Also we can avoid checking whether content type is valid if we loaded it from old node:

<?php
// If no type is provided use the existing node type.
if (empty($node['type'])) {
  
$node['type'] = $old_node->type;
}
else {
 
// Validate the node. If there is validation error Exception will be thrown
  // so code below won't be executed.
 
_node_resource_validate_type($node);
}
?>

Everything else I am happy with. Thanks for great work @sanduhrs and @marcingy!

marcingy’s picture

Status:Needs work» Needs review
StatusFileSize
new4.04 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch allow-no-node-type-2.patch. This may be a -p0 (old style) patch, which is no longer supported by the testbots.
[ View ]

Reroll with changes above

ygerasimov’s picture

@marcingy, what do you think about attached patch. Code is just moved around but in my opinion looks bit clearer.

marcingy’s picture

Status:Needs review» Reviewed & tested by the community

Looks good would like Kyle to commit this and give a once over - I'll happily roll a d6 version of the patch once this is committed.

kylebrowning’s picture

Version:7.x-3.x-dev» 6.x-3.x-dev
Status:Reviewed & tested by the community» Patch (to be ported)

Port it!

marcingy’s picture

Status:Patch (to be ported)» Needs review
StatusFileSize
new5.83 KB

Reroll for d6

marcingy’s picture

Would be nice to get this into 3.2 ;)

kylebrowning’s picture

Status:Needs review» Reviewed & tested by the community

looks great.

kylebrowning’s picture

Status:Reviewed & tested by the community» Needs work

actually this break in 6.x

kylebrowning’s picture

Assigned:marcingy» cotto
kylebrowning’s picture

Status:Needs work» Closed (fixed)