diff --git a/src/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacer.php b/src/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacer.php index d915b15..6788682 100644 --- a/src/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacer.php +++ b/src/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacer.php @@ -4,6 +4,7 @@ namespace BeSimple\SoapClient\Xml; use BeSimple\SoapClient\Curl\Curl; use BeSimple\SoapClient\WsdlDownloader; +use BeSimple\SoapClient\Xml\Path\RelativePathResolver; use DOMElement; use DOMXPath; @@ -45,7 +46,8 @@ class XmlDomDocumentImportReplacer $locationAttributeName, WsdlDownloader::instantiateDownloader()->getWsdlPath( $curl, - self::resolveRelativePathInUrl($parentFilePath, $locationPath), + RelativePathResolver::instantiateResolver() + ->resolveRelativePathInUrl($parentFilePath, $locationPath), $cacheType, true ) @@ -55,68 +57,4 @@ class XmlDomDocumentImportReplacer } } } - - /** - * Resolves the relative path to base into an absolute. - * - * @param string $base Base path - * @param string $relative Relative path - * - * @return string - */ - private static function resolveRelativePathInUrl($base, $relative) - { - $urlParts = parse_url($base); - $isRelativePathAbsolute = 0 === strpos($relative, '/') || 0 === strpos($relative, '..'); - - // combine base path with relative path - if (isset($urlParts['path']) && mb_strlen($relative) > 0 && $isRelativePathAbsolute) { - // $relative is absolute path from domain (starts with /) - $path = $relative; - } elseif (isset($urlParts['path']) && strrpos($urlParts['path'], '/') === (strlen($urlParts['path']) )) { - // base path is directory - $path = $urlParts['path'].$relative; - } elseif (isset($urlParts['path'])) { - // strip filename from base path - $path = substr($urlParts['path'], 0, strrpos($urlParts['path'], '/')).'/'.$relative; - } else { - // no base path - $path = '/'.$relative; - } - - // foo/./bar ==> foo/bar - // remove double slashes - $path = preg_replace(array('#/\./#', '#/+#'), '/', $path); - - // split path by '/' - $parts = explode('/', $path); - - // resolve /../ - foreach ($parts as $key => $part) { - if ($part === '..') { - $keyToDelete = $key - 1; - while ($keyToDelete > 0) { - if (isset($parts[$keyToDelete])) { - unset($parts[$keyToDelete]); - - break; - } - - $keyToDelete--; - } - - unset($parts[$key]); - } - } - - $hostname = $urlParts['scheme'].'://'.$urlParts['host']; - if (isset($urlParts['port'])) { - $hostname .= ':'.$urlParts['port']; - } - if (substr($hostname, -1) !== '/') { - $hostname .= '/'; - } - - return $hostname.implode('/', $parts); - } } diff --git a/tests/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacerTest.php b/tests/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacerTest.php index 0f2c4b9..11a435d 100644 --- a/tests/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacerTest.php +++ b/tests/BeSimple/SoapClient/Xml/XmlDomDocumentImportReplacerTest.php @@ -97,9 +97,18 @@ class XmlDomDocumentImportReplacerTest extends PHPUnit_Framework_TestCase Helper::PFX_XML_SCHEMA, Helper::NS_XML_SCHEMA, 'schemaLocation', - 'http://endpoint-location.ltd:8080/endpoint/', + 'http://endpoint-location.ltd:8080/endpoint/wsdl.wsdl', '' ], + 'schemaWithParentPathAndSubDir' => [ + file_get_contents(__DIR__.'/testUpdateXmlDocument.wsdl'), + new Curl(CurlOptionsBuilder::buildDefault()), + Helper::PFX_XML_SCHEMA, + Helper::NS_XML_SCHEMA, + 'schemaLocation', + 'http://endpoint-location.ltd:8080/endpoint/subdir/wsdl.wsdl', + '' + ], ]; } }