Merge pull request #5 from aschamberger/master
Interfaces for processing SoapRequest/SoapResponse in Client/Server #2
This commit is contained in:
commit
f6a0dcf9a7
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapClient.
|
||||
*
|
||||
* (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\Converter;
|
||||
|
||||
use BeSimple\SoapCommon\Helper;
|
||||
use BeSimple\SoapCommon\Mime\Part as MimePart;
|
||||
use BeSimple\SoapCommon\SoapKernel;
|
||||
use BeSimple\SoapCommon\Converter\SoapKernelAwareInterface;
|
||||
use BeSimple\SoapCommon\Converter\TypeConverterInterface;
|
||||
|
||||
/**
|
||||
* MTOM type converter.
|
||||
*
|
||||
* @author Andreas Schamberger <mail@andreass.net>
|
||||
*/
|
||||
class MtomTypeConverter implements TypeConverterInterface, SoapKernelAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var \BeSimple\SoapCommon\SoapKernel $soapKernel SoapKernel instance
|
||||
*/
|
||||
protected $soapKernel = null;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getTypeNamespace()
|
||||
{
|
||||
return 'http://www.w3.org/2001/XMLSchema';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getTypeName()
|
||||
{
|
||||
return 'base64Binary';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function convertXmlToPhp($data)
|
||||
{
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadXML($data);
|
||||
|
||||
$includes = $doc->getElementsByTagNameNS(Helper::NS_XOP, 'Include');
|
||||
$include = $includes->item(0);
|
||||
|
||||
// convert href -> myhref for external references as PHP throws exception in this case
|
||||
// http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/ext/soap/php_encoding.c?view=markup#l3436
|
||||
$ref = $include->getAttribute('myhref');
|
||||
|
||||
if ('cid:' === substr($ref, 0, 4)) {
|
||||
$contentId = urldecode(substr($ref, 4));
|
||||
|
||||
if (null !== ($part = $this->soapKernel->getAttachment($contentId))) {
|
||||
|
||||
return $part->getContent();
|
||||
} else {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function convertPhpToXml($data)
|
||||
{
|
||||
$part = new MimePart($data);
|
||||
$contentId = trim($part->getHeader('Content-ID'), '<>');
|
||||
|
||||
$this->soapKernel->addAttachment($part);
|
||||
|
||||
$doc = new \DOMDocument();
|
||||
$node = $doc->createElement($this->getTypeName());
|
||||
$doc->appendChild($node);
|
||||
|
||||
// add xop:Include element
|
||||
$xinclude = $doc->createElementNS(Helper::NS_XOP, Helper::PFX_XOP . ':Include');
|
||||
$xinclude->setAttribute('href', 'cid:' . $contentId);
|
||||
$node->appendChild($xinclude);
|
||||
|
||||
return $doc->saveXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setKernel(SoapKernel $soapKernel)
|
||||
{
|
||||
$this->soapKernel = $soapKernel;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the 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\Converter;
|
||||
|
||||
use BeSimple\SoapCommon\SoapKernel;
|
||||
|
||||
/**
|
||||
* Internal type converter interface.
|
||||
*
|
||||
* @author Andreas Schamberger <mail@andreass.net>
|
||||
*/
|
||||
interface SoapKernelAwareInterface
|
||||
{
|
||||
/**
|
||||
* Set SoapKernel instance.
|
||||
*
|
||||
* @param \BeSimple\SoapCommon\SoapKernel $soapKernel SoapKernel instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function setKernel(SoapKernel $soapKernel);
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapClient.
|
||||
*
|
||||
* (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\Converter;
|
||||
|
||||
use BeSimple\SoapCommon\Helper;
|
||||
use BeSimple\SoapCommon\Mime\Part as MimePart;
|
||||
use BeSimple\SoapCommon\SoapKernel;
|
||||
use BeSimple\SoapCommon\Converter\SoapKernelAwareInterface;
|
||||
use BeSimple\SoapCommon\Converter\TypeConverterInterface;
|
||||
|
||||
/**
|
||||
* SwA type converter.
|
||||
*
|
||||
* @author Andreas Schamberger <mail@andreass.net>
|
||||
*/
|
||||
class SwaTypeConverter implements TypeConverterInterface, SoapKernelAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var \BeSimple\SoapCommon\SoapKernel $soapKernel SoapKernel instance
|
||||
*/
|
||||
protected $soapKernel = null;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getTypeNamespace()
|
||||
{
|
||||
return 'http://www.w3.org/2001/XMLSchema';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getTypeName()
|
||||
{
|
||||
return 'base64Binary';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function convertXmlToPhp($data)
|
||||
{
|
||||
$doc = new \DOMDocument();
|
||||
$doc->loadXML($data);
|
||||
|
||||
// convert href -> myhref for external references as PHP throws exception in this case
|
||||
// http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/ext/soap/php_encoding.c?view=markup#l3436
|
||||
$ref = $doc->documentElement->getAttribute('myhref');
|
||||
|
||||
if ('cid:' === substr($ref, 0, 4)) {
|
||||
$contentId = urldecode(substr($ref, 4));
|
||||
|
||||
if (null !== ($part = $this->soapKernel->getAttachment($contentId))) {
|
||||
|
||||
return $part->getContent();
|
||||
} else {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function convertPhpToXml($data)
|
||||
{
|
||||
$part = new MimePart($data);
|
||||
$contentId = trim($part->getHeader('Content-ID'), '<>');
|
||||
|
||||
$this->soapKernel->addAttachment($part);
|
||||
|
||||
return sprintf('<%s href="%s"/>', $this->getTypeName(), $contentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setKernel(SoapKernel $soapKernel)
|
||||
{
|
||||
$this->soapKernel = $soapKernel;
|
||||
}
|
||||
}
|
|
@ -13,15 +13,41 @@
|
|||
namespace BeSimple\SoapCommon\Converter;
|
||||
|
||||
/**
|
||||
* Type converter interface.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
*/
|
||||
interface TypeConverterInterface
|
||||
{
|
||||
/**
|
||||
* Get type namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getTypeNamespace();
|
||||
|
||||
/**
|
||||
* Get type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getTypeName();
|
||||
|
||||
/**
|
||||
* Convert given XML string to PHP type.
|
||||
*
|
||||
* @param string $data XML string
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function convertXmlToPhp($data);
|
||||
|
||||
/**
|
||||
* Convert PHP type to XML string.
|
||||
*
|
||||
* @param mixed $data PHP type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function convertPhpToXml($data);
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapClient.
|
||||
*
|
||||
* (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;
|
||||
|
||||
/**
|
||||
* Soap request/response filter helper for manipulating SOAP messages.
|
||||
*
|
||||
* @author Andreas Schamberger <mail@andreass.net>
|
||||
*/
|
||||
class FilterHelper
|
||||
{
|
||||
/**
|
||||
* DOMDocument on which the helper functions operate.
|
||||
*
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
protected $domDocument = null;
|
||||
|
||||
/**
|
||||
* Namespaces added.
|
||||
*
|
||||
* @var array(string=>string)
|
||||
*/
|
||||
protected $namespaces = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \DOMDocument $domDocument SOAP document
|
||||
*/
|
||||
public function __construct(\DOMDocument $domDocument)
|
||||
{
|
||||
$this->domDocument = $domDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new soap header.
|
||||
*
|
||||
* @param \DOMElement $node DOMElement to add
|
||||
* @param boolean $mustUnderstand SOAP header mustUnderstand attribute
|
||||
* @param string $actor SOAP actor/role
|
||||
* @param string $soapVersion SOAP version SOAP_1_1|SOAP_1_2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addHeaderElement(\DOMElement $node, $mustUnderstand = null, $actor = null, $soapVersion = SOAP_1_1)
|
||||
{
|
||||
$root = $this->domDocument->documentElement;
|
||||
$namespace = $root->namespaceURI;
|
||||
$prefix = $root->prefix;
|
||||
if (null !== $mustUnderstand) {
|
||||
$node->appendChild(new \DOMAttr($prefix . ':mustUnderstand', (int) $mustUnderstand));
|
||||
}
|
||||
if (null !== $actor) {
|
||||
$attributeName = ($soapVersion == SOAP_1_1) ? 'actor' : 'role';
|
||||
$node->appendChild(new \DOMAttr($prefix . ':' . $attributeName, $actor));
|
||||
}
|
||||
$nodeListHeader = $root->getElementsByTagNameNS($namespace, 'Header');
|
||||
// add header if not there
|
||||
if ($nodeListHeader->length == 0) {
|
||||
// new header element
|
||||
$header = $this->domDocument->createElementNS($namespace, $prefix . ':Header');
|
||||
// try to add it before body
|
||||
$nodeListBody = $root->getElementsByTagNameNS($namespace, 'Body');
|
||||
if ($nodeListBody->length == 0) {
|
||||
$root->appendChild($header);
|
||||
} else {
|
||||
$body = $nodeListBody->item(0);
|
||||
$header = $body->parentNode->insertBefore($header, $body);
|
||||
}
|
||||
$header->appendChild($node);
|
||||
} else {
|
||||
$nodeListHeader->item(0)->appendChild($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new soap body element.
|
||||
*
|
||||
* @param \DOMElement $node DOMElement to add
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addBodyElement(\DOMElement $node)
|
||||
{
|
||||
$root = $this->domDocument->documentElement;
|
||||
$namespace = $root->namespaceURI;
|
||||
$prefix = $root->prefix;
|
||||
$nodeList = $this->domDocument->getElementsByTagNameNS($namespace, 'Body');
|
||||
// add body if not there
|
||||
if ($nodeList->length == 0) {
|
||||
// new body element
|
||||
$body = $this->domDocument->createElementNS($namespace, $prefix . ':Body');
|
||||
$root->appendChild($body);
|
||||
$body->appendChild($node);
|
||||
} else {
|
||||
$nodeList->item(0)->appendChild($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new namespace to root tag.
|
||||
*
|
||||
* @param string $prefix Namespace prefix
|
||||
* @param string $namespaceURI Namespace URI
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($prefix, $namespaceURI)
|
||||
{
|
||||
if (!isset($this->namespaces[$namespaceURI])) {
|
||||
$root = $this->domDocument->documentElement;
|
||||
$root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $prefix, $namespaceURI);
|
||||
$this->namespaces[$namespaceURI] = $prefix;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new element for given namespace.
|
||||
*
|
||||
* @param string $namespaceURI Namespace URI
|
||||
* @param string $name Element name
|
||||
* @param string $value Element value
|
||||
*
|
||||
* @return \DOMElement
|
||||
*/
|
||||
public function createElement($namespaceURI, $name, $value = null)
|
||||
{
|
||||
$prefix = $this->namespaces[$namespaceURI];
|
||||
|
||||
return $this->domDocument->createElementNS($namespaceURI, $prefix . ':' . $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new attribute to element with given namespace.
|
||||
*
|
||||
* @param \DOMElement $element DOMElement to edit
|
||||
* @param string $namespaceURI Namespace URI
|
||||
* @param string $name Attribute name
|
||||
* @param string $value Attribute value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAttribute(\DOMElement $element, $namespaceURI, $name, $value)
|
||||
{
|
||||
if (null !== $namespaceURI) {
|
||||
$prefix = $this->namespaces[$namespaceURI];
|
||||
$element->setAttributeNS($namespaceURI, $prefix . ':' . $name, $value);
|
||||
} else {
|
||||
$element->setAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register namespace.
|
||||
*
|
||||
* @param string $prefix Namespace prefix
|
||||
* @param string $namespaceURI Namespace URI
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerNamespace($prefix, $namespaceURI)
|
||||
{
|
||||
if (!isset($this->namespaces[$namespaceURI])) {
|
||||
$this->namespaces[$namespaceURI] = $prefix;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -191,6 +191,7 @@ class Helper
|
|||
* Get SOAP namespace for the given $version.
|
||||
*
|
||||
* @param int $version SOAP_1_1|SOAP_1_2
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getSoapNamespace($version)
|
||||
|
@ -206,6 +207,7 @@ class Helper
|
|||
* Get SOAP version from namespace URI.
|
||||
*
|
||||
* @param string $namespace NS_SOAP_1_1|NS_SOAP_1_2
|
||||
*
|
||||
* @return int SOAP_1_1|SOAP_1_2
|
||||
*/
|
||||
public static function getSoapVersionFromNamespace($namespace)
|
||||
|
|
|
@ -46,6 +46,7 @@ class MultiPart extends PartHeader
|
|||
* Construct new mime object.
|
||||
*
|
||||
* @param string $boundary Boundary string
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($boundary = null)
|
||||
|
@ -64,6 +65,7 @@ class MultiPart extends PartHeader
|
|||
* Get mime message of this object (without headers).
|
||||
*
|
||||
* @param boolean $withHeaders Returned mime message contains headers
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMimeMessage($withHeaders = false)
|
||||
|
@ -106,6 +108,7 @@ class MultiPart extends PartHeader
|
|||
*
|
||||
* @param \BeSimple\SoapCommon\Mime\Part $part Part that is added
|
||||
* @param boolean $isMain Is the given part the main part of mime message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPart(Part $part, $isMain = false)
|
||||
|
@ -124,6 +127,7 @@ class MultiPart extends PartHeader
|
|||
* parameter.
|
||||
*
|
||||
* @param string $contentId Content id of desired part
|
||||
*
|
||||
* @return \BeSimple\SoapCommon\Mime\Part|null
|
||||
*/
|
||||
public function getPart($contentId = null)
|
||||
|
@ -141,6 +145,7 @@ class MultiPart extends PartHeader
|
|||
* Get all parts.
|
||||
*
|
||||
* @param boolean $includeMainPart Should main part be in result set
|
||||
*
|
||||
* @return array(\BeSimple\SoapCommon\Mime\Part)
|
||||
*/
|
||||
public function getParts($includeMainPart = false)
|
||||
|
|
|
@ -24,6 +24,7 @@ class Parser
|
|||
*
|
||||
* @param string $mimeMessage Mime message string
|
||||
* @param array(string=>string) $headers Array of header elements (e.g. coming from http request)
|
||||
*
|
||||
* @return \BeSimple\SoapCommon\Mime\MultiPart
|
||||
*/
|
||||
public static function parseMimeMessage($mimeMessage, array $headers = array())
|
||||
|
@ -31,6 +32,8 @@ class Parser
|
|||
$boundary = null;
|
||||
$start = null;
|
||||
$multipart = new MultiPart();
|
||||
$hitFirstBoundary = false;
|
||||
$inHeader = true;
|
||||
// add given headers, e.g. coming from HTTP headers
|
||||
if (count($headers) > 0) {
|
||||
foreach ($headers as $name => $value) {
|
||||
|
@ -42,12 +45,11 @@ class Parser
|
|||
$multipart->setHeader($name, $value);
|
||||
}
|
||||
}
|
||||
$inHeader = false;
|
||||
}
|
||||
$hitFirstBoundary = false;
|
||||
$inHeader = true;
|
||||
$content = '';
|
||||
$currentPart = $multipart;
|
||||
$lines = preg_split("/\r\n|\n/", $mimeMessage);
|
||||
$lines = preg_split("/(\r\n)/", $mimeMessage);
|
||||
foreach ($lines as $line) {
|
||||
// ignore http status code and POST *
|
||||
if (substr($line, 0, 5) == 'HTTP/' || substr($line, 0, 4) == 'POST') {
|
||||
|
@ -72,7 +74,7 @@ class Parser
|
|||
unset($currentHeader);
|
||||
}
|
||||
if ($inHeader) {
|
||||
if ($line == '') {
|
||||
if (trim($line) == '') {
|
||||
$inHeader = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -83,7 +85,7 @@ class Parser
|
|||
if (strlen($line) > 0 && $line[0] == "-") {
|
||||
if (strcmp(trim($line), '--' . $boundary) === 0) {
|
||||
if ($currentPart instanceof Part) {
|
||||
$content = iconv_substr($content, 0, -2, 'utf-8');
|
||||
$content = substr($content, 0, -2);
|
||||
self::decodeContent($currentPart, $content);
|
||||
// check if there is a start parameter given, if not set first part
|
||||
$isMain = (is_null($start) || $start == $currentPart->getHeader('Content-ID')) ? true : false;
|
||||
|
@ -97,7 +99,7 @@ class Parser
|
|||
$inHeader = true;
|
||||
$content = '';
|
||||
} elseif (strcmp(trim($line), '--' . $boundary . '--') === 0) {
|
||||
$content = iconv_substr($content, 0, -2, 'utf-8');
|
||||
$content = substr($content, 0, -2);
|
||||
self::decodeContent($currentPart, $content);
|
||||
// check if there is a start parameter given, if not set first part
|
||||
$isMain = (is_null($start) || $start == $currentPart->getHeader('Content-ID')) ? true : false;
|
||||
|
@ -109,7 +111,7 @@ class Parser
|
|||
}
|
||||
} else {
|
||||
if ($hitFirstBoundary === false) {
|
||||
if ($line != '') {
|
||||
if (trim($line) != '') {
|
||||
$inHeader = true;
|
||||
$currentHeader = $line;
|
||||
continue;
|
||||
|
@ -118,7 +120,6 @@ class Parser
|
|||
$content .= $line . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $multipart;
|
||||
}
|
||||
|
@ -133,6 +134,7 @@ class Parser
|
|||
* @param \BeSimple\SoapCommon\Mime\PartHeader $part Header part
|
||||
* @param string $headerName Header name
|
||||
* @param string $headerValue Header value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private static function parseContentTypeHeader(PartHeader $part, $headerName, $headerValue)
|
||||
|
@ -165,6 +167,7 @@ class Parser
|
|||
*
|
||||
* @param \BeSimple\SoapCommon\Mime\Part $part Part to add content
|
||||
* @param string $content Content to decode
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
private static function decodeContent(Part $part, $content)
|
||||
|
|
|
@ -68,6 +68,7 @@ class Part extends PartHeader
|
|||
* @param string $charset Charset
|
||||
* @param string $encoding Encoding
|
||||
* @param string $contentId Content id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($content = null, $contentType = 'application/octet-stream', $charset = null, $encoding = self::ENCODING_BINARY, $contentId = null)
|
||||
|
@ -76,7 +77,7 @@ class Part extends PartHeader
|
|||
$this->setHeader('Content-Type', $contentType);
|
||||
if (!is_null($charset)) {
|
||||
$this->setHeader('Content-Type', 'charset', $charset);
|
||||
} else { // if (substr($contentType, 0, 4) == 'text') {
|
||||
} else {
|
||||
$this->setHeader('Content-Type', 'charset', 'utf-8');
|
||||
}
|
||||
$this->setHeader('Content-Transfer-Encoding', $encoding);
|
||||
|
@ -110,6 +111,7 @@ class Part extends PartHeader
|
|||
* Set mime content.
|
||||
*
|
||||
* @param mixed $content Content to set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setContent($content)
|
||||
|
@ -147,6 +149,7 @@ class Part extends PartHeader
|
|||
case self::ENCODING_QUOTED_PRINTABLE:
|
||||
return quoted_printable_encode($content);
|
||||
case self::ENCODING_BINARY:
|
||||
return $content;
|
||||
case self::ENCODING_SEVEN_BIT:
|
||||
case self::ENCODING_EIGHT_BIT:
|
||||
default:
|
||||
|
|
|
@ -32,6 +32,7 @@ abstract class PartHeader
|
|||
* @param string $name Header name
|
||||
* @param string $value Header value
|
||||
* @param string $subValue Is sub value?
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHeader($name, $value, $subValue = null)
|
||||
|
@ -57,6 +58,7 @@ abstract class PartHeader
|
|||
*
|
||||
* @param string $name Header name
|
||||
* @param string $subValue Sub value name
|
||||
*
|
||||
* @return mixed|array(mixed)
|
||||
*/
|
||||
public function getHeader($name, $subValue = null)
|
||||
|
@ -104,6 +106,7 @@ abstract class PartHeader
|
|||
* Generates a header field value from the given value paramater.
|
||||
*
|
||||
* @param array(string=>string)|string $value Header value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateHeaderFieldValue($value)
|
||||
|
@ -129,6 +132,7 @@ abstract class PartHeader
|
|||
* "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" / <"> / "/" / "[" / "]" / "?" / "="
|
||||
*
|
||||
* @param string $string String to quote
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function quoteValueString($string)
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapCommon.
|
||||
*
|
||||
* (c) Christian Kerl <christian-kerl@web.de>
|
||||
* (c) Francis Besset <francis.besset@gmail.com>
|
||||
* (c) Andreas Schamberger <mail@andreass.net>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\Mime\Part as MimePart;
|
||||
|
||||
use BeSimple\SoapCommon\Converter\MtomTypeConverter;
|
||||
use BeSimple\SoapCommon\Converter\SwaTypeConverter;
|
||||
use BeSimple\SoapCommon\SoapRequest;
|
||||
use BeSimple\SoapCommon\SoapResponse;
|
||||
use BeSimple\SoapCommon\SoapRequestFilter;
|
||||
use BeSimple\SoapCommon\SoapResponseFilter;
|
||||
|
||||
/**
|
||||
* SoapKernel provides methods to pre- and post-process SoapRequests and SoapResponses using
|
||||
* chains of SoapRequestFilter and SoapResponseFilter objects (roughly following
|
||||
* the chain-of-responsibility pattern).
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
*/
|
||||
class SoapKernel
|
||||
{
|
||||
/**
|
||||
* Mime attachments.
|
||||
*
|
||||
* @var array(\BeSimple\SoapCommon\Mime\Part)
|
||||
*/
|
||||
protected $attachments = array();
|
||||
|
||||
/**
|
||||
* Request filters.
|
||||
*
|
||||
* @var array(SoapRequestFilter)
|
||||
*/
|
||||
private $requestFilters = array();
|
||||
|
||||
/**
|
||||
* Response filters.
|
||||
*
|
||||
* @var array(SoapResponseFilter)
|
||||
*/
|
||||
private $responseFilters = array();
|
||||
|
||||
/**
|
||||
* Add attachment.
|
||||
*
|
||||
* @param \BeSimple\SoapCommon\Mime\Part $attachment New attachment
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addAttachment(MimePart $attachment)
|
||||
{
|
||||
$contentId = trim($attachment->getHeader('Content-ID'), '<>');
|
||||
|
||||
$this->attachments[$contentId] = $attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachment and remove from array.
|
||||
*
|
||||
* @param string $contentId Content ID of attachment
|
||||
*
|
||||
* @return \BeSimple\SoapCommon\Mime\Part|null
|
||||
*/
|
||||
public function getAttachment($contentId)
|
||||
{
|
||||
if (isset($this->attachments[$contentId])) {
|
||||
$part = $this->attachments[$contentId];
|
||||
unset($this->attachments[$contentId]);
|
||||
|
||||
return $part;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given object either as filter for SoapRequests or as filter for SoapResponses
|
||||
* or as filter for both depending on the implemented interfaces. Inner filters have to be registered
|
||||
* before outer filters. This means the order is as follows: RequestFilter2->RequestFilter1 and
|
||||
* ResponseFilter1->ResponseFilter2.
|
||||
*
|
||||
* TODO: add priority mechanism to ensure correct order of filters
|
||||
*
|
||||
* @param SoapRequestFilter|SoapResponseFilter $filter Filter to register
|
||||
*/
|
||||
public function registerFilter($filter)
|
||||
{
|
||||
if ($filter instanceof SoapRequestFilter) {
|
||||
array_unshift($this->requestFilters, $filter);
|
||||
}
|
||||
|
||||
if ($filter instanceof SoapResponseFilter) {
|
||||
array_push($this->responseFilters, $filter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all registered SoapRequestFilter to the given SoapRequest.
|
||||
*
|
||||
* @param SoapRequest $request Soap request
|
||||
*/
|
||||
public function filterRequest(SoapRequest $request)
|
||||
{
|
||||
$request->setAttachments($this->attachments);
|
||||
$this->attachments = array();
|
||||
|
||||
foreach ($this->requestFilters as $filter) {
|
||||
$filter->filterRequest($request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all registered SoapResponseFilter to the given SoapResponse.
|
||||
*
|
||||
* @param SoapResponse $response SOAP response
|
||||
*/
|
||||
public function filterResponse(SoapResponse $response)
|
||||
{
|
||||
foreach ($this->responseFilters as $filter) {
|
||||
$filter->filterResponse($response);
|
||||
}
|
||||
|
||||
$this->attachments = $response->getAttachments();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapCommon.
|
||||
*
|
||||
* (c) Christian Kerl <christian-kerl@web.de>
|
||||
* (c) Francis Besset <francis.besset@gmail.com>
|
||||
* (c) Andreas Schamberger <mail@andreass.net>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\Mime\Part as MimePart;
|
||||
|
||||
/**
|
||||
* Base class for SoapRequest and SoapResponse.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
* @author Andreas Schamberger <mail@andreass.net>
|
||||
*/
|
||||
abstract class SoapMessage
|
||||
{
|
||||
/**
|
||||
* $_SERVER key for 'Content-Type' header.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const CONTENT_TYPE_HEADER = 'CONTENT_TYPE';
|
||||
|
||||
/**
|
||||
* $_SERVER key for 'SOAPAction' header.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SOAP_ACTION_HEADER = 'HTTP_SOAPACTION';
|
||||
|
||||
/**
|
||||
* Content types for SOAP versions.
|
||||
*
|
||||
* @var array(string=>string)
|
||||
*/
|
||||
static protected $versionToContentTypeMap = array(
|
||||
SOAP_1_1 => 'text/xml; charset=utf-8',
|
||||
SOAP_1_2 => 'application/soap+xml; charset=utf-8'
|
||||
);
|
||||
|
||||
/**
|
||||
* SOAP action.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $action;
|
||||
|
||||
/**
|
||||
* Mime attachments.
|
||||
*
|
||||
* @var array(\BeSimple\SoapCommon\Mime\Part)
|
||||
*/
|
||||
protected $attachments = array();
|
||||
|
||||
/**
|
||||
* Message content (MIME Message or SOAP Envelope).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
*
|
||||
* Enter description here ...
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
protected $contentDomDocument = null;
|
||||
|
||||
/**
|
||||
* Message content type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contentType;
|
||||
|
||||
/**
|
||||
* Service location.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $location;
|
||||
|
||||
/**
|
||||
* SOAP version (SOAP_1_1|SOAP_1_2)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* Get content type for given SOAP version.
|
||||
*
|
||||
* @param string $version SOAP version constant SOAP_1_1|SOAP_1_2
|
||||
*
|
||||
* @return string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function getContentTypeForVersion($version)
|
||||
{
|
||||
if (!in_array($version, array(SOAP_1_1, SOAP_1_2))) {
|
||||
throw new \InvalidArgumentException("The 'version' argument has to be either 'SOAP_1_1' or 'SOAP_1_2'!");
|
||||
}
|
||||
|
||||
return self::$versionToContentTypeMap[$version];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SOAP action.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SOAP action.
|
||||
*
|
||||
* @param string $action SOAP action
|
||||
*/
|
||||
public function setAction($action)
|
||||
{
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachments.
|
||||
*
|
||||
* @return array(\BeSimple\SoapCommon\Mime\Part)
|
||||
*/
|
||||
public function getAttachments()
|
||||
{
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SOAP action.
|
||||
*
|
||||
* @param array(\BeSimple\SoapCommon\Mime\Part) $attachments Attachment array
|
||||
*/
|
||||
public function setAttachments(array $attachments)
|
||||
{
|
||||
$this->attachments = $attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message content (MIME Message or SOAP Envelope).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
if (null !== $this->contentDomDocument) {
|
||||
$this->content = $this->contentDomDocument->saveXML();
|
||||
}
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set message content (MIME Message or SOAP Envelope).
|
||||
*
|
||||
* @param string $content SOAP message
|
||||
*/
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
if (null !== $this->contentDomDocument) {
|
||||
$this->contentDomDocument->loadXML($this->content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SOAP message as \DOMDocument
|
||||
*
|
||||
* @return \DOMDocument
|
||||
*/
|
||||
public function getContentDocument()
|
||||
{
|
||||
if (null === $this->contentDomDocument) {
|
||||
$this->contentDomDocument = new \DOMDocument();
|
||||
$this->contentDomDocument->loadXML($this->content);
|
||||
}
|
||||
|
||||
return $this->contentDomDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set content type.
|
||||
*
|
||||
* @param string $contentType Content type header
|
||||
*/
|
||||
public function setContentType($contentType)
|
||||
{
|
||||
$this->contentType = $contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get location.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocation()
|
||||
{
|
||||
return $this->location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set location.
|
||||
*
|
||||
* @param string $location Location string
|
||||
*/
|
||||
public function setLocation($location)
|
||||
{
|
||||
$this->location = $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set version.
|
||||
*
|
||||
* @param string $version SOAP version SOAP_1_1|SOAP_1_2
|
||||
*/
|
||||
public function setVersion($version)
|
||||
{
|
||||
$this->version = $version;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapCommon.
|
||||
*
|
||||
* (c) Christian Kerl <christian-kerl@web.de>
|
||||
* (c) Francis Besset <francis.besset@gmail.com>
|
||||
* (c) Andreas Schamberger <mail@andreass.net>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\SoapMessage;
|
||||
|
||||
/**
|
||||
* SOAP request message.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
*/
|
||||
class SoapRequest extends SoapMessage
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapCommon.
|
||||
*
|
||||
* (c) Christian Kerl <christian-kerl@web.de>
|
||||
* (c) Francis Besset <francis.besset@gmail.com>
|
||||
* (c) Andreas Schamberger <mail@andreass.net>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\SoapRequest;
|
||||
|
||||
/**
|
||||
* SOAP request filter interface.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
*/
|
||||
interface SoapRequestFilter
|
||||
{
|
||||
/**
|
||||
* Modify SOAP response.
|
||||
*
|
||||
* @param SoapRequest $request SOAP request
|
||||
*/
|
||||
public function filterRequest(SoapRequest $request);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapCommon.
|
||||
*
|
||||
* (c) Christian Kerl <christian-kerl@web.de>
|
||||
* (c) Francis Besset <francis.besset@gmail.com>
|
||||
* (c) Andreas Schamberger <mail@andreass.net>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\SoapMessage;
|
||||
|
||||
/**
|
||||
* SOAP response message.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
*/
|
||||
class SoapResponse extends SoapMessage
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the BeSimpleSoapCommon.
|
||||
*
|
||||
* (c) Christian Kerl <christian-kerl@web.de>
|
||||
* (c) Francis Besset <francis.besset@gmail.com>
|
||||
* (c) Andreas Schamberger <mail@andreass.net>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\SoapResponse;
|
||||
|
||||
/**
|
||||
* SOAP response filter interface.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
*/
|
||||
interface SoapResponseFilter
|
||||
{
|
||||
/**
|
||||
* Modify SOAP response.
|
||||
*
|
||||
* @param SoapResponse $response SOAP response
|
||||
*/
|
||||
public function filterResponse(SoapResponse $response);
|
||||
}
|
|
@ -42,6 +42,7 @@ class WsSecurityKey
|
|||
* @param string $key Private key
|
||||
* @param boolean $keyIsFile Given key parameter is path to key file
|
||||
* @param string $passphrase Passphrase for key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPrivateKey($encryptionType, $key = null, $keyIsFile = true, $passphrase = null)
|
||||
|
@ -55,6 +56,7 @@ class WsSecurityKey
|
|||
* @param string $encryptionType Encryption type
|
||||
* @param string $key Public key
|
||||
* @param boolean $keyIsFile Given key parameter is path to key file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPublicKey($encryptionType, $key = null, $keyIsFile = true)
|
||||
|
|
|
@ -87,6 +87,7 @@ class WsdlHandler
|
|||
* Gets the mime type information from the WSDL file.
|
||||
*
|
||||
* @param string $soapAction Soap action to analyse
|
||||
*
|
||||
* @return array(string=>array(string=>array(string)))
|
||||
*/
|
||||
private function getMimeTypesForSoapAction($soapAction)
|
||||
|
@ -152,6 +153,7 @@ class WsdlHandler
|
|||
* @param string $operationType Operation type
|
||||
* @param string $part Part name
|
||||
* @param string $currentMimeType Current mime type
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValidMimeTypeType($soapAction, $operationType, $part, $currentMimeType)
|
||||
|
|
|
@ -52,7 +52,7 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
|||
$p2 = $mp->getPart('0x9d6ad00-0xa19ef48-0x9de7500-0xa4fae78-0xa382698');
|
||||
$this->assertEquals('binary', $p2->getHeader('Content-Transfer-Encoding'));
|
||||
$this->assertEquals('application/binary', $p2->getHeader('Content-Type'));
|
||||
$this->assertEquals(81, strlen($p2->getContent()));
|
||||
$this->assertEquals(79, strlen($p2->getContent()));
|
||||
}
|
||||
|
||||
public function testParserResponseAxis()
|
||||
|
|
Loading…
Reference in New Issue