diff --git a/lib/tests/moodle_url_test.php b/lib/tests/moodle_url_test.php index 786736a4ed3..4c36c81a311 100644 --- a/lib/tests/moodle_url_test.php +++ b/lib/tests/moodle_url_test.php @@ -16,6 +16,8 @@ namespace core; +use GuzzleHttp\Psr7\Uri; + /** * Tests for moodle_url. * @@ -414,4 +416,33 @@ class moodle_url_test extends \advanced_testcase { ], ]; } + + public function test_from_uri(): void { + global $CFG; + + $uri = new Uri('http://www.example.org:447/my/file/is/here.txt?really=1'); + $url = \moodle_url::from_uri($uri); + $this->assertSame('http://www.example.org:447/my/file/is/here.txt?really=1', $url->out(false)); + $this->assertEquals(1, $url->param('really')); + + $uri = new Uri('https://www.example.org/my/file/is/here.txt?really=1'); + $url = \moodle_url::from_uri($uri); + $this->assertSame('https://www.example.org/my/file/is/here.txt?really=1', $url->out(false)); + $this->assertEquals(1, $url->param('really')); + + // Multiple params. + $uri = new Uri('https://www.example.org/my/file/is/here.txt?really=1&another=2&&more=3&moar=4'); + $url = \moodle_url::from_uri($uri); + $this->assertSame('https://www.example.org/my/file/is/here.txt?really=1&another=2&more=3&moar=4', $url->out(false)); + $this->assertEquals(1, $url->param('really')); + $this->assertEquals(2, $url->param('another')); + $this->assertEquals(3, $url->param('more')); + $this->assertEquals(4, $url->param('moar')); + + // Anchors. + $uri = new Uri("{$CFG->wwwroot}/course/view/#section-1"); + $url = \moodle_url::from_uri($uri); + $this->assertSame("{$CFG->wwwroot}/course/view/#section-1", $url->out(false)); + $this->assertEmpty($url->params()); + } } diff --git a/lib/weblib.php b/lib/weblib.php index 0cac8cf5e83..a4e6dbb9cd5 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -30,6 +30,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use Psr\Http\Message\UriInterface; + defined('MOODLE_INTERNAL') || die(); // Constants. @@ -770,6 +772,26 @@ class moodle_url { // Static factory methods. + /** + * Create a new moodle_url instance from a UriInterface. + * + * @param UriInterface $uri + * @return self + */ + public static function from_uri(UriInterface $uri): self { + $url = new self( + url: $uri->getScheme() . '://' . $uri->getAuthority() . $uri->getPath(), + anchor: $uri->getFragment() ?: null, + ); + + $params = $uri->getQuery(); + foreach (explode('&', $params) as $param) { + $url->param(...explode('=', $param, 2)); + } + + return $url; + } + /** * General moodle file url. *