end_test('Data encoding (large array)', 'automatic encoding', $out); if (function_exists('xmlrpc_set_type')) { begin_test('Data encoding (large array)', 'xmlrpc-epi encoding'); for ($i = 0; $i < $num_tests; $i++) { for ($j = 0; $j < 10; $j++) { foreach ($keys as $k) { xmlrpc_set_type($data[$j][$k][4], 'datetime'); xmlrpc_set_type($data[$j][$k][8], 'datetime'); } } $out = xmlrpc_encode($data); } end_test('Data encoding (large array)', 'xmlrpc-epi encoding', $out); } // test 'old style' data decoding vs. 'automatic style' decoding $dummy = new Request(''); $out = new Response($value); $in = '<?xml version="1.0" ?>' . "\n" . $out->serialize(); begin_test('Data decoding (large array)', 'manual decoding'); for ($i = 0; $i < $num_tests; $i++) { $response = $dummy->ParseResponse($in, true); $value = $response->value(); $result = array(); foreach ($value as $val1) { $out = array(); foreach ($val1 as $name => $val) { $out[$name] = array(); foreach ($val as $data) { $out[$name][] = $data->scalarval(); } }
public static function _xmlrpcs_multicall_do_call($server, $call) { if ($call->kindOf() != 'struct') { return static::_xmlrpcs_multicall_error('notstruct'); } $methName = @$call['methodName']; if (!$methName) { return static::_xmlrpcs_multicall_error('nomethod'); } if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string') { return static::_xmlrpcs_multicall_error('notstring'); } if ($methName->scalarval() == 'system.multicall') { return static::_xmlrpcs_multicall_error('recursion'); } $params = @$call['params']; if (!$params) { return static::_xmlrpcs_multicall_error('noparams'); } if ($params->kindOf() != 'array') { return static::_xmlrpcs_multicall_error('notarray'); } $req = new Request($methName->scalarval()); foreach ($params as $i => $param) { if (!$req->addParam($param)) { $i++; // for error message, we count params from 1 return static::_xmlrpcs_multicall_error(new Response(0, PhpXmlRpc::$xmlrpcerr['incorrect_params'], PhpXmlRpc::$xmlrpcstr['incorrect_params'] . ": probable xml error in param " . $i)); } } $result = $server->execute($req); if ($result->faultCode() != 0) { return static::_xmlrpcs_multicall_error($result); // Method returned fault. } return new Value(array($result->value()), 'array'); }
/** * Convert the xml representation of a method response, method request or single * xmlrpc value into the appropriate object (a.k.a. deserialize). * * @param string $xmlVal * @param array $options * * @return mixed false on error, or an instance of either Value, Request or Response */ public function decodeXml($xmlVal, $options = array()) { // 'guestimate' encoding $valEncoding = XMLParser::guessEncoding('', $xmlVal); if ($valEncoding != '') { // Since parsing will fail if charset is not specified in the xml prologue, // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that... // The following code might be better for mb_string enabled installs, but // makes the lib about 200% slower... //if (!is_valid_charset($valEncoding, array('UTF-8')) if (!in_array($valEncoding, array('UTF-8', 'US-ASCII')) && !XMLParser::hasEncoding($xmlVal)) { if ($valEncoding == 'ISO-8859-1') { $xmlVal = utf8_encode($xmlVal); } else { if (extension_loaded('mbstring')) { $xmlVal = mb_convert_encoding($xmlVal, 'UTF-8', $valEncoding); } else { error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of xml text: ' . $valEncoding); } } } } $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); // What if internal encoding is not in one of the 3 allowed? // we use the broadest one, ie. utf8! if (!in_array(PhpXmlRpc::$xmlrpc_internalencoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII'))) { xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8'); } else { xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, PhpXmlRpc::$xmlrpc_internalencoding); } $xmlRpcParser = new XMLParser(); xml_set_object($parser, $xmlRpcParser); xml_set_element_handler($parser, 'xmlrpc_se_any', 'xmlrpc_ee'); xml_set_character_data_handler($parser, 'xmlrpc_cd'); xml_set_default_handler($parser, 'xmlrpc_dh'); if (!xml_parse($parser, $xmlVal, 1)) { $errstr = sprintf('XML error: %s at line %d, column %d', xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), xml_get_current_column_number($parser)); error_log($errstr); xml_parser_free($parser); return false; } xml_parser_free($parser); if ($xmlRpcParser->_xh['isf'] > 1) { // test that $xmlrpc->_xh['value'] is an obj, too??? error_log($xmlRpcParser->_xh['isf_reason']); return false; } switch ($xmlRpcParser->_xh['rt']) { case 'methodresponse': $v =& $xmlRpcParser->_xh['value']; if ($xmlRpcParser->_xh['isf'] == 1) { $vc = $v['faultCode']; $vs = $v['faultString']; $r = new Response(0, $vc->scalarval(), $vs->scalarval()); } else { $r = new Response($v); } return $r; case 'methodcall': $req = new Request($xmlRpcParser->_xh['method']); for ($i = 0; $i < count($xmlRpcParser->_xh['params']); $i++) { $req->addParam($xmlRpcParser->_xh['params'][$i]); } return $req; case 'value': return $xmlRpcParser->_xh['value']; default: return false; } }
public function workflow($model, $method, $record_id) { $client = new Client($this->server . "object"); $client->setSSLVerifyPeer(0); $client->return_type = 'phpvals'; $msg = new Request('exec_workflow'); $msg->addParam(new Value($this->database, "string")); //* database name */ $msg->addParam(new Value($this->uid, "int")); /* useid */ $msg->addParam(new Value($this->password, "string")); /** password */ $msg->addParam(new Value($model, "string")); /** model name where operation will held * */ $msg->addParam(new Value($method, "string")); /** method which u like to execute */ $msg->addParam(new Value($record_id, "int")); /** parameters of the methods with values.... */ $resp = $client->send($msg); if ($resp->faultCode()) { return -1; } else { return $resp->value(); } /* return new generated id of record */ }
/** * Attempt to boxcar $reqs via system.multicall. * * Returns either an array of Response, a single error Response or false (when received response does not respect * valid multicall syntax). * * @param Request[] $reqs * @param int $timeout * @param string $method * @return Response[]|bool|mixed|Response */ private function _try_multicall($reqs, $timeout, $method) { // Construct multicall request $calls = array(); foreach ($reqs as $req) { $call['methodName'] = new Value($req->method(), 'string'); $numParams = $req->getNumParams(); $params = array(); for ($i = 0; $i < $numParams; $i++) { $params[$i] = $req->getParam($i); } $call['params'] = new Value($params, 'array'); $calls[] = new Value($call, 'struct'); } $multiCall = new Request('system.multicall'); $multiCall->addParam(new Value($calls, 'array')); // Attempt RPC call $result = $this->send($multiCall, $timeout, $method); if ($result->faultCode() != 0) { // call to system.multicall failed return $result; } // Unpack responses. $rets = $result->value(); if ($this->return_type == 'xml') { return $rets; } elseif ($this->return_type == 'phpvals') { /// @todo test this code branch... $rets = $result->value(); if (!is_array($rets)) { return false; // bad return type from system.multicall } $numRets = count($rets); if ($numRets != count($reqs)) { return false; // wrong number of return values. } $response = array(); for ($i = 0; $i < $numRets; $i++) { $val = $rets[$i]; if (!is_array($val)) { return false; } switch (count($val)) { case 1: if (!isset($val[0])) { return false; // Bad value } // Normal return value $response[$i] = new Response($val[0], 0, '', 'phpvals'); break; case 2: /// @todo remove usage of @: it is apparently quite slow $code = @$val['faultCode']; if (!is_int($code)) { return false; } $str = @$val['faultString']; if (!is_string($str)) { return false; } $response[$i] = new Response(0, $code, $str); break; default: return false; } } return $response; } else { // return type == 'xmlrpcvals' $rets = $result->value(); if ($rets->kindOf() != 'array') { return false; // bad return type from system.multicall } $numRets = $rets->count(); if ($numRets != count($reqs)) { return false; // wrong number of return values. } $response = array(); foreach ($rets as $val) { switch ($val->kindOf()) { case 'array': if ($val->count() != 1) { return false; // Bad value } // Normal return value $response[] = new Response($val[0]); break; case 'struct': $code = $val['faultCode']; if ($code->kindOf() != 'scalar' || $code->scalartyp() != 'int') { return false; } $str = $val['faultString']; if ($str->kindOf() != 'scalar' || $str->scalartyp() != 'string') { return false; } $response[] = new Response(0, $code->scalarval(), $str->scalarval()); break; default: return false; } } return $response; } }