Project:AMFPHP
Version:master
Component:Code
Category:task
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

I wanted to bring up a particularly frustrating problem when using this module with Flex. Flex takes over 'uid' on any object and fills it with its own unique identifier value for the object. This means if a user object is returned, accessing 'uid' of the user in Flex will not actually return the $user->uid, but the Flex unique object key.

As a temporary fix, I am converting any 'uid' to 'userid' using the function below.

<?php
function amfphp_fix_uid($data, $direction = 1) {
 
$uid    = 's:3:"uid";';
 
$userid = 's:6:"userid";';
 
 
$from = ($direction) ? $uid : $userid;
 
$to   = (!$direction) ? $uid : $userid;
 
 
$data = serialize($data);
 
$data = str_replace($from, $to, $data);
 
$data = unserialize($data);
 
  return
$data;
}
?>

I'd like to find a better solution to this problem, so ideas appreciated.

Thanks,
Scott

Comments

#1

Came across exactly the same issue,
my workaround adds

$node->userid = $node->uid;

to the function

services_node_load($node, $fields = array())

in the services.module file

#2

The function I posted above is already in AMFPHP core. Your code will only solve the problem in 1 place, when it can be in many, such as user service. Too, this problem only applies to Flash and Flex apps, so it shouldn't affect everybody.

The code in AMFPHP serializes the data, then looks for any "uid" replacing it with "userid". This should take care of any kind of data passed back into Flash or Flex from any service callback. I just think there's got to be a better way than the way I've done it.

If you're not getting a "userid" back from amfphp without your patch, please let me know so I can fix it.

Thanks,
Scott

#3

It looks like the service module or AMFPHP module has problem to save author information when creating a new node. Here is my code:

public function createNode(): void
{
var edit:Object;
edit = new Object;
edit.field_sub_title = new Array({value: sub_title_create.text});
//edit.field_story_type = new Array({value:"1"});
edit.title = title_create.text;
edit.body = body_create.text;
edit.field_story_type = new Array({value: story_type_new.selectedValue.toString()});
edit.field_year = new Array({value: year_new.selectedItem.toString()});
edit.type = 'story';
edit.status = 1;
var formated_where:Array = new Array();
var index:int = 0;
for each (var val:String in where_new.selectedItems) {
formated_where.push({value:val});
}

edit.userid =2;
node.save(edit);
}

Every field works fine; however, the new node always not saving the author information. Thus for every node i created using this function create a node with anonymous author.
And idea on this? Many thanks.

#4

I think the problem is that you use "edit.userid = 2" instead of "edit.uid = 2"

#5

Chris,

I tried that as well, but that didn't work.
I end up to modify the node_service module to get the author work correctly. Here is a what i have added to the service module:

function node_service_save($edit) {
if ($edit['nid']) {
$node = node_load($edit['nid']);
if ($node->nid) {
$ret = drupal_execute($node->type .'_node_form', $edit, $edit);
}
}
else {
$ret= drupal_execute($edit['type'] .'_node_form', $edit, $edit);

/*****APPLY PATH TO SAVE CORRECT USER INFO*******/
global $user;
$nid = db_result(db_query('SELECT max(nid) FROM {node} WHERE type = "%s"', $edit['type']));
db_query('UPDATE {node} SET uid = %d WHERE nid = %d', $user->uid, $nid);
/******END PATCH********/

}
if ($errors = form_get_errors()) {
return services_error(implode("\n", $errors));
}
watchdog('content', t('@type: updated %title.', array('@type' => t($node->type), '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
return $node;
}

#6

You needed to include the user name in the node.save operation. Without the name, drupal will not save the correct author. Add node.name = "username" and you should be good to go.

Scott

#7

I have modified the serialize function call to be more memory efficient based on #344476: Trouble with serialize call in amfphp module using ridiculous amounts of memory., but I still don't like this. Any thoughts, solutions / suggestions would be great.

- Scott

#8

Today when calling system.connect from flash, sometimes it was returning false, dunno why.
Tracked it down to:
$data = unserialize($data);
in the fix_uid function.

As Im using flash and only wanting the sessionId, I could skip the fix_uid function no worries.

There's some sort of issue there, thats all I'm sayin'

#9

Hi snelson thank you for the awesome service you have provided. I am dealing with a flex/drupal mixture and have come down to the last function of system.connect. I see that the amfphp_fix_uid function is there but it doesnt seem to be renaming it to userid. When I get run system.connect in the module it returns the value still as uid. Flex is converting it to its own uid in a trace I did. Is there a workaround for this? Thank you in advance.

I noticed there was a post above about adding a line of code to the services.module and tried that as well with no luck but I do not think that was affecting the part of code I am looking for. I will continue to search for the answer and post if I can find the answer :)

#10

*UPDATE* Problem resolved at least for now. I am using name instead of uid to check the profile and system.connect to see if they are the same. Since the same user name is not aloud it should be ok :). I fixed this problem on the 31st but have been finishing up everything before I posted. I guess thanks again? lol

#11

Set the makeObjectsBindable property in the RemoteObject in Flex to false to prevent this from happening. No data binding though but you can set it per method.

nobody click here