function decodeDataTypes($node, $complexDataTypeName = "") { global $xsd_simple_type; $returnValue = false; $attr = $node->getAttribute("type"); if ($attr and strlen($attr)) { return new CSOAPFault("Server Error", "Server supports only document/literal binding."); } $rootDataName = $this->Name; if (strlen(trim($complexDataTypeName))) { $rootDataName = trim($complexDataTypeName); } if (!$rootDataName or !isset($this->typensVars[$rootDataName])) { return new CSOAPFault("Server Error", "decodeDataTypes() can't find function type declaration."); } $name = $node->name(); $typeDeclaration = array(); $dataType = ""; /* * Typen can be: * 1) Whole Complex Data Type * 2) Complex Data Type Part * 3) Input decl * 3) Output decl */ if (isset($this->typensVars[$name])) { $typeDeclaration = $this->typensVars[$name]; } if (isset($this->typensVars[$rootDataName][$name])) { $typeDeclaration = $this->typensVars[$rootDataName][$name]; } else { if (isset($this->typensVars[$rootDataName]["input"][$name])) { $typeDeclaration = $this->typensVars[$rootDataName]["input"][$name]; } else { if (isset($this->typensVars[$rootDataName]["output"][$name])) { $typeDeclaration = $this->typensVars[$rootDataName]["output"][$name]; } } } if (!count($typeDeclaration)) { return new CSOAPFault("Server Error", "decodeDataTypes() can't find type declaration for {$name} param."); } else { if (isset($typeDeclaration["varType"])) { $dataType = $typeDeclaration["varType"]; } else { $dataType = $name; } // case 1 of typens choose. } if (isset($xsd_simple_type[$dataType])) { $dataType = $xsd_simple_type[$dataType]; } switch ($dataType) { case "string": $returnValue = strval($node->textContent()); break; case "integer": $returnValue = intval($node->textContent()); break; case "float": case 'double': $returnValue = $node->textContent(); break; case "boolean": if ($node->textContent() == "true") { $returnValue = true; } else { $returnValue = false; } break; case "base64": case "base64Binary": $returnValue = base64_decode($node->textContent()); break; case "any": $returnValue = $node; break; default: if (isset($typeDeclaration["arrType"])) { // Decode array $maxOccurs = 0; $returnValue = array(); $arrayType = $typeDeclaration["arrType"]; if (isset($typeDeclaration["maxOccursA"])) { $maxOccurs = $typeDeclaration["maxOccursA"]; } if (isset($xsd_simple_type[$arrayType])) { $i = 0; $childs = $node->children(); foreach ($childs as $child) { $i++; $returnValue[] = $child->textContent(); if (intval($maxOccurs) and $i > intval($maxOccurs)) { break; } } } else { foreach ($node->children() as $child) { /* * Mega hack. Usually as name for this used * ArrayOf{STRUCT|CLASS}El. So decoder must have * a chance to find true data type = arrayType; */ if (!isset($this->typensVars[$child->name])) { $child->name = $arrayType; } // Decode complex data type for an array $decoded = $this->decodeDataTypes($child, $arrayType); if (is_object($decoded) and (get_class($decoded) == "CSOAPFault" or get_class($decoded) == "csoapfault")) { CSOAPServer::ShowSOAPFault($decoded); return; } $returnValue[] = $decoded; } } break; } else { // Here we goes with struct, or with class // First, try to find declaration $objectDecl = 0; $returnValue = array(); $params = array(); if (!isset($this->typensVars[$dataType])) { break; } $objectDecl = $this->typensVars[$dataType]; // Type of serialization: class/assoc array $objectClass = null; $serialize = "assoc"; if (isset($objectDecl["serialize"])) { $serialize = $objectDecl["serialize"]; unset($objectDecl["serialize"]); } $requestParams = array(); // reorganize params foreach ($node->children() as $parameterNode) { if (!$parameterNode->name()) { continue; } $requestParams[$parameterNode->name()] = $parameterNode; } foreach ($objectDecl as $pname => $param) { $decoded = null; if (isset($requestParams[$pname])) { $decoded = $this->decodeDataTypes($requestParams[$pname], $dataType); } if (is_object($decoded) and (get_class($decoded) == "CSOAPFault" or get_class($decoded) == "csoapfault")) { CSOAPServer::ShowSOAPFault($decoded); return; } if (!$decoded and (!isset($param["strict"]) or isset($param["strict"]) and $param["strict"] == "strict")) { return new CSOAPFault("Server Error", "Request has no enought params of strict type to be decoded. "); } $params[$pname] = $decoded; } if ($serialize == "class") { $stillValid = true; $classRequest = $params; $params = null; if (class_exists($dataType)) { $objectClass = new $dataType(); if ($objectClass) { $existedVars = get_object_vars($objectClass); foreach ($classRequest as $pname => $value) { if (!is_set($existedVars, $pname)) { $stillValid = false; } $objectClass->{$pname} = $value; } } else { $stillValid = false; } } if ($stillValid) { $params = $objectClass; } } $returnValue = $params; } break; } return $returnValue; }
function ProcessRequestBody(&$cserver, $body) { $functionName = $body->name(); $namespaceURI = $body->namespaceURI(); $requestNode = $body; // If this is request name in functionName, get functionName. if (!in_array($functionName, $this->FunctionList) and isset($this->MessageTags[$functionName])) { $functionName = $this->MessageTags[$functionName]; } if (!in_array($functionName, $this->FunctionList)) { CSOAPServer::ShowSOAPFault("Trying to access unregistered function: " . $functionName); return true; } $objectName = ""; $params = array(); $paramsDecoder = new CSOAPResponse($functionName, $namespaceURI); $paramsDecoder->setTypensVars($this->TypensVars); if (!isset($this->TypensVars[$functionName]) or !isset($this->TypensVars[$functionName]["myclassname"]) or !isset($this->TypensVars[$functionName]["input"])) { CSOAPServer::ShowSOAPFault("Requested function has no type specified: " . $functionName); return true; } $objectName = $this->TypensVars[$functionName]["myclassname"]; $inputParams = $this->TypensVars[$functionName]["input"]; $httpAuth = "N"; if (isset($this->TypensVars[$functionName]["httpauth"])) { $httpAuth = $this->TypensVars[$functionName]["httpauth"]; } if ($httpAuth == "Y" and !CWebService::MethodRequireHTTPAuth($objectName, $functionName)) { CSOAPServer::ShowSOAPFault("Requested function requires HTTP Basic Auth to be done before."); return true; } $requestParams = array(); // reorganize params foreach ($requestNode->children() as $parameterNode) { if (!$parameterNode->name()) { continue; } $requestParams[$parameterNode->name()] = $parameterNode; } // check parameters/decode // check strict params foreach ($inputParams as $pname => $param) { $decoded = null; if (isset($requestParams[$pname])) { $decoded = $paramsDecoder->decodeDataTypes($requestParams[$pname]); } if (is_object($decoded) and (get_class($decoded) == "CSOAPFault" or get_class($decoded) == "csoapfault")) { CSOAPServer::ShowSOAPFault($decoded); return true; } if (!isset($decoded) and (!isset($param["strict"]) or isset($param["strict"]) and $param["strict"] == "strict")) { CSOAPServer::ShowSOAPFault("Request has no enought params of strict type to be decoded. "); return true; } $params[] = $decoded; } //AddMessage2Log(mydump($params)); unset($paramsDecoder); $object = null; if (class_exists($objectName)) { $object = new $objectName(); } if (is_object($object) && method_exists($object, $functionName)) { $this->ShowResponse($cserver, $functionName, $namespaceURI, call_user_func_array(array($object, $functionName), $params)); } else { if (!class_exists($objectName)) { $this->ShowResponse($cserver, $functionName, $namespaceURI, new CSOAPFault('Server Error', 'Object not found')); } else { $this->ShowResponse($cserver, $functionName, $namespaceURI, new CSOAPFault('Server Error', 'Method not found')); } } return true; }
function encodeValue($name, $value, $complexDataTypeName = "") { global $xsd_simple_type; if (!is_array($this->outputVars) or !count($this->outputVars)) { CSOAPServer::ShowSOAPFault("encodeValue() has no Output Data Type Declaration for validation."); exit; } $dataType = ""; $typeDeclaration = ""; if (isset($this->outputVars[$name])) { $typeDeclaration = $this->outputVars[$name]; } else { if (isset($this->typensVars[$name])) { $typeDeclaration = $this->typensVars[$name]; } else { if (isset($this->typensVars[$complexDataTypeName][$name])) { $typeDeclaration = $this->typensVars[$complexDataTypeName][$name]; } } } if (isset($typeDeclaration["varType"])) { // if not, name = complex data type $dataType = $typeDeclaration["varType"]; } else { $dataType = $name; } if (isset($xsd_simple_type[$dataType])) { $dataType = $xsd_simple_type[$dataType]; } // Type validation $this->_validateType($dataType, $value); switch ($dataType) { case "string": $node = new CXMLCreator($name); //$node->setAttribute( "type", BX_SOAP_XSD_PREFIX . ":string" ); $node->setData($value); return $node; break; case "boolean": $node = new CXMLCreator($name); //$node->setAttribute( "type", BX_SOAP_XSD_PREFIX . ":boolean" ); if ($value === true) { $node->setData("true"); } else { $node->setData("false"); } return $node; break; case "integer": $node = new CXMLCreator($name); //$node->setAttribute( "type", BX_SOAP_XSD_PREFIX . ":int" ); $node->setData(intval($value)); return $node; break; case "float": case "double": $node = new CXMLCreator($name); //$node->setAttribute( "type", BX_SOAP_XSD_PREFIX . ":float" ); $node->setData($value); return $node; break; // added by Sigurd // added by Sigurd case "base64": case "base64Binary": $node = new CXMLCreator($name); //$node->setAttribute("type", BX_SOAP_XSD_PREFIX . ":base64Binary" ); $node->setData(base64_encode($value)); return $node; break; case 'any': $node = new CXMLCreator($name); if (is_object($value)) { // $fp = fopen($_SERVER['DOCUMENT_ROOT'].'/ws.log', 'a'); // fwrite($fp, $value->GetTree()."\n"); // fwrite($fp, '===================================='."\r\n"); // fclose($fp); if (get_class($value) == 'CDataXML') { $node->addChild(CXMLCreator::CreateFromDOM($value->GetTree())); } elseif (get_class($value) == 'CDataXMLDocument') { $node->addChild(CXMLCreator::CreateFromDOM($value)); } elseif (get_class($value) == 'CXMLCreator') { $node->addChild($value); } } else { $data = new CDataXML(); if ($data->LoadString($value)) { $node->addChild(CXMLCreator::CreateFromDOM($data->GetTree())); } else { $node->setData($value); } } return $node; break; default: $node = new CXMLCreator($name); if (isset($typeDeclaration["arrType"])) { if (!isset($typeDeclaration["varType"])) { $this->_errorTypeValidation("varType [undef]", $value); } $varType = $typeDeclaration["varType"]; // Decode array $maxOccurs = 0; $arrayType = $typeDeclaration["arrType"]; if (isset($typeDeclaration["maxOccursA"])) { $maxOccurs = $typeDeclaration["maxOccursA"]; } if (isset($xsd_simple_type[$arrayType])) { $i = 0; $arrayType = $xsd_simple_type[$arrayType]; $arrayTypeEl = $varType . "El"; // TODO: non fixed. get El name from wsdl. or decl. if (!is_array($value)) { CSOAPCodec::_errorTypeValidation("Array", $value); } foreach ($value as $valnode) { $i++; $this->_validateType($arrayType, $valnode); $cndata = new CXMLCreator($arrayTypeEl); $cndata->setData($valnode); $node->addChild($cndata); if (intval($maxOccurs) > 0 and $i > $maxOccurs) { break; } } } else { // Complex data type arrays // $arrayType as is. // TODO: non fixed. get $arrayTypeEl name from wsdl. or decl. $i = 0; $arrayTypeEl = $varType . "El"; if (!is_array($value)) { CSOAPCodec::_errorTypeValidation("Array", $value); } foreach ($value as $valnode) { $decoded = null; $i++; $this->_validateType($arrayType, $valnode); $decoded = $this->encodeValue($arrayType, $valnode); $cndata = new CXMLCreator($arrayTypeEl); if ($decoded) { $this->_validateClassType("CXMLCreator", $decoded); $decoded->setName($arrayTypeEl); $node->addChild($decoded); } if (intval($maxOccurs) > 0 and $i > $maxOccurs) { break; } } } } else { // Here we goes with struct, or with class // First, try to find declaration $objectDecl = 0; $returnValue = array(); $params = array(); if (!isset($this->typensVars[$dataType])) { break; } $objectDecl = $this->typensVars[$dataType]; if (!$objectDecl) { CSOAPServer::ShowSOAPFault("encodeValue() cant find complex type declaration for {$dataType}."); exit; } // Type of serialization: class/assoc array $objectClass = null; $serialize = "assoc"; if (isset($objectDecl["serialize"])) { $serialize = $objectDecl["serialize"]; unset($objectDecl["serialize"]); } // Validate hard complex data types if ($serialize == "assoc") { $this->_validateType("array", $value); } if ($serialize != "assoc") { $this->_validateClassType($dataType, $value); } foreach ($objectDecl as $pname => $param) { $decoded = null; $strict = true; if (isset($param["strict"])) { $strict = $param["strict"] == "strict" ? true : false; } if ($serialize == "assoc") { //var_dump($pname); var_dump($value[$pname]); die(); if (isset($value[$pname])) { $decoded = $this->encodeValue($pname, $value[$pname], $dataType); } } else { if ($serialize != "assoc") { if (isset($value->{$pname})) { $decoded = $this->encodeValue($pname, $value->{$pname}, $dataType); } } } if ($decoded) { $this->_validateClassType("CXMLCreator", $decoded); } if (!$decoded and !$strict) { CSOAPServer::ShowSOAPFault("Request has no enought params of strict type to be decoded. "); exit; } $node->addChild($decoded); } } return $node; break; } return false; }