Merge pull request #159 from tractorcow/pulls/2.0/editor-management

API New permissions for writers, editors, and contributors
This commit is contained in:
Michael Strong 2015-03-13 14:55:00 +13:00
commit c5d32f7fb2
14 changed files with 685 additions and 93 deletions

View File

@ -5,65 +5,8 @@ Silverstripe Blogger
A fresh take on blogging in Silverstripe set out to tackle the issue of a cluttered Site Tree.
## Documentation index
## Requirements
```
silverstripe/cms: ~3.1
```
## Suggested Modules
```
silverstripe/widgets: *
silverstripe/comments: *
```
## Installation
```
composer require micmania1/silverstripe-blog:1.0.*
```
## Features
* Blog Posts extend SiteTree so no Page functionality is lost by using DataObject's.
* Blog Posts can be listed in the SiteTree **OR** in a GridField within the blog, removing clutter for large blogs.
* Filter blog posts by category
* Filter blog posts by tag
* Full blog Archive by Year, month or day
* 4 widgets included (category listing, tag listing, archive & recent posts).
* Publish Date - Set a blog post to publish in the future.
* Custom GridField components for quickly adding new objects.
* RSS Feed of the blog
## Screenshots
*Easily manage and add new blog posts through a GridField.*
![](screenshots/blog-post-management.png)
*Quickly add new tags and categories.*
![](screenshots/blogpost-add-tags-categories.png)
## Usage
Because the blog is part of the SiteTree the usage is the same as any other page.
By default, blog posts are filtered out of the SiteTree to avoid clutter and instead put in a GridField inside of the blog. If you wish to display the blog posts within the site tree you can do so using Silverstripe config.
**YAML**
```
BlogPost:
show_in_sitetree: true
```
**PHP**
```
<?php
Config::inst()->update("BlogPost", "show_in_sitetree", true);
```
Doing this will remove the GridField & result in a normal behaving SiteTree.
## Theme
You can download a blog sub-theme of Silverstripe's default 'Simple' theme: https://github.com/micmania1/simple_blog
* [Features](docs/en/features.md)
* [Setup](docs/en/setup.md)
* [Roles](docs/en/roles.md)

View File

@ -29,7 +29,7 @@ class BlogFilter extends Lumberjack {
// Get the current stage.
$stage = Versioned::current_stage();
if($stage == "Stage") $stage = "";
else $stage = "_" . Convert::raw2sql($stage);
elseif($stage) $stage = "_{$stage}";
// Filter published posts
$dataQuery = $staged->dataQuery()
@ -40,28 +40,50 @@ class BlogFilter extends Lumberjack {
return $staged;
}
/**
* Augments (@link Hierarchy::liveChildren()}
*
* @param $staged DataList
* @param $showAll boolean
**/
public function liveChildren($showAll = false, $onlyDeletedFromStage = false) {
$staged = parent::liveChildren($showAll, $onlyDeletedFromStage);
if(!$this->shouldFilter()
&& in_array(get_class($this->owner), ClassInfo::subClassesFor("Blog"))
&& $this->owner instanceof Blog
&& !Permission::check("VIEW_DRAFT_CONTENT")
) {
// Filter publish posts
$dataQuery = $staged->dataQuery()
->innerJoin("BlogPost", '"BlogPost_Live"."ID" = "SiteTree"_"Live"."ID"')
->where('"PublishDate" < \'' . Convert::raw2sql(SS_Datetime::now()) . '\'');
->innerJoin("BlogPost", '"BlogPost_Live"."ID" = "SiteTree_Live"."ID"')
->where('"BlogPost"."PublishDate" < \'' . Convert::raw2sql(SS_Datetime::now()->getValue()) . '\'');
$staged = $staged->setDataQuery($dataQuery);
}
return $staged;
}
}
public function updateCMSFields(FieldList $fields) {
$excluded = $this->owner->getExcludedSiteTreeClassNames();
if(!empty($excluded)) {
$pages = SiteTree::get()->filter(array(
'ParentID' => $this->owner->ID,
'ClassName' => $excluded
));
$gridField = new BlogFilter_GridField(
"ChildPages",
$this->getLumberjackTitle(),
$pages,
$this->getLumberjackGridFieldConfig()
);
$tab = new Tab('ChildPages', $this->getLumberjackTitle(), $gridField);
$fields->insertAfter($tab, 'Main');
}
}
}
/**
* Enables children of non-editable pages to be edited
*/
class BlogFilter_GridField extends GridField {
public function transform(FormTransformation $trans) {
// Don't allow parent object transformations to propegate automatically to child records
return $this;
}
}

