diff --git a/src/Symfony/Component/DomCrawler/AbstractUriElement.php b/src/Symfony/Component/DomCrawler/AbstractUriElement.php index 39ae522fd178..e26be3fcf694 100644 --- a/src/Symfony/Component/DomCrawler/AbstractUriElement.php +++ b/src/Symfony/Component/DomCrawler/AbstractUriElement.php @@ -40,15 +40,17 @@ abstract class AbstractUriElement * * @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->method = $method ? strtoupper($method) : null; $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)); + } } /** diff --git a/src/Symfony/Component/DomCrawler/CHANGELOG.md b/src/Symfony/Component/DomCrawler/CHANGELOG.md index e65176f5ac0b..c2065c591154 100644 --- a/src/Symfony/Component/DomCrawler/CHANGELOG.md +++ b/src/Symfony/Component/DomCrawler/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +4.2.0 +----- + +* The `$currentUri` constructor argument of the `AbstractUriElement`, `Link` and + `Image` classes is now optional. + 3.1.0 ----- diff --git a/src/Symfony/Component/DomCrawler/Image.php b/src/Symfony/Component/DomCrawler/Image.php index fb83eaac1989..b1ac5ca2ccb4 100644 --- a/src/Symfony/Component/DomCrawler/Image.php +++ b/src/Symfony/Component/DomCrawler/Image.php @@ -16,7 +16,7 @@ */ class Image extends AbstractUriElement { - public function __construct(\DOMElement $node, string $currentUri) + public function __construct(\DOMElement $node, string $currentUri = null) { parent::__construct($node, $currentUri, 'GET'); } diff --git a/src/Symfony/Component/DomCrawler/Tests/ImageTest.php b/src/Symfony/Component/DomCrawler/Tests/ImageTest.php index 309578a90233..5cac757cdfb3 100644 --- a/src/Symfony/Component/DomCrawler/Tests/ImageTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/ImageTest.php @@ -27,6 +27,27 @@ public function testConstructorWithANonImgTag() new Image($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/'); } + public function testBaseUriIsOptionalWhenImageUrlIsAbsolute() + { + $dom = new \DOMDocument(); + $dom->loadHTML('foo'); + + $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('foo'); + + $image = new Image($dom->getElementsByTagName('img')->item(0), 'example.com'); + $image->getUri(); + } + /** * @dataProvider getGetUriTests */ diff --git a/src/Symfony/Component/DomCrawler/Tests/LinkTest.php b/src/Symfony/Component/DomCrawler/Tests/LinkTest.php index 3f0364705f98..f485cc2ac1ee 100644 --- a/src/Symfony/Component/DomCrawler/Tests/LinkTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/LinkTest.php @@ -27,15 +27,25 @@ public function testConstructorWithANonATag() new Link($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/'); } + public function testBaseUriIsOptionalWhenLinkUrlIsAbsolute() + { + $dom = new \DOMDocument(); + $dom->loadHTML('foo'); + + $link = new Link($dom->getElementsByTagName('a')->item(0)); + $this->assertSame('https://example.com/foo', $link->getUri()); + } + /** * @expectedException \InvalidArgumentException */ - public function testConstructorWithAnInvalidCurrentUri() + public function testAbsoluteBaseUriIsMandatoryWhenLinkUrlIsRelative() { $dom = new \DOMDocument(); $dom->loadHTML('foo'); - new Link($dom->getElementsByTagName('a')->item(0), 'example.com'); + $link = new Link($dom->getElementsByTagName('a')->item(0), 'example.com'); + $link->getUri(); } public function testGetNode()