From 3f24858b73424f731b34d25824d91cb740400b93 Mon Sep 17 00:00:00 2001 From: zanderwar Date: Wed, 14 Mar 2018 18:01:09 +1000 Subject: [PATCH] ENHANCEMENT added MinutesToRead() --- lang/en.yml | 2 ++ src/Model/BlogPost.php | 34 +++++++++++++++++++ .../SilverStripe/Blog/Includes/EntryMeta.ss | 6 ++++ tests/BlogPostTest.php | 21 ++++++++++++ tests/blog.yml | 11 ++++++ 5 files changed, 74 insertions(+) diff --git a/lang/en.yml b/lang/en.yml index 051441c..611a8d2 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -47,6 +47,8 @@ en: UsersWritersFieldDescription: "A writer has full control over creating, editing and publishing BlogPosts they have authored\n or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.\n

\n Writers have these permissions:
\n
\n Update or publish any BlogPost they have authored or have been assigned to
\n Assign/unassign any member as an author of a particular BlogPost they have authored or have been \n assigned to" WRITER: Writer Categorisation: 'Categorisation' + MinutesToRead: 'Minute(s) to read' + LessThanAMinuteToRead: 'Less than a minute to read' SilverStripe\Blog\Model\BlogCategory: Duplicate: 'A blog category already exists with that name.' PLURALNAME: 'Blog Categories' diff --git a/src/Model/BlogPost.php b/src/Model/BlogPost.php index 14ea9fa..c528a3d 100644 --- a/src/Model/BlogPost.php +++ b/src/Model/BlogPost.php @@ -22,6 +22,7 @@ use SilverStripe\Security\Security; use SilverStripe\TagField\TagField; use SilverStripe\Versioned\Versioned; use SilverStripe\View\ArrayData; +use SilverStripe\View\Parsers\ShortcodeParser; use SilverStripe\View\Requirements; /** @@ -146,6 +147,14 @@ class BlogPost extends Page */ private static $show_in_sitetree = false; + /** + * This helps estimate how long an article will take to read, if your target audience + * is elderly then you should lower this value. See {@link getMinutesToRead()} + * + * @var int + */ + private static $minutes_to_read_wpm = 200; + /** * Determine the role of the given member. * @@ -756,6 +765,31 @@ class BlogPost extends Page return !empty($this->PublishDate) ? $this->PublishDate : null; } + /** + * Provides a rough estimate of how long this post will take to read based on wikipedias answer to "How fast can a + * human read" of 200wpm. Source https://en.wikipedia.org/wiki/Speed_reading + * + * @param null|integer $wpm + * + * @return string + */ + public function MinutesToRead($wpm = null) + { + $wpm = $wpm ?: $this->config()->get('minutes_to_read_wpm'); + + if (!is_numeric($wpm)) { + throw new \InvalidArgumentException(sprintf("Expecting integer but got %s instead", gettype($wpm))); + } + + $wordCount = str_word_count(strip_tags($this->Content)); + + if ($wordCount < $wpm) { + return 0; + } + + return round($wordCount / $wpm, 0); + } + /** * {@inheritdoc} */ diff --git a/templates/SilverStripe/Blog/Includes/EntryMeta.ss b/templates/SilverStripe/Blog/Includes/EntryMeta.ss index 1b0044e..ce76bec 100644 --- a/templates/SilverStripe/Blog/Includes/EntryMeta.ss +++ b/templates/SilverStripe/Blog/Includes/EntryMeta.ss @@ -36,4 +36,10 @@ <% end_if %> <% end_loop %> <% end_if %> + + <% if $MinutesToRead < 1 %> + <%t SilverStripe\\Blog\\Model\\Blog.LessThanAMinuteToRead "Less than a minute to read" %> + <% else %> + $MinutesToRead <%t SilverStripe\\Blog\\Model\\Blog.MinutesToRead "Minute(s) to read" %> + <% end_if %>