View File

@ -5,39 +5,79 @@
*
* @package silverstripe
* @subpackage blog
*
* @method HasManyList Tags() List of tags in this blog
* @method HasManyList Categories() List of categories in this blog
* @method ManyManyList Editors() List of editors
* @method ManyManyList Writers() List of writers
* @method ManyManyList Contributors() List of contributors
*
* @author Michael Strong <github@michaelstrong.co.uk>
**/
class Blog extends Page {
class Blog extends Page implements PermissionProvider {
/**
* Permission for user management
*
* @var string
*/
const MANAGE_USERS = 'BLOG_MANAGE_USERS';
/**
* If true, users assigned as editor, writer, or contributor will be automatically
* granted CMS_ACCESS_CMSMain permission. If false, only users with this permission
* already may be assigned.
*
* @var boolean
* @config
*/
private static $grant_user_access = true;
/**
* Permission to either require, or grant to users assigned to work on this blog
*
* @var string
* @config
*/
private static $grant_user_permission = 'CMS_ACCESS_CMSMain';
/**
* Group code to assign newly granted users toh
*
* @var string
* @config
*/
private static $grant_user_group = 'blog-users';
private static $db = array(
"PostsPerPage" => "Int",
);
private static $has_many = array(
"Tags" => "BlogTag",
"Categories" => "BlogCategory",
);
private static $many_many = array(
'Editors' => 'Member',
'Writers' => 'Member',
'Contributors' => 'Member',
);
private static $allowed_children = array(
"BlogPost",
);
private static $extensions = array(
"BlogFilter",
);
private static $defaults = array(
"ProvideComments" => false,
);
private static $description = 'Adds a blog to your website.';
public function getCMSFields() {
$self =& $this;
$this->beforeUpdateCMSFields(function($fields) use ($self) {
@ -65,13 +105,144 @@ class Blog extends Page {
$categories,
$tags
));
});
$fields = parent::getCMSFields();
return $fields;
}
/**
* Check if this member is an editor of the blog
*
* @param Member $member
* @return boolean
*/
public function isEditor($member) {
$isEditor = $this->isMemberOf($member, $this->Editors());
$this->extend('updateIsEditor', $isEditor, $member);
return $isEditor;
}
/**
* Check if this member is a writer of the blog
*
* @param Member $member
* @return boolean
*/
public function isWriter($member) {
$isWriter = $this->isMemberOf($member, $this->Writers());
$this->extend('updateIsWriter', $isWriter, $member);
return $isWriter;
}
/**
* Check if this member is a contributor of the blog
*
* @param Member $member
* @return boolean
*/
public function isContributor($member) {
$isContributor = $this->isMemberOf($member, $this->Contributors());
$this->extend('updateIsContributor', $isContributor, $member);
return $isContributor;
}
/**
* Determine if the given member belongs to the given subrelation
*
* @param Member $member
* @param DataList $list Relation to check
* @return boolean
*/
protected function isMemberOf($member, $list) {
if(!$member || !$member->exists()) return false;
if($list instanceof UnsavedRelationList) {
return in_array($member->ID, $list->getIDList());
}
return $list->byID($member->ID) !== null;
}
public function canEdit($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
// Allow editors to edit this page
if($this->isEditor($member)) return true;
return parent::canEdit($member);
}
/**
* Determine if this user can edit the editors list
*
* @param Member $member
* @return boolean
*/
public function canEditEditors($member = null) {
$member = $member ?: Member::currentUser();
$extended = $this->extendedCan('canEditEditors', $member);
if($extended !== null) return $extended;
// Check permission
return Permission::checkMember($member, self::MANAGE_USERS);
}
/**
* Determine if this user can edit writers list
*
* @param Member $member
* @return boolean
*/
public function canEditWriters($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
$extended = $this->extendedCan('canEditWriters', $member);
if($extended !== null) return $extended;
// Editors can edit writers
if($this->isEditor($member)) return true;
// Check permission
return Permission::checkMember($member, self::MANAGE_USERS);
}
/**
* Determines if this user can edit the contributors list
*
* @param type $member
* @return boolean
*/
public function canEditContributors($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
$extended = $this->extendedCan('canEditContributors', $member);
if($extended !== null) return $extended;
// Editors can edit writers
if($this->isEditor($member)) return true;
// Check permission
return Permission::checkMember($member, self::MANAGE_USERS);
}
public function canAddChildren($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
// Editors, Writers and Contributors can add children
if($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) {
return true;
}
return parent::canAddChildren($member);
}
public function getSettingsFields() {
@ -79,11 +250,44 @@ class Blog extends Page {
$fields->addFieldToTab("Root.Settings",
NumericField::create("PostsPerPage", _t("Blog.PostsPerPage", "Posts Per Page"))
);
// Roles and Permissions
$members = $this->getCandidateUsers()->map()->toArray();
// Editors
$editorField = ListboxField::create('Editors', 'Editors', $members)
->setMultiple(true)
->setDescription('Editors are able to manage this blog and its posts');
if(!$this->canEditEditors()) {
$editorField = $editorField->performDisabledTransformation();
}
// Writers
$writerField = ListboxField::create('Writers', 'Writers', $members)
->setMultiple(true)
->setDescription('Writers are able to write and publish posts');
if(!$this->canEditWriters()) {
$writerField = $writerField->performDisabledTransformation();
}
// Contributors
$contributorField = ListboxField::create('Contributors', 'Contributors', $members)
->setMultiple(true)
->setDescription('Contributors are able to write, but not publish, posts');
if(!$this->canEditContributors()) {
$contributorField = $contributorField->performDisabledTransformation();
}
$fields->addFieldsToTab('Root.Users', array(
$editorField,
$writerField,
$contributorField
));
return $fields;
}
/**
* Return blog posts
*
@ -103,7 +307,7 @@ class Blog extends Page {
*
* @param $year int
* @param $month int
* @param $dat int
* @param $day int
*
* @return DataList
**/
@ -147,6 +351,86 @@ class Blog extends Page {
return GridFieldConfig_BlogPost::create();
}
public function providePermissions() {
return array(
Blog::MANAGE_USERS => array(
'name' => _t(
'Blog.PERMISSION_MANAGE_USERS_DESCRIPTION',
'Manage users for individual blogs'
),
'help' => _t(
'Blog.PERMISSION_MANAGE_USERS_HELP',
'Allow assignment of Editors, Writers, or Contributors to blogs'
),
'category' => _t('Blog.PERMISSIONS_CATEGORY', 'Blog permissions'),
'sort' => 100
)
);
}
/**
* Gets the list of user candidates to be assigned to assist with this blog
*
* @return SS_List
*/
protected function getCandidateUsers() {
if($this->config()->grant_user_access) {
// If we are allowed to grant CMS access, all users are candidates
return Member::get();
} else {
// If access cannot be granted, limit users to those who can access the CMS
// This is useful for more secure sites
$permission = $this->config()->grant_user_permission;
return Permission::get_members_by_permission($permission);
}
}
/**
* Gets or creates the group used to assign CMS access
*
* @return Group
*/
protected function getUserGroup() {
$code = $this->config()->grant_user_group;
$group = Group::get()->filter('Code', $code)->first();
if($group) return $group;
// Create new group
$group = new Group();
$group->Title = 'Blog users';
$group->Code = $code;
$group->write();
// Add permission
$permission = new Permission();
$permission->Code = $this->config()->grant_user_permission;
$group->Permissions()->add($permission);
return $group;
}
protected function onBeforeWrite() {
parent::onBeforeWrite();
$this->assignGroup();
}
/**
* Assign users as necessary to the blog group
*/
protected function assignGroup() {
// Ensure that any user granted editor, writer, or contributor have CMS_ACCESS_CMSMain access
if(!$this->config()->grant_user_access) return;
// Generate or retrieve the group
$group = $this->getUserGroup();
foreach(array($this->Editors(), $this->Writers(), $this->Contributors()) as $userlist) {
foreach($userlist as $user) {
// Ensure user exists in the group
if(!$user->inGroup($group)) $user->Groups()->add($group);
}
}
}
}

View File

@ -6,12 +6,17 @@
* @package silverstripe
* @subpackage blog
*
* @method ManyManyList Categories()
* @method ManyManyList Tags()
* @method ManyManyList Authors()
*
* @author Michael Strong <github@michaelstrong.co.uk>
**/
class BlogPost extends Page {
private static $db = array(
"PublishDate" => "SS_Datetime",
"AuthorNames" => "Varchar(1024)"
);
private static $has_one = array(
@ -21,6 +26,7 @@ class BlogPost extends Page {
private static $many_many = array(
"Categories" => "BlogCategory",
"Tags" => "BlogTag",
"Authors" => "Member",
);
private static $defaults = array(
@ -60,6 +66,23 @@ class BlogPost extends Page {
private static $show_in_sitetree = false;
/**
* Determine if the given member is an author of this post
*
* @param Member $member
* @return boolean
*/
protected function isAuthor($member) {
if(!$member || !$member->exists()) return false;
$list = $this->Authors();
if($list instanceof UnsavedRelationList) {
return in_array($member->ID, $list->getIDList());
}
return $list->byID($member->ID) !== null;
}
public function getCMSFields() {
Requirements::css(BLOGGER_DIR . '/css/cms.css');
@ -87,6 +110,24 @@ class BlogPost extends Page {
'URLSegment',
));
// Author field
$authorField = ListboxField::create(
"Authors",
_t("BlogPost.Authors", "Authors"),
Member::get()->map()->toArray()
)->setMultiple(true);
$authorNames = TextField::create(
"AuthorNames",
_t("BlogPost.AdditionalCredits", "Additional Credits"),
null,
1024
)->setDescription('Comma separated list of names');
if(!$this->canEditAuthors()) {
$authorField = $authorField->performDisabledTransformation();
$authorNames = $authorNames->performDisabledTransformation();
}
// Build up our sidebar
$options = BlogAdminSidebar::create(
$publishDate = DatetimeField::create("PublishDate", _t("BlogPost.PublishDate", "Publish Date")),
@ -100,7 +141,9 @@ class BlogPost extends Page {
"Tags",
_t("BlogPost.Tags", "Tags"),
$self->Parent()->Tags()->map()->toArray()
)->setMultiple(true)
)->setMultiple(true),
$authorField,
$authorNames
)->setTitle('Post Options');
$publishDate->getDateField()->setConfig("showcalendar", true);
@ -116,14 +159,17 @@ class BlogPost extends Page {
return $fields;
}
/**
* If no publish date is set, set the date to now.
**/
protected function onBeforeWrite() {
parent::onBeforeWrite();
if(!$this->PublishDate) $this->setCastedField("PublishDate", time());
// If no publish date is set, set the date to now.
if(!$this->PublishDate) $this->PublishDate = SS_Datetime::now()->getValue();
// If creating a new entry, assign the current member as an author
// This allows writers and contributors to then edit their new post
if(!$this->exists() && ($member = Member::currentUser())) {
$this->Authors()->add($member);
}
}
@ -133,7 +179,7 @@ class BlogPost extends Page {
**/
public function onBeforePublish() {
if ($this->dbObject('PublishDate')->InPast() && !$this->isPublished()) {
$this->setCastedField("PublishDate", time());
$this->PublishDate = SS_Datetime::now()->getValue();
$this->write();
}
}
@ -159,6 +205,81 @@ class BlogPost extends Page {
return true;
}
public function canEdit($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
// Inherit permission
if(parent::canEdit($member)) return true;
// Check if assigned to a blog
$parent = $this->Parent();
if(!$parent || !$parent->exists() || !($parent instanceof Blog)) return false;
// Editors have full control
if($parent->isEditor($member)) return true;
// Only writers or contributors can edit
if(!$parent->isWriter($member) && !$parent->isContributor($member)) return false;
// And only if they are also authors
return $this->isAuthor($member);
}
/**
* Determine if this user can edit the authors list
*
* @param Member $member
* @return boolean
*/
public function canEditAuthors($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
$extended = $this->extendedCan('canEditAuthors', $member);
if($extended !== null) return $extended;
// Check blog roles
$parent = $this->Parent();
if($parent instanceof Blog && $parent->exists()) {
// Editors can do anything
if($parent->isEditor($member)) return true;
// Writers who are also authors can edit authors
if($parent->isWriter($member) && $this->isAuthor($member)) return true;
}
// Check permission
return Permission::checkMember($member, Blog::MANAGE_USERS);
}
public function canPublish($member = null) {
$member = $member ?: Member::currentUser();
if(is_numeric($member)) $member = Member::get()->byID($member);
if(Permission::checkMember($member, "ADMIN")) return true;
// Standard mechanism for accepting permission changes from extensions
$extended = $this->extendedCan('canPublish', $member);
if($extended !== null) return $extended;
// Check blog roles
$parent = $this->Parent();
if($parent instanceof Blog && $parent->exists()) {
// Editors can do anything
if($parent->isEditor($member)) return true;
// Writers who are also authors can edit authors
if($parent->isWriter($member) && $this->isAuthor($member)) return true;
// Contributors can ONLY publish this page if they somehow have global publish permissions
// In this case defer to old canEdit implementation
if($parent->isContributor($member)) return parent::canEdit($member);
}
// Normal case - fail over to canEdit()
return $this->canEdit($member);
}
/**
@ -183,7 +304,6 @@ class BlogPost extends Page {
**/
public function getMonthlyArchiveLink($type = "day") {
$date = $this->dbObject("PublishDate");
$year = $date->format("Y");
if($type != "year") {
if($type == "day") {
return Controller::join_links(

0
docs/_manifest_exclude Normal file
View File

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

20
docs/en/features.md Normal file
View File

@ -0,0 +1,20 @@
# Features
* Blog Posts extend SiteTree so no Page functionality is lost by using DataObject's.
* Blog Posts can be listed in the SiteTree **OR** in a GridField within the blog, removing clutter for large blogs.
* Filter blog posts by category
* Filter blog posts by tag
* Full blog Archive by Year, month or day
* 4 widgets included (category listing, tag listing, archive & recent posts).
* Publish Date - Set a blog post to publish in the future.
* Custom GridField components for quickly adding new objects.
* RSS Feed of the blog
## Screenshots
*Easily manage and add new blog posts through a GridField.*
![](_images/blog-post-management.png)
*Quickly add new tags and categories.*
![](_images/blogpost-add-tags-categories.png)

43
docs/en/roles.md Normal file
View File

@ -0,0 +1,43 @@
# Roles
Blog authoring and management can be delegated to users at up to three different levels. Users assigned to a blog
using one of the below methods will be automatically assigned to the "Blog users" group and granted basic CMS access.
Note: If it's necessary to restrict access to non-blog pages to any of the below users, ensure that
the "Who can edit pages on this site?" option under Settings is changed from "Anyone who can log-in to the CMS"
to a specific selection of groups.
## Editor
An editor has control over specific Blogs, and their respective BlogPost subpages. Short of being able to assign
other editors to a Blog, they are able to handle most changes to their assigned section.
Editors have these permissions:
* Update or Publish any BlogPost in their Blog
* Update or Publish their Blog
* Assign/Unassign writers to their Blog
* Assign/Unassign contributors to their Blog
* Assign/Unassign any member as an author of a particular BlogPost
## Writer
A writer is able to handle most tasks involving writing and publishing BlogPosts. While they
are not able to edit a Blog directly, they are able to add new BlogPost entries within a Blog.
They can't edit BlogPosts, however, that they are not been assigned to or have authored themselves.
Writers have these permissions:
* Update or Publish any BlogPost they have authored (or are assigned as author of)
* Assign/Unassign any member as an author of a particular BlogPost they have authored
(or are assigned as author of)
## Contributor
Contributors have the ability to create or edit BlogPosts, but are unable to publish without
authorisation of an editor. They are also unable to assign other contributing authors to
any of their BlogPosts.
Contributors have these permissions:
* Update or edit any BlogPost they have authored (or are assigned as author of)

36
docs/en/setup.md Normal file
View File

@ -0,0 +1,36 @@
# Setup
## Requirements
```
silverstripe/cms: ~3.1
```
## Suggested Modules
```
silverstripe/widgets: *
silverstripe/comments: *
```
## Installation
```
composer require silverstripe/blog 2.0.x-dev
```
## Usage
Because the blog is part of the SiteTree the usage is the same as any other page.
By default, blog posts are filtered out of the SiteTree to avoid clutter and instead put in a GridField inside
of the blog. If you wish to display the blog posts within the site tree you can do so using Silverstripe config.
In mysite/_config/settings.yml
```yaml
BlogPost:
show_in_sitetree: true
```
Doing this will remove the GridField & result in a normal behaving SiteTree.

View File

@ -22,4 +22,14 @@
<%t Blog.Posted "Posted" %>
<a href="$MonthlyArchiveLink">$PublishDate.ago</a>
<% if $Authors || $AuthorNames %>
<%t Blog.By "by" %>
<% if $Authors %><% loop $Authors %>
$Name.XML<% if not $Last || $Up.AuthorNames %>,<% end_if %>
<% end_loop %><% end_if %>
<% if $AuthorNames %>
$AuthorNames
<% end_if %>
<% end_if %>
</p>

View File

@ -18,11 +18,13 @@ class BlogPostFilterTest extends SapphireTest {
$member = Member::currentUser();
if($member) $member->logout();
$count = BlogPost::get()->count();
$blog = $this->objFromFixture('Blog', 'firstblog');
$count = $blog->AllChildren()->Count();
$this->assertEquals(3, $count, "Filtered blog posts");
SS_Datetime::set_mock_now("2020-01-01 00:00:00");
$count = BlogPost::get()->count();
$count = $blog->AllChildren()->Count();
$this->assertEquals(5, $count, "Unfiltered blog posts");
}

View File

@ -98,4 +98,65 @@ class BlogTest extends SapphireTest {
}
public function testRoles() {
$blog = $this->objFromFixture('Blog', 'fourthblog');
$blog2 = $this->objFromFixture('Blog', 'firstblog');
$postA = $this->objFromFixture('BlogPost', 'post-a');
$postB = $this->objFromFixture('BlogPost', 'post-b');
$postC = $this->objFromFixture('BlogPost', 'post-c');
$editor = $this->objFromFixture('Member', 'blogeditor');
$writer = $this->objFromFixture('Member', 'writer');
$contributor = $this->objFromFixture('Member', 'contributor');
$visitor = $this->objFromFixture('Member', 'visitor');
// Check that editors have all permissions on their own blog
$this->assertTrue($blog->canEdit($editor));
Debug::dump($blog2->Editors()->count());
$this->assertFalse($blog2->canEdit($editor));
$this->assertTrue($blog->canAddChildren($editor));
$this->assertFalse($blog2->canAddChildren($editor));
$this->assertTrue($postA->canEdit($editor));
$this->assertTrue($postB->canEdit($editor));
$this->assertTrue($postC->canEdit($editor));
$this->assertTrue($postA->canPublish($editor));
$this->assertTrue($postB->canPublish($editor));
$this->assertTrue($postC->canPublish($editor));
// check rights of writers
$this->assertFalse($blog->canEdit($writer));
$this->assertFalse($blog2->canEdit($writer));
$this->assertTrue($blog->canAddChildren($writer));
$this->assertFalse($blog2->canAddChildren($writer));
$this->assertTrue($postA->canEdit($writer));
$this->assertFalse($postB->canEdit($writer));
$this->assertTrue($postC->canEdit($writer));
$this->assertTrue($postA->canPublish($writer));
$this->assertFalse($postB->canPublish($writer));
$this->assertTrue($postC->canPublish($writer));
// Check rights of contributors
$this->assertFalse($blog->canEdit($contributor));
$this->assertFalse($blog2->canEdit($contributor));
$this->assertTrue($blog->canAddChildren($contributor));
$this->assertFalse($blog2->canAddChildren($contributor));
$this->assertTrue($postA->canEdit($contributor));
$this->assertFalse($postB->canEdit($contributor));
$this->assertTrue($postC->canEdit($contributor));
$this->assertFalse($postA->canPublish($contributor));
$this->assertFalse($postB->canPublish($contributor));
$this->assertFalse($postC->canPublish($contributor));
// Check rights of non-cms user
$this->assertFalse($blog->canEdit($visitor));
$this->assertFalse($blog2->canEdit($visitor));
$this->assertFalse($blog->canAddChildren($visitor));
$this->assertFalse($blog2->canAddChildren($visitor));
$this->assertFalse($postA->canEdit($visitor));
$this->assertFalse($postB->canEdit($visitor));
$this->assertFalse($postC->canEdit($visitor));
$this->assertFalse($postA->canPublish($visitor));
$this->assertFalse($postB->canPublish($visitor));
$this->assertFalse($postC->canPublish($visitor));
}
}

View File

@ -6,6 +6,9 @@ Group:
Title: Administrators
editors:
Title: Editors
blog-users:
Title: Blog Users
Code: blog-users
Permission:
admins:
@ -14,6 +17,17 @@ Permission:
editors:
Code: CMS_ACCESS_CMSMain
Group: =>Group.editors
blog-users:
Code: CMS_ACCESS_CMSMain
Group: =>Group.blog-users
SiteConfig:
default:
CanEditType: 'OnlyTheseUsers'
CanCreateTopLevelType: 'OnlyTheseUsers'
EditorGroups: =>Group.admins,=>Group.editors
CreateTopLevelGroups: =>Group.admins,=>Group.editors
Member:
admin:
@ -24,6 +38,21 @@ Member:
FirstName: Test
Surname: Editor
Groups: =>Group.editors
blogeditor:
FirstName: Blog
Surname: Editor
Groups: =>Group.blog-users
writer:
FirstName: Blog
Surname: Writer
Groups: =>Group.blog-users
contributor:
FirstName: Blog
Surname: Contributor
Groups: =>Group.blog-users
visitor:
FirstName: Blog
Surname: Visitor
Blog:
firstblog:
@ -38,6 +67,11 @@ Blog:
Title: 'Third Blog'
CanEditType: 'OnlyTheseUsers'
EditorGroups: =>Group.editors
fourthblog:
Title: 'Fourth Blog'
Editors: =>Member.blogeditor
Writers: =>Member.writer
Contributors: =>Member.contributor
BlogTag:
firsttag:
@ -91,9 +125,26 @@ BlogPost:
PublishDate: '2015-01-01 00:00:00'
Tags: =>BlogTag.firsttag
Categories: =>BlogCategory.firstcategory
Parent: =>Blog.firstblog
futurepost2:
Title: 'Future Post 2'
URLSegment: future-post-2
PublishDate: '2013-11-01 00:00:00'
Tags: =>BlogTag.firsttag
Categories: =>BlogCategory.firstcategory
Parent: =>Blog.firstblog
post-a:
Title: 'One Post'
PublishDate: '2012-01-09 15:00:00'
Parent: =>Blog.fourthblog
Authors: =>Member.writer,=>Member.contributor
post-b:
Title: 'Second Post'
PublishDate: '2012-01-09 15:00:00'
Parent: =>Blog.fourthblog
Authors: =>Member.blogeditor
post-c:
Title: 'Third Post'
PublishDate: '2012-01-09 15:00:00'
Parent: =>Blog.fourthblog
Authors: =>Member.blogeditor,=>Member.writer,=>Member.contributor