moved code to common

This commit is contained in:
Andreas Schamberger 2012-01-07 13:18:52 +01:00
parent daadd04657
commit 4d05f2889f
7 changed files with 3 additions and 541 deletions

View File

@ -1,178 +0,0 @@
<?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\SoapClient;
/**
* 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;
}
}
}

View File

@ -1,138 +0,0 @@
<?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\SoapClient;
use BeSimple\SoapCommon\Helper;
use BeSimple\SoapCommon\Mime\MultiPart as MimeMultiPart;
use BeSimple\SoapCommon\Mime\Parser as MimeParser;
use BeSimple\SoapCommon\Mime\Part as MimePart;
use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
use BeSimple\SoapCommon\SoapRequestFilter;
use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
use BeSimple\SoapCommon\SoapResponseFilter;
/**
* MIME filter.
*
* @author Andreas Schamberger <mail@andreass.net>
*/
class MimeFilter implements SoapRequestFilter, SoapResponseFilter
{
/**
* Attachment type.
*
* @var int Helper::ATTACHMENTS_TYPE_SWA | Helper::ATTACHMENTS_TYPE_MTOM
*/
protected $attachmentType = Helper::ATTACHMENTS_TYPE_SWA;
/**
* Constructor.
*
* @param int $attachmentType Helper::ATTACHMENTS_TYPE_SWA | Helper::ATTACHMENTS_TYPE_MTOM
*/
public function __construct($attachmentType)
{
$this->attachmentType = $attachmentType;
}
/**
* Reset all properties to default values.
*/
public function resetFilter()
{
$this->attachmentType = Helper::ATTACHMENTS_TYPE_SWA;
}
/**
* Modify the given request XML.
*
* @param \BeSimple\SoapCommon\SoapRequest $request SOAP request
*
* @return void
*/
public function filterRequest(CommonSoapRequest $request)
{
// get attachments from request object
$attachmentsToSend = $request->getAttachments();
// build mime message if we have attachments
if (count($attachmentsToSend) > 0) {
$multipart = new MimeMultiPart();
$soapPart = new MimePart($request->getContent(), 'text/xml', 'utf-8', MimePart::ENCODING_EIGHT_BIT);
$soapVersion = $request->getVersion();
// change content type headers for MTOM with SOAP 1.1
if ($soapVersion == SOAP_1_1 && $this->attachmentType & Helper::ATTACHMENTS_TYPE_MTOM) {
$multipart->setHeader('Content-Type', 'type', 'application/xop+xml');
$multipart->setHeader('Content-Type', 'start-info', 'text/xml');
$soapPart->setHeader('Content-Type', 'application/xop+xml');
$soapPart->setHeader('Content-Type', 'type', 'text/xml');
}
// change content type headers for SOAP 1.2
elseif ($soapVersion == SOAP_1_2) {
$multipart->setHeader('Content-Type', 'type', 'application/soap+xml');
$soapPart->setHeader('Content-Type', 'application/soap+xml');
}
$multipart->addPart($soapPart, true);
foreach ($attachmentsToSend as $cid => $attachment) {
$multipart->addPart($attachment, false);
}
$request->setContent($multipart->getMimeMessage());
// TODO
$headers = $multipart->getHeadersForHttp();
list($name, $contentType) = explode(': ', $headers[0]);
$request->setContentType($contentType);
}
}
/**
* Modify the given response XML.
*
* @param \BeSimple\SoapCommon\SoapResponse $response SOAP response
*
* @return void
*/
public function filterResponse(CommonSoapResponse $response)
{
// array to store attachments
$attachmentsRecieved = array();
// check content type if it is a multipart mime message
$responseContentType = $response->getContentType();
if (false !== stripos($responseContentType, 'multipart/related')) {
// parse mime message
$headers = array(
'Content-Type' => trim($responseContentType),
);
$multipart = MimeParser::parseMimeMessage($response->getContent(), $headers);
// get soap payload and update SoapResponse object
$soapPart = $multipart->getPart();
// 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
$content = preg_replace('/href=(?!#)/', 'myhref=', $soapPart->getContent());
$response->setContent($content);
$response->setContentType($soapPart->getHeader('Content-Type'));
// store attachments
$attachments = $multipart->getParts(false);
foreach ($attachments as $cid => $attachment) {
$attachmentsRecieved[$cid] = $attachment;
}
}
// add attachments to response object
if (count($attachmentsRecieved) > 0) {
$response->setAttachments($attachmentsRecieved);
}
}
}

