浏览代码

[DomCrawler] Fixed Form::getUri() and Link::getUri() issue if the form action attribute is an absolute url

Nicolas Fabre 15 年之前
父节点
当前提交
6613555059

+ 3 - 2
src/Symfony/Components/DomCrawler/Form.php

@@ -169,17 +169,18 @@ class Form implements \ArrayAccess
     public function getUri($absolute = true)
     {
         $uri = $this->node->getAttribute('action');
+        $urlHaveScheme = 'http' === substr($uri, 0, 4);
 
         if (!in_array($this->getMethod(), array('post', 'put', 'delete')) && $queryString = http_build_query($this->getValues(), null, '&')) {
             $sep = false === strpos($uri, '?') ? '?' : '&';
             $uri .= $sep.$queryString;
         }
 
-        if ($uri && '/' !== $uri[0]) {
+        if ($uri && '/' !== $uri[0] && !$urlHaveScheme) {
             $uri = $this->path.$uri;
         }
 
-        if ($absolute && null !== $this->host) {
+        if ($absolute && null !== $this->host && !$urlHaveScheme) {
             return $this->host.$uri;
         }
 

+ 3 - 2
src/Symfony/Components/DomCrawler/Link.php

@@ -67,12 +67,13 @@ class Link
     public function getUri($absolute = true)
     {
         $uri = $this->node->getAttribute('href');
+        $urlHaveScheme = 'http' === substr($uri, 0, 4);
 
-        if ($uri && '/' !== $uri[0]) {
+        if ($uri && '/' !== $uri[0] && !$urlHaveScheme) {
             $uri = $this->path.$uri;
         }
 
-        if ($absolute && null !== $this->host) {
+        if ($absolute && null !== $this->host && !$urlHaveScheme) {
             return $this->host.$uri;
         }
 

+ 21 - 0
tests/Symfony/Tests/Components/DomCrawler/FormTest.php

@@ -244,6 +244,27 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($uri, $form->getUri(), '->getUri() '.$message);
     }
 
+    public function testGetUriActionAbsolute()
+    {
+        $formHtml='<form id="login_form" action="https://login.foo.com/login.php?login_attempt=1" method="POST"><input type="text" name="foo" value="foo" /><input type="submit" /></form>';
+
+        $form = $this->createForm($formHtml);
+        $this->assertEquals('https://login.foo.com/login.php?login_attempt=1', $form->getUri(), '->getUri() returns absolute URIs set in the action form');
+
+        $form = $this->createForm($formHtml, null, 'https://login.foo.com');
+        $this->assertEquals('https://login.foo.com/login.php?login_attempt=1', $form->getUri(), '->getUri() returns absolute URIs set in the action form');
+
+        $form = $this->createForm($formHtml, null, 'https://login.foo.com', '/bar/');
+        $this->assertEquals('https://login.foo.com/login.php?login_attempt=1', $form->getUri(), '->getUri() returns absolute URIs set in the action form');
+
+        // The action URI haven't the same domain Host have an another domain as Host
+        $form = $this->createForm($formHtml, null, 'https://www.foo.com');
+        $this->assertEquals('https://login.foo.com/login.php?login_attempt=1', $form->getUri(), '->getUri() returns absolute URIs set in the action form');
+
+        $form = $this->createForm($formHtml, null, 'https://www.foo.com', '/bar/');
+        $this->assertEquals('https://login.foo.com/login.php?login_attempt=1', $form->getUri(), '->getUri() returns absolute URIs set in the action form');
+    }
+
     public function testGetUriAbsolute()
     {
         $form = $this->createForm('<form action="foo"><input type="submit" /></form>', null, 'http://localhost', '/foo/');

+ 16 - 0
tests/Symfony/Tests/Components/DomCrawler/LinkTest.php

@@ -56,5 +56,21 @@ class LinkTest extends \PHPUnit_Framework_TestCase
         $link = new Link($node, 'get', 'http://localhost', '/bar/');
         $this->assertEquals('http://localhost/bar/foo', $link->getUri(), '->getUri() returns the absolute URI of the link for relative hrefs');
         $this->assertEquals('/bar/foo', $link->getUri(false), '->getUri() returns the relative URI of the link if false is the first argument');
+
+        $dom = new \DOMDocument();
+        $dom->loadHTML('<html><a href="http://login.foo.com/foo">foo</a></html>');
+        $node = $dom->getElementsByTagName('a')->item(0);
+
+        $link = new Link($node, 'get', 'http://www.foo.com');
+        $this->assertEquals('http://login.foo.com/foo', $link->getUri(), '->getUri() returns the absolute URI of the link, regardless of the context of the object');
+
+        $link = new Link($node, 'get');
+        $this->assertEquals('http://login.foo.com/foo', $link->getUri(), '->getUri() returns the absolute URI of the link, regardless of the context of the object');
+
+        $link = new Link($node, 'get', null, '/bar/');
+        $this->assertEquals('http://login.foo.com/foo', $link->getUri(), '->getUri() returns the absolute URI of the link, regardless of the context of the object');
+
+        $link = new Link($node, 'get','http://www.foo.com','/bar/');
+        $this->assertEquals('http://login.foo.com/foo', $link->getUri(), '->getUri() returns the absolute URI of the link, regardless of the context of the object');
     }
 }