%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/webservice/classes/general/soap/
Upload File :
Create Path :
Current File : //proc/self/root/home/bitrix/www/bitrix/modules/webservice/classes/general/soap/soapresponse.php

<?php

class CSOAPResponse extends CSOAPEnvelope
{
	/// Contains the response value
	var $Value = false;
	var $ValueName = 0;
	/// Contains the response type
	var $Type = false;
	/// Contains fault string
	var $FaultString = false;
	/// Contains the fault code
	var $FaultCode = false;
	/// Contains true if the response was an fault
	var $IsFault = false;
	/// Contains the name of the response, i.e. function call name
	var $Name;
	/// Contains the target namespace for the response
	var $Namespace;

	var $typensVars = array();

	/// Contains the DOM document for the current SOAP response
	var $DOMDocument = false;

	function CSOAPResponse( $name="", $namespace="" )
	{
		$this->Name = $name;
		$this->Namespace = $namespace;

		// call the parents constructor
		$this->CSOAPEnvelope();
	}

	//	Decodes the SOAP response stream
	function decodeStream( $request, $stream )
	{
		global $APPLICATION;

		$stream_cutted = $this->stripHTTPHeader( $stream );
		if ( !$stream_cutted or !class_exists("CDataXML"))
		{
			$APPLICATION->ThrowException("Error: BitrixXMLParser. "
				."Downloaded page: <br>". htmlspecialcharsEx($stream));
			return;
		}

		$stream = $stream_cutted;

		$xml = new CDataXML();

		$stream = $APPLICATION->ConvertCharset($stream, "UTF-8", SITE_CHARSET);
		if (!$xml->LoadString( $stream ))
		{
			$APPLICATION->ThrowException( "Error: Can't parse request xml data. ");
			return;
		}

		$dom = $xml->GetTree();
		$this->DOMDocument = $dom;
		if ( get_class( $dom ) == "CDataXMLDocument" || get_class( $dom ) == "cdataxmldocument")
		{
			// check for fault
			$response = $dom->elementsByName( 'Fault' );

			if ( count( $response ) == 1 )
			{
				$this->IsFault = 1;
				$faultStringArray = $dom->elementsByName( "faultstring" );
				$this->FaultString = $faultStringArray[0]->textContent();

				$faultCodeArray = $dom->elementsByName( "faultcode" );
				$this->FaultCode = $faultCodeArray[0]->textContent();
				return;
			}

			// get the response
			$body = $dom->elementsByName( "Body" );
			$body = $body[0];

			if($body)
			{
				$response = $body->children();
				$response = $response[0];

				if(get_class($response) == "CDataXMLNode" || get_class($response) == "cdataxmlnode")
				{
					/*Cut from the SOAP spec:
					The method response is viewed as a single struct containing an accessor
					for the return value and each [out] or [in/out] parameter.
					The first accessor is the return value followed by the parameters
					in the same order as in the method signature.

					Each parameter accessor has a name corresponding to the name
					of the parameter and type corresponding to the type of the parameter.
					The name of the return value accessor is not significant.
					Likewise, the name of the struct is not significant.
					However, a convention is to name it after the method name
					with the string "Response" appended.
					*/

					$responseAccessors = $response->children();
					//echo '<pre>'; print_r($responseAccessors); echo '</pre>';
					if(count($responseAccessors) > 0)
					{
						$this->Value = array();
						foreach($responseAccessors as $arChild)
						{
							$value = $arChild->decodeDataTypes();
							$this->Value = array_merge($this->Value, $value);
						}
					}
				}
				else
				{
					$APPLICATION->ThrowException("Could not understand type of class decoded");
				}
			}
			else
			{
				$APPLICATION->ThrowException("Wrong XML in response");
			}
		}
		else
		{
			$APPLICATION->ThrowException( "Could not process XML in response" );
		}
	}

	// Decodes a DOM node and returns the PHP datatype instance of it.
	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 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;
	}

	//	  Returns the XML payload for the response.
	function payload( )
	{
		$root = new CXMLCreator("soap:Envelope");
		$root->setAttribute("xmlns:soap", BX_SOAP_ENV);

		// add the body
		$body = new CXMLCreator( "soap:Body" );

		// Check if it's a fault
		if (is_object($this->Value) && ToUpper(get_class($this->Value)) == 'CSOAPFAULT')
		{
			$fault = new CXMLCreator( "soap:Fault" );

			$faultCodeNode = new CXMLCreator( "faultcode" );
			$faultCodeNode->setData($this->Value->faultCode());

			$fault->addChild( $faultCodeNode );

			$faultStringNode = new CXMLCreator( "faultstring" );
			$faultStringNode->setData( $this->Value->faultString() );

			$fault->addChild( $faultStringNode );
			
			if ($this->Value->detail)
				$fault->addChild($this->Value->detail());

			$body->addChild( $fault );
		}
		else
		{
			// add the request
			$responseName = $this->Name . "Response";
			$response = new CXMLCreator( $responseName );
			$response->setAttribute("xmlns", $this->Namespace);
			if (!isset($this->typensVars[$this->Name]["output"]) or !count($this->typensVars[$this->Name]["output"]))
			{
				if (count($this->typensVars))
				{
					$GLOBALS['APPLICATION']->ThrowException("payload() can't find output type declaration.", "SoapRespnose::payload()");
					return;
				}
				else
				{
					//print_r($this->Value);
					//die();
					// EncodeLight
					$value = CXMLCreator::encodeValueLight( $this->ValueName, $this->Value );
				}

				$response->addChild( $value );
			}
			else
			{
				//$return = new CXMLCreator($returnType);
				$valueEncoder = new CSOAPCodec();
				$valueEncoder->setTypensVars($this->typensVars);

				foreach ($this->typensVars[$this->Name]["output"] as $returnType => $returnParam)
				{
					if (!$returnType)
					{
						$GLOBALS['APPLICATION']->ThrowException("payload() can't find output type declaration for {$this->Name}.", "SoapRespnose::payload()");
						return;
					}

					$valueEncoder->setOutputVars($this->Name);

					$value = $valueEncoder->encodeValue($returnType, isset($this->Value[$returnType]) ? $this->Value[$returnType] : $this->Value);

					$response->addChild($value);
				}

				//AddM
			}


			$body->addChild( $response );
		}

		$root->addChild( $body );

		//AddMessage2Log($root->getXML());
		return CXMLCreator::getXMLHeader().$root->getXML();
	}

	//	 Strips the header information from the HTTP raw response.
	function stripHTTPHeader( $data )
	{
		$missingxml = false;
		//$start = strpos( $data, "<"."?xml" );
		$start = strpos( $data, "\r\n\r\n" );
		if ($start === false) return null;
		$data = substr( $data, $start, strlen( $data ) - $start );
		return $data;
	}

	function value()
	{
		return $this->Value;
	}

	function setValue( $value )
	{
		$this->Value = $value;
	}

	function setValueName ( $valname )
	{
		$this->ValueName = $valname;
	}

	function isFault()
	{
		return $this->IsFault;
	}

	function faultCode()
	{
		return $this->FaultCode;
	}

	function faultString()
	{
		return $this->FaultString;
	}

	function setTypensVars($vars)
	{
		$this->typensVars = $vars;
	}
}

?>

Zerion Mini Shell 1.0