diff --git a/tests/BlogPostTest.php b/tests/BlogPostTest.php index 9f95f96..30bb4e9 100644 --- a/tests/BlogPostTest.php +++ b/tests/BlogPostTest.php @@ -132,4 +132,25 @@ class BlogPostTest extends SapphireTest $blogPost = $this->objFromFixture(BlogPost::class, 'PostA'); $this->assertEquals('2012-01-09 15:00:00', $blogPost->getDate()); } + + public function testMinutesToRead() + { + /** @var BlogPost $blogPost */ + $blogPost = $this->objFromFixture(BlogPost::class, 'FirstBlogPost'); + + // over 400 words, should take slightly longer than 2 minutes + $this->assertEquals(2, $blogPost->MinutesToRead()); + + $blogPost = $this->objFromFixture(BlogPost::class, 'SecondBlogPost'); + + // over 200 words, should take slighter longer than 1 minute + $this->assertEquals(1, $blogPost->MinutesToRead()); + + $blogPost = $this->objFromFixture(BlogPost::class, 'ThirdBlogPost'); + // less than 200 words, should take less than a minute thus return an integer of 0 (zero) + $this->assertEquals(0, $blogPost->MinutesToRead()); + + $this->expectException(\InvalidArgumentException::class); + $blogPost->MinutesToRead('not-a-number'); + } } diff --git a/tests/blog.yml b/tests/blog.yml index 0b389da..699395e 100755 --- a/tests/blog.yml +++ b/tests/blog.yml @@ -144,18 +144,29 @@ SilverStripe\Blog\Model\BlogPost: PublishDate: '2013-10-01 15:00:00' Tags: =>SilverStripe\Blog\Model\BlogTag.FirstTag Categories: =>SilverStripe\Blog\Model\BlogCategory.FirstCategory + Content: > +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo tristique ipsum. Vestibulum ut sagittis elit. Curabitur accumsan dui ac iaculis fermentum. Suspendisse consectetur sapien a dignissim porta. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam mollis, est quis mollis posuere, purus diam interdum magna, vel tempus libero nibh a nunc. Duis enim lectus, consectetur dapibus interdum quis, dignissim at neque. Maecenas efficitur nibh et ipsum mattis molestie. Sed id euismod risus, a efficitur nibh. Nullam erat nibh, aliquam non ante quis, euismod facilisis dui. Fusce eget tellus nec mi accumsan iaculis vitae id neque. Ut rhoncus, felis id venenatis porttitor, ex nibh varius turpis, in pulvinar sem ligula at odio. Suspendisse molestie eros et elit sagittis, nec condimentum quam scelerisque. Donec maximus ligula nec nunc mattis imperdiet. Vestibulum maximus mauris quis pulvinar iaculis.

+

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi non sapien eget elit venenatis tristique. Nunc mollis ante eu metus iaculis tempus. Nulla at nibh nisl. Phasellus a lacus urna. Fusce vulputate elit eu aliquet fringilla. Donec vitae efficitur ex, et rutrum nunc. Quisque sed sem at dui congue venenatis vel sit amet lectus.

+

Fusce fermentum sapien massa, in vehicula massa faucibus ultrices. In tempor nunc at sodales pellentesque. Proin nunc elit, faucibus non vestibulum sed, varius a felis. Maecenas in justo ut ante mollis mattis. Nam placerat mi nec justo semper blandit. Ut pretium nibh justo, sit amet molestie lorem tempus vitae. Integer vehicula eget purus sed mattis. Nam sit amet lobortis quam. Vestibulum nisl diam, commodo eget maximus at, interdum non quam. Praesent et lorem consequat, ornare nulla id, ultricies odio. Ut porta dapibus metus ut fringilla. Vivamus sit amet elit eu dolor varius blandit. Morbi pharetra a odio id tempus.

+

Phasellus at ipsum faucibus, auctor nisi eu, vestibulum diam. Cras viverra ut massa eleifend volutpat. Ut vel sapien et mi pharetra tempor. Nam at scelerisque orci. Pellentesque pulvinar in dui ut scelerisque. Sed ultrices mauris nec commodo faucibus. Sed urna erat, faucibus quis sem non, auctor tincidunt mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ac tellus orci. Vivamus tincidunt turpis a sem ullamcorper, eu porttitor mauris condimentum. Aliquam auctor nisl quis massa sodales, nec venenatis metus facilisis. Duis posuere, ante at tristique tristique, sapien ligula sollicitudin purus, ut vehicula tellus mi sed mi. Fusce tortor mi, imperdiet non sollicitudin.

+

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi non sapien eget elit venenatis tristique. Nunc mollis ante eu metus iaculis tempus. Nulla at nibh nisl. Phasellus a lacus urna. Fusce vulputate elit eu aliquet fringilla. Donec vitae efficitur ex, et rutrum nunc. Quisque sed sem at dui congue venenatis vel sit amet lectus.

SecondBlogPost: ClassName: SilverStripe\Blog\Model\BlogPost Title: 'Second Post' URLSegment: second-post ParentID: =>SilverStripe\Blog\Model\Blog.FirstBlog PublishDate: '2013-09-01 15:00:00' + Content: > +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nec accumsan dolor, at viverra nibh. Vivamus lectus magna, interdum sit amet libero non, fermentum semper nunc. Nunc eu arcu euismod mauris auctor venenatis. Integer sem lorem, varius iaculis congue et, blandit eget nisi. Quisque ullamcorper laoreet sagittis. Nulla enim metus, viverra ut commodo ut, imperdiet et velit. Sed tincidunt mi condimentum, sodales lectus id, dictum neque. Suspendisse placerat, nibh at mattis volutpat, mauris augue congue dui, lobortis tempor diam magna vitae ligula. Proin sed turpis quis enim maximus sodales sit amet id diam. Proin sollicitudin elementum suscipit.

+

Nullam at odio eget orci porttitor pharetra. Proin scelerisque mauris quam, non laoreet lectus tempor sed. Curabitur eleifend vel augue et vulputate. In porta magna vitae felis rutrum, et sodales elit ultricies. Proin ac justo nec sem maximus ultrices. Praesent nibh turpis, congue non malesuada id, tincidunt id augue. Aenean vulputate ullamcorper dapibus. Maecenas tincidunt sapien in dolor feugiat porta. Aenean venenatis nibh nunc, ut lacinia dolor luctus at. Integer viverra velit nec tincidunt venenatis. Duis congue blandit ante et convallis. Donec id convallis lorem. Vestibulum vel pellentesque nisl. Nunc accumsan non nisi vitae ultricies. Nam tempus elit at ornare volutpat. Nullam et.

ThirdBlogPost: ClassName: SilverStripe\Blog\Model\BlogPost Title: 'Old Post' URLSegment: old-post ParentID: =>SilverStripe\Blog\Model\Blog.FirstBlog PublishDate: '2012-01-09 15:00:00' + Content: > +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nec accumsan dolor, at viverra nibh. Vivamus lectus magna, interdum sit amet libero non, fermentum semper nunc. Nunc eu arcu euismod mauris auctor venenatis. Integer sem lorem, varius iaculis congue et, blandit eget nisi. Quisque ullamcorper laoreet sagittis. Nulla enim metus, viverra ut commodo ut, imperdiet et velit. Sed tincidunt mi condimentum, sodales lectus id, dictum neque. Suspendisse placerat, nibh at mattis volutpat, mauris augue congue dui, lobortis tempor diam magna vitae ligula. Proin sed turpis quis enim maximus sodales sit amet id diam. Proin sollicitudin elementum suscipit.

FirstFutureBlogPost: ClassName: SilverStripe\Blog\Model\BlogPost Title: 'Future Post'