diff --git a/src/BeSimple/SoapClient/SoapClient.php b/src/BeSimple/SoapClient/SoapClient.php
index 19d5be9..79d7e31 100644
--- a/src/BeSimple/SoapClient/SoapClient.php
+++ b/src/BeSimple/SoapClient/SoapClient.php
@@ -241,19 +241,17 @@ class SoapClient extends \SoapClient
*/
private function loadWsdl($wsdl, array $options)
{
- // option to resolve xsd includes
- $resolveXsdIncludes = true;
- if (isset($options['resolve_xsd_includes']))
- {
- $resolveXsdIncludes = $options['resolve_xsd_includes'];
+ // option to resolve wsdl/xsd includes
+ $resolveRemoteIncludes = true;
+ if (isset($options['resolve_wsdl_remote_includes'])) {
+ $resolveRemoteIncludes = $options['resolve_wsdl_remote_includes'];
}
// option to enable cache
$wsdlCache = WSDL_CACHE_DISK;
- if (isset($options['cache_wsdl']))
- {
+ if (isset($options['cache_wsdl'])) {
$wsdlCache = $options['cache_wsdl'];
}
- $wsdlDownloader = new WsdlDownloader($this->curl, $resolveXsdIncludes, $wsdlCache);
+ $wsdlDownloader = new WsdlDownloader($this->curl, $resolveRemoteIncludes, $wsdlCache);
try {
$cacheFileName = $wsdlDownloader->download($wsdl);
} catch (\RuntimeException $e) {
diff --git a/src/BeSimple/SoapClient/WsdlDownloader.php b/src/BeSimple/SoapClient/WsdlDownloader.php
index 540c801..1894269 100644
--- a/src/BeSimple/SoapClient/WsdlDownloader.php
+++ b/src/BeSimple/SoapClient/WsdlDownloader.php
@@ -54,23 +54,23 @@ class WsdlDownloader
private $curl;
/**
- * Resolve XSD includes.
+ * Resolve WSDl/XSD includes.
*
* @var boolean
*/
- protected $resolveXsdIncludes = true;
+ protected $resolveRemoteIncludes = true;
/**
* Constructor.
*
- * @param \BeSimple\SoapClient\Curl $curl Curl instance
- * @param boolean $resolveXsdIncludes XSD include enabled?
- * @param boolean $cacheWsdl Cache constant
+ * @param \BeSimple\SoapClient\Curl $curl Curl instance
+ * @param boolean $resolveRemoteIncludes WSDL/XSD include enabled?
+ * @param boolean $cacheWsdl Cache constant
*/
- public function __construct(Curl $curl, $resolveXsdIncludes = true, $cacheWsdl = WSDL_CACHE_DISK)
+ public function __construct(Curl $curl, $resolveRemoteIncludes = true, $cacheWsdl = WSDL_CACHE_DISK)
{
$this->curl = $curl;
- $this->resolveXsdIncludes = $resolveXsdIncludes;
+ $this->resolveRemoteIncludes = $resolveRemoteIncludes;
// get current WSDL caching config
$this->cacheEnabled = (bool)ini_get('soap.wsdl_cache_enabled');
if ($this->cacheEnabled === true
@@ -96,7 +96,7 @@ class WsdlDownloader
// download and cache remote WSDL files or local ones where we want to
// resolve remote XSD includes
$isRemoteFile = $this->isRemoteFile($wsdl);
- if ($isRemoteFile === true || $this->resolveXsdIncludes === true) {
+ if ($isRemoteFile === true || $this->resolveRemoteIncludes === true) {
$cacheFile = $this->cacheDir . DIRECTORY_SEPARATOR . 'wsdl_' . md5($wsdl) . '.cache';
if ($this->cacheEnabled === false
|| !file_exists($cacheFile)
@@ -107,8 +107,8 @@ class WsdlDownloader
// get content
if ($responseSuccessfull === true) {
$response = $this->curl->getResponseBody();
- if ($this->resolveXsdIncludes === true) {
- $this->resolveXsdIncludes($response, $cacheFile, $wsdl);
+ if ($this->resolveRemoteIncludes === true) {
+ $this->resolveRemoteIncludes($response, $cacheFile, $wsdl);
} else {
file_put_contents($cacheFile, $response);
}
@@ -117,7 +117,7 @@ class WsdlDownloader
}
} elseif (file_exists($wsdl)) {
$response = file_get_contents($wsdl);
- $this->resolveXsdIncludes($response, $cacheFile);
+ $this->resolveRemoteIncludes($response, $cacheFile);
} else {
throw new \ErrorException("SOAP-ERROR: Parsing WSDL: Couldn't load from '" . $wsdl ."'");
}
@@ -149,20 +149,38 @@ class WsdlDownloader
}
/**
- * Resolves remote XSD includes within the WSDL files.
+ * Resolves remote WSDL/XSD includes within the WSDL files.
*
* @param string $xml
* @param string $cacheFile
* @param unknown_type $parentIsRemote
* @return string
*/
- private function resolveXsdIncludes($xml, $cacheFile, $parentFile = null)
+ private function resolveRemoteIncludes($xml, $cacheFile, $parentFile = null)
{
$doc = new \DOMDocument();
$doc->loadXML($xml);
$xpath = new \DOMXPath($doc);
$xpath->registerNamespace(Helper::PFX_XML_SCHEMA, Helper::NS_XML_SCHEMA);
- $query = './/' . Helper::PFX_XML_SCHEMA . ':include';
+ $xpath->registerNamespace('wsdl', 'http://schemas.xmlsoap.org/wsdl/'); // TODO add to Helper
+ // WSDL include/import
+ $query = './/wsdl:include | .//wsdl:import';
+ $nodes = $xpath->query($query);
+ if ($nodes->length > 0) {
+ foreach ($nodes as $node) {
+ $location = $node->getAttribute('location');
+ if ($this->isRemoteFile($location)) {
+ $location = $this->download($location);
+ $node->setAttribute('location', $location);
+ } elseif (!is_null($parentFile)) {
+ $location = $this->resolveRelativePathInUrl($parentFile, $location);
+ $location = $this->download($location);
+ $node->setAttribute('location', $location);
+ }
+ }
+ }
+ // XML schema include/import
+ $query = './/' . Helper::PFX_XML_SCHEMA . ':include | .//' . Helper::PFX_XML_SCHEMA . ':import';
$nodes = $xpath->query($query);
if ($nodes->length > 0) {
foreach ($nodes as $node) {
diff --git a/tests/BeSimple/Tests/SoapClient/Fixtures/wsdl_include.wsdl b/tests/BeSimple/Tests/SoapClient/Fixtures/wsdl_include.wsdl
new file mode 100644
index 0000000..775240a
--- /dev/null
+++ b/tests/BeSimple/Tests/SoapClient/Fixtures/wsdl_include.wsdl
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/BeSimple/Tests/SoapClient/Fixtures/wsdlinclude/wsdlinctest_absolute.xml b/tests/BeSimple/Tests/SoapClient/Fixtures/wsdlinclude/wsdlinctest_absolute.xml
new file mode 100644
index 0000000..dae033e
--- /dev/null
+++ b/tests/BeSimple/Tests/SoapClient/Fixtures/wsdlinclude/wsdlinctest_absolute.xml
@@ -0,0 +1,5 @@
+
+
+ wsdlincludetest
+
+
diff --git a/tests/BeSimple/Tests/SoapClient/Fixtures/wsdlinclude/wsdlinctest_relative.xml b/tests/BeSimple/Tests/SoapClient/Fixtures/wsdlinclude/wsdlinctest_relative.xml
new file mode 100644
index 0000000..8148e60
--- /dev/null
+++ b/tests/BeSimple/Tests/SoapClient/Fixtures/wsdlinclude/wsdlinctest_relative.xml
@@ -0,0 +1,5 @@
+
+
+ wsdlincludetest
+
+
diff --git a/tests/BeSimple/Tests/SoapClient/WsdlDownloaderTest.php b/tests/BeSimple/Tests/SoapClient/WsdlDownloaderTest.php
index f294a8b..14ac58a 100644
--- a/tests/BeSimple/Tests/SoapClient/WsdlDownloaderTest.php
+++ b/tests/BeSimple/Tests/SoapClient/WsdlDownloaderTest.php
@@ -115,6 +115,63 @@ class WsdlDownloaderTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($method->invoke($wd, '../dir/test.html'));
}
+ public function testResolveWsdlIncludes()
+ {
+ $this->startPhpWebserver();
+
+ $curl = new Curl();
+ $wd = new WsdlDownloader($curl);
+
+ $class = new \ReflectionClass($wd);
+ $method = $class->getMethod('resolveRemoteIncludes');
+ $method->setAccessible(true);
+
+ $cacheDir = ini_get('soap.wsdl_cache_dir');
+ if (!is_dir($cacheDir)) {
+ $cacheDir = sys_get_temp_dir();
+ $cacheDirForRegExp = preg_quote( $cacheDir );
+ }
+
+ $remoteUrlAbsolute = 'http://localhost:8000/wsdlinclude/wsdlinctest_absolute.xml';
+ $remoteUrlRelative = 'http://localhost:8000/wsdlinclude/wsdlinctest_relative.xml';
+ $tests = array(
+ 'localWithAbsolutePath' => array(
+ 'source' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/wsdlinclude/wsdlinctest_absolute.xml',
+ 'cacheFile' => $cacheDir.'/cache_local_absolute.xml',
+ 'remoteParentUrl' => null,
+ 'assertRegExp' => '~.*'.$cacheDirForRegExp.'\\\wsdl_.*\.cache.*~',
+ ),
+ 'localWithRelativePath' => array(
+ 'source' => __DIR__.DIRECTORY_SEPARATOR.'Fixtures/wsdlinclude/wsdlinctest_relative.xml',
+ 'cacheFile' => $cacheDir.'/cache_local_relative.xml',
+ 'remoteParentUrl' => null,
+ 'assertRegExp' => '~.*\.\./wsdl_include\.wsdl.*~',
+ ),
+ 'remoteWithAbsolutePath' => array(
+ 'source' => $remoteUrlAbsolute,
+ 'cacheFile' => $cacheDir.'/cache_remote_absolute.xml',
+ 'remoteParentUrl' => $remoteUrlAbsolute,
+ 'assertRegExp' => '~.*'.$cacheDirForRegExp.'\\\wsdl_.*\.cache.*~',
+ ),
+ 'remoteWithAbsolutePath' => array(
+ 'source' => $remoteUrlRelative,
+ 'cacheFile' => $cacheDir.'/cache_remote_relative.xml',
+ 'remoteParentUrl' => $remoteUrlRelative,
+ 'assertRegExp' => '~.*'.$cacheDirForRegExp.'\\\wsdl_.*\.cache.*~',
+ ),
+ );
+
+ foreach ($tests as $name => $values) {
+ $wsdl = file_get_contents( $values['source'] );
+ $method->invoke($wd, $wsdl, $values['cacheFile'],$values['remoteParentUrl']);
+ $result = file_get_contents($values['cacheFile']);
+ $this->assertRegExp($values['assertRegExp'],$result,$name);
+ unlink($values['cacheFile']);
+ }
+
+ $this->stopPhpWebserver();
+ }
+
public function testResolveXsdIncludes()
{
$this->startPhpWebserver();
@@ -123,7 +180,7 @@ class WsdlDownloaderTest extends \PHPUnit_Framework_TestCase
$wd = new WsdlDownloader($curl);
$class = new \ReflectionClass($wd);
- $method = $class->getMethod('resolveXsdIncludes');
+ $method = $class->getMethod('resolveRemoteIncludes');
$method->setAccessible(true);
$cacheDir = ini_get('soap.wsdl_cache_dir');