• Модуль: 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;
}