From d6c2593d61908a852bd4677cd79d669a4506204a Mon Sep 17 00:00:00 2001 From: Cam Findlay Date: Fri, 30 Oct 2015 11:13:51 +1300 Subject: [PATCH] ENHANCEMENT filtering for large user base sites. --- code/model/Blog.php | 4 +- code/model/BlogPost.php | 25 +++++++++- docs/en/configuring-large-websites.md | 72 +++++++++++++++++++++++++++ tests/BlogPostTest.php | 13 +++++ 4 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 docs/en/configuring-large-websites.md diff --git a/code/model/Blog.php b/code/model/Blog.php index 2d07901..b445f18 100644 --- a/code/model/Blog.php +++ b/code/model/Blog.php @@ -360,7 +360,9 @@ class Blog extends Page implements PermissionProvider { */ protected function getCandidateUsers() { if($this->config()->grant_user_access) { - return Member::get(); + $list = Member::get(); + $this->extend('updateCandidateUsers', $list); + return $list; } else { return Permission::get_members_by_permission( $this->config()->grant_user_permission diff --git a/code/model/BlogPost.php b/code/model/BlogPost.php index b196809..b7b126f 100644 --- a/code/model/BlogPost.php +++ b/code/model/BlogPost.php @@ -16,6 +16,14 @@ * @property int $ParentID */ class BlogPost extends Page { + + /** + * Same as above, but for list of users that can be + * given credit in the author field for blog posts + * @var string|bool false or group code + */ + private static $restrict_authors_to_group = false; + /** * @var array */ @@ -205,7 +213,7 @@ class BlogPost extends Page { $authorField = ListboxField::create( 'Authors', _t('BlogPost.Authors', 'Authors'), - Member::get()->map()->toArray() + $this->getCandidateAuthors()->map()->toArray() )->setMultiple(true); $authorNames = TextField::create( @@ -274,6 +282,21 @@ class BlogPost extends Page { return $fields; } + /** + * Gets the list of author candidates to be assigned as authors of this blog post. + * + * @return SS_List + */ + public function getCandidateAuthors() { + if($this->config()->restrict_authors_to_group) { + return Group::get()->filter('Code', $this->config()->restrict_authors_to_group)->first()->Members(); + } else { + $list = Member::get(); + $this->extend('updateCandidateAuthors', $list); + return $list; + } + } + /** * Determine if this user can edit the authors list. * diff --git a/docs/en/configuring-large-websites.md b/docs/en/configuring-large-websites.md new file mode 100644 index 0000000..cf98ea2 --- /dev/null +++ b/docs/en/configuring-large-websites.md @@ -0,0 +1,72 @@ +# Configuring Blog for large user bases + +By default the blog module user and author selection form fields include all users in your website as +candidates for writers, editors and contributors. Additionally, when adding a blog post, again all users are selectable. +This can cause issue with websites that store a large number of users in the database. + +In this case you may need to restrict the number of user accounts that are elegable to be selected. +The module has some useful configuration options for this that can be added to your projects config.yml + +## Restricting blog managers to a permission setting +Default is to list all users and when one is selected, they are added to a `blog-users` group with `CMS_ACCESS_CMSMain` permissions. +To only include those already having these permissions you can set in your `config.yml`: + +```yaml +Blog: + grant_user_access: false +``` + +Note: depending on the incusion order of your config.yml you may need to clear the condifg setting +before updating it. In this case use the folling in yout `mysite/_config.php`: + +```php +Config::inst()->remove('Blog', 'grant_user_access'); +``` + +If you create your own permission and want to ensure the pool of possible selectable users includes +those with this permission you can set the checked permission in `config.yml` with: + +```yaml +Blog: + grant_user_permission: SOME_PERMISSION_here +``` + +## Restricting blog post authors selection to a known group +In a blog post when selecting an author it will default to you (the logged in person creating the post), +however you may be posting on behalf of another person. In this case the slection form field will offer +all users as potential blog authors. Again for large websites with many thousands of users this can cause +the site to be slow or non-responsive. We can turn on a filter so that authors need to be in a defined +user group to be able to be selected as an author. + +Enable this in your `config.yml` by adding a group code: + +```yaml +BlogPost: + restrict_authors_to_group: 'group_code' +``` + +## Extension points in Blog and BlogPost users and how to use +Both Blog and BlogPost have methods which return the list of candidate users or authors. If the previously +mentioned mothods of reducing this list are not suitable or you wish to roll your own, you can utilise a +DataExtension to get the controll you require. + +For example in BlogPost: + +```php +protected function getCandidateAuthors() { + if($this->config()->restrict_authors_to_group) { + return Group::get()->filter('Code', $this->config()->restrict_authors_to_group)->first()->Members(); + } else { + $list = Member::get(); + $this->extend('updateCandidateAuthors', $list); + return $list; + } + } +``` + +Note the line `$this->extend('updateCandidateAuthors', $list);` which allows you to call a +`updateCandidateAuthors` method in a DataExtension to the Blog Post class if you have not set a `restrict_authors_to_group` config, further filter the passed +in Member list before it gets sent back to the form field. + +See the documentation on [DataExtension](https://docs.silverstripe.org/en/developer_guides/extending/extensions/) for further implementation notes. + diff --git a/tests/BlogPostTest.php b/tests/BlogPostTest.php index c4e9100..7e02336 100644 --- a/tests/BlogPostTest.php +++ b/tests/BlogPostTest.php @@ -63,4 +63,17 @@ class BlogPostTest extends SapphireTest { array($somePastDate, 'Writer', 'FirstBlogPost', false), ); } + + public function testCandidateAuthors() { + $blogpost = $this->objFromFixture('BlogPost', 'PostC'); + + $this->assertEquals(7, $blogpost->getCandidateAuthors()->count()); + + //Set the group to draw Members from + Config::inst()->update('BlogPost', 'restrict_authors_to_group','BlogUsers'); + + $this->assertEquals(3, $blogpost->getCandidateAuthors()->count()); + + + } }