diff --git a/src/Routing/Routable.php b/src/Routing/Routable.php index e31f3430cc8..cc084b10769 100644 --- a/src/Routing/Routable.php +++ b/src/Routing/Routable.php @@ -36,7 +36,12 @@ public function url() return $this->redirectUrl(); } - return URL::makeRelative($this->absoluteUrl()); + return $this->urlWithoutRedirect(); + } + + public function urlWithoutRedirect() + { + return URL::makeRelative($this->absoluteUrlWithoutRedirect()); } public function absoluteUrl() @@ -45,6 +50,11 @@ public function absoluteUrl() return $this->redirectUrl(); } + return $this->absoluteUrlWithoutRedirect(); + } + + public function absoluteUrlWithoutRedirect() + { $url = vsprintf('%s/%s', [ rtrim($this->site()->absoluteUrl(), '/'), ltrim($this->uri(), '/'), diff --git a/src/Structures/Page.php b/src/Structures/Page.php index 75569478eeb..102c066ea0f 100644 --- a/src/Structures/Page.php +++ b/src/Structures/Page.php @@ -42,22 +42,17 @@ public function setUrl($url) public function url() { - if ($this->url) { - return $this->url; - } - - if ($this->isRedirect()) { - return $this->redirectUrl(); - } + return $this->url ?? optional($this->entry())->url(); + } - if ($this->reference && $this->referenceExists()) { - return URL::makeRelative($this->absoluteUrl()); - } + public function urlWithoutRedirect() + { + return $this->url ?? optional($this->entry())->urlWithoutRedirect(); } public function isRedirect() { - return optional($this->entry())->isRedirect(); + return optional($this->entry())->isRedirect() ?? false; } public function setDepth($depth) @@ -157,8 +152,12 @@ public function slug() public function uri() { + if ($this->url) { + return $this->url(); + } + if (! $this->reference) { - return optional($this->parent)->uri(); + return null; } $uris = Blink::store('structure-uris'); @@ -185,21 +184,19 @@ public function uri() public function absoluteUrl() { if ($this->url) { - return $this->url; + return URL::makeAbsolute($this->url); } - if ($this->isRedirect()) { - return $this->redirectUrl(); - } - - if ($this->reference && $this->referenceExists()) { - $url = vsprintf('%s/%s', [ - rtrim($this->site()->absoluteUrl(), '/'), - ltrim($this->uri(), '/'), - ]); + return optional($this->entry())->absoluteUrl(); + } - return $url === '/' ? $url : rtrim($url, '/'); + public function absoluteUrlWithoutRedirect() + { + if ($this->url) { + return $this->absoluteUrl(); } + + return optional($this->entry())->absoluteUrlWithoutRedirect(); } public function isRoot() diff --git a/src/Tags/Structure.php b/src/Tags/Structure.php index 0567b1a5cd8..03c4f5c2a4a 100644 --- a/src/Tags/Structure.php +++ b/src/Tags/Structure.php @@ -56,7 +56,7 @@ public function toArray($tree, $parent = null, $depth = 1) 'parent' => $parent, 'depth' => $depth, 'is_current' => rtrim(URL::getCurrent(), '/') == rtrim($page->url(), '/'), - 'is_parent' => Site::current()->url() === $page->url() ? false : URL::isAncestorOf(URL::getCurrent(), $page->url()), + 'is_parent' => Site::current()->url() === $page->url() ? false : URL::isAncestorOf(URL::getCurrent(), $page->urlWithoutRedirect()), 'is_external' => URL::isExternal($page->absoluteUrl()), ]); })->filter()->values()->all(); diff --git a/tests/Data/Entries/EntryTest.php b/tests/Data/Entries/EntryTest.php index ed7510d8690..c4e244b0cfb 100644 --- a/tests/Data/Entries/EntryTest.php +++ b/tests/Data/Entries/EntryTest.php @@ -204,31 +204,41 @@ public function it_gets_the_url_from_the_collection() $this->assertEquals('/blog/foo', $entryEn->uri()); $this->assertEquals('/blog/foo', $entryEn->url()); + $this->assertEquals('/blog/foo', $entryEn->urlWithoutRedirect()); $this->assertEquals('http://domain.com/blog/foo', $entryEn->absoluteUrl()); + $this->assertEquals('http://domain.com/blog/foo', $entryEn->absoluteUrlWithoutRedirect()); $this->assertEquals('http://domain.com/amp/blog/foo', $entryEn->ampUrl()); $this->assertNull($entryEn->redirectUrl()); $this->assertEquals('/le-blog/le-foo', $entryFr->uri()); $this->assertEquals('/fr/le-blog/le-foo', $entryFr->url()); + $this->assertEquals('/fr/le-blog/le-foo', $entryFr->urlWithoutRedirect()); $this->assertEquals('http://domain.com/fr/le-blog/le-foo', $entryFr->absoluteUrl()); + $this->assertEquals('http://domain.com/fr/le-blog/le-foo', $entryFr->absoluteUrlWithoutRedirect()); $this->assertEquals('http://domain.com/fr/amp/le-blog/le-foo', $entryFr->ampUrl()); $this->assertNull($entryFr->redirectUrl()); $this->assertEquals('/das-blog/das-foo', $entryDe->uri()); $this->assertEquals('/das-blog/das-foo', $entryDe->url()); + $this->assertEquals('/das-blog/das-foo', $entryDe->urlWithoutRedirect()); $this->assertEquals('http://domain.de/das-blog/das-foo', $entryDe->absoluteUrl()); + $this->assertEquals('http://domain.de/das-blog/das-foo', $entryDe->absoluteUrlWithoutRedirect()); $this->assertEquals('http://domain.de/amp/das-blog/das-foo', $entryDe->ampUrl()); $this->assertNull($entryDe->redirectUrl()); $this->assertEquals('/blog/redirected', $redirectEntry->uri()); $this->assertEquals('http://example.com/page', $redirectEntry->url()); + $this->assertEquals('/blog/redirected', $redirectEntry->urlWithoutRedirect()); $this->assertEquals('http://example.com/page', $redirectEntry->absoluteUrl()); + $this->assertEquals('http://domain.com/blog/redirected', $redirectEntry->absoluteUrlWithoutRedirect()); $this->assertNull($redirectEntry->ampUrl()); $this->assertEquals('http://example.com/page', $redirectEntry->redirectUrl()); $this->assertEquals('/blog/redirect-404', $redirect404Entry->uri()); $this->assertEquals('/blog/redirect-404', $redirect404Entry->url()); + $this->assertEquals('/blog/redirect-404', $redirect404Entry->urlWithoutRedirect()); $this->assertEquals('http://domain.com/blog/redirect-404', $redirect404Entry->absoluteUrl()); + $this->assertEquals('http://domain.com/blog/redirect-404', $redirect404Entry->absoluteUrlWithoutRedirect()); $this->assertEquals('http://domain.com/amp/blog/redirect-404', $redirect404Entry->ampUrl()); $this->assertEquals(404, $redirect404Entry->redirectUrl()); } @@ -274,14 +284,17 @@ public function it_gets_urls_for_first_child_redirects() $this->assertEquals('/parent', $parent->uri()); $this->assertEquals('/parent/child', $parent->url()); + $this->assertEquals('/parent', $parent->urlWithoutRedirect()); $this->assertEquals('/parent/child', $parent->redirectUrl()); $this->assertEquals('/parent/child', $child->uri()); $this->assertEquals('/parent/child', $child->url()); + $this->assertEquals('/parent/child', $child->urlWithoutRedirect()); $this->assertNull($child->redirectUrl()); $this->assertEquals('/nochildren', $noChildren->uri()); $this->assertEquals('/nochildren', $noChildren->url()); + $this->assertEquals('/nochildren', $noChildren->urlWithoutRedirect()); $this->assertEquals(404, $noChildren->redirectUrl()); } diff --git a/tests/Data/Structures/PageTest.php b/tests/Data/Structures/PageTest.php index 1ca7408320d..f4ea66f0bcb 100644 --- a/tests/Data/Structures/PageTest.php +++ b/tests/Data/Structures/PageTest.php @@ -148,7 +148,9 @@ public function it_gets_the_entrys_uri_when_the_structure_does_not_have_a_collec $this->assertEquals('/the/actual/entry/uri', $page->uri()); $this->assertEquals('/the/actual/entry/uri', $page->url()); + $this->assertEquals('/the/actual/entry/uri', $page->urlWithoutRedirect()); $this->assertEquals('http://localhost/the/actual/entry/uri', $page->absoluteUrl()); + $this->assertEquals('http://localhost/the/actual/entry/uri', $page->absoluteUrlWithoutRedirect()); $this->assertFalse($page->isRedirect()); } @@ -171,10 +173,69 @@ public function it_gets_the_uri_of_a_redirect_entry() $this->assertEquals('/the/actual/entry/uri', $page->uri()); $this->assertEquals('http://example.com/page', $page->url()); + $this->assertEquals('/the/actual/entry/uri', $page->urlWithoutRedirect()); $this->assertEquals('http://example.com/page', $page->absoluteUrl()); + $this->assertEquals('http://localhost/the/actual/entry/uri', $page->absoluteUrlWithoutRedirect()); $this->assertTrue($page->isRedirect()); } + /** @test */ + public function it_gets_the_uri_of_a_hardcoded_relative_link() + { + $tree = $this->newTree()->setStructure( + $this->mock(Nav::class) + ); + + $page = (new Page) + ->setTree($tree) + ->setUrl('/blog'); + + $this->assertEquals('/blog', $page->uri()); + $this->assertEquals('/blog', $page->url()); + $this->assertEquals('/blog', $page->urlWithoutRedirect()); + $this->assertEquals('http://localhost/blog', $page->absoluteUrl()); + $this->assertEquals('http://localhost/blog', $page->absoluteUrlWithoutRedirect()); + $this->assertFalse($page->isRedirect()); + } + + /** @test */ + public function it_gets_the_uri_of_a_hardcoded_absolute_link() + { + $tree = $this->newTree()->setStructure( + $this->mock(Nav::class) + ); + + $page = (new Page) + ->setTree($tree) + ->setUrl('https://google.com'); + + $this->assertEquals('https://google.com', $page->uri()); + $this->assertEquals('https://google.com', $page->url()); + $this->assertEquals('https://google.com', $page->urlWithoutRedirect()); + $this->assertEquals('https://google.com', $page->absoluteUrl()); + $this->assertEquals('https://google.com', $page->absoluteUrlWithoutRedirect()); + $this->assertFalse($page->isRedirect()); + } + + /** @test */ + public function it_gets_the_uri_of_a_hardcoded_text_only_page() + { + $tree = $this->newTree()->setStructure( + $this->mock(Nav::class) + ); + + $page = (new Page) + ->setTree($tree) + ->setTitle('Test'); + + $this->assertNull($page->uri()); + $this->assertNull($page->url()); + $this->assertNull($page->urlWithoutRedirect()); + $this->assertNull($page->absoluteUrl()); + $this->assertNull($page->absoluteUrlWithoutRedirect()); + $this->assertFalse($page->isRedirect()); + } + /** @test */ public function it_gets_child_pages() {