toxmlrpc.inc.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. /**
  3. * Helper functions to convert between ADODB recordset objects and XMLRPC values.
  4. * Uses John Lim's AdoDB and Edd Dumbill's phpxmlrpc libs
  5. *
  6. * @author Daniele Baroncelli
  7. * @author Gaetano Giunta
  8. * @copyright (c) 2003-2004 Giunta/Baroncelli. All rights reserved.
  9. *
  10. * @todo some more error checking here and there
  11. * @todo document the xmlrpc-struct used to encode recordset info
  12. * @todo verify if using xmlrpc_encode($rs->GetArray()) would work with:
  13. * - ADODB_FETCH_BOTH
  14. * - null values
  15. */
  16. /**
  17. * Include the main libraries
  18. */
  19. require_once('xmlrpc.inc');
  20. if (!defined('ADODB_DIR')) require_once('adodb.inc.php');
  21. /**
  22. * Builds an xmlrpc struct value out of an AdoDB recordset
  23. */
  24. function rs2xmlrpcval(&$adodbrs) {
  25. $header = rs2xmlrpcval_header($adodbrs);
  26. $body = rs2xmlrpcval_body($adodbrs);
  27. // put it all together and build final xmlrpc struct
  28. $xmlrpcrs = new xmlrpcval ( array(
  29. "header" => $header,
  30. "body" => $body,
  31. ), "struct");
  32. return $xmlrpcrs;
  33. }
  34. /**
  35. * Builds an xmlrpc struct value describing an AdoDB recordset
  36. */
  37. function rs2xmlrpcval_header($adodbrs)
  38. {
  39. $numfields = $adodbrs->FieldCount();
  40. $numrecords = $adodbrs->RecordCount();
  41. // build structure holding recordset information
  42. $fieldstruct = array();
  43. for ($i = 0; $i < $numfields; $i++) {
  44. $fld = $adodbrs->FetchField($i);
  45. $fieldarray = array();
  46. if (isset($fld->name))
  47. $fieldarray["name"] = new xmlrpcval ($fld->name);
  48. if (isset($fld->type))
  49. $fieldarray["type"] = new xmlrpcval ($fld->type);
  50. if (isset($fld->max_length))
  51. $fieldarray["max_length"] = new xmlrpcval ($fld->max_length, "int");
  52. if (isset($fld->not_null))
  53. $fieldarray["not_null"] = new xmlrpcval ($fld->not_null, "boolean");
  54. if (isset($fld->has_default))
  55. $fieldarray["has_default"] = new xmlrpcval ($fld->has_default, "boolean");
  56. if (isset($fld->default_value))
  57. $fieldarray["default_value"] = new xmlrpcval ($fld->default_value);
  58. $fieldstruct[$i] = new xmlrpcval ($fieldarray, "struct");
  59. }
  60. $fieldcount = new xmlrpcval ($numfields, "int");
  61. $recordcount = new xmlrpcval ($numrecords, "int");
  62. $sql = new xmlrpcval ($adodbrs->sql);
  63. $fieldinfo = new xmlrpcval ($fieldstruct, "array");
  64. $header = new xmlrpcval ( array(
  65. "fieldcount" => $fieldcount,
  66. "recordcount" => $recordcount,
  67. "sql" => $sql,
  68. "fieldinfo" => $fieldinfo
  69. ), "struct");
  70. return $header;
  71. }
  72. /**
  73. * Builds an xmlrpc struct value out of an AdoDB recordset
  74. * (data values only, no data definition)
  75. */
  76. function rs2xmlrpcval_body($adodbrs)
  77. {
  78. $numfields = $adodbrs->FieldCount();
  79. // build structure containing recordset data
  80. $adodbrs->MoveFirst();
  81. $rows = array();
  82. while (!$adodbrs->EOF) {
  83. $columns = array();
  84. // This should work on all cases of fetch mode: assoc, num, both or default
  85. if ($adodbrs->fetchMode == 'ADODB_FETCH_BOTH' || count($adodbrs->fields) == 2 * $adodbrs->FieldCount())
  86. for ($i = 0; $i < $numfields; $i++)
  87. if ($adodbrs->fields[$i] === null)
  88. $columns[$i] = new xmlrpcval ('');
  89. else
  90. $columns[$i] = xmlrpc_encode ($adodbrs->fields[$i]);
  91. else
  92. foreach ($adodbrs->fields as $val)
  93. if ($val === null)
  94. $columns[] = new xmlrpcval ('');
  95. else
  96. $columns[] = xmlrpc_encode ($val);
  97. $rows[] = new xmlrpcval ($columns, "array");
  98. $adodbrs->MoveNext();
  99. }
  100. $body = new xmlrpcval ($rows, "array");
  101. return $body;
  102. }
  103. /**
  104. * Returns an xmlrpc struct value as string out of an AdoDB recordset
  105. */
  106. function rs2xmlrpcstring (&$adodbrs) {
  107. $xmlrpc = rs2xmlrpcval ($adodbrs);
  108. if ($xmlrpc)
  109. return $xmlrpc->serialize();
  110. else
  111. return null;
  112. }
  113. /**
  114. * Given a well-formed xmlrpc struct object returns an AdoDB object
  115. *
  116. * @todo add some error checking on the input value
  117. */
  118. function xmlrpcval2rs (&$xmlrpcval) {
  119. $fields_array = array();
  120. $data_array = array();
  121. // rebuild column information
  122. $header = $xmlrpcval->structmem('header');
  123. $numfields = $header->structmem('fieldcount');
  124. $numfields = $numfields->scalarval();
  125. $numrecords = $header->structmem('recordcount');
  126. $numrecords = $numrecords->scalarval();
  127. $sqlstring = $header->structmem('sql');
  128. $sqlstring = $sqlstring->scalarval();
  129. $fieldinfo = $header->structmem('fieldinfo');
  130. for ($i = 0; $i < $numfields; $i++) {
  131. $temp = $fieldinfo->arraymem($i);
  132. $fld = new ADOFieldObject();
  133. while (list($key,$value) = $temp->structeach()) {
  134. if ($key == "name") $fld->name = $value->scalarval();
  135. if ($key == "type") $fld->type = $value->scalarval();
  136. if ($key == "max_length") $fld->max_length = $value->scalarval();
  137. if ($key == "not_null") $fld->not_null = $value->scalarval();
  138. if ($key == "has_default") $fld->has_default = $value->scalarval();
  139. if ($key == "default_value") $fld->default_value = $value->scalarval();
  140. } // while
  141. $fields_array[] = $fld;
  142. } // for
  143. // fetch recordset information into php array
  144. $body = $xmlrpcval->structmem('body');
  145. for ($i = 0; $i < $numrecords; $i++) {
  146. $data_array[$i]= array();
  147. $xmlrpcrs_row = $body->arraymem($i);
  148. for ($j = 0; $j < $numfields; $j++) {
  149. $temp = $xmlrpcrs_row->arraymem($j);
  150. $data_array[$i][$j] = $temp->scalarval();
  151. } // for j
  152. } // for i
  153. // finally build in-memory recordset object and return it
  154. $rs = new ADORecordSet_array();
  155. $rs->InitArrayFields($data_array,$fields_array);
  156. return $rs;
  157. }