From 25882ad92605e597bc107138d896d990431a2f0e Mon Sep 17 00:00:00 2001
From: Yuriy Gerasimov <yuri.gerasimov@gmail.com>
Date: Fri, 1 Apr 2011 20:40:16 +0300
Subject: [PATCH] Issue #954964 by ygerasimov,marcingy: Remove argument type struct in favour of array.

---
 resources/comment_resource.inc                     |   26 +++++-------
 resources/file_resource.inc                        |    4 +-
 resources/node_resource.inc                        |   45 +++++++++-----------
 resources/taxonomy_resource.inc                    |    8 ++--
 resources/user_resource.inc                        |   39 +++++++++--------
 servers/rest_server/includes/RESTServer.inc        |   17 +------
 services.services.api.php                          |    8 ++--
 tests/functional/ServicesResourceFileTests.test    |   11 +++--
 tests/functional/ServicesResourceNodeTests.test    |   16 ++++----
 .../functional/ServicesResourceTaxonomyTests.test  |    8 ++--
 10 files changed, 82 insertions(+), 100 deletions(-)

diff --git a/resources/comment_resource.inc b/resources/comment_resource.inc
index 94ce4ad..1490b77 100644
--- a/resources/comment_resource.inc
+++ b/resources/comment_resource.inc
@@ -17,7 +17,7 @@ function _comment_resource_definition() {
         'args' => array(
           array(
             'name' => 'comment',
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'The comment object',
             'source' => 'data',
             'optional' => FALSE,
@@ -60,7 +60,7 @@ function _comment_resource_definition() {
           ),
           array(
             'name' => 'data',
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'The comment object with updated information',
             'source' => 'data',
             'optional' => FALSE,
@@ -177,13 +177,11 @@ function _comment_resource_definition() {
  */
 
 function _comment_resource_create($comment) {
-  $comment = (object)$comment;
-
-  $form_state['values'] = (array)$comment;
+  $form_state['values'] = (array) $comment;
   $form_state['values']['op'] = t('Save');
 
-  $comment_empty = (object)array(
-    'nid' => $comment->nid,
+  $comment_empty = (object) array(
+    'nid' => $comment['nid'],
     'cid' => NULL,
   );
 
@@ -225,18 +223,16 @@ function _comment_resource_retrieve($cid) {
  *   Unique identifier for the comment (cid) or FALSE if there was a problem.
  */
 function _comment_resource_update($cid, $comment) {
-  $comment = (object)$comment;
-
-  $comment->cid = $cid;
+  $comment = (array) $comment;
+  $comment['cid'] = $cid;
 
-  $old_comment = comment_load($comment->cid);
+  $old_comment = comment_load($cid);
   if (empty($old_comment)) {
-    return services_error(t('Comment @cid not found', array('@cid' => $comment->cid)), 404);
+    return services_error(t('Comment @cid not found', array('@cid' => $cid), 404));
   }
-
   // Setup form_state.
   $form_state = array();
-  $form_state['values'] = (array) $comment;
+  $form_state['values'] = $comment;
   $form_state['values']['op'] = t('Save');
   $form_state['comment'] = $old_comment;
 
@@ -246,7 +242,7 @@ function _comment_resource_update($cid, $comment) {
     return services_error(implode(" ", $errors), 406);
   }
 
-  return $comment->cid;
+  return $cid;
 }
 
 /**
diff --git a/resources/file_resource.inc b/resources/file_resource.inc
index cb12368..a3580ed 100644
--- a/resources/file_resource.inc
+++ b/resources/file_resource.inc
@@ -24,8 +24,8 @@ function _file_resource_definition() {
         'args' => array(
           array(
             'name' => 'file',
-            'type' => 'struct',
-            'description'    => t('An object representing a file.'),
+            'type' => 'array',
+            'description'    => t('An array representing a file.'),
             'source' => 'data',
             'optional' => FALSE,
           ),
diff --git a/resources/node_resource.inc b/resources/node_resource.inc
index 64ab64b..9c8d85e 100644
--- a/resources/node_resource.inc
+++ b/resources/node_resource.inc
@@ -28,7 +28,7 @@ function _node_resource_definition() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The node object to create',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access callback' => '_node_resource_access',
@@ -51,7 +51,7 @@ function _node_resource_definition() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The node data to update',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access callback' => '_node_resource_access',
@@ -96,7 +96,7 @@ function _node_resource_definition() {
           array(
             'name' => 'parameters',
             'optional' => TRUE,
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'Parameters',
             'default value' => NULL,
             'source' => array('param' => 'parameters'),
@@ -178,31 +178,29 @@ function _node_resource_retrieve($nid) {
  * @see drupal_execute()
  */
 function _node_resource_create($node) {
-  $node = (object)$node;
-
-  if (!isset($node->type)) {
+  $node = (array) $node;
+  if (!isset($node['type'])) {
     return services_error(t('Missing node type'), 406);
   }
 
   // Load the required includes for drupal_execute
   module_load_include('inc', 'node', 'node.pages');
-  $nid = NULL;
   // Setup form_state
-  $values = (array)$node;
   $form_state = array();
-  $form_state['values'] = $values;
+  $form_state['values'] = $node;
   $form_state['values']['op'] = t('Save');
 
-  //Wanted to return a gracefull error instead of a blank nid, this should allow for that.
+  // Wanted to return a gracefull error instead of a blank nid, this should
+  // allow for that.
   $types = node_type_get_types();
-  if (array_key_exists($node->type, $types)) {
-    drupal_form_submit($node->type . '_node_form', $form_state, $node);
+  $node_type = $node['type'];
+  if (isset($types[$node_type])) {
+    drupal_form_submit($node_type . '_node_form', $form_state, (object)$node);
   }
   else {
-    return services_error(t('Node type @type does not exist.', array('@type' => $node->type)), 406);
+    return services_error(t('Node type @type does not exist.', array('@type' => $node_type)), 406);
   }
 
-
   if ($errors = form_get_errors()) {
     return services_error(implode(" ", $errors), 406);
   }
@@ -233,22 +231,21 @@ function _node_resource_create($node) {
  * @see drupal_execute()
  */
 function _node_resource_update($nid, $node) {
-  $node = (object)$node;
-  $node->nid = $nid;
+  $node = (array) $node;
+  $node['nid'] = $nid;
 
-  $old_node = node_load($node->nid);
+  $old_node = node_load($nid);
   node_object_prepare($old_node);
   if ($old_node->nid) {
     // Load the required includes for drupal_execute
     module_load_include('inc', 'node', 'node.pages');
 
     // Setup form_state.
-    $values = (array)$node;
     $form_state = array();
-    $form_state['values'] = $values;
+    $form_state['values'] = $node;
     $form_state['values']['op'] = t('Save');
     $form_state['node'] = $old_node;
-    drupal_form_submit($node->type . '_node_form', $form_state, $old_node);
+    drupal_form_submit($node['type'] . '_node_form', $form_state, $old_node);
 
 
     if ($errors = form_get_errors()) {
@@ -259,7 +256,6 @@ function _node_resource_update($nid, $node) {
     return services_error(t('Node @nid not found', array('@nid' => $old_node->nid)), 404);
   }
 
-  $nid = $node->nid;
   $node = array('nid' => $nid);
   if ($uri = services_resource_uri(array('node', $nid))) {
     $node['uri'] = $uri;
@@ -325,10 +321,9 @@ function _node_resource_index($page = 0, $fields = '*', $parameters = NULL) {
     $node_select->condition('status', 1);
   }
 
-  if (is_object($parameters)) {
-    foreach ($parameters as $parameter => $parameter_value) {
-      $node_select->condition($parameter, $parameter_value, '=');
-    }
+  $parameters = (array)$parameters;
+  foreach ($parameters as $parameter => $parameter_value) {
+    $node_select->condition($parameter, $parameter_value, '=');
   }
 
   $result = $node_select->execute();
diff --git a/resources/taxonomy_resource.inc b/resources/taxonomy_resource.inc
index 7961c02..39c8e55 100644
--- a/resources/taxonomy_resource.inc
+++ b/resources/taxonomy_resource.inc
@@ -33,7 +33,7 @@ function _taxonomy_resource_definition() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The taxonomy term object to create',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access callback' => '_taxonomy_resource_create_access',
@@ -55,7 +55,7 @@ function _taxonomy_resource_definition() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The taxonomy term data to update',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access callback' => '_taxonomy_resource_update_access',
@@ -142,7 +142,7 @@ function _taxonomy_resource_definition() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The taxonomy vocabulary object to create',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access arguments' => array('administer taxonomy'),
@@ -163,7 +163,7 @@ function _taxonomy_resource_definition() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The taxonomy vocabulary data to update',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access arguments' => array('administer taxonomy'),
diff --git a/resources/user_resource.inc b/resources/user_resource.inc
index e667854..1d95d6a 100644
--- a/resources/user_resource.inc
+++ b/resources/user_resource.inc
@@ -31,7 +31,7 @@ function _user_resource_definition() {
         'args' => array(
           array(
             'name' => 'account',
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'The user object',
             'source' => 'data',
             'optional' => FALSE,
@@ -56,7 +56,7 @@ function _user_resource_definition() {
           ),
           array(
             'name' => 'data',
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'The user object with updated information',
             'source' => 'data',
             'optional' => FALSE,
@@ -104,7 +104,7 @@ function _user_resource_definition() {
           array(
             'name' => 'parameters',
             'optional' => TRUE,
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'Parameters',
             'default value' => array(),
             'source' => array('param' => 'parameters'),
@@ -194,15 +194,16 @@ function _user_resource_retrieve($uid) {
  *   The user object of the newly created user.
  */
 function _user_resource_create($account) {
+  $account = (array)$account;
   // Load the required includes for saving profile information
   // with drupal_form_submit().
   module_load_include('inc', 'user', 'user.pages');
 
   // register a new user
-  $form_state['values'] = (array) $account;
+  $form_state['values'] = $account;
   $form_state['values']['pass'] = array(
-    'pass1' => $account->pass,
-    'pass2' => $account->pass,
+    'pass1' => $account['pass'],
+    'pass2' => $account['pass'],
   );
   $form_state['values']['op'] = t('Create new account');
 
@@ -236,14 +237,11 @@ function _user_resource_create($account) {
  *   The modified user object.
  */
 function _user_resource_update($uid, $account) {
-  $account = (object)$account;
-  $account->uid = $uid;
+  $account = (array) $account;
+  $account['uid'] = $uid;
 
   $account_loaded = user_load($uid);
 
-  if (!isset($account->roles)) {
-    $account->roles = $account_loaded->roles;
-  }
   // Load the required includes for saving profile information
   // with drupal_form_submit().
   module_load_include('inc', 'user', 'user.pages');
@@ -251,22 +249,25 @@ function _user_resource_update($uid, $account) {
   // If a profile category was passed in, use it. Otherwise default
   // to 'account' (for saving core user data.)
   $category = 'account';
-  if (isset($account->category)) {
-    $category = $account->category;
-    unset($account->category);
+  if (isset($account['category'])) {
+    $category = $account['category'];
+    unset($account['category']);
   }
 
   // Drop any passed in values into the $account var. Anything
   // unused by the form just gets ignored. We handle roles and
   // password separately.
-  foreach ((array)$account as $key => $value) {
+  foreach ($account as $key => $value) {
     if ($key != 'pass' || $key != 'roles') {
       $form_state['values'][$key] = $value;
     }
   }
 
   // Prepare values of roles.
-  foreach ($account->roles as $key => $value) {
+  if (!isset($account['roles'])) {
+    $account['roles'] = $account_loaded->roles;
+  }
+  foreach ($account['roles'] as $key => $value) {
     if (!empty($value)) {
       $form_state['values']['roles'][$key] = $key;
     }
@@ -274,9 +275,9 @@ function _user_resource_update($uid, $account) {
   unset($form_state['values']['roles'][2]);
 
   // Prepare values for password.
-  if (isset($account->pass)) {
-    $form_state['values']['pass']['pass1'] = $account->pass;
-    $form_state['values']['pass']['pass2'] = $account->pass;
+  if (isset($account['pass'])) {
+    $form_state['values']['pass']['pass1'] = $account['pass'];
+    $form_state['values']['pass']['pass2'] = $account['pass'];
   }
 
   $form_state['values']['op'] = t('Save');
diff --git a/servers/rest_server/includes/RESTServer.inc b/servers/rest_server/includes/RESTServer.inc
index 5c2d4fe..a0f097f 100755
--- a/servers/rest_server/includes/RESTServer.inc
+++ b/servers/rest_server/includes/RESTServer.inc
@@ -213,20 +213,9 @@ class RESTServer {
                 $arguments[$i] = $sources[$info['source']][$info['name']];
               }
           }
-          // Convert arrays to objects and objects to arrays to be more tolerant
-          // towards client. Not all formats and languages handle arrays &
-          // objects as php does.
-          switch ($info['type']) {
-            case 'struct':
-              if (isset($arguments[$i]) && is_array($arguments[$i])) {
-                $arguments[$i] = (object)$arguments[$i];
-              }
-              break;
-            case 'array':
-              if (is_object($arguments[$i])) {
-                $arguments[$i] = get_object_vars($arguments[$i]);
-              }
-              break;
+          // Convert to array if argument expected to be array.
+          if ($info['type'] == 'array' && isset($arguments[$i])) {
+            $arguments[$i] = (array)$arguments[$i];
           }
         }
         // When argument isn't set, insert default value if provided or
diff --git a/services.services.api.php b/services.services.api.php
index 02d6dda..2eeb7cc 100644
--- a/services.services.api.php
+++ b/services.services.api.php
@@ -71,7 +71,7 @@
   *     array containing the following keys:
   *
   *     - name: The name of this argument.
-  *     - type: The data type of this argument (int, string, array, struct)
+  *     - type: The data type of this argument (int, string, array)
   *     - description: Text describing this argument's usage.
   *     - optional: A boolean indicating whether or not this argument is optional.
   *     - source: Where this argument should be retrieved from. This can be
@@ -113,7 +113,7 @@ function hook_services_resources() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The node object to create',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access callback' => '_node_resource_access',
@@ -136,7 +136,7 @@ function hook_services_resources() {
             'optional' => FALSE,
             'source' => 'data',
             'description' => 'The node data to update',
-            'type' => 'struct',
+            'type' => 'array',
           ),
         ),
         'access callback' => '_node_resource_access',
@@ -181,7 +181,7 @@ function hook_services_resources() {
           array(
             'name' => 'parameters',
             'optional' => TRUE,
-            'type' => 'struct',
+            'type' => 'array',
             'description' => 'Parameters',
             'default value' => NULL,
             'source' => array('param' => 'parameters'),
diff --git a/tests/functional/ServicesResourceFileTests.test b/tests/functional/ServicesResourceFileTests.test
index 4fed21e..fb88581 100644
--- a/tests/functional/ServicesResourceFileTests.test
+++ b/tests/functional/ServicesResourceFileTests.test
@@ -56,11 +56,12 @@ class ServicesResourceFileTests extends ServicesWebTestCase {
    */
   public function testResourceFileCreate() {
     // Create file argument with data.
-    $file = new stdClass();
-    $file->filesize = filesize($this->testfile->uri);
-    $file->filename = $this->testfile->filename;
-    $file->file = base64_encode(file_get_contents($this->testfile->uri));
-    $file->uid = $this->privileged_user->uid;
+    $file = array(
+      'filesize' => filesize($this->testfile->uri),
+      'filename' => $this->testfile->filename,
+      'file' => base64_encode(file_get_contents($this->testfile->uri)),
+      'uid' => $this->privileged_user->uid,
+    );
 
     // Create file with call.
     $result = $this->servicesPost($this->endpoint->path . '/file', array('file' => $file));
diff --git a/tests/functional/ServicesResourceNodeTests.test b/tests/functional/ServicesResourceNodeTests.test
index 73a40e1..40cee19 100644
--- a/tests/functional/ServicesResourceNodeTests.test
+++ b/tests/functional/ServicesResourceNodeTests.test
@@ -193,16 +193,16 @@ class ServicesResourceNodetests extends ServicesWebTestCase {
     $this->drupalLogin($this->privilegedUser);
     $node = $this->drupalCreateNode();
 
-    $node_update = clone $node;
-    $node_update->title = $this->randomName();
-    $node_update->body[LANGUAGE_NONE][0]['value'] = $this->randomName();
+    $node_update = (array) $node;
+    $node_update['title'] = $this->randomName();
+    $node_update['body'][LANGUAGE_NONE][0]['value'] = $this->randomName();
 
     $responseArray = $this->servicesPut($this->endpoint->path . '/node/' . $node->nid, array('node' => $node_update));
     // Load node not from cache.
     $nodeAfterUpdate = node_load($responseArray['body']['nid'], NULL, TRUE);
     $this->assertTrue(isset($nodeAfterUpdate->nid), t('Node was successfully updated'), 'NodeResource: Updated');
-    $this->assertEqual($nodeAfterUpdate->title, $node_update->title, t('Title is the same'), 'NodeResource: Update');
-    $this->assertEqual($nodeAfterUpdate->body[LANGUAGE_NONE][0]['value'], $node_update->body[LANGUAGE_NONE][0]['value'], t('Body is the same'), 'NodeResource: Update');
+    $this->assertEqual($nodeAfterUpdate->title, $node_update['title'], t('Title is the same'), 'NodeResource: Update');
+    $this->assertEqual($nodeAfterUpdate->body[LANGUAGE_NONE][0]['value'], $node_update['body'][LANGUAGE_NONE][0]['value'], t('Body is the same'), 'NodeResource: Update');
   }
 
   /**
@@ -222,9 +222,9 @@ class ServicesResourceNodetests extends ServicesWebTestCase {
 
     // Try to update this node with different user not
     // having permission to edit any story content.
-    $node_update = clone $node;
-    $node_update->title = $this->randomName();
-    $node_update->body[LANGUAGE_NONE][0]['value'] = $this->randomName();
+    $node_update = (array) $node;
+    $node_update['title'] = $this->randomName();
+    $node_update['body'][LANGUAGE_NONE][0]['value'] = $this->randomName();
 
     $responseArray = $this->servicesPut($this->endpoint->path . '/node/' . $node->nid, array('node' => $node_update));
 
diff --git a/tests/functional/ServicesResourceTaxonomyTests.test b/tests/functional/ServicesResourceTaxonomyTests.test
index e31a8e3..23a1d48 100644
--- a/tests/functional/ServicesResourceTaxonomyTests.test
+++ b/tests/functional/ServicesResourceTaxonomyTests.test
@@ -46,7 +46,7 @@ class ServicesResourceTaxonomyTests extends ServicesWebtestCase {
   function testVocabularyCreate() {
     $path = $this->endpoint->path;
 
-    $vocabulary = (object)array(
+    $vocabulary = array(
       'name'        => $this->randomName(),
       'machine_name'=> $this->randomName(),
       'description' => $this->randomString(),
@@ -59,13 +59,13 @@ class ServicesResourceTaxonomyTests extends ServicesWebtestCase {
 
     $query = db_select('taxonomy_vocabulary', 'v')
       ->fields('v', array('vid'))
-      ->condition('v.name', $vocabulary->name);
+      ->condition('v.name', $vocabulary['name']);
     $vid = $query->execute()->fetchField();
 
     $vocabulary_load = (array)taxonomy_vocabulary_load($vid);
-    $vocabulary_intersect = array_intersect_assoc((array)$vocabulary, $vocabulary_load);
+    $vocabulary_intersect = array_intersect_assoc($vocabulary, $vocabulary_load);
 
-    $this->assertEqual((array)$vocabulary, $vocabulary_intersect, t('Taxonomy vocabulary created properly.'), 'TaxonomyVocabularyResource: Create');
+    $this->assertEqual($vocabulary, $vocabulary_intersect, t('Taxonomy vocabulary created properly.'), 'TaxonomyVocabularyResource: Create');
   }
 
   /**
-- 
1.7.0.4

