From 90d4ba05fb648ab0995538a95a71605afb9b6c47 Mon Sep 17 00:00:00 2001 From: Andreas Schantl Date: Wed, 30 Dec 2020 09:28:33 +0100 Subject: [PATCH 1/6] Fix is_parent not working with redirect '@child' --- src/Facades/Endpoint/URL.php | 2 +- src/Tags/Structure.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Facades/Endpoint/URL.php b/src/Facades/Endpoint/URL.php index 54adb10b23f..22331af66b6 100644 --- a/src/Facades/Endpoint/URL.php +++ b/src/Facades/Endpoint/URL.php @@ -86,7 +86,7 @@ public function isAncestorOf($child, $ancestor) $child = Str::ensureRight($child, '/'); $ancestor = Str::ensureRight($ancestor, '/'); - if ($child === $ancestor) { + if ($child === $ancestor || $ancestor === '/') { return false; } diff --git a/src/Tags/Structure.php b/src/Tags/Structure.php index c3b4ab01b5e..6777933649c 100644 --- a/src/Tags/Structure.php +++ b/src/Tags/Structure.php @@ -57,13 +57,14 @@ public function toArray($tree, $parent = null, $depth = 1) $data = $page->toAugmentedArray(); $children = empty($item['children']) ? [] : $this->toArray($item['children'], $data, $depth + 1); + $redirect_child = isset($data['redirect']) ? $data['redirect']->raw() == '@child' : false; return array_merge($data, [ 'children' => $children, '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(), $redirect_child ? Str::beforeLast($page->url(), '/') : $page->url()), // remove last URL segment if redirect is @child 'is_external' => URL::isExternal($page->absoluteUrl()), ]); })->filter()->values()->all(); From 432016625728b43c4ef96133e76e51024d9767b0 Mon Sep 17 00:00:00 2001 From: Andreas Schantl Date: Wed, 30 Dec 2020 10:49:38 +0100 Subject: [PATCH 2/6] If the string is empty, return with false immediately --- src/Facades/Endpoint/URL.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Facades/Endpoint/URL.php b/src/Facades/Endpoint/URL.php index 22331af66b6..747fd6f9cea 100644 --- a/src/Facades/Endpoint/URL.php +++ b/src/Facades/Endpoint/URL.php @@ -82,11 +82,15 @@ public function parent($url) */ public function isAncestorOf($child, $ancestor) { + if ($ancestor === '') { + return false; + } + $child = Str::before($child, '?'); $child = Str::ensureRight($child, '/'); $ancestor = Str::ensureRight($ancestor, '/'); - if ($child === $ancestor || $ancestor === '/') { + if ($child === $ancestor) { return false; } From 4c0cc10c458af06830e6dd64f639e0f6f5ca2306 Mon Sep 17 00:00:00 2001 From: Andreas Schantl Date: Wed, 30 Dec 2020 11:07:37 +0100 Subject: [PATCH 3/6] Fix styleci --- src/Facades/Endpoint/URL.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facades/Endpoint/URL.php b/src/Facades/Endpoint/URL.php index 747fd6f9cea..409c1c6f287 100644 --- a/src/Facades/Endpoint/URL.php +++ b/src/Facades/Endpoint/URL.php @@ -85,7 +85,7 @@ public function isAncestorOf($child, $ancestor) if ($ancestor === '') { return false; } - + $child = Str::before($child, '?'); $child = Str::ensureRight($child, '/'); $ancestor = Str::ensureRight($ancestor, '/'); From a8b88a934551cf7fce19aef8406e328366a5eee6 Mon Sep 17 00:00:00 2001 From: Andreas Schantl Date: Wed, 30 Dec 2020 11:30:32 +0100 Subject: [PATCH 4/6] Import Str class --- src/Tags/Structure.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tags/Structure.php b/src/Tags/Structure.php index 6777933649c..26283cbfb2e 100644 --- a/src/Tags/Structure.php +++ b/src/Tags/Structure.php @@ -6,6 +6,7 @@ use Statamic\Facades\Site; use Statamic\Facades\URL; use Statamic\Structures\TreeBuilder; +use Statamic\Support\Str; class Structure extends Tags { From 0f6f43e55341a7dbd8147b34c62c386ef0e75702 Mon Sep 17 00:00:00 2001 From: Andreas Schantl Date: Wed, 20 Jan 2021 15:27:35 +0100 Subject: [PATCH 5/6] Fix is_parent for all scenarios Tested with: - redirect_child > entry > entry - redirect_child > redirect_child > entry Why does this work? The uri() method gives the actual URL of the one entry, while the url() method gives the url() of the child in case of redirect child --- src/Facades/Endpoint/URL.php | 4 ---- src/Tags/Structure.php | 4 +--- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Facades/Endpoint/URL.php b/src/Facades/Endpoint/URL.php index 409c1c6f287..54adb10b23f 100644 --- a/src/Facades/Endpoint/URL.php +++ b/src/Facades/Endpoint/URL.php @@ -82,10 +82,6 @@ public function parent($url) */ public function isAncestorOf($child, $ancestor) { - if ($ancestor === '') { - return false; - } - $child = Str::before($child, '?'); $child = Str::ensureRight($child, '/'); $ancestor = Str::ensureRight($ancestor, '/'); diff --git a/src/Tags/Structure.php b/src/Tags/Structure.php index 26283cbfb2e..a34482a4cce 100644 --- a/src/Tags/Structure.php +++ b/src/Tags/Structure.php @@ -6,7 +6,6 @@ use Statamic\Facades\Site; use Statamic\Facades\URL; use Statamic\Structures\TreeBuilder; -use Statamic\Support\Str; class Structure extends Tags { @@ -58,14 +57,13 @@ public function toArray($tree, $parent = null, $depth = 1) $data = $page->toAugmentedArray(); $children = empty($item['children']) ? [] : $this->toArray($item['children'], $data, $depth + 1); - $redirect_child = isset($data['redirect']) ? $data['redirect']->raw() == '@child' : false; return array_merge($data, [ 'children' => $children, 'parent' => $parent, 'depth' => $depth, 'is_current' => rtrim(URL::getCurrent(), '/') == rtrim($page->url(), '/'), - 'is_parent' => Site::current()->url() === $page->url() ? false : URL::isAncestorOf(URL::getCurrent(), $redirect_child ? Str::beforeLast($page->url(), '/') : $page->url()), // remove last URL segment if redirect is @child + 'is_parent' => Site::current()->url() === $page->url() ? false : URL::isAncestorOf(URL::getCurrent(), $page->uri()), 'is_external' => URL::isExternal($page->absoluteUrl()), ]); })->filter()->values()->all(); From ddc7fe6d28f00eb080d3e47418c57fd472880d79 Mon Sep 17 00:00:00 2001 From: Andreas Schantl Date: Fri, 12 Feb 2021 11:54:22 +0100 Subject: [PATCH 6/6] Refactoring Structure to use the $page->url() method instead again - adding a $follow_redirect parameter to the url() and absoluteUrl() method to both, Routeable and Page class --- src/Routing/Routable.php | 10 +++++----- src/Structures/Page.php | 10 +++++----- src/Tags/Structure.php | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Routing/Routable.php b/src/Routing/Routable.php index e31f3430cc8..69978f284e1 100644 --- a/src/Routing/Routable.php +++ b/src/Routing/Routable.php @@ -30,18 +30,18 @@ public function uri() return app(UrlBuilder::class)->content($this)->build($route); } - public function url() + public function url($follow_redirect = true) { - if ($this->isRedirect()) { + if ($this->isRedirect() && $follow_redirect) { return $this->redirectUrl(); } - return URL::makeRelative($this->absoluteUrl()); + return URL::makeRelative($this->absoluteUrl($follow_redirect)); } - public function absoluteUrl() + public function absoluteUrl($follow_redirect = true) { - if ($this->isRedirect()) { + if ($this->isRedirect() && $follow_redirect) { return $this->redirectUrl(); } diff --git a/src/Structures/Page.php b/src/Structures/Page.php index d922803ee55..3b3df0eccce 100644 --- a/src/Structures/Page.php +++ b/src/Structures/Page.php @@ -36,18 +36,18 @@ public function setUrl($url) return $this; } - public function url() + public function url($follow_redirect = true) { if ($this->url) { return $this->url; } - if ($this->isRedirect()) { + if ($this->isRedirect() && $follow_redirect) { return $this->redirectUrl(); } if ($this->reference && $this->referenceExists()) { - return URL::makeRelative($this->absoluteUrl()); + return URL::makeRelative($this->absoluteUrl($follow_redirect)); } } @@ -178,13 +178,13 @@ public function uri() ->build($this->route); } - public function absoluteUrl() + public function absoluteUrl($follow_redirect = true) { if ($this->url) { return $this->url; } - if ($this->isRedirect()) { + if ($this->isRedirect() && $follow_redirect) { return $this->redirectUrl(); } diff --git a/src/Tags/Structure.php b/src/Tags/Structure.php index a34482a4cce..e292847ccd2 100644 --- a/src/Tags/Structure.php +++ b/src/Tags/Structure.php @@ -63,7 +63,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->uri()), + 'is_parent' => Site::current()->url() === $page->url() ? false : URL::isAncestorOf(URL::getCurrent(), $page->url(false)), 'is_external' => URL::isExternal($page->absoluteUrl()), ]); })->filter()->values()->all();