View File

@ -1,94 +0,0 @@
<?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\SoapClient;
use BeSimple\SoapCommon\Helper;
use BeSimple\SoapCommon\Mime\Part as MimePart;
use BeSimple\SoapCommon\SoapKernel;
use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
use BeSimple\SoapCommon\Converter\TypeConverterInterface;
/**
* MTOM type converter.
*
* @author Andreas Schamberger <mail@andreass.net>
*/
class MtomTypeConverter
{
/**
* {@inheritDoc}
*/
public function getTypeNamespace()
{
return 'http://www.w3.org/2001/XMLSchema';
}
/**
* {@inheritDoc}
*/
public function getTypeName()
{
return 'base64Binary';
}
/**
* {@inheritDoc}
*/
public function convertXmlToPhp($data, $soapKernel)
{
$doc = new \DOMDocument();
$doc->loadXML($data);
$includes = $doc->getElementsByTagNameNS(Helper::NS_XOP, 'Include');
$include = $includes->item(0);
$ref = $include->getAttribute('myhref');
if ('cid:' === substr($ref, 0, 4)) {
$contentId = urldecode(substr($ref, 4));
if (null !== ($part = $soapKernel->getAttachment($contentId))) {
return $part->getContent();
} else {
return null;
}
}
return $data;
}
/**
* {@inheritDoc}
*/
public function convertPhpToXml($data, $soapKernel)
{
$part = new MimePart($data);
$contentId = trim($part->getHeader('Content-ID'), '<>');
$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();
}
}

View File

@ -25,13 +25,6 @@ use BeSimple\SoapCommon\SoapKernel;
*/ */
class SoapClient extends \SoapClient class SoapClient extends \SoapClient
{ {
/**
* SOAP attachment type.
*
* @var int
*/
protected $attachmentType = Helper::ATTACHMENTS_TYPE_BASE64;
/** /**
* Soap version. * Soap version.
* *
@ -104,16 +97,12 @@ class SoapClient extends \SoapClient
if (isset($options['soap_version'])) { if (isset($options['soap_version'])) {
$this->soapVersion = $options['soap_version']; $this->soapVersion = $options['soap_version'];
} }
// attachment handling
if (isset($options['attachment_type'])) {
$this->attachmentType = $options['attachment_type'];
}
$this->curl = new Curl($options); $this->curl = new Curl($options);
$wsdlFile = $this->loadWsdl($wsdl, $options); $wsdlFile = $this->loadWsdl($wsdl, $options);
// TODO $wsdlHandler = new WsdlHandler($wsdlFile, $this->soapVersion); // TODO $wsdlHandler = new WsdlHandler($wsdlFile, $this->soapVersion);
$this->soapKernel = new SoapKernel(); $this->soapKernel = new SoapKernel();
// set up type converter and mime filter // set up type converter and mime filter
$this->configureMime($options); $this->soapKernel->configureMime($options);
// we want the exceptions option to be set // we want the exceptions option to be set
$options['exceptions'] = true; $options['exceptions'] = true;
// disable obsolete trace option for native SoapClient as we need to do our own tracing anyways // disable obsolete trace option for native SoapClient as we need to do our own tracing anyways
@ -258,43 +247,6 @@ class SoapClient extends \SoapClient
return $this->lastResponse; return $this->lastResponse;
} }
/**
* Configure filter and type converter for SwA/MTOM.
*
* @param array &$options SOAP constructor options array.
*
* @return void
*/
private function configureMime(array &$options)
{
if (Helper::ATTACHMENTS_TYPE_BASE64 !== $this->attachmentType) {
// register mime filter in SoapKernel
$mimeFilter = new MimeFilter($this->attachmentType);
$this->soapKernel->registerFilter($mimeFilter);
// configure type converter
if (Helper::ATTACHMENTS_TYPE_SWA === $this->attachmentType) {
$converter = new SwaTypeConverter();
} elseif (Helper::ATTACHMENTS_TYPE_MTOM === $this->attachmentType) {
$converter = new MtomTypeConverter();
}
// configure typemap
if (!isset($options['typemap'])) {
$options['typemap'] = array();
}
$soapKernel = $this->soapKernel;
$options['typemap'][] = array(
'type_name' => $converter->getTypeName(),
'type_ns' => $converter->getTypeNamespace(),
'from_xml' => function($input) use ($converter, $soapKernel) {
return $converter->convertXmlToPhp($input, $soapKernel);
},
'to_xml' => function($input) use ($converter, $soapKernel) {
return $converter->convertPhpToXml($input, $soapKernel);
},
);
}
}
/** /**
* Get SoapKernel instance. * Get SoapKernel instance.
* *

View File

@ -1,82 +0,0 @@
<?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\SoapClient;
use BeSimple\SoapCommon\Helper;
use BeSimple\SoapCommon\Mime\Part as MimePart;
use BeSimple\SoapCommon\SoapKernel;
use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
use BeSimple\SoapCommon\Converter\TypeConverterInterface;
/**
* SwA type converter.
*
* @author Andreas Schamberger <mail@andreass.net>
*/
class SwaTypeConverter
{
/**
* {@inheritDoc}
*/
public function getTypeNamespace()
{
return 'http://www.w3.org/2001/XMLSchema';
}
/**
* {@inheritDoc}
*/
public function getTypeName()
{
return 'base64Binary';
}
/**
* {@inheritDoc}
*/
public function convertXmlToPhp($data, $soapKernel)
{
$doc = new \DOMDocument();
$doc->loadXML($data);
$ref = $doc->documentElement->getAttribute('myhref');
if ('cid:' === substr($ref, 0, 4)) {
$contentId = urldecode(substr($ref, 4));
if (null !== ($part = $soapKernel->getAttachment($contentId))) {
return $part->getContent();
} else {
return null;
}
}
return $data;
}
/**
* {@inheritDoc}
*/
public function convertPhpToXml($data, $soapKernel)
{
$part = new MimePart($data);
$contentId = trim($part->getHeader('Content-ID'), '<>');
$soapKernel->addAttachment($part);
return sprintf('<%s href="%s"/>', $this->getTypeName(), $contentId);
}
}

View File

@ -12,6 +12,7 @@
namespace BeSimple\SoapClient; namespace BeSimple\SoapClient;
use BeSimple\SoapCommon\FilterHelper;
use BeSimple\SoapCommon\Helper; use BeSimple\SoapCommon\Helper;
use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest; use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
use BeSimple\SoapCommon\SoapRequestFilter; use BeSimple\SoapCommon\SoapRequestFilter;

View File

@ -16,6 +16,7 @@ use ass\XmlSecurity\DSig as XmlSecurityDSig;
use ass\XmlSecurity\Enc as XmlSecurityEnc; use ass\XmlSecurity\Enc as XmlSecurityEnc;
use ass\XmlSecurity\Key as XmlSecurityKey; use ass\XmlSecurity\Key as XmlSecurityKey;
use BeSimple\SoapCommon\FilterHelper;
use BeSimple\SoapCommon\Helper; use BeSimple\SoapCommon\Helper;
use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest; use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
use BeSimple\SoapCommon\SoapRequestFilter; use BeSimple\SoapCommon\SoapRequestFilter;