[DomCrawler] Allow using non-absolute base URIs

This commit is contained in:
Javier Eguiluz 2018-07-23 13:39:46 +02:00 committed by Fabien Potencier
parent f834c9262b
commit 130119ff6a
5 changed files with 47 additions and 8 deletions

View File

@ -40,15 +40,17 @@ abstract class AbstractUriElement
* *
* @throws \InvalidArgumentException if the node is not a link * @throws \InvalidArgumentException if the node is not a link
*/ */
public function __construct(\DOMElement $node, string $currentUri, ?string $method = 'GET') public function __construct(\DOMElement $node, string $currentUri = null, ?string $method = 'GET')
{ {
if (!\in_array(strtolower(substr($currentUri, 0, 4)), array('http', 'file'))) {
throw new \InvalidArgumentException(sprintf('Current URI must be an absolute URL ("%s").', $currentUri));
}
$this->setNode($node); $this->setNode($node);
$this->method = $method ? strtoupper($method) : null; $this->method = $method ? strtoupper($method) : null;
$this->currentUri = $currentUri; $this->currentUri = $currentUri;
$elementUriIsRelative = null === parse_url(trim($this->getRawUri()), PHP_URL_SCHEME);
$baseUriIsAbsolute = \in_array(strtolower(substr($this->currentUri, 0, 4)), array('http', 'file'));
if ($elementUriIsRelative && !$baseUriIsAbsolute) {
throw new \InvalidArgumentException(sprintf('The URL of the element is relative, so you must define its base URI passing an absolute URL to the constructor of the %s class ("%s" was passed).', __CLASS__, $this->currentUri));
}
} }
/** /**

View File

@ -1,6 +1,12 @@
CHANGELOG CHANGELOG
========= =========
4.2.0
-----
* The `$currentUri` constructor argument of the `AbstractUriElement`, `Link` and
`Image` classes is now optional.
3.1.0 3.1.0
----- -----

View File

@ -16,7 +16,7 @@ namespace Symfony\Component\DomCrawler;
*/ */
class Image extends AbstractUriElement class Image extends AbstractUriElement
{ {
public function __construct(\DOMElement $node, string $currentUri) public function __construct(\DOMElement $node, string $currentUri = null)
{ {
parent::__construct($node, $currentUri, 'GET'); parent::__construct($node, $currentUri, 'GET');
} }

View File

@ -27,6 +27,27 @@ class ImageTest extends TestCase
new Image($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/'); new Image($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/');
} }
public function testBaseUriIsOptionalWhenImageUrlIsAbsolute()
{
$dom = new \DOMDocument();
$dom->loadHTML('<html><img alt="foo" src="https://example.com/foo" /></html>');
$image = new Image($dom->getElementsByTagName('img')->item(0));
$this->assertSame('https://example.com/foo', $image->getUri());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testAbsoluteBaseUriIsMandatoryWhenImageUrlIsRelative()
{
$dom = new \DOMDocument();
$dom->loadHTML('<html><img alt="foo" src="/foo" /></html>');
$image = new Image($dom->getElementsByTagName('img')->item(0), 'example.com');
$image->getUri();
}
/** /**
* @dataProvider getGetUriTests * @dataProvider getGetUriTests
*/ */

View File

@ -27,15 +27,25 @@ class LinkTest extends TestCase
new Link($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/'); new Link($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/');
} }
public function testBaseUriIsOptionalWhenLinkUrlIsAbsolute()
{
$dom = new \DOMDocument();
$dom->loadHTML('<html><a href="https://example.com/foo">foo</a></html>');
$link = new Link($dom->getElementsByTagName('a')->item(0));
$this->assertSame('https://example.com/foo', $link->getUri());
}
/** /**
* @expectedException \InvalidArgumentException * @expectedException \InvalidArgumentException
*/ */
public function testConstructorWithAnInvalidCurrentUri() public function testAbsoluteBaseUriIsMandatoryWhenLinkUrlIsRelative()
{ {
$dom = new \DOMDocument(); $dom = new \DOMDocument();
$dom->loadHTML('<html><a href="/foo">foo</a></html>'); $dom->loadHTML('<html><a href="/foo">foo</a></html>');
new Link($dom->getElementsByTagName('a')->item(0), 'example.com'); $link = new Link($dom->getElementsByTagName('a')->item(0), 'example.com');
$link->getUri();
} }
public function testGetNode() public function testGetNode()