2011-11-01 10:45:02 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of BeSimpleSoapCommon.
|
|
|
|
*
|
|
|
|
* (c) Christian Kerl <christian-kerl@web.de>
|
|
|
|
* (c) Francis Besset <francis.besset@gmail.com>
|
|
|
|
*
|
|
|
|
* This source file is subject to the MIT license that is bundled
|
|
|
|
* with this source code in the file LICENSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace BeSimple\SoapCommon;
|
|
|
|
|
2011-12-04 15:38:23 +01:00
|
|
|
use BeSimple\SoapCommon\Helper;
|
|
|
|
|
2011-11-01 10:45:02 +01:00
|
|
|
/**
|
|
|
|
* This class loads the given WSDL file and allows to check MIME binding
|
|
|
|
* information.
|
|
|
|
*
|
|
|
|
* @author Andreas Schamberger <mail@andreass.net>
|
|
|
|
*/
|
|
|
|
class WsdlHandler
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Binding type 'input' .
|
|
|
|
*/
|
|
|
|
const BINDING_OPERATION_INPUT = 'input';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Binding type 'output' .
|
|
|
|
*/
|
|
|
|
const BINDING_OPERATION_OUTPUT = 'output';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* WSDL file name.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
private $wsdlFile;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* DOMDocument WSDL file.
|
|
|
|
*
|
|
|
|
* @var \DOMDocument
|
|
|
|
*/
|
|
|
|
private $domDocument;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* DOMXPath WSDL file.
|
|
|
|
*
|
|
|
|
* @var DOMXPath
|
|
|
|
*/
|
|
|
|
private $domXpath;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Array of mime type information.
|
|
|
|
*
|
|
|
|
* @var array(string=>array(string=>array(string=>array(string))))
|
|
|
|
*/
|
|
|
|
private $mimeTypes = array();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* WSDL namespace of current WSDL file.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
private $wsdlSoapNamespace;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param string $wsdlFile WSDL file name
|
|
|
|
* @param string $soapVersion SOAP version constant
|
|
|
|
*/
|
|
|
|
public function __construct($wsdlFile, $soapVersion)
|
|
|
|
{
|
|
|
|
$this->wsdlFile = $wsdlFile;
|
|
|
|
if ($soapVersion == SOAP_1_1) {
|
2011-12-04 15:38:23 +01:00
|
|
|
$this->wsdlSoapNamespace = Helper::NS_WSDL_SOAP_1_1;
|
2011-11-01 10:45:02 +01:00
|
|
|
} else {
|
2011-12-04 15:38:23 +01:00
|
|
|
$this->wsdlSoapNamespace = Helper::NS_WSDL_SOAP_1_2;
|
2011-11-01 10:45:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the mime type information from the WSDL file.
|
|
|
|
*
|
|
|
|
* @param string $soapAction Soap action to analyse
|
2011-12-17 16:25:49 +01:00
|
|
|
*
|
2011-11-01 10:45:02 +01:00
|
|
|
* @return array(string=>array(string=>array(string)))
|
|
|
|
*/
|
|
|
|
private function getMimeTypesForSoapAction($soapAction)
|
|
|
|
{
|
|
|
|
$query = '/wsdl:definitions/wsdl:binding/wsdl:operation/soap:operation[@soapAction="'.$soapAction.'"]/..';
|
|
|
|
$nodes = $this->domXpath->query($query);
|
|
|
|
$mimeTypes = array();
|
2011-12-04 17:29:50 +01:00
|
|
|
if (null !== $wsdlOperation = $nodes->item(0)) {
|
2011-11-01 10:45:02 +01:00
|
|
|
//$wsdlOperationName = $wsdlOperation->getAttribute('name');
|
|
|
|
foreach ($wsdlOperation->childNodes as $soapOperationChild) {
|
|
|
|
// wsdl:input or wsdl:output
|
|
|
|
if ($soapOperationChild->localName == 'input' || $soapOperationChild->localName == 'output') {
|
|
|
|
$operationType = $soapOperationChild->localName;
|
|
|
|
// mime:multipartRelated/mime:part
|
2011-12-04 15:38:23 +01:00
|
|
|
$mimeParts = $soapOperationChild->getElementsByTagNameNS(Helper::NS_WSDL_MIME, 'part');
|
2011-11-01 10:45:02 +01:00
|
|
|
if ($mimeParts->length > 0) {
|
|
|
|
foreach ($mimeParts as $mimePart) {
|
|
|
|
foreach ($mimePart->childNodes as $child) {
|
|
|
|
switch ($child->localName) {
|
|
|
|
case 'body':
|
|
|
|
$parts = $child->getAttribute('parts');
|
|
|
|
$parts = ($parts == '') ? '[body]' : $parts;
|
|
|
|
$mimeTypes[$operationType][$parts] = array('text/xml');
|
|
|
|
break;
|
|
|
|
case 'content':
|
|
|
|
$part = $child->getAttribute('part');
|
|
|
|
$part = ($part == '') ? null : $part;
|
|
|
|
$type = $child->getAttribute('type');
|
|
|
|
$type = ($type == '') ? '*/*' : $type;
|
|
|
|
if (!isset($mimeTypes[$operationType][$part])) {
|
|
|
|
$mimeTypes[$operationType][$part] = array();
|
|
|
|
}
|
|
|
|
$mimeTypes[$operationType][$part][] = $type;
|
|
|
|
break;
|
|
|
|
case 'mimeXml':
|
|
|
|
// this does not conform to the spec
|
|
|
|
$part = $child->getAttribute('part');
|
|
|
|
$part = ($part == '') ? null : $part;
|
|
|
|
$mimeTypes[$operationType][$part] = array('text/xml');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$child = $soapOperationChild->getElementsByTagNameNS($this->wsdlSoapNamespace, 'body')->item(0);
|
2011-12-04 17:29:50 +01:00
|
|
|
if (null !== $child) {
|
2011-11-01 10:45:02 +01:00
|
|
|
$parts = $child->getAttribute('parts');
|
|
|
|
$parts = ($parts == '') ? '[body]' : $parts;
|
|
|
|
$mimeTypes[$operationType][$parts] = array('text/xml');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-04 17:29:50 +01:00
|
|
|
|
2011-11-01 10:45:02 +01:00
|
|
|
return $mimeTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks the mime type of the part for the given operation.
|
|
|
|
*
|
|
|
|
* @param string $soapAction Soap action
|
|
|
|
* @param string $operationType Operation type
|
|
|
|
* @param string $part Part name
|
|
|
|
* @param string $currentMimeType Current mime type
|
2011-12-17 16:25:49 +01:00
|
|
|
*
|
2011-11-01 10:45:02 +01:00
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function isValidMimeTypeType($soapAction, $operationType, $part, $currentMimeType)
|
|
|
|
{
|
2011-11-01 17:17:16 +01:00
|
|
|
// create DOMDocument from WSDL file
|
|
|
|
$this->loadWsdlInDom();
|
2011-11-01 10:45:02 +01:00
|
|
|
// load data from WSDL
|
|
|
|
if (!isset($this->mimeTypes[$soapAction])) {
|
|
|
|
$this->mimeTypes[$soapAction] = $this->getMimeTypesForSoapAction($soapAction);
|
|
|
|
}
|
|
|
|
// part is valid as we do not have an explicit entry for current part
|
|
|
|
if (!isset($this->mimeTypes[$soapAction][$operationType][$part])) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
$mimeTypes = $this->mimeTypes[$soapAction][$operationType][$part];
|
|
|
|
// wildcard or exact match
|
|
|
|
if (in_array('*/*', $mimeTypes) || in_array($currentMimeType, $mimeTypes)) {
|
|
|
|
return true;
|
|
|
|
// type/* match
|
|
|
|
} else {
|
|
|
|
list($ctype, $csubtype) = explode('/', $currentMimeType);
|
|
|
|
foreach ($mimeTypes as $mimeType) {
|
|
|
|
list($type, $subtype) = explode('/', $mimeType);
|
|
|
|
if ($subtype == '*' && $type == $ctype) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-12-04 17:29:50 +01:00
|
|
|
|
2011-11-01 10:45:02 +01:00
|
|
|
return false;
|
|
|
|
}
|
2011-11-01 17:17:16 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads the WSDL file into a DOM
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
private function loadWsdlInDom()
|
|
|
|
{
|
2011-12-04 17:29:50 +01:00
|
|
|
if (null === $this->domDocument) {
|
2011-11-01 17:17:16 +01:00
|
|
|
$this->domDocument = new \DOMDocument('1.0', 'utf-8');
|
|
|
|
$this->domDocument->load($this->wsdlFile);
|
|
|
|
$this->domXpath = new \DOMXPath($this->domDocument);
|
2011-12-04 15:38:23 +01:00
|
|
|
$this->domXpath->registerNamespace('wsdl', Helper::NS_WSDL);
|
|
|
|
$this->domXpath->registerNamespace('mime', Helper::NS_WSDL_MIME);
|
2011-11-01 17:17:16 +01:00
|
|
|
$this->domXpath->registerNamespace('soap', $this->wsdlSoapNamespace);
|
|
|
|
}
|
|
|
|
}
|
2011-11-01 10:45:02 +01:00
|
|
|
}
|