From f1c0effe5e2cb9bcdd5648fc95932d457d7d8e40 Mon Sep 17 00:00:00 2001 From: Sim Brody Date: Wed, 13 May 2026 14:59:25 +0100 Subject: [PATCH 1/2] Add filter to chapter navigation url Will allow custom url to be supplied, for example to replace with preview link for non logged in users. Post ID is also set before the foreach loop so it can be reliably passed to the filter without being reset by get_permalink --- spec/chapter_navigation.spec.php | 80 +++++++++++++++++++++++++++++--- src/ChapterNavigation.php | 3 +- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/spec/chapter_navigation.spec.php b/spec/chapter_navigation.spec.php index b4f1262..6e131b9 100644 --- a/spec/chapter_navigation.spec.php +++ b/spec/chapter_navigation.spec.php @@ -1,7 +1,5 @@ chapterNavigation = new \LongReadPlugin\ChapterNavigation(); @@ -15,7 +13,18 @@ 'ID' => 123, 'post_title' => 'Chapter One' ]; - allow('apply_filters')->toBeCalled()->andReturn(['publish']); + $chapterUrlCallArgs = []; + allow('apply_filters')->toBeCalled()->andRun(function (string $filterName, $value, $chapterPostId = null) use (&$chapterUrlCallArgs) { + if ($filterName === 'long_read_plugin_post_status') { + return ['publish']; + } + + if ($filterName === 'long_read_plugin_chapter_url') { + $chapterUrlCallArgs[] = $chapterPostId; + } + + return $value; + }); allow('get_post_parent')->toBeCalled()->andReturn(false); allow('get_posts')->toBeCalled()->andReturn([ (object) [ @@ -39,6 +48,9 @@ allow('get_permalink')->toBeCalled()->andReturn('http://chapter-two-link', 'http://chapter-three-link'); $result = $this->chapterNavigation->getItems(); + expect($chapterUrlCallArgs[0])->toEqual(123); + expect($chapterUrlCallArgs[1])->toEqual(456); + expect($chapterUrlCallArgs[2])->toEqual(789); expect(count($result))->toEqual(3); expect($result[0]->title)->toEqual('Chapter One'); @@ -61,10 +73,21 @@ 'ID' => 123, 'post_title' => 'Chapter One' ]; - allow('apply_filters')->toBeCalled()->andReturn(['publish']); + $chapterUrlCallArgs = []; + allow('apply_filters')->toBeCalled()->andRun(function (string $filterName, $value, $chapterPostId = null) use (&$chapterUrlCallArgs) { + if ($filterName === 'long_read_plugin_post_status') { + return ['publish']; + } + + if ($filterName === 'long_read_plugin_chapter_url') { + $chapterUrlCallArgs[] = $chapterPostId; + } + + return $value; + }); allow('get_post_parent')->toBeCalled()->andReturn($parentPost); allow('get_posts')->toBeCalled()->andReturn([ - $post = (object) [ + (object) [ 'ID' => 456, 'post_title' => 'Chapter Two' ], @@ -85,6 +108,9 @@ allow('get_permalink')->toBeCalled()->andReturn('http://chapter-one-link', 'http://chapter-three-link'); $result = $this->chapterNavigation->getItems(); + expect($chapterUrlCallArgs[0])->toEqual(123); + expect($chapterUrlCallArgs[1])->toEqual(456); + expect($chapterUrlCallArgs[2])->toEqual(789); expect(count($result))->toEqual(3); expect($result[0]->title)->toEqual('Chapter One'); @@ -108,7 +134,13 @@ 'post_title' => 'Chapter One', 'post_status' => 'publish' ]; - allow('apply_filters')->toBeCalled()->andReturn(['publish', 'draft']); + allow('apply_filters')->toBeCalled()->andRun(function (string $filterName, $value) { + if ($filterName === 'long_read_plugin_post_status') { + return ['publish', 'draft']; + } + + return $value; + }); allow('get_post_parent')->toBeCalled()->andReturn($parentPost); allow('get_posts')->toBeCalled()->andReturn([ (object) [ @@ -138,5 +170,41 @@ expect(count($result))->toEqual(3); }); }); + + context('when long read chapter URL filter changes an item URL', function () { + it('returns the filtered chapter URL in the navigation item', function () { + global $post; + $post = (object) [ + 'ID' => 123, + 'post_title' => 'Chapter One' + ]; + allow('apply_filters')->toBeCalled()->andRun(function (string $filterName, $value, $chapterPostId = null) { + if ($filterName === 'long_read_plugin_post_status') { + return ['publish']; + } + + if ( + $filterName === 'long_read_plugin_chapter_url' + && $chapterPostId === 456 + ) { + return 'http://filtered-chapter-two-link'; + } + + return $value; + }); + allow('get_post_parent')->toBeCalled()->andReturn(false); + allow('get_posts')->toBeCalled()->andReturn([ + (object) [ + 'ID' => 456, + 'post_title' => 'Chapter Two' + ] + ]); + allow('get_permalink')->toBeCalled()->andReturn('http://chapter-two-link'); + + $result = $this->chapterNavigation->getItems(); + + expect($result[1]->url)->toEqual('http://filtered-chapter-two-link'); + }); + }); }); }); diff --git a/src/ChapterNavigation.php b/src/ChapterNavigation.php index fd41acb..a7fbeee 100644 --- a/src/ChapterNavigation.php +++ b/src/ChapterNavigation.php @@ -20,11 +20,12 @@ public function getItems(): array 'order' => 'ASC' ]); array_unshift($chapterPosts, $parentPost); + $currentPostId = $post->ID; $chapterNavigationItems = []; foreach ($chapterPosts as $chapterPost) { $chapterNavigationItems[] = (object) [ 'title' => $chapterPost->post_title, - 'url' => $chapterPost->ID == $post->ID ? null : get_permalink($chapterPost) + 'url' => apply_filters('long_read_plugin_chapter_url', $chapterPost->ID == $currentPostId ? null : get_permalink($chapterPost), $chapterPost->ID) ]; } return $chapterNavigationItems; From d0bbba788b23694065f44c0797437ebbea598a80 Mon Sep 17 00:00:00 2001 From: Sim Brody Date: Wed, 13 May 2026 16:07:04 +0100 Subject: [PATCH 2/2] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9130251..aa7833f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Filter replaces hard-coded addition of draft posts to navigation +- Filter url passed to chapter navigation items ## [v2.3.0] - 2026-04-29