SoapClient large refactoring & tests update
This commit is contained in:
@ -12,6 +12,8 @@
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Francis Besset <francis.besset@gmail.com>
|
||||
*/
|
||||
@ -32,22 +34,22 @@ class Cache
|
||||
self::TYPE_DISK_MEMORY,
|
||||
];
|
||||
|
||||
static public function getTypes()
|
||||
public static function getTypes()
|
||||
{
|
||||
return self::$types;
|
||||
}
|
||||
|
||||
static public function hasType($cacheType)
|
||||
public static function hasType($cacheType)
|
||||
{
|
||||
return in_array($cacheType, self::$types);
|
||||
}
|
||||
|
||||
static public function isEnabled()
|
||||
public static function isEnabled()
|
||||
{
|
||||
return self::iniGet('soap.wsdl_cache_enabled');
|
||||
return self::iniGet('soap.wsdl_cache_enabled') === '1';
|
||||
}
|
||||
|
||||
static public function setEnabled($enabled)
|
||||
public static function setEnabled($enabled)
|
||||
{
|
||||
if (!in_array($enabled, array(self::ENABLED, self::DISABLED), true)) {
|
||||
throw new \InvalidArgumentException();
|
||||
@ -56,60 +58,58 @@ class Cache
|
||||
self::iniSet('soap.wsdl_cache_enabled', $enabled);
|
||||
}
|
||||
|
||||
static public function getType()
|
||||
public static function getType()
|
||||
{
|
||||
return self::iniGet('soap.wsdl_cache');
|
||||
}
|
||||
|
||||
static public function setType($type)
|
||||
public static function setType($type)
|
||||
{
|
||||
if (!in_array($type, self::getTypes(), true)) {
|
||||
throw new \InvalidArgumentException('The cache type has to be either Cache::TYPE_NONE, Cache::TYPE_DISK, Cache::TYPE_MEMORY or Cache::TYPE_DISK_MEMORY');
|
||||
throw new InvalidArgumentException(
|
||||
'The cache type has to be either Cache::TYPE_NONE, Cache::TYPE_DISK, Cache::TYPE_MEMORY or Cache::TYPE_DISK_MEMORY'
|
||||
);
|
||||
}
|
||||
|
||||
self::iniSet('soap.wsdl_cache', $type);
|
||||
}
|
||||
|
||||
static public function getDirectory()
|
||||
public static function getDirectory()
|
||||
{
|
||||
return self::iniGet('soap.wsdl_cache_dir');
|
||||
}
|
||||
|
||||
static public function setDirectory($directory)
|
||||
public static function setDirectory($directory)
|
||||
{
|
||||
if (!is_dir($directory)) {
|
||||
mkdir($directory, 0777, true);
|
||||
}
|
||||
|
||||
self::iniSet('soap.wsdl_cache_dir', $directory);
|
||||
}
|
||||
|
||||
static public function getLifetime()
|
||||
public static function getLifetime()
|
||||
{
|
||||
return self::iniGet('soap.wsdl_cache_ttl');
|
||||
}
|
||||
|
||||
static public function setLifetime($lifetime)
|
||||
public static function setLifetime($lifetime)
|
||||
{
|
||||
self::iniSet('soap.wsdl_cache_ttl', $lifetime);
|
||||
}
|
||||
|
||||
static public function getLimit()
|
||||
public static function getLimit()
|
||||
{
|
||||
return self::iniGet('soap.wsdl_cache_limit');
|
||||
}
|
||||
|
||||
static public function setLimit($limit)
|
||||
public static function setLimit($limit)
|
||||
{
|
||||
self::iniSet('soap.wsdl_cache_limit', $limit);
|
||||
}
|
||||
|
||||
static protected function iniGet($key)
|
||||
protected static function iniGet($key)
|
||||
{
|
||||
return ini_get($key);
|
||||
}
|
||||
|
||||
static protected function iniSet($key, $value)
|
||||
protected static function iniSet($key, $value)
|
||||
{
|
||||
ini_set($key, $value);
|
||||
}
|
||||
|
@ -22,11 +22,6 @@ use BeSimple\SoapCommon\Mime\Part as MimePart;
|
||||
*/
|
||||
class MtomTypeConverter implements TypeConverterInterface
|
||||
{
|
||||
/**
|
||||
* @var \BeSimple\SoapCommon\SoapKernel $soapKernel SoapKernel instance
|
||||
*/
|
||||
protected $soapKernel = null;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
10
src/BeSimple/SoapCommon/Fault/SoapFaultEnum.php
Normal file
10
src/BeSimple/SoapCommon/Fault/SoapFaultEnum.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace BeSimple\SoapCommon\Fault;
|
||||
|
||||
class SoapFaultEnum
|
||||
{
|
||||
const SOAP_FAULT_WSDL = 'wsdl';
|
||||
const SOAP_FAULT_HTTP = 'http';
|
||||
const SOAP_FAULT_SOAP_CLIENT_ERROR = 'soap-client-error';
|
||||
}
|
@ -181,4 +181,9 @@ class MultiPart extends PartHeader
|
||||
{
|
||||
return 'multipart-boundary-' . Helper::generateUUID() . '@response.info';
|
||||
}
|
||||
|
||||
public function getMainPartContentId()
|
||||
{
|
||||
return $this->mainPartContentId;
|
||||
}
|
||||
}
|
@ -12,183 +12,241 @@
|
||||
|
||||
namespace BeSimple\SoapCommon\Mime;
|
||||
|
||||
use BeSimple\SoapCommon\Mime\Parser\ContentTypeParser;
|
||||
use BeSimple\SoapCommon\Mime\Parser\ParsedPart;
|
||||
use BeSimple\SoapCommon\Mime\Parser\ParsedPartList;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Simple Multipart-Mime parser.
|
||||
*
|
||||
* @author Andreas Schamberger <mail@andreass.net>
|
||||
* @author Petr Bechyne <mail@petrbechyne.com>
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
const HAS_HTTP_REQUEST_HEADERS = true;
|
||||
const HAS_NO_HTTP_REQUEST_HEADERS = false;
|
||||
|
||||
/**
|
||||
* Parse the given Mime-Message and return a \BeSimple\SoapCommon\Mime\MultiPart object.
|
||||
*
|
||||
* @param string $mimeMessage Mime message string
|
||||
* @param array(string=>string) $headers Array of header elements (e.g. coming from http request)
|
||||
* @param string[] $headers array(string=>string) of header elements (e.g. coming from http request)
|
||||
*
|
||||
* @return \BeSimple\SoapCommon\Mime\MultiPart
|
||||
*/
|
||||
public static function parseMimeMessage($mimeMessage, array $headers = [])
|
||||
{
|
||||
$boundary = null;
|
||||
$start = null;
|
||||
$multipart = new MultiPart();
|
||||
$hitFirstBoundary = false;
|
||||
$inHeader = true;
|
||||
$multiPart = new MultiPart();
|
||||
$mimeMessageLines = preg_split("/(\n)/", $mimeMessage);
|
||||
// add given headers, e.g. coming from HTTP headers
|
||||
if (count($headers) > 0) {
|
||||
foreach ($headers as $name => $value) {
|
||||
if ($name === 'Content-Type') {
|
||||
self::parseContentTypeHeader($multipart, $name, $value);
|
||||
$boundary = $multipart->getHeader('Content-Type', 'boundary');
|
||||
$start = $multipart->getHeader('Content-Type', 'start');
|
||||
} else {
|
||||
$multipart->setHeader($name, $value);
|
||||
}
|
||||
}
|
||||
$inHeader = false;
|
||||
self::setMultiPartHeaders($multiPart, $headers);
|
||||
$hasHttpRequestHeaders = self::HAS_HTTP_REQUEST_HEADERS;
|
||||
} else {
|
||||
$hasHttpRequestHeaders = self::HAS_NO_HTTP_REQUEST_HEADERS;
|
||||
}
|
||||
$content = '';
|
||||
$currentPart = $multipart;
|
||||
$lines = preg_split("/(\r\n)|(\n)/", $mimeMessage);
|
||||
if (self::hasBoundary($lines)) {
|
||||
foreach ($lines as $line) {
|
||||
// ignore http status code and POST *
|
||||
if (substr($line, 0, 5) == 'HTTP/' || substr($line, 0, 4) == 'POST') {
|
||||
if (self::hasBoundary($mimeMessageLines)) {
|
||||
$parsedPartList = self::getPartsFromMimeMessageLines(
|
||||
$multiPart,
|
||||
$mimeMessageLines,
|
||||
$hasHttpRequestHeaders
|
||||
);
|
||||
if ($parsedPartList->hasParts() === false) {
|
||||
throw new Exception(
|
||||
'Could not parse MimeMessage: no Parts for MultiPart given'
|
||||
);
|
||||
}
|
||||
if ($parsedPartList->hasExactlyOneMainPart() === false) {
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'Could not parse MimeMessage %s HTTP headers: unexpected count of main ParsedParts: %s (total: %d)',
|
||||
$hasHttpRequestHeaders ? 'with' : 'w/o',
|
||||
implode(', ', $parsedPartList->getPartContentIds()),
|
||||
$parsedPartList->getMainPartCount()
|
||||
)
|
||||
);
|
||||
}
|
||||
self::appendPartsToMultiPart(
|
||||
$parsedPartList,
|
||||
$multiPart
|
||||
);
|
||||
} else {
|
||||
self::appendSingleMainPartToMultiPart(new Part($mimeMessage), $multiPart);
|
||||
}
|
||||
|
||||
return $multiPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MultiPart $multiPart
|
||||
* @param string[] $mimeMessageLines
|
||||
* @param bool $hasHttpHeaders = self::HAS_HTTP_REQUEST_HEADERS|self::HAS_NO_HTTP_REQUEST_HEADERS
|
||||
* @return ParsedPartList
|
||||
*/
|
||||
private static function getPartsFromMimeMessageLines(
|
||||
MultiPart $multiPart,
|
||||
array $mimeMessageLines,
|
||||
$hasHttpHeaders
|
||||
) {
|
||||
$parsedParts = [];
|
||||
$contentTypeBoundary = $multiPart->getHeader('Content-Type', 'boundary');
|
||||
$contentTypeContentIdStart = $multiPart->getHeader('Content-Type', 'start');
|
||||
$currentPart = $multiPart;
|
||||
$messagePartStringContent = '';
|
||||
$inHeader = $hasHttpHeaders;
|
||||
$hitFirstBoundary = false;
|
||||
|
||||
foreach ($mimeMessageLines as $mimeMessageLine) {
|
||||
// ignore http status code and POST *
|
||||
if (substr($mimeMessageLine, 0, 5) == 'HTTP/' || substr($mimeMessageLine, 0, 4) == 'POST') {
|
||||
continue;
|
||||
}
|
||||
if (isset($currentHeader)) {
|
||||
if (isset($mimeMessageLine[0]) && ($mimeMessageLine[0] === ' ' || $mimeMessageLine[0] === "\t")) {
|
||||
$currentHeader .= $mimeMessageLine;
|
||||
continue;
|
||||
}
|
||||
if (isset($currentHeader)) {
|
||||
if (isset($line[0]) && ($line[0] === ' ' || $line[0] === "\t")) {
|
||||
$currentHeader .= $line;
|
||||
continue;
|
||||
if (strpos($currentHeader, ':') !== false) {
|
||||
list($headerName, $headerValue) = explode(':', $currentHeader, 2);
|
||||
$headerValue = iconv_mime_decode($headerValue, 0, Part::CHARSET_UTF8);
|
||||
$parsedMimeHeaders = ContentTypeParser::parseContentTypeHeader($headerName, $headerValue);
|
||||
foreach ($parsedMimeHeaders as $parsedMimeHeader) {
|
||||
$currentPart->setHeader(
|
||||
$parsedMimeHeader->getName(),
|
||||
$parsedMimeHeader->getValue(),
|
||||
$parsedMimeHeader->getSubValue()
|
||||
);
|
||||
}
|
||||
if (strpos($currentHeader, ':') !== false) {
|
||||
list($headerName, $headerValue) = explode(':', $currentHeader, 2);
|
||||
$headerValue = iconv_mime_decode($headerValue, 0, 'utf-8');
|
||||
if (strpos($headerValue, ';') !== false) {
|
||||
self::parseContentTypeHeader($currentPart, $headerName, $headerValue);
|
||||
$boundary = $multipart->getHeader('Content-Type', 'boundary');
|
||||
$start = $multipart->getHeader('Content-Type', 'start');
|
||||
} else {
|
||||
$currentPart->setHeader($headerName, trim($headerValue));
|
||||
}
|
||||
}
|
||||
unset($currentHeader);
|
||||
$contentTypeBoundary = $multiPart->getHeader('Content-Type', 'boundary');
|
||||
$contentTypeContentIdStart = $multiPart->getHeader('Content-Type', 'start');
|
||||
}
|
||||
if ($inHeader) {
|
||||
if (trim($line) == '') {
|
||||
$inHeader = false;
|
||||
continue;
|
||||
}
|
||||
$currentHeader = $line;
|
||||
unset($currentHeader);
|
||||
}
|
||||
if ($inHeader === true) {
|
||||
if (trim($mimeMessageLine) == '') {
|
||||
$inHeader = false;
|
||||
continue;
|
||||
} else {
|
||||
if (self::isBoundary($line)) {
|
||||
if (strcmp(trim($line), '--' . $boundary) === 0) {
|
||||
if ($currentPart instanceof Part) {
|
||||
$content = substr($content, 0, -1);
|
||||
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;
|
||||
if ($isMain === true) {
|
||||
$start = $currentPart->getHeader('Content-ID');
|
||||
}
|
||||
$multipart->addPart($currentPart, $isMain);
|
||||
}
|
||||
$currentPart = new Part();
|
||||
$hitFirstBoundary = true;
|
||||
$inHeader = true;
|
||||
$content = '';
|
||||
} elseif (strcmp(trim($line), '--' . $boundary . '--') === 0) {
|
||||
$content = substr($content, 0, -1);
|
||||
self::decodeContent($currentPart, $content);
|
||||
}
|
||||
$currentHeader = $mimeMessageLine;
|
||||
continue;
|
||||
} else {
|
||||
if (self::isBoundary($mimeMessageLine)) {
|
||||
if (self::isMiddleBoundary($mimeMessageLine, $contentTypeBoundary)) {
|
||||
if ($currentPart instanceof Part) {
|
||||
$currentPartContent = self::decodeContent(
|
||||
$currentPart,
|
||||
substr($messagePartStringContent, 0, -1)
|
||||
);
|
||||
$currentPart->setContent($currentPartContent);
|
||||
// check if there is a start parameter given, if not set first part
|
||||
$isMain = (is_null($start) || $start == $currentPart->getHeader('Content-ID')) ? true : false;
|
||||
if ($isMain === true) {
|
||||
$start = $currentPart->getHeader('Content-ID');
|
||||
if ($contentTypeContentIdStart === null || $currentPart->hasContentId($contentTypeContentIdStart) === true) {
|
||||
$contentTypeContentIdStart = $currentPart->getHeader('Content-ID');
|
||||
$parsedParts[] = new ParsedPart($currentPart, ParsedPart::PART_IS_MAIN);
|
||||
} else {
|
||||
$parsedParts[] = new ParsedPart($currentPart, ParsedPart::PART_IS_NOT_MAIN);
|
||||
}
|
||||
$multipart->addPart($currentPart, $isMain);
|
||||
$content = '';
|
||||
}
|
||||
$currentPart = new Part();
|
||||
$hitFirstBoundary = true;
|
||||
$inHeader = true;
|
||||
$messagePartStringContent = '';
|
||||
} else if (self::isLastBoundary($mimeMessageLine, $contentTypeBoundary)) {
|
||||
$currentPartContent = self::decodeContent(
|
||||
$currentPart,
|
||||
substr($messagePartStringContent, 0, -1)
|
||||
);
|
||||
$currentPart->setContent($currentPartContent);
|
||||
// check if there is a start parameter given, if not set first part
|
||||
if ($contentTypeContentIdStart === null || $currentPart->hasContentId($contentTypeContentIdStart) === true) {
|
||||
$contentTypeContentIdStart = $currentPart->getHeader('Content-ID');
|
||||
$parsedParts[] = new ParsedPart($currentPart, ParsedPart::PART_IS_MAIN);
|
||||
} else {
|
||||
$parsedParts[] = new ParsedPart($currentPart, ParsedPart::PART_IS_NOT_MAIN);
|
||||
}
|
||||
$messagePartStringContent = '';
|
||||
} else {
|
||||
if ($hitFirstBoundary === false) {
|
||||
if (trim($line) !== '') {
|
||||
$inHeader = true;
|
||||
$currentHeader = $line;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$content .= $line . "\n";
|
||||
// else block migrated from https://github.com/progmancod/BeSimpleSoap/commit/bf9437e3bcf35c98c6c2f26aca655ec3d3514694
|
||||
// be careful to replace \r\n with \n
|
||||
$messagePartStringContent .= $mimeMessageLine . "\n";
|
||||
}
|
||||
} else {
|
||||
if ($hitFirstBoundary === false) {
|
||||
if (trim($mimeMessageLine) !== '') {
|
||||
$inHeader = true;
|
||||
$currentHeader = $mimeMessageLine;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$messagePartStringContent .= $mimeMessageLine . "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$multipart->addPart(new Part($mimeMessage), true);
|
||||
}
|
||||
|
||||
return $multipart;
|
||||
return new ParsedPartList($parsedParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a "Content-Type" header with multiple sub values.
|
||||
* e.g. Content-Type: multipart/related; boundary=boundary; type=text/xml;
|
||||
* start="<123@abc>"
|
||||
*
|
||||
* Based on: https://labs.omniti.com/alexandria/trunk/OmniTI/Mail/Parser.php
|
||||
*
|
||||
* @param \BeSimple\SoapCommon\Mime\PartHeader $part Header part
|
||||
* @param string $headerName Header name
|
||||
* @param string $headerValue Header value
|
||||
*
|
||||
* @param ParsedPartList $parsedPartList
|
||||
* @param MultiPart $multiPart
|
||||
*/
|
||||
private static function parseContentTypeHeader(PartHeader $part, $headerName, $headerValue)
|
||||
private static function appendPartsToMultiPart(ParsedPartList $parsedPartList, MultiPart $multiPart)
|
||||
{
|
||||
if (strpos($headerValue, ';')) {
|
||||
list($value, $remainder) = explode(';', $headerValue, 2);
|
||||
$value = trim($value);
|
||||
$part->setHeader($headerName, $value);
|
||||
$remainder = trim($remainder);
|
||||
while (strlen($remainder) > 0) {
|
||||
if (!preg_match('/^([a-zA-Z0-9_-]+)=(.{1})/', $remainder, $matches)) {
|
||||
break;
|
||||
foreach ($parsedPartList->getParts() as $parsedPart) {
|
||||
$multiPart->addPart(
|
||||
$parsedPart->getPart(),
|
||||
$parsedPart->isMain()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static function appendSingleMainPartToMultiPart(Part $part, MultiPart $multiPart)
|
||||
{
|
||||
$multiPart->addPart($part, true);
|
||||
}
|
||||
|
||||
private static function setMultiPartHeaders(MultiPart $multiPart, $headers)
|
||||
{
|
||||
foreach ($headers as $name => $value) {
|
||||
if ($name === 'Content-Type') {
|
||||
$parsedMimeHeaders = ContentTypeParser::parseContentTypeHeader($name, $value);
|
||||
foreach ($parsedMimeHeaders as $parsedMimeHeader) {
|
||||
$multiPart->setHeader(
|
||||
$parsedMimeHeader->getName(),
|
||||
$parsedMimeHeader->getValue(),
|
||||
$parsedMimeHeader->getSubValue()
|
||||
);
|
||||
}
|
||||
$name = $matches[1];
|
||||
$delimiter = $matches[2];
|
||||
$remainder = substr($remainder, strlen($name) + 1);
|
||||
if (!preg_match('/([^;]+)(;)?(\s|$)?/', $remainder, $matches)) {
|
||||
break;
|
||||
}
|
||||
$value = rtrim($matches[1], ';');
|
||||
if ($delimiter == "'" || $delimiter == '"') {
|
||||
$value = trim($value, $delimiter);
|
||||
}
|
||||
$part->setHeader($headerName, $name, $value);
|
||||
$remainder = substr($remainder, strlen($matches[0]));
|
||||
} else {
|
||||
$multiPart->setHeader($name, $value);
|
||||
}
|
||||
} else {
|
||||
$part->setHeader($headerName, $headerValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the content of a Mime part.
|
||||
*
|
||||
* @param \BeSimple\SoapCommon\Mime\Part $part Part to add content
|
||||
* @param string $content Content to decode
|
||||
* Decodes the content of a Mime part
|
||||
*
|
||||
* @param Part $part Part to add content
|
||||
* @param string $partStringContent Content to decode
|
||||
* @return string $partStringContent decodedContent
|
||||
*/
|
||||
private static function decodeContent(Part $part, $content)
|
||||
private static function decodeContent(Part $part, $partStringContent)
|
||||
{
|
||||
$encoding = strtolower($part->getHeader('Content-Transfer-Encoding'));
|
||||
$charset = strtolower($part->getHeader('Content-Type', 'charset'));
|
||||
if ($encoding == Part::ENCODING_BASE64) {
|
||||
$content = base64_decode($content);
|
||||
} elseif ($encoding == Part::ENCODING_QUOTED_PRINTABLE) {
|
||||
$content = quoted_printable_decode($content);
|
||||
|
||||
if ($encoding === Part::ENCODING_BASE64) {
|
||||
$partStringContent = base64_decode($partStringContent);
|
||||
} else if ($encoding === Part::ENCODING_QUOTED_PRINTABLE) {
|
||||
$partStringContent = quoted_printable_decode($partStringContent);
|
||||
}
|
||||
if ($charset != 'utf-8') {
|
||||
$content = iconv($charset, 'utf-8', $content);
|
||||
|
||||
if ($charset !== Part::CHARSET_UTF8) {
|
||||
return iconv($charset, Part::CHARSET_UTF8, $partStringContent);
|
||||
}
|
||||
$part->setContent($content);
|
||||
|
||||
return $partStringContent;
|
||||
}
|
||||
|
||||
private static function hasBoundary(array $lines)
|
||||
@ -203,8 +261,18 @@ class Parser
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function isBoundary($line)
|
||||
private static function isBoundary($mimeMessageLine)
|
||||
{
|
||||
return strlen($line) > 0 && $line[0] === "-";
|
||||
return strlen($mimeMessageLine) > 0 && $mimeMessageLine[0] === "-";
|
||||
}
|
||||
|
||||
private static function isMiddleBoundary($mimeMessageLine, $contentTypeBoundary)
|
||||
{
|
||||
return strcmp(trim($mimeMessageLine), '--'.$contentTypeBoundary) === 0;
|
||||
}
|
||||
|
||||
private static function isLastBoundary($mimeMessageLine, $contentTypeBoundary)
|
||||
{
|
||||
return strcmp(trim($mimeMessageLine), '--'.$contentTypeBoundary.'--') === 0;
|
||||
}
|
||||
}
|
64
src/BeSimple/SoapCommon/Mime/Parser/ContentTypeParser.php
Normal file
64
src/BeSimple/SoapCommon/Mime/Parser/ContentTypeParser.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace BeSimple\SoapCommon\Mime\Parser;
|
||||
|
||||
class ContentTypeParser
|
||||
{
|
||||
/**
|
||||
* Parse a "Content-Type" header with multiple sub values.
|
||||
* e.g. Content-Type: multipart/related; boundary=boundary; type=text/xml;
|
||||
* start="<123@abc>"
|
||||
*
|
||||
* Based on: https://labs.omniti.com/alexandria/trunk/OmniTI/Mail/Parser.php
|
||||
*
|
||||
* @param string $headerName Header name
|
||||
* @param string $headerValue Header value
|
||||
* @return ParsedMimeHeader[]
|
||||
*/
|
||||
public static function parseContentTypeHeader($headerName, $headerValue)
|
||||
{
|
||||
if (self::isCompositeHeaderValue($headerValue)) {
|
||||
$parsedMimeHeaders = self::parseCompositeValue($headerName, $headerValue);
|
||||
} else {
|
||||
$parsedMimeHeaders = [
|
||||
new ParsedMimeHeader($headerName, trim($headerValue))
|
||||
];
|
||||
}
|
||||
|
||||
return $parsedMimeHeaders;
|
||||
}
|
||||
|
||||
private static function parseCompositeValue($headerName, $headerValue)
|
||||
{
|
||||
$parsedMimeHeaders = [];
|
||||
list($value, $remainder) = explode(';', $headerValue, 2);
|
||||
$value = trim($value);
|
||||
$parsedMimeHeaders[] = new ParsedMimeHeader($headerName, $value);
|
||||
$remainder = trim($remainder);
|
||||
while (strlen($remainder) > 0) {
|
||||
if (!preg_match('/^([a-zA-Z0-9_-]+)=(.{1})/', $remainder, $matches)) {
|
||||
break;
|
||||
}
|
||||
$name = $matches[1];
|
||||
$delimiter = $matches[2];
|
||||
$remainder = substr($remainder, strlen($name) + 1);
|
||||
// preg_match migrated from https://github.com/progmancod/BeSimpleSoap/commit/6bc8f6a467616c934b0a9792f0efece55054db97
|
||||
if (!preg_match('/([^;]+)(;\s*|\s*$)/', $remainder, $matches)) {
|
||||
break;
|
||||
}
|
||||
$value = rtrim($matches[1], ';');
|
||||
if ($delimiter == "'" || $delimiter == '"') {
|
||||
$value = trim($value, $delimiter);
|
||||
}
|
||||
$remainder = substr($remainder, strlen($matches[0]));
|
||||
$parsedMimeHeaders[] = new ParsedMimeHeader($headerName, $name, $value);
|
||||
}
|
||||
|
||||
return $parsedMimeHeaders;
|
||||
}
|
||||
|
||||
private static function isCompositeHeaderValue($headerValue)
|
||||
{
|
||||
return strpos($headerValue, ';');
|
||||
}
|
||||
}
|
37
src/BeSimple/SoapCommon/Mime/Parser/ParsedMimeHeader.php
Normal file
37
src/BeSimple/SoapCommon/Mime/Parser/ParsedMimeHeader.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace BeSimple\SoapCommon\Mime\Parser;
|
||||
|
||||
class ParsedMimeHeader
|
||||
{
|
||||
private $name;
|
||||
private $value;
|
||||
private $subValue;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param string|null $subValue
|
||||
*/
|
||||
public function __construct($name, $value, $subValue = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->value = $value;
|
||||
$this->subValue = $subValue;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function getSubValue()
|
||||
{
|
||||
return $this->subValue;
|
||||
}
|
||||
}
|
34
src/BeSimple/SoapCommon/Mime/Parser/ParsedPart.php
Normal file
34
src/BeSimple/SoapCommon/Mime/Parser/ParsedPart.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace BeSimple\SoapCommon\Mime\Parser;
|
||||
|
||||
use BeSimple\SoapCommon\Mime\Part;
|
||||
|
||||
class ParsedPart
|
||||
{
|
||||
const PART_IS_MAIN = true;
|
||||
const PART_IS_NOT_MAIN = false;
|
||||
|
||||
private $part;
|
||||
private $isMain;
|
||||
|
||||
/**
|
||||
* @param Part $part
|
||||
* @param bool $isMain
|
||||
*/
|
||||
public function __construct(Part $part, $isMain)
|
||||
{
|
||||
$this->part = $part;
|
||||
$this->isMain = $isMain;
|
||||
}
|
||||
|
||||
public function getPart()
|
||||
{
|
||||
return $this->part;
|
||||
}
|
||||
|
||||
public function isMain()
|
||||
{
|
||||
return $this->isMain;
|
||||
}
|
||||
}
|
60
src/BeSimple/SoapCommon/Mime/Parser/ParsedPartList.php
Normal file
60
src/BeSimple/SoapCommon/Mime/Parser/ParsedPartList.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace BeSimple\SoapCommon\Mime\Parser;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ParsedPartList
|
||||
{
|
||||
private $parts;
|
||||
|
||||
/**
|
||||
* @param ParsedPart[] $parts
|
||||
*/
|
||||
public function __construct(array $parts)
|
||||
{
|
||||
$this->parts = $parts;
|
||||
}
|
||||
|
||||
public function getMainPartCount()
|
||||
{
|
||||
$mainPartsCount = 0;
|
||||
foreach ($this->getParts() as $parsedPart) {
|
||||
if ($parsedPart->isMain() === true) {
|
||||
$mainPartsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return $mainPartsCount;
|
||||
}
|
||||
|
||||
public function hasExactlyOneMainPart()
|
||||
{
|
||||
return $this->getMainPartCount() === 1;
|
||||
}
|
||||
|
||||
public function getPartContentIds()
|
||||
{
|
||||
$partContentIds = [];
|
||||
foreach ($this->getParts() as $parsedPart) {
|
||||
$partContentIds[] = $parsedPart->getPart()->getContentId();
|
||||
}
|
||||
|
||||
return $partContentIds;
|
||||
}
|
||||
|
||||
public function getParts()
|
||||
{
|
||||
return $this->parts;
|
||||
}
|
||||
|
||||
public function getPartCount()
|
||||
{
|
||||
return count($this->parts);
|
||||
}
|
||||
|
||||
public function hasParts()
|
||||
{
|
||||
return $this->getPartCount() > 0;
|
||||
}
|
||||
}
|
@ -28,57 +28,38 @@ use BeSimple\SoapCommon\Helper;
|
||||
*/
|
||||
class Part extends PartHeader
|
||||
{
|
||||
/**
|
||||
* Encoding type base 64
|
||||
*/
|
||||
const ENCODING_BASE64 = 'base64';
|
||||
|
||||
/**
|
||||
* Encoding type binary
|
||||
*/
|
||||
const ENCODING_BINARY = 'binary';
|
||||
|
||||
/**
|
||||
* Encoding type eight bit
|
||||
*/
|
||||
const ENCODING_EIGHT_BIT = '8bit';
|
||||
|
||||
/**
|
||||
* Encoding type seven bit
|
||||
*/
|
||||
const ENCODING_SEVEN_BIT = '7bit';
|
||||
|
||||
/**
|
||||
* Encoding type quoted printable
|
||||
*/
|
||||
const ENCODING_QUOTED_PRINTABLE = 'quoted-printable';
|
||||
|
||||
/**
|
||||
* Content.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
const CHARSET_UTF8 = 'utf-8';
|
||||
|
||||
const CONTENT_TYPE_STREAM = 'application/octet-stream';
|
||||
const CONTENT_TYPE_PDF = 'application/pdf';
|
||||
|
||||
/** @var mixed */
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
* Construct new mime object.
|
||||
*
|
||||
* @param mixed $content Content
|
||||
* @param string $contentType Content type
|
||||
* @param string $charset Charset
|
||||
* @param string $encoding Encoding
|
||||
* @param string $contentId Content id
|
||||
*
|
||||
*/
|
||||
public function __construct($content = null, $contentType = 'application/octet-stream', $charset = null, $encoding = self::ENCODING_BINARY, $contentId = null)
|
||||
{
|
||||
public function __construct(
|
||||
$content = null,
|
||||
$contentType = self::CONTENT_TYPE_STREAM,
|
||||
$charset = self::CHARSET_UTF8,
|
||||
$encoding = self::ENCODING_BINARY,
|
||||
$contentId = null
|
||||
) {
|
||||
$this->content = $content;
|
||||
|
||||
$this->setHeader('Content-Type', $contentType);
|
||||
if (!is_null($charset)) {
|
||||
$this->setHeader('Content-Type', 'charset', $charset);
|
||||
} else {
|
||||
$this->setHeader('Content-Type', 'charset', 'utf-8');
|
||||
}
|
||||
$this->setHeader('Content-Type', 'charset', $charset);
|
||||
$this->setHeader('Content-Transfer-Encoding', $encoding);
|
||||
if (is_null($contentId)) {
|
||||
$contentId = $this->generateContentId();
|
||||
@ -106,6 +87,16 @@ class Part extends PartHeader
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function hasContentId($contentTypeContentId)
|
||||
{
|
||||
return $contentTypeContentId === $this->getContentId();
|
||||
}
|
||||
|
||||
public function getContentId()
|
||||
{
|
||||
return $this->getHeader('Content-ID');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set mime content.
|
||||
*
|
||||
@ -137,10 +128,10 @@ class Part extends PartHeader
|
||||
{
|
||||
$encoding = strtolower($this->getHeader('Content-Transfer-Encoding'));
|
||||
$charset = strtolower($this->getHeader('Content-Type', 'charset'));
|
||||
if ($charset != 'utf-8') {
|
||||
$content = iconv('utf-8', $charset . '//TRANSLIT', $this->content);
|
||||
if ($charset !== self::CHARSET_UTF8) {
|
||||
$content = iconv(self::CHARSET_UTF8, $charset.'//TRANSLIT', $this->getContent());
|
||||
} else {
|
||||
$content = $this->content;
|
||||
$content = $this->getContent();
|
||||
}
|
||||
switch ($encoding) {
|
||||
case self::ENCODING_BASE64:
|
||||
|
33
src/BeSimple/SoapCommon/Mime/PartFactory.php
Normal file
33
src/BeSimple/SoapCommon/Mime/PartFactory.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace BeSimple\SoapCommon\Mime;
|
||||
|
||||
use BeSimple\SoapBundle\Soap\SoapAttachment;
|
||||
|
||||
class PartFactory
|
||||
{
|
||||
public static function createFromSoapAttachment(SoapAttachment $attachment)
|
||||
{
|
||||
return new Part(
|
||||
$attachment->getContent(),
|
||||
Part::CONTENT_TYPE_PDF,
|
||||
Part::CHARSET_UTF8,
|
||||
Part::ENCODING_BINARY,
|
||||
$attachment->getId()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SoapAttachment[] $attachments SOAP attachments
|
||||
* @return Part[]
|
||||
*/
|
||||
public static function createAttachmentParts(array $attachments = [])
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($attachments as $attachment) {
|
||||
$parts[] = self::createFromSoapAttachment($attachment);
|
||||
}
|
||||
|
||||
return $parts;
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ namespace BeSimple\SoapCommon;
|
||||
* the chain-of-responsibility pattern).
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
* @author Petr Bechyně <petr.bechyne@vodafone.com>
|
||||
* @author Petr Bechyně <mail@petrbechyne.com>
|
||||
*/
|
||||
class SoapKernel
|
||||
{
|
||||
@ -20,7 +20,7 @@ class SoapKernel
|
||||
* @param int $attachmentType = SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA|SoapOptions::ATTACHMENTS_TYPE_MTOM|SoapOptions::ATTACHMENTS_TYPE_BASE64
|
||||
* @return SoapRequest
|
||||
*/
|
||||
public function filterRequest(SoapRequest $request, array $filters, $attachmentType)
|
||||
public static function filterRequest(SoapRequest $request, array $filters, $attachmentType)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
if ($filter instanceof SoapRequestFilter) {
|
||||
@ -37,9 +37,9 @@ class SoapKernel
|
||||
* @param SoapResponse $response SOAP response
|
||||
* @param SoapRequestFilter[]|SoapResponseFilter[] $filters
|
||||
* @param int $attachmentType = SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA|SoapOptions::ATTACHMENTS_TYPE_MTOM|SoapOptions::ATTACHMENTS_TYPE_BASE64
|
||||
* @return SoapResponse
|
||||
* @return \BeSimple\SoapClient\SoapResponse|\BeSimple\SoapServer\SoapResponse
|
||||
*/
|
||||
public function filterResponse(SoapResponse $response, array $filters, $attachmentType)
|
||||
public static function filterResponse(SoapResponse $response, array $filters, $attachmentType)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
if ($filter instanceof SoapResponseFilter) {
|
||||
|
@ -62,7 +62,7 @@ abstract class SoapMessage
|
||||
/**
|
||||
* Mime attachments.
|
||||
*
|
||||
* @var array(\BeSimple\SoapCommon\Mime\Part)
|
||||
* @var \BeSimple\SoapCommon\Mime\Part[]
|
||||
*/
|
||||
protected $attachments;
|
||||
|
||||
|
@ -66,6 +66,7 @@ class SoapOptions
|
||||
$this->soapFeatures = $features;
|
||||
$this->wsdlFile = $wsdlFile;
|
||||
$this->wsdlCacheType = $wsdlCacheType;
|
||||
$this->wsdlCacheDir = $wsdlCacheDir;
|
||||
$this->classMap = $classMap;
|
||||
$this->typeConverterCollection = $typeConverterCollection;
|
||||
$this->attachmentType = $attachmentType;
|
||||
|
@ -18,11 +18,11 @@ use BeSimple\SoapCommon\SoapOptions\SoapOptions;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Petr Bechyně <petr.bechyne@vodafone.com>
|
||||
* @author Petr Bechyně <mail@petrbechyne.com>
|
||||
*/
|
||||
class SoapOptionsBuilder
|
||||
{
|
||||
static public function createWithDefaults(
|
||||
public static function createWithDefaults(
|
||||
$wsdlFile,
|
||||
$wsdlCacheType = SoapOptions::SOAP_CACHE_TYPE_NONE,
|
||||
$wsdlCacheDir = null
|
||||
@ -30,16 +30,37 @@ class SoapOptionsBuilder
|
||||
return self::createWithClassMap($wsdlFile, new ClassMap(), $wsdlCacheType, $wsdlCacheDir);
|
||||
}
|
||||
|
||||
static public function createSwaWithClassMap(
|
||||
public static function createSwaWithClassMap(
|
||||
$wsdlFile,
|
||||
ClassMap $classMap,
|
||||
$wsdlCacheType = SoapOptions::SOAP_CACHE_TYPE_NONE,
|
||||
$wsdlCacheDir = null
|
||||
) {
|
||||
return self::createWithClassMap($wsdlFile, $classMap, $wsdlCacheType, $wsdlCacheDir, SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA);
|
||||
return self::createWithClassMap(
|
||||
$wsdlFile,
|
||||
$classMap,
|
||||
$wsdlCacheType,
|
||||
$wsdlCacheDir,
|
||||
SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA
|
||||
);
|
||||
}
|
||||
|
||||
static public function createWithClassMap(
|
||||
public static function createSwaWithClassMapV11(
|
||||
$wsdlFile,
|
||||
ClassMap $classMap,
|
||||
$wsdlCacheType = SoapOptions::SOAP_CACHE_TYPE_NONE,
|
||||
$wsdlCacheDir = null
|
||||
) {
|
||||
return self::createWithClassMapV11(
|
||||
$wsdlFile,
|
||||
$classMap,
|
||||
$wsdlCacheType,
|
||||
$wsdlCacheDir,
|
||||
SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA
|
||||
);
|
||||
}
|
||||
|
||||
public static function createWithClassMap(
|
||||
$wsdlFile,
|
||||
ClassMap $classMap,
|
||||
$wsdlCacheType = SoapOptions::SOAP_CACHE_TYPE_NONE,
|
||||
@ -54,7 +75,8 @@ class SoapOptionsBuilder
|
||||
throw new InvalidArgumentException('Cache dir must be set for this wsdl cache type');
|
||||
}
|
||||
}
|
||||
$soapOptions = new SoapOptions(
|
||||
|
||||
return new SoapOptions(
|
||||
SoapOptions::SOAP_VERSION_1_2,
|
||||
SoapOptions::SOAP_ENCODING_UTF8,
|
||||
SoapOptions::SOAP_CONNECTION_KEEP_ALIVE_OFF,
|
||||
@ -68,7 +90,37 @@ class SoapOptionsBuilder
|
||||
new TypeConverterCollection(),
|
||||
$attachmentType
|
||||
);
|
||||
}
|
||||
|
||||
return $soapOptions;
|
||||
public static function createWithClassMapV11(
|
||||
$wsdlFile,
|
||||
ClassMap $classMap,
|
||||
$wsdlCacheType = SoapOptions::SOAP_CACHE_TYPE_NONE,
|
||||
$wsdlCacheDir = null,
|
||||
$attachmentType = null
|
||||
) {
|
||||
if (!Cache::hasType($wsdlCacheType)) {
|
||||
throw new InvalidArgumentException('Invalid cache type');
|
||||
}
|
||||
if ($wsdlCacheType !== SoapOptions::SOAP_CACHE_TYPE_NONE) {
|
||||
if ($wsdlCacheDir === null) {
|
||||
throw new InvalidArgumentException('Cache dir must be set for this wsdl cache type');
|
||||
}
|
||||
}
|
||||
|
||||
return new SoapOptions(
|
||||
SoapOptions::SOAP_VERSION_1_1,
|
||||
SoapOptions::SOAP_ENCODING_UTF8,
|
||||
SoapOptions::SOAP_CONNECTION_KEEP_ALIVE_OFF,
|
||||
new SoapFeatures([
|
||||
SoapFeatures::SINGLE_ELEMENT_ARRAYS
|
||||
]),
|
||||
$wsdlFile,
|
||||
$wsdlCacheType,
|
||||
$wsdlCacheDir,
|
||||
$classMap,
|
||||
new TypeConverterCollection(),
|
||||
$attachmentType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,19 +7,22 @@ class SoapRequestFactory
|
||||
/**
|
||||
* Factory function for SoapRequest.
|
||||
*
|
||||
* @param string $location Location
|
||||
* @param string $action SOAP action
|
||||
* @param string $version SOAP version
|
||||
* @param string $contentType Content Type
|
||||
* @param string $content Content
|
||||
*
|
||||
* @param string $location Location
|
||||
* @param string $action SOAP action
|
||||
* @param string $version SOAP version
|
||||
* @param string $contentType Content Type
|
||||
* @param string $content Content
|
||||
* @return SoapRequest
|
||||
*/
|
||||
public static function create($location, $action, $version, $contentType, $content = null)
|
||||
{
|
||||
public static function createWithContentType(
|
||||
$location,
|
||||
$action,
|
||||
$version,
|
||||
$contentType,
|
||||
$content = null
|
||||
) {
|
||||
$request = new SoapRequest();
|
||||
// $content is if unmodified from SoapClient not a php string type!
|
||||
$request->setContent((string) $content);
|
||||
$request->setContent($content);
|
||||
$request->setLocation($location);
|
||||
$request->setAction($action);
|
||||
$request->setVersion($version);
|
||||
@ -27,4 +30,29 @@ class SoapRequestFactory
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function for SoapRequest.
|
||||
*
|
||||
* @param string $location Location
|
||||
* @param string $action SOAP action
|
||||
* @param string $version SOAP version
|
||||
* @param string $content Content
|
||||
* @return SoapRequest
|
||||
*/
|
||||
public static function create(
|
||||
$location,
|
||||
$action,
|
||||
$version,
|
||||
$content = null
|
||||
) {
|
||||
|
||||
return self::createWithContentType(
|
||||
$location,
|
||||
$action,
|
||||
$version,
|
||||
SoapRequest::getContentTypeForVersion($version),
|
||||
$content
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,31 @@
|
||||
|
||||
namespace BeSimple\SoapCommon;
|
||||
|
||||
use BeSimple\SoapCommon\SoapMessage;
|
||||
use BeSimple\SoapClient\SoapResponseTracingData;
|
||||
|
||||
/**
|
||||
* SOAP response message.
|
||||
*
|
||||
* @author Christian Kerl <christian-kerl@web.de>
|
||||
* @author Petr Bechyně <mail@petrbechyne.com>
|
||||
*/
|
||||
class SoapResponse extends SoapMessage
|
||||
{
|
||||
/** @var SoapResponseTracingData */
|
||||
protected $tracingData;
|
||||
|
||||
}
|
||||
public function hasTracingData()
|
||||
{
|
||||
return $this->tracingData !== null;
|
||||
}
|
||||
|
||||
public function getTracingData()
|
||||
{
|
||||
return $this->tracingData;
|
||||
}
|
||||
|
||||
public function setTracingData(SoapResponseTracingData $tracingData)
|
||||
{
|
||||
$this->tracingData = $tracingData;
|
||||
}
|
||||
}
|
||||
|
@ -23,43 +23,43 @@ class ClassMapTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testAll()
|
||||
{
|
||||
$classmap = new ClassMap();
|
||||
$classMap = new ClassMap();
|
||||
|
||||
$this->assertSame(array(), $classmap->getAll());
|
||||
$this->assertSame([], $classMap->getAll());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$classmap = new ClassMap();
|
||||
$classMap = new ClassMap();
|
||||
|
||||
$classmap->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
$classMap->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$classmap->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
$classMap->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$classmap = new ClassMap();
|
||||
$classMap = new ClassMap();
|
||||
|
||||
$classmap->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
$this->assertSame('BeSimple\SoapCommon\ClassMap', $classmap->get('foobar'));
|
||||
$classMap->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
$this->assertSame('BeSimple\SoapCommon\ClassMap', $classMap->get('foobar'));
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$classmap->get('bar');
|
||||
$this->setExpectedException('Exception');
|
||||
$classMap->get('bar');
|
||||
}
|
||||
|
||||
public function testAddClassMap()
|
||||
{
|
||||
$classmap1 = new ClassMap();
|
||||
$classmap2 = new ClassMap();
|
||||
$classMap1 = new ClassMap();
|
||||
$classMap2 = new ClassMap();
|
||||
|
||||
$classmap2->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
$classmap1->addClassMap($classmap2);
|
||||
$classMap2->add('foobar', 'BeSimple\SoapCommon\ClassMap');
|
||||
$classMap1->addClassMap($classMap2);
|
||||
|
||||
$this->assertEquals(array('foobar' => 'BeSimple\SoapCommon\ClassMap'), $classmap1->getAll());
|
||||
$this->assertEquals(['foobar' => 'BeSimple\SoapCommon\ClassMap'], $classMap1->getAll());
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$classmap1->addClassMap($classmap2);
|
||||
$this->setExpectedException('Exception');
|
||||
$classMap1->addClassMap($classMap2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user