- Модуль: webservice
- Путь к файлу: ~/bitrix/modules/webservice/classes/general/soap/soapresponse.php
- Класс: forCSOAPResponse
- Вызов: CSOAPResponse::decodeDataTypes
function decodeDataTypes( $node, $complexDataTypeName = "" )
{
global $xsd_simple_type;
$returnValue = false;
$attr = $node->getAttribute("type");
if ($attr and mb_strlen($attr))
{
return new CSOAPFault("Server Error", "Server supports only document/literal binding.");
}
$rootDataName = $this->Name;
if(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 not enough 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;
}