From f82825d9a671eb1399513114bb401d59ced172ab Mon Sep 17 00:00:00 2001 From: helpfulrobot Date: Sat, 21 Nov 2015 19:17:29 +1300 Subject: [PATCH] Converted to PSR-2 --- code/admin/GridFieldCategorisationConfig.php | 91 +- code/admin/GridFieldFormAction.php | 47 +- code/admin/GridFieldMergeAction.php | 237 +- code/compat/pages/BlogEntry.php | 173 +- code/compat/pages/BlogHolder.php | 112 +- code/compat/pages/BlogTree.php | 81 +- code/compat/tasks/BlogMigrationTask.php | 151 +- code/compat/tasks/MigratableObject.php | 11 +- code/compat/widgets/ArchiveWidget.php | 74 +- code/compat/widgets/TagCloudWidget.php | 65 +- code/extensions/BlogCommentExtension.php | 32 +- code/extensions/BlogFilter.php | 220 +- code/extensions/BlogMemberExtension.php | 163 +- code/extensions/BlogPostFilter.php | 87 +- code/extensions/BlogPostNotifications.php | 43 +- code/extensions/URLSegmentExtension.php | 89 +- code/forms/BlogAdminSidebar.php | 34 +- .../forms/gridfield/GridFieldAddByDBField.php | 393 +-- .../gridfield/GridFieldBlogPostState.php | 191 +- .../gridfield/GridFieldConfig_BlogPost.php | 40 +- code/model/Blog.php | 2131 +++++++++-------- code/model/BlogCategory.php | 298 +-- code/model/BlogPost.php | 1393 +++++------ code/model/BlogTag.php | 224 +- code/model/CategorisationObject.php | 4 +- code/widgets/BlogArchiveWidget.php | 273 +-- code/widgets/BlogCategoriesWidget.php | 197 +- code/widgets/BlogRecentPostsWidget.php | 157 +- code/widgets/BlogTagsWidget.php | 197 +- tests/BlogCategoryTest.php | 170 +- tests/BlogPostFilterTest.php | 56 +- tests/BlogPostTest.php | 139 +- tests/BlogTagTest.php | 178 +- tests/BlogTest.php | 603 ++--- 34 files changed, 4276 insertions(+), 4078 deletions(-) diff --git a/code/admin/GridFieldCategorisationConfig.php b/code/admin/GridFieldCategorisationConfig.php index 423a34e..e390bff 100644 --- a/code/admin/GridFieldCategorisationConfig.php +++ b/code/admin/GridFieldCategorisationConfig.php @@ -1,54 +1,57 @@ removeComponentsByType('GridFieldAddNewButton'); + $this->removeComponentsByType('GridFieldAddNewButton'); - $this->addComponent( - new GridFieldAddByDBField('buttons-before-left') - ); + $this->addComponent( + new GridFieldAddByDBField('buttons-before-left') + ); - $this->addComponent( - new GridFieldMergeAction($mergeRecords, $parentType, $parentMethod, $childMethod) - ); + $this->addComponent( + new GridFieldMergeAction($mergeRecords, $parentType, $parentMethod, $childMethod) + ); - /** - * @var GridFieldDataColumns $columns - */ - $columns = $this->getComponentByType('GridFieldDataColumns'); + /** + * @var GridFieldDataColumns $columns + */ + $columns = $this->getComponentByType('GridFieldDataColumns'); - $columns->setFieldFormatting(array( - 'BlogPostsCount' => function ($value, CategorisationObject $item) { - return $item->BlogPosts()->Count(); - } - )); + $columns->setFieldFormatting(array( + 'BlogPostsCount' => function ($value, CategorisationObject $item) { + return $item->BlogPosts()->Count(); + } + )); - $this->changeColumnOrder(); - } + $this->changeColumnOrder(); + } - /** - * Reorders GridField columns so that Actions is last. - */ - protected function changeColumnOrder() { - /** - * @var GridFieldDataColumns $columns - */ - $columns = $this->getComponentByType('GridFieldDataColumns'); + /** + * Reorders GridField columns so that Actions is last. + */ + protected function changeColumnOrder() + { + /** + * @var GridFieldDataColumns $columns + */ + $columns = $this->getComponentByType('GridFieldDataColumns'); - $columns->setDisplayFields(array( - 'Title' => 'Title', - 'BlogPostsCount' => 'Posts', - 'MergeAction' => 'MergeAction', - 'Actions' => 'Actions', - )); - } -} \ No newline at end of file + $columns->setDisplayFields(array( + 'Title' => 'Title', + 'BlogPostsCount' => 'Posts', + 'MergeAction' => 'MergeAction', + 'Actions' => 'Actions', + )); + } +} diff --git a/code/admin/GridFieldFormAction.php b/code/admin/GridFieldFormAction.php index 6632722..47d448f 100644 --- a/code/admin/GridFieldFormAction.php +++ b/code/admin/GridFieldFormAction.php @@ -1,27 +1,30 @@ extraAttributes = $attributes; - } + /** + * @param array $attributes + */ + public function setExtraAttributes(array $attributes) + { + $this->extraAttributes = $attributes; + } - /** - * @return array - */ - public function getAttributes() { - $attributes = parent::getAttributes(); + /** + * @return array + */ + public function getAttributes() + { + $attributes = parent::getAttributes(); - return array_merge( - $attributes, - $this->extraAttributes - ); - } -} \ No newline at end of file + return array_merge( + $attributes, + $this->extraAttributes + ); + } +} diff --git a/code/admin/GridFieldMergeAction.php b/code/admin/GridFieldMergeAction.php index ce21302..42efb8d 100644 --- a/code/admin/GridFieldMergeAction.php +++ b/code/admin/GridFieldMergeAction.php @@ -1,140 +1,149 @@ records = $records; - $this->parentType = $parentType; - $this->parentMethod = $parentMethod; - $this->childMethod = $childMethod; - } + /** + * @param array|SS_List $records + * @param string $parentType + * @param string $parentMethod + * @param string $childMethod + */ + public function __construct($records = array(), $parentType, $parentMethod, $childMethod) + { + $this->records = $records; + $this->parentType = $parentType; + $this->parentMethod = $parentMethod; + $this->childMethod = $childMethod; + } - /** - * {@inheritdoc} - */ - public function augmentColumns($gridField, &$columns) { - if(!in_array('MergeAction', $columns)) { - $columns[] = 'MergeAction'; - } + /** + * {@inheritdoc} + */ + public function augmentColumns($gridField, &$columns) + { + if (!in_array('MergeAction', $columns)) { + $columns[] = 'MergeAction'; + } - return $columns; - } + return $columns; + } - /** - * {@inheritdoc} - */ - public function getColumnsHandled($gridField) { - return array('MergeAction'); - } + /** + * {@inheritdoc} + */ + public function getColumnsHandled($gridField) + { + return array('MergeAction'); + } - /** - * {@inheritdoc} - */ - public function getColumnContent($gridField, $record, $columnName) { - if($columnName === 'MergeAction' && $record->{$this->childMethod}()->Count() > 0) { - $dropdown = new DropdownField('Target', 'Target', $this->records->exclude('ID', $record->ID)->map()); - $dropdown->setAttribute('id', 'Target_'.$record->ID); - $prefix = strtolower($this->parentMethod . '-' . $this->childMethod); + /** + * {@inheritdoc} + */ + public function getColumnContent($gridField, $record, $columnName) + { + if ($columnName === 'MergeAction' && $record->{$this->childMethod}()->Count() > 0) { + $dropdown = new DropdownField('Target', 'Target', $this->records->exclude('ID', $record->ID)->map()); + $dropdown->setAttribute('id', 'Target_'.$record->ID); + $prefix = strtolower($this->parentMethod . '-' . $this->childMethod); - $action = GridFieldFormAction::create( - $gridField, - 'MergeAction' . $record->ID, - 'Move', - 'merge', - array( - 'record' => $record->ID, - 'target' => $prefix . '-target-record-' . $record->ID, - ) - ); + $action = GridFieldFormAction::create( + $gridField, + 'MergeAction' . $record->ID, + 'Move', + 'merge', + array( + 'record' => $record->ID, + 'target' => $prefix . '-target-record-' . $record->ID, + ) + ); - $action->setExtraAttributes(array( - 'data-target' => $prefix . '-target-record-' . $record->ID - )); + $action->setExtraAttributes(array( + 'data-target' => $prefix . '-target-record-' . $record->ID + )); - return $dropdown->Field() . $action->Field() . 'move posts to'; - } + return $dropdown->Field() . $action->Field() . 'move posts to'; + } - return null; - } + return null; + } - /** - * {@inheritdoc} - */ - public function getColumnAttributes($gridField, $record, $columnName) { - return array('class' => 'MergeAction'); - } + /** + * {@inheritdoc} + */ + public function getColumnAttributes($gridField, $record, $columnName) + { + return array('class' => 'MergeAction'); + } - /** - * {@inheritdoc} - */ - public function getColumnMetadata($gridField, $columnName) { - return array('title' => 'Move posts to'); - } + /** + * {@inheritdoc} + */ + public function getColumnMetadata($gridField, $columnName) + { + return array('title' => 'Move posts to'); + } - /** - * {@inheritdoc} - */ - public function getActions($gridField) { - return array('merge'); - } + /** + * {@inheritdoc} + */ + public function getActions($gridField) + { + return array('merge'); + } - /** - * {@inheritdoc} - */ - public function handleAction(GridField $gridField, $actionName, $arguments, $data) { - if($actionName === 'merge') { - $controller = Controller::curr(); + /** + * {@inheritdoc} + */ + public function handleAction(GridField $gridField, $actionName, $arguments, $data) + { + if ($actionName === 'merge') { + $controller = Controller::curr(); - $request = $controller->getRequest(); + $request = $controller->getRequest(); - $target = $request->requestVar($arguments["target"]); + $target = $request->requestVar($arguments["target"]); - $parentType = $this->parentType; + $parentType = $this->parentType; - $fromParent = $parentType::get()->byId($arguments['record']); - $toParent = $parentType::get()->byId($target); + $fromParent = $parentType::get()->byId($arguments['record']); + $toParent = $parentType::get()->byId($target); - $posts = $fromParent->{$this->childMethod}(); + $posts = $fromParent->{$this->childMethod}(); - foreach($posts as $post) { - $relationship = $post->{$this->parentMethod}(); + foreach ($posts as $post) { + $relationship = $post->{$this->parentMethod}(); - $relationship->remove($fromParent); - $relationship->add($toParent); - } - } - } + $relationship->remove($fromParent); + $relationship->add($toParent); + } + } + } } diff --git a/code/compat/pages/BlogEntry.php b/code/compat/pages/BlogEntry.php index 7068752..6c51530 100644 --- a/code/compat/pages/BlogEntry.php +++ b/code/compat/pages/BlogEntry.php @@ -8,105 +8,106 @@ * @property string $PublishDate * @property string $Tags */ -class BlogEntry extends BlogPost implements MigratableObject { - /** - * @var string - */ - private static $hide_ancestor = 'BlogEntry'; +class BlogEntry extends BlogPost implements MigratableObject +{ + /** + * @var string + */ + private static $hide_ancestor = 'BlogEntry'; - /** - * @var array - */ - private static $db = array( - 'Date' => 'SS_Datetime', - 'Author' => 'Text', - 'Tags' => 'Text', - ); + /** + * @var array + */ + private static $db = array( + 'Date' => 'SS_Datetime', + 'Author' => 'Text', + 'Tags' => 'Text', + ); - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } + /** + * {@inheritdoc} + */ + public function canCreate($member = null) + { + return false; + } - /** - * {@inheritdoc} - */ - public function up() { - - //Migrate comma separated tags into BlogTag objects. - foreach($this->TagNames() as $tag) { - - $existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); - if($existingTag->count()) { - //if tag already exists we will simply add it to this post. - $tagObject = $existingTag->First(); - - } else { + /** + * {@inheritdoc} + */ + public function up() + { + + //Migrate comma separated tags into BlogTag objects. + foreach ($this->TagNames() as $tag) { + $existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); + if ($existingTag->count()) { + //if tag already exists we will simply add it to this post. + $tagObject = $existingTag->First(); + } else { - //if the tag is now we create it and add it to this post. - $tagObject = new BlogTag(); - $tagObject->Title = $tag; - $tagObject->BlogID = $this->ParentID; - $tagObject->write(); + //if the tag is now we create it and add it to this post. + $tagObject = new BlogTag(); + $tagObject->Title = $tag; + $tagObject->BlogID = $this->ParentID; + $tagObject->write(); + } - - } + if ($tagObject) { + $this->Tags()->add($tagObject); + } + } - if($tagObject){ - $this->Tags()->add($tagObject); - } - } + //Store if the original entity was published or not (draft) + $published = $this->IsPublished(); + // If a user has subclassed BlogEntry, it should not be turned into a BlogPost. + if ($this->ClassName === 'BlogEntry') { + $this->ClassName = 'BlogPost'; + $this->RecordClassName = 'BlogPost'; + } + //Migrate these key data attributes + $this->PublishDate = $this->Date; + $this->AuthorNames = $this->Author; + $this->InheritSideBar = true; + + //Write and additionally publish the item if it was published before. + $this->write(); + if ($published) { + $this->publish('Stage', 'Live'); + $message = "PUBLISHED: "; + } else { + $message = "DRAFT: "; + } + + return $message . $this->Title; + } - //Store if the original entity was published or not (draft) - $published = $this->IsPublished(); - // If a user has subclassed BlogEntry, it should not be turned into a BlogPost. - if($this->ClassName === 'BlogEntry') { - $this->ClassName = 'BlogPost'; - $this->RecordClassName = 'BlogPost'; - } - //Migrate these key data attributes - $this->PublishDate = $this->Date; - $this->AuthorNames = $this->Author; - $this->InheritSideBar = true; - - //Write and additionally publish the item if it was published before. - $this->write(); - if($published){ - $this->publish('Stage','Live'); - $message = "PUBLISHED: "; - } else { - $message = "DRAFT: "; - } - - return $message . $this->Title; - } + /** + * Safely split and parse all distinct tags assigned to this BlogEntry. + * + * @deprecated since version 2.0 + * + * @return array + */ + public function TagNames() + { + $tags = preg_split('/\s*,\s*/', trim($this->Tags)); - /** - * Safely split and parse all distinct tags assigned to this BlogEntry. - * - * @deprecated since version 2.0 - * - * @return array - */ - public function TagNames() { - $tags = preg_split('/\s*,\s*/', trim($this->Tags)); + $results = array(); - $results = array(); - - foreach($tags as $tag) { - if($tag) $results[mb_strtolower($tag)] = $tag; - } - - return $results; - } + foreach ($tags as $tag) { + if ($tag) { + $results[mb_strtolower($tag)] = $tag; + } + } + return $results; + } } /** * @deprecated since version 2.0 */ -class BlogEntry_Controller extends BlogPost_Controller { - +class BlogEntry_Controller extends BlogPost_Controller +{ } diff --git a/code/compat/pages/BlogHolder.php b/code/compat/pages/BlogHolder.php index 86b8cdd..49bc287 100644 --- a/code/compat/pages/BlogHolder.php +++ b/code/compat/pages/BlogHolder.php @@ -3,71 +3,75 @@ /** * @deprecated since version 2.0 */ -class BlogHolder extends BlogTree implements MigratableObject { - /** - * @var string - */ - private static $hide_ancestor = 'BlogHolder'; +class BlogHolder extends BlogTree implements MigratableObject +{ + /** + * @var string + */ + private static $hide_ancestor = 'BlogHolder'; - /** - * @var array - */ - private static $db = array( - 'AllowCustomAuthors' => 'Boolean', - 'ShowFullEntry' => 'Boolean', - ); + /** + * @var array + */ + private static $db = array( + 'AllowCustomAuthors' => 'Boolean', + 'ShowFullEntry' => 'Boolean', + ); - /** - * @var array - */ - private static $has_one = array( - 'Owner' => 'Member', - ); + /** + * @var array + */ + private static $has_one = array( + 'Owner' => 'Member', + ); - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } + /** + * {@inheritdoc} + */ + public function canCreate($member = null) + { + return false; + } - //Overload these to stop the Uncaught Exception: Object->__call(): the method 'parent' does not exist on 'BlogHolder' error. - public function validURLSegment() { - return true; - } - public function syncLinkTracking() { - return null; - } + //Overload these to stop the Uncaught Exception: Object->__call(): the method 'parent' does not exist on 'BlogHolder' error. + public function validURLSegment() + { + return true; + } + public function syncLinkTracking() + { + return null; + } - /** - * {@inheritdoc} - */ - public function up() { + /** + * {@inheritdoc} + */ + public function up() + { + $published = $this->IsPublished(); - $published = $this->IsPublished(); + if ($this->ClassName === 'BlogHolder') { + $this->ClassName = 'Blog'; + $this->RecordClassName = 'Blog'; + $this->PostsPerPage = 10; + $this->write(); + } - if($this->ClassName === 'BlogHolder') { - $this->ClassName = 'Blog'; - $this->RecordClassName = 'Blog'; - $this->PostsPerPage = 10; - $this->write(); - } - - if($published){ - $this->publish('Stage','Live'); - $message = "PUBLISHED: "; - } else { - $message = "DRAFT: "; - } - - return $message . $this->Title; - } + if ($published) { + $this->publish('Stage', 'Live'); + $message = "PUBLISHED: "; + } else { + $message = "DRAFT: "; + } + + return $message . $this->Title; + } } /** * @deprecated since version 2.0 */ -class BlogHolder_Controller extends BlogTree_Controller { - +class BlogHolder_Controller extends BlogTree_Controller +{ } diff --git a/code/compat/pages/BlogTree.php b/code/compat/pages/BlogTree.php index 9c72681..0998de2 100644 --- a/code/compat/pages/BlogTree.php +++ b/code/compat/pages/BlogTree.php @@ -3,51 +3,54 @@ /** * @deprecated since version 2.0 */ -class BlogTree extends Page implements MigratableObject { - /** - * @var string - */ - private static $hide_ancestor = 'BlogTree'; +class BlogTree extends Page implements MigratableObject +{ + /** + * @var string + */ + private static $hide_ancestor = 'BlogTree'; - /** - * @var array - */ - private static $db = array( - 'Name' => 'Varchar(255)', - 'LandingPageFreshness' => 'Varchar', - ); + /** + * @var array + */ + private static $db = array( + 'Name' => 'Varchar(255)', + 'LandingPageFreshness' => 'Varchar', + ); - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } + /** + * {@inheritdoc} + */ + public function canCreate($member = null) + { + return false; + } - /** - * {@inheritdoc} - */ - public function up() { - $published = $this->IsPublished(); - if($this->ClassName === 'BlogTree') { - $this->ClassName = 'Page'; - $this->RecordClassName = 'Page'; - $this->write(); - } - if($published){ - $this->publish('Stage','Live'); - $message = "PUBLISHED: "; - } else { - $message = "DRAFT: "; - } - - return $message . $this->Title; - } + /** + * {@inheritdoc} + */ + public function up() + { + $published = $this->IsPublished(); + if ($this->ClassName === 'BlogTree') { + $this->ClassName = 'Page'; + $this->RecordClassName = 'Page'; + $this->write(); + } + if ($published) { + $this->publish('Stage', 'Live'); + $message = "PUBLISHED: "; + } else { + $message = "DRAFT: "; + } + + return $message . $this->Title; + } } /** * @deprecated since version 2.0 */ -class BlogTree_Controller extends Page_Controller { - +class BlogTree_Controller extends Page_Controller +{ } diff --git a/code/compat/tasks/BlogMigrationTask.php b/code/compat/tasks/BlogMigrationTask.php index d222633..143fb7c 100644 --- a/code/compat/tasks/BlogMigrationTask.php +++ b/code/compat/tasks/BlogMigrationTask.php @@ -1,89 +1,92 @@ message('Migrating legacy blog records'); + $this->message('Migrating legacy blog records'); - foreach($classes as $class) { - - $this->upClass($class); - } - - } + foreach ($classes as $class) { + $this->upClass($class); + } + } - /** - * @param string $text - */ - protected function message($text) { - if(Controller::curr() instanceof DatabaseAdmin) { - DB::alteration_message($text, 'obsolete'); - } else { - echo $text . "
"; - } - } + /** + * @param string $text + */ + protected function message($text) + { + if (Controller::curr() instanceof DatabaseAdmin) { + DB::alteration_message($text, 'obsolete'); + } else { + echo $text . "
"; + } + } - /** - * Migrate records of a single class - * - * @param string $class - * @param null|string $stage - */ - protected function upClass($class) { - if(!class_exists($class)) { - return; - } + /** + * Migrate records of a single class + * + * @param string $class + * @param null|string $stage + */ + protected function upClass($class) + { + if (!class_exists($class)) { + return; + } - if(is_subclass_of($class, 'SiteTree')) { - $items = SiteTree::get()->filter('ClassName', $class); - } else { - $items = $class::get(); - } + if (is_subclass_of($class, 'SiteTree')) { + $items = SiteTree::get()->filter('ClassName', $class); + } else { + $items = $class::get(); + } - if($count = $items->count()) { - $this->message( - sprintf( - 'Migrating %s legacy %s records.', - $count, - $class - ) - ); + if ($count = $items->count()) { + $this->message( + sprintf( + 'Migrating %s legacy %s records.', + $count, + $class + ) + ); - foreach($items as $item) { - $cancel = $item->extend('onBeforeUp'); + foreach ($items as $item) { + $cancel = $item->extend('onBeforeUp'); - if($cancel && min($cancel) === false) { - continue; - } + if ($cancel && min($cancel) === false) { + continue; + } - /** - * @var MigratableObject $item - */ - $result = $item->up(); - $this->message($result); + /** + * @var MigratableObject $item + */ + $result = $item->up(); + $this->message($result); - $item->extend('onAfterUp'); - } - } - } + $item->extend('onAfterUp'); + } + } + } - /** - * {@inheritdoc} - */ - public function down() { - $this->message('BlogMigrationTask::down() not implemented'); - } + /** + * {@inheritdoc} + */ + public function down() + { + $this->message('BlogMigrationTask::down() not implemented'); + } } diff --git a/code/compat/tasks/MigratableObject.php b/code/compat/tasks/MigratableObject.php index 59af4ae..2c747a8 100644 --- a/code/compat/tasks/MigratableObject.php +++ b/code/compat/tasks/MigratableObject.php @@ -1,8 +1,9 @@ 'Varchar', - ); +class ArchiveWidget extends BlogArchiveWidget implements MigratableObject +{ + /** + * @var array + */ + private static $db = array( + 'DisplayMode' => 'Varchar', + ); - /** - * @var array - */ - private static $only_available_in = array( - 'none', - ); + /** + * @var array + */ + private static $only_available_in = array( + 'none', + ); - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } + /** + * {@inheritdoc} + */ + public function canCreate($member = null) + { + return false; + } - /** - * {@inheritdoc} - */ - public function up() { - if($this->DisplayMode) { - $this->ArchiveType = 'Monthly'; + /** + * {@inheritdoc} + */ + public function up() + { + if ($this->DisplayMode) { + $this->ArchiveType = 'Monthly'; - if($this->DisplayMode === 'year') { - $this->ArchiveType = 'Yearly'; - } - } + if ($this->DisplayMode === 'year') { + $this->ArchiveType = 'Yearly'; + } + } - $this->ClassName = 'BlogArchiveWidget'; - $this->write(); - return "Migrated " . $this->ArchiveType . " archive widget"; - - } + $this->ClassName = 'BlogArchiveWidget'; + $this->write(); + return "Migrated " . $this->ArchiveType . " archive widget"; + } } diff --git a/code/compat/widgets/TagCloudWidget.php b/code/compat/widgets/TagCloudWidget.php index 5f7f832..a527ddd 100644 --- a/code/compat/widgets/TagCloudWidget.php +++ b/code/compat/widgets/TagCloudWidget.php @@ -1,7 +1,7 @@ 'Varchar', - 'Limit' => 'Int', - 'Sortby' => 'Varchar', - ); +class TagCloudWidget extends BlogTagsWidget implements MigratableObject +{ + /** + * @var array + */ + private static $db = array( + 'Title' => 'Varchar', + 'Limit' => 'Int', + 'Sortby' => 'Varchar', + ); - /** - * @var array - */ - private static $only_available_in = array( - 'none', - ); + /** + * @var array + */ + private static $only_available_in = array( + 'none', + ); - /** - * {@inheritdoc} - */ - public function canCreate($member = null) { - return false; - } + /** + * {@inheritdoc} + */ + public function canCreate($member = null) + { + return false; + } - /** - * {@inheritdoc} - */ - public function up() { - $this->ClassName = 'BlogTagsWidget'; - $this->write(); - return "Migrated " . $this->Title . " widget"; - } + /** + * {@inheritdoc} + */ + public function up() + { + $this->ClassName = 'BlogTagsWidget'; + $this->write(); + return "Migrated " . $this->Title . " widget"; + } } diff --git a/code/extensions/BlogCommentExtension.php b/code/extensions/BlogCommentExtension.php index 7431e4d..de4576a 100644 --- a/code/extensions/BlogCommentExtension.php +++ b/code/extensions/BlogCommentExtension.php @@ -3,21 +3,23 @@ /** * Adds Blog specific behaviour to Comment. */ -class BlogCommentExtension extends DataExtension { - /** - * Extra CSS classes for styling different comment types. - * - * @return string - */ - public function getExtraClass() { - $blogPost = $this->owner->getParent(); +class BlogCommentExtension extends DataExtension +{ + /** + * Extra CSS classes for styling different comment types. + * + * @return string + */ + public function getExtraClass() + { + $blogPost = $this->owner->getParent(); - if($blogPost instanceof BlogPost) { - if($blogPost->isAuthor($this->owner->Author())) { - return 'author-comment'; - } - } + if ($blogPost instanceof BlogPost) { + if ($blogPost->isAuthor($this->owner->Author())) { + return 'author-comment'; + } + } - return ''; - } + return ''; + } } diff --git a/code/extensions/BlogFilter.php b/code/extensions/BlogFilter.php index a34a813..65dc027 100644 --- a/code/extensions/BlogFilter.php +++ b/code/extensions/BlogFilter.php @@ -1,106 +1,114 @@ -shouldFilter() && $this->subclassForBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { - $stage = Versioned::current_stage(); - - if($stage == 'Stage') { - $stage = ''; - } elseif($stage) { - $stage = '_' . $stage; - } - - $dataQuery = $staged->dataQuery() - ->innerJoin('BlogPost', sprintf('"BlogPost%s"."ID" = "SiteTree%s"."ID"', $stage, $stage)) - ->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); - - $staged = $staged->setDataQuery($dataQuery); - } - - return $staged; - } - - /** - * @return bool - */ - protected function subclassForBlog() { - return in_array(get_class($this->owner), ClassInfo::subClassesFor('Blog')); - } - - /** - * {@inheritdoc} - */ - public function liveChildren($showAll = false, $onlyDeletedFromStage = false) { - $staged = parent::liveChildren($showAll, $onlyDeletedFromStage); - - if(!$this->shouldFilter() && $this->isBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { - $dataQuery = $staged->dataQuery() - ->innerJoin('BlogPost', '"BlogPost_Live"."ID" = "SiteTree_Live"."ID"') - ->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); - - $staged = $staged->setDataQuery($dataQuery); - } - - return $staged; - } - - /** - * @return bool - */ - protected function isBlog() { - return $this->owner instanceof Blog; - } - - /** - * {@inheritdoc} - */ - public function updateCMSFields(FieldList $fields) { - $excluded = $this->owner->getExcludedSiteTreeClassNames(); - - if(!empty($excluded)) { - $pages = BlogPost::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->insertBefore($tab, 'Main'); - } - } -} - - -/** - * Enables children of non-editable pages to be edited. - */ -class BlogFilter_GridField extends GridField { - /** - * @param FormTransformation $transformation - * - * @return $this - */ - public function transform(FormTransformation $transformation) { - return $this; - } -} +shouldFilter() && $this->subclassForBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { + $stage = Versioned::current_stage(); + + if ($stage == 'Stage') { + $stage = ''; + } elseif ($stage) { + $stage = '_' . $stage; + } + + $dataQuery = $staged->dataQuery() + ->innerJoin('BlogPost', sprintf('"BlogPost%s"."ID" = "SiteTree%s"."ID"', $stage, $stage)) + ->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); + + $staged = $staged->setDataQuery($dataQuery); + } + + return $staged; + } + + /** + * @return bool + */ + protected function subclassForBlog() + { + return in_array(get_class($this->owner), ClassInfo::subClassesFor('Blog')); + } + + /** + * {@inheritdoc} + */ + public function liveChildren($showAll = false, $onlyDeletedFromStage = false) + { + $staged = parent::liveChildren($showAll, $onlyDeletedFromStage); + + if (!$this->shouldFilter() && $this->isBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { + $dataQuery = $staged->dataQuery() + ->innerJoin('BlogPost', '"BlogPost_Live"."ID" = "SiteTree_Live"."ID"') + ->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); + + $staged = $staged->setDataQuery($dataQuery); + } + + return $staged; + } + + /** + * @return bool + */ + protected function isBlog() + { + return $this->owner instanceof Blog; + } + + /** + * {@inheritdoc} + */ + public function updateCMSFields(FieldList $fields) + { + $excluded = $this->owner->getExcludedSiteTreeClassNames(); + + if (!empty($excluded)) { + $pages = BlogPost::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->insertBefore($tab, 'Main'); + } + } +} + + +/** + * Enables children of non-editable pages to be edited. + */ +class BlogFilter_GridField extends GridField +{ + /** + * @param FormTransformation $transformation + * + * @return $this + */ + public function transform(FormTransformation $transformation) + { + return $this; + } +} diff --git a/code/extensions/BlogMemberExtension.php b/code/extensions/BlogMemberExtension.php index 4e82ba2..1a3f2d7 100644 --- a/code/extensions/BlogMemberExtension.php +++ b/code/extensions/BlogMemberExtension.php @@ -6,105 +6,110 @@ * @package silverstripe * @subpackage blog */ -class BlogMemberExtension extends DataExtension { - /** - * @var array - */ - private static $db = array( - 'URLSegment' => 'Varchar', - 'BlogProfileSummary' => 'Text', - ); +class BlogMemberExtension extends DataExtension +{ + /** + * @var array + */ + private static $db = array( + 'URLSegment' => 'Varchar', + 'BlogProfileSummary' => 'Text', + ); - /** - * @var array - */ - private static $has_one = array( - 'BlogProfileImage' => 'Image', - ); + /** + * @var array + */ + private static $has_one = array( + 'BlogProfileImage' => 'Image', + ); - /** - * @var array - */ - private static $belongs_many_many = array( - 'BlogPosts' => 'BlogPost', - ); + /** + * @var array + */ + private static $belongs_many_many = array( + 'BlogPosts' => 'BlogPost', + ); - /** - * {@inheritdoc} - */ - public function onBeforeWrite() { - $count = 1; + /** + * {@inheritdoc} + */ + public function onBeforeWrite() + { + $count = 1; - $this->owner->URLSegment = $this->generateURLSegment(); + $this->owner->URLSegment = $this->generateURLSegment(); - while(!$this->validURLSegment()) { - $this->owner->URLSegment = preg_replace('/-[0-9]+$/', null, $this->owner->URLSegment) . '-' . $count; - $count++; - } - } + while (!$this->validURLSegment()) { + $this->owner->URLSegment = preg_replace('/-[0-9]+$/', null, $this->owner->URLSegment) . '-' . $count; + $count++; + } + } - /** - * Generate a unique URL segment based on the Member's name. - * - * @return string - */ - public function generateURLSegment() { - $filter = URLSegmentFilter::create(); - $name = $this->owner->FirstName . ' ' . $this->owner->Surname; - $urlSegment = $filter->filter($name); + /** + * Generate a unique URL segment based on the Member's name. + * + * @return string + */ + public function generateURLSegment() + { + $filter = URLSegmentFilter::create(); + $name = $this->owner->FirstName . ' ' . $this->owner->Surname; + $urlSegment = $filter->filter($name); - if(!$urlSegment || $urlSegment == '-' || $urlSegment == '-1') { - $urlSegment = 'profile-' . $this->owner->ID; - } + if (!$urlSegment || $urlSegment == '-' || $urlSegment == '-1') { + $urlSegment = 'profile-' . $this->owner->ID; + } - return $urlSegment; - } + return $urlSegment; + } - /** - * Returns TRUE if this object has a URL segment value that does not conflict with any other - * objects. - * - * @return bool - */ - public function validURLSegment() { - $conflict = Member::get()->filter('URLSegment', $this->owner->URLSegment); + /** + * Returns TRUE if this object has a URL segment value that does not conflict with any other + * objects. + * + * @return bool + */ + public function validURLSegment() + { + $conflict = Member::get()->filter('URLSegment', $this->owner->URLSegment); - if($this->owner->ID) { - $conflict = $conflict->exclude('ID', $this->owner->ID); - } + if ($this->owner->ID) { + $conflict = $conflict->exclude('ID', $this->owner->ID); + } - return $conflict->count() == 0; - } + return $conflict->count() == 0; + } - /** - * {@inheritdoc} - */ - public function updateCMSFields(FieldList $fields) { - $fields->removeByName('URLSegment'); + /** + * {@inheritdoc} + */ + public function updateCMSFields(FieldList $fields) + { + $fields->removeByName('URLSegment'); - // Remove the automatically-generated posts tab. + // Remove the automatically-generated posts tab. - $fields->removeFieldFromTab('Root', 'BlogPosts'); + $fields->removeFieldFromTab('Root', 'BlogPosts'); - // Construct a better posts tab. + // Construct a better posts tab. - Requirements::css(BLOGGER_DIR . '/css/cms.css'); - Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); + Requirements::css(BLOGGER_DIR . '/css/cms.css'); + Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); - $tab = new Tab('BlogPosts', 'Blog Posts'); + $tab = new Tab('BlogPosts', 'Blog Posts'); - $gridField = new GridField( - 'BlogPosts', - 'Blog Posts', - $this->owner->BlogPosts(), - new GridFieldConfig_BlogPost() - ); + $gridField = new GridField( + 'BlogPosts', + 'Blog Posts', + $this->owner->BlogPosts(), + new GridFieldConfig_BlogPost() + ); - $tab->Fields()->add($gridField); + $tab->Fields()->add($gridField); - $fields->addFieldToTab('Root', $tab); + $fields->addFieldToTab('Root', $tab); - return $fields; - } + return $fields; + } } diff --git a/code/extensions/BlogPostFilter.php b/code/extensions/BlogPostFilter.php index 367e636..1795bc8 100644 --- a/code/extensions/BlogPostFilter.php +++ b/code/extensions/BlogPostFilter.php @@ -1,42 +1,45 @@ -addWhere(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); - } - } - - /** - * This is a fix so that when we try to fetch subclasses of BlogPost, lazy loading includes the - * BlogPost table in its query. Leaving this table out means the default sort order column - * PublishDate causes an error. - * - * @see https://github.com/silverstripe/silverstripe-framework/issues/1682 - * - * @param SQLQuery $query - * @param mixed $dataQuery - * @param mixed $parent - */ - public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent) { - $dataQuery->innerJoin('BlogPost', '"SiteTree"."ID" = "BlogPost"."ID"'); - } -} +addWhere(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); + } + } + + /** + * This is a fix so that when we try to fetch subclasses of BlogPost, lazy loading includes the + * BlogPost table in its query. Leaving this table out means the default sort order column + * PublishDate causes an error. + * + * @see https://github.com/silverstripe/silverstripe-framework/issues/1682 + * + * @param SQLQuery $query + * @param mixed $dataQuery + * @param mixed $parent + */ + public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent) + { + $dataQuery->innerJoin('BlogPost', '"SiteTree"."ID" = "BlogPost"."ID"'); + } +} diff --git a/code/extensions/BlogPostNotifications.php b/code/extensions/BlogPostNotifications.php index 0d4d8ee..ff4a38f 100644 --- a/code/extensions/BlogPostNotifications.php +++ b/code/extensions/BlogPostNotifications.php @@ -5,25 +5,28 @@ * * Extends {@see BlogPost} with extensions to {@see CommentNotifiable}. */ -class BlogPostNotifications extends DataExtension { - /** - * Notify all authors of notifications. - * - * @param SS_List $list - * @param mixed $comment - */ - public function updateNotificationRecipients(&$list, &$comment) { - $list = $this->owner->Authors(); - } +class BlogPostNotifications extends DataExtension +{ + /** + * Notify all authors of notifications. + * + * @param SS_List $list + * @param mixed $comment + */ + public function updateNotificationRecipients(&$list, &$comment) + { + $list = $this->owner->Authors(); + } - /** - * Update comment to include the page title. - * - * @param string $subject - * @param Comment $comment - * @param Member|string $recipient - */ - public function updateNotificationSubject(&$subject, &$comment, &$recipient) { - $subject = sprintf('A new comment has been posted on ', $this->owner->Title); - } + /** + * Update comment to include the page title. + * + * @param string $subject + * @param Comment $comment + * @param Member|string $recipient + */ + public function updateNotificationSubject(&$subject, &$comment, &$recipient) + { + $subject = sprintf('A new comment has been posted on ', $this->owner->Title); + } } diff --git a/code/extensions/URLSegmentExtension.php b/code/extensions/URLSegmentExtension.php index f6f6105..fd13d45 100644 --- a/code/extensions/URLSegmentExtension.php +++ b/code/extensions/URLSegmentExtension.php @@ -6,56 +6,59 @@ * @package silverstripe * @subpackage blog */ -class URLSegmentExtension extends DataExtension { - /** - * @var array - */ - private static $db = array( - 'URLSegment' => 'Varchar(255)', - ); +class URLSegmentExtension extends DataExtension +{ + /** + * @var array + */ + private static $db = array( + 'URLSegment' => 'Varchar(255)', + ); - /** - * {@inheritdoc} - */ - public function onBeforeWrite() { - $this->owner->generateURLSegment(); - } + /** + * {@inheritdoc} + */ + public function onBeforeWrite() + { + $this->owner->generateURLSegment(); + } - /** - * Generates a unique URLSegment from the title. - * - * @param int $increment - * - * @return string - */ - public function generateURLSegment($increment = null) { - $filter = new URLSegmentFilter(); + /** + * Generates a unique URLSegment from the title. + * + * @param int $increment + * + * @return string + */ + public function generateURLSegment($increment = null) + { + $filter = new URLSegmentFilter(); - $this->owner->URLSegment = $filter->filter($this->owner->Title); + $this->owner->URLSegment = $filter->filter($this->owner->Title); - if(is_int($increment)) { - $this->owner->URLSegment .= '-' . $increment; - } + if (is_int($increment)) { + $this->owner->URLSegment .= '-' . $increment; + } - $duplicate = DataList::create($this->owner->ClassName)->filter(array( - 'URLSegment' => $this->owner->URLSegment, - 'BlogID' => $this->owner->BlogID, - )); + $duplicate = DataList::create($this->owner->ClassName)->filter(array( + 'URLSegment' => $this->owner->URLSegment, + 'BlogID' => $this->owner->BlogID, + )); - if($this->owner->ID) { - $duplicate = $duplicate->exclude('ID', $this->owner->ID); - } + if ($this->owner->ID) { + $duplicate = $duplicate->exclude('ID', $this->owner->ID); + } - if($duplicate->count() > 0) { - if(is_int($increment)) { - $increment += 1; - } else { - $increment = 0; - } + if ($duplicate->count() > 0) { + if (is_int($increment)) { + $increment += 1; + } else { + $increment = 0; + } - $this->owner->generateURLSegment((int) $increment); - } + $this->owner->generateURLSegment((int) $increment); + } - return $this->owner->URLSegment; - } + return $this->owner->URLSegment; + } } diff --git a/code/forms/BlogAdminSidebar.php b/code/forms/BlogAdminSidebar.php index ea812a3..67deac5 100644 --- a/code/forms/BlogAdminSidebar.php +++ b/code/forms/BlogAdminSidebar.php @@ -1,16 +1,18 @@ -targetFragment = $targetFragment; - $this->dataObjectField = (string) $dataObjectField; - } - - /** - * Provide actions to this component. - * - * @param GridField $gridField - * - * @return array - */ - public function getActions($gridField) { - return array( - 'add', - ); - } - - /** - * Handles the add action for the given DataObject. - * - * @param $gridField GridField - * @param $actionName string - * @param $arguments mixed - * @param $data array - * - * @return null|SS_HTTPResponse - * - * @throws UnexpectedValueException - */ - public function handleAction(GridField $gridField, $actionName, $arguments, $data) { - if($actionName == 'add') { - $dbField = $this->getDataObjectField(); - - $objClass = $gridField->getModelClass(); - - /** - * @var DataObject $obj - */ - $obj = new $objClass(); - - if($obj->hasField($dbField)) { - $obj->setCastedField($dbField, $data['gridfieldaddbydbfield'][$obj->ClassName][$dbField]); - - if($obj->canCreate()) { - $id = $gridField->getList()->add($obj); - if(!$id) { - $gridField->setError( - _t( - 'GridFieldAddByDBField.AddFail', - 'Unable to save {class} to the database.', - 'Unable to add the DataObject.', - array( - 'class' => get_class($obj), - ) - ), - 'error' - ); - } - } else { - return Security::permissionFailure( - Controller::curr(), - _t( - 'GridFieldAddByDBField.PermissionFail', - 'You don\'t have permission to create a {class}.', - 'Unable to add the DataObject.', - array( - 'class' => get_class($obj) - ) - ) - ); - } - } else { - throw new UnexpectedValueException( - sprintf( - 'Invalid field (%s) on %s.', - $dbField, - $obj->ClassName - ) - ); - } - } - - return null; - } - - /** - * Returns the database field for which we'll add the new data object. - * - * @return string - */ - public function getDataObjectField() { - return $this->dataObjectField; - } - - /** - * Set the database field. - * - * @param $field string - */ - public function setDataObjectField($field) { - $this->dataObjectField = (string) $field; - } - - /** - * Renders the TextField and add button to the GridField. - * - * @param $gridField GridField - * - * @return string - */ - public function getHTMLFragments($gridField) { - /** - * @var DataList $dataList - */ - $dataList = $gridField->getList(); - - $dataClass = $dataList->dataClass(); - - $obj = singleton($dataClass); - - if(!$obj->canCreate()) { - return ""; - } - - $dbField = $this->getDataObjectField(); - - $textField = TextField::create( - sprintf( - "gridfieldaddbydbfield[%s][%s]", - $obj->ClassName, - Convert::raw2htmlatt($dbField) - ) - ) - ->setAttribute('placeholder', $obj->fieldLabel($dbField)) - ->addExtraClass('no-change-track'); - - $addAction = new GridField_FormAction( - $gridField, - 'add', - _t('GridFieldAddByDBField.Add', - 'Add {name}', "Add button text", - array( - 'name' => $obj->i18n_singular_name(), - ) - ), - 'add', - 'add' - ); - - $addAction->setAttribute('data-icon', 'add'); - - $forTemplate = new ArrayData(array()); - - $forTemplate->Fields = new ArrayList(); - $forTemplate->Fields->push($textField); - $forTemplate->Fields->push($addAction); - - return array( - $this->targetFragment => $forTemplate->renderWith('GridFieldAddByDBField') - ); - } -} +targetFragment = $targetFragment; + $this->dataObjectField = (string) $dataObjectField; + } + + /** + * Provide actions to this component. + * + * @param GridField $gridField + * + * @return array + */ + public function getActions($gridField) + { + return array( + 'add', + ); + } + + /** + * Handles the add action for the given DataObject. + * + * @param $gridField GridField + * @param $actionName string + * @param $arguments mixed + * @param $data array + * + * @return null|SS_HTTPResponse + * + * @throws UnexpectedValueException + */ + public function handleAction(GridField $gridField, $actionName, $arguments, $data) + { + if ($actionName == 'add') { + $dbField = $this->getDataObjectField(); + + $objClass = $gridField->getModelClass(); + + /** + * @var DataObject $obj + */ + $obj = new $objClass(); + + if ($obj->hasField($dbField)) { + $obj->setCastedField($dbField, $data['gridfieldaddbydbfield'][$obj->ClassName][$dbField]); + + if ($obj->canCreate()) { + $id = $gridField->getList()->add($obj); + if (!$id) { + $gridField->setError( + _t( + 'GridFieldAddByDBField.AddFail', + 'Unable to save {class} to the database.', + 'Unable to add the DataObject.', + array( + 'class' => get_class($obj), + ) + ), + 'error' + ); + } + } else { + return Security::permissionFailure( + Controller::curr(), + _t( + 'GridFieldAddByDBField.PermissionFail', + 'You don\'t have permission to create a {class}.', + 'Unable to add the DataObject.', + array( + 'class' => get_class($obj) + ) + ) + ); + } + } else { + throw new UnexpectedValueException( + sprintf( + 'Invalid field (%s) on %s.', + $dbField, + $obj->ClassName + ) + ); + } + } + + return null; + } + + /** + * Returns the database field for which we'll add the new data object. + * + * @return string + */ + public function getDataObjectField() + { + return $this->dataObjectField; + } + + /** + * Set the database field. + * + * @param $field string + */ + public function setDataObjectField($field) + { + $this->dataObjectField = (string) $field; + } + + /** + * Renders the TextField and add button to the GridField. + * + * @param $gridField GridField + * + * @return string + */ + public function getHTMLFragments($gridField) + { + /** + * @var DataList $dataList + */ + $dataList = $gridField->getList(); + + $dataClass = $dataList->dataClass(); + + $obj = singleton($dataClass); + + if (!$obj->canCreate()) { + return ""; + } + + $dbField = $this->getDataObjectField(); + + $textField = TextField::create( + sprintf( + "gridfieldaddbydbfield[%s][%s]", + $obj->ClassName, + Convert::raw2htmlatt($dbField) + ) + ) + ->setAttribute('placeholder', $obj->fieldLabel($dbField)) + ->addExtraClass('no-change-track'); + + $addAction = new GridField_FormAction( + $gridField, + 'add', + _t('GridFieldAddByDBField.Add', + 'Add {name}', "Add button text", + array( + 'name' => $obj->i18n_singular_name(), + ) + ), + 'add', + 'add' + ); + + $addAction->setAttribute('data-icon', 'add'); + + $forTemplate = new ArrayData(array()); + + $forTemplate->Fields = new ArrayList(); + $forTemplate->Fields->push($textField); + $forTemplate->Fields->push($addAction); + + return array( + $this->targetFragment => $forTemplate->renderWith('GridFieldAddByDBField') + ); + } +} diff --git a/code/forms/gridfield/GridFieldBlogPostState.php b/code/forms/gridfield/GridFieldBlogPostState.php index fb695b7..c9a4900 100644 --- a/code/forms/gridfield/GridFieldBlogPostState.php +++ b/code/forms/gridfield/GridFieldBlogPostState.php @@ -1,94 +1,97 @@ -isModifiedOnStage) { - $modifiedLabel = '' . _t('GridFieldBlogPostState.Modified') . ''; - } - - if(!$record->isPublished()) { - /** - * @var SS_Datetime $lastEdited - */ - $lastEdited = $record->dbObject('LastEdited'); - - return _t( - 'GridFieldBlogPostState.Draft', - ' Saved as Draft on {date}', - 'State for when a post is saved.', - array( - 'date' => $lastEdited->Nice(), - ) - ); - } - - /** - * @var SS_Datetime $publishDate - */ - $publishDate = $record->dbObject('PublishDate'); - - if(strtotime($record->PublishDate) > time()) { - return _t( - 'GridFieldBlogPostState.Timer', - ' Publish at {date}', - 'State for when a post is published.', - array( - 'date' => $publishDate->Nice(), - ) - ) . $modifiedLabel; - } - - return _t( - 'GridFieldBlogPostState.Published', - ' Published on {date}', - 'State for when a post is published.', - array( - 'date' => $publishDate->Nice(), - ) - ) . $modifiedLabel; - } - } - - return ''; - } - - /** - * {@inheritdoc} - */ - public function getColumnAttributes($gridField, $record, $columnName) { - if($columnName == 'State') { - if($record instanceof BlogPost) { - $published = $record->isPublished(); - - if(!$published) { - $class = 'gridfield-icon draft'; - } else if(strtotime($record->PublishDate) > time()) { - $class = 'gridfield-icon timer'; - } else { - $class = 'gridfield-icon published'; - } - - return array( - 'class' => $class, - ); - } - } - - return array(); - } -} +isModifiedOnStage) { + $modifiedLabel = '' . _t('GridFieldBlogPostState.Modified') . ''; + } + + if (!$record->isPublished()) { + /** + * @var SS_Datetime $lastEdited + */ + $lastEdited = $record->dbObject('LastEdited'); + + return _t( + 'GridFieldBlogPostState.Draft', + ' Saved as Draft on {date}', + 'State for when a post is saved.', + array( + 'date' => $lastEdited->Nice(), + ) + ); + } + + /** + * @var SS_Datetime $publishDate + */ + $publishDate = $record->dbObject('PublishDate'); + + if (strtotime($record->PublishDate) > time()) { + return _t( + 'GridFieldBlogPostState.Timer', + ' Publish at {date}', + 'State for when a post is published.', + array( + 'date' => $publishDate->Nice(), + ) + ) . $modifiedLabel; + } + + return _t( + 'GridFieldBlogPostState.Published', + ' Published on {date}', + 'State for when a post is published.', + array( + 'date' => $publishDate->Nice(), + ) + ) . $modifiedLabel; + } + } + + return ''; + } + + /** + * {@inheritdoc} + */ + public function getColumnAttributes($gridField, $record, $columnName) + { + if ($columnName == 'State') { + if ($record instanceof BlogPost) { + $published = $record->isPublished(); + + if (!$published) { + $class = 'gridfield-icon draft'; + } elseif (strtotime($record->PublishDate) > time()) { + $class = 'gridfield-icon timer'; + } else { + $class = 'gridfield-icon published'; + } + + return array( + 'class' => $class, + ); + } + } + + return array(); + } +} diff --git a/code/forms/gridfield/GridFieldConfig_BlogPost.php b/code/forms/gridfield/GridFieldConfig_BlogPost.php index 9383559..321e023 100644 --- a/code/forms/gridfield/GridFieldConfig_BlogPost.php +++ b/code/forms/gridfield/GridFieldConfig_BlogPost.php @@ -1,19 +1,21 @@ -removeComponentsByType('GridFieldSiteTreeState'); - $this->addComponent(new GridFieldBlogPostState()); - } -} +removeComponentsByType('GridFieldSiteTreeState'); + $this->addComponent(new GridFieldBlogPostState()); + } +} diff --git a/code/model/Blog.php b/code/model/Blog.php index 01eaff9..6570d17 100644 --- a/code/model/Blog.php +++ b/code/model/Blog.php @@ -1,1045 +1,1086 @@ - 'Int', - ); - - /** - * @var array - */ - private static $has_many = array( - 'Tags' => 'BlogTag', - 'Categories' => 'BlogCategory', - ); - - /** - * @var array - */ - private static $many_many = array( - 'Editors' => 'Member', - 'Writers' => 'Member', - 'Contributors' => 'Member', - ); - - /** - * @var array - */ - private static $allowed_children = array( - 'BlogPost', - ); - - /** - * @var array - */ - private static $extensions = array( - 'BlogFilter', - ); - - /** - * @var array - */ - private static $defaults = array( - 'ProvideComments' => false, - 'PostsPerPage' => 10, - ); - - /** - * @var string - */ - private static $description = 'Adds a blog to your website.'; - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - Requirements::css(BLOGGER_DIR . '/css/cms.css'); - Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); - - $self =& $this; - - $this->beforeUpdateCMSFields(function ($fields) use ($self) { - if(!$self->canEdit()) { - return; - } - - $categories = GridField::create( - 'Categories', - _t('Blog.Categories', 'Categories'), - $self->Categories(), - GridFieldCategorisationConfig::create(15, $self->Categories()->sort('Title'), 'BlogCategory', 'Categories', 'BlogPosts') - ); - - $tags = GridField::create( - 'Tags', - _t('Blog.Tags', 'Tags'), - $self->Tags(), - GridFieldCategorisationConfig::create(15, $self->Tags()->sort('Title'), 'BlogTag', 'Tags', 'BlogPosts') - ); - - /** - * @var FieldList $fields - */ - $fields->addFieldsToTab('Root.Categorisation', array( - $categories, - $tags - )); - - $fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation'); - }); - - return parent::getCMSFields(); - } - - /** - * {@inheritdoc} - */ - public function canEdit($member = null) { - $member = $this->getMember($member); - - if($this->isEditor($member)) { - return true; - } - - return parent::canEdit($member); - } - - /** - * @param null|int|Member $member - * - * @return null|Member - */ - protected function getMember($member = null) { - if(!$member) { - $member = Member::currentUser(); - } - - if(is_numeric($member)) { - $member = Member::get()->byID($member); - } - - return $member; - } - - /** - * Check if this member is an editor of the blog. - * - * @param Member $member - * - * @return bool - */ - public function isEditor($member) { - $isEditor = $this->isMemberOf($member, $this->Editors()); - $this->extend('updateIsEditor', $isEditor, $member); - - return $isEditor; - } - - /** - * Determine if the given member belongs to the given relation. - * - * @param Member $member - * @param DataList $relation - * - * @return bool - */ - protected function isMemberOf($member, $relation) { - if(!$member || !$member->exists()) { - return false; - } - - if($relation instanceof UnsavedRelationList) { - return in_array($member->ID, $relation->getIDList()); - } - - return $relation->byID($member->ID) !== null; - } - - /** - * Determine the role of the given member. - * - * Call be called via template to determine the current user. - * - * @example "Hello $RoleOf($CurrentMember.ID)" - * - * @param int|Member $member - * - * @return null|string - */ - public function RoleOf($member) { - if(is_numeric($member)) { - $member = DataObject::get_by_id('Member', $member); - } - - if(!$member) { - return null; - } - - if($this->isEditor($member)) { - return _t('Blog.EDITOR', 'Editor'); - } - - if($this->isWriter($member)) { - return _t('Blog.WRITER', 'Writer'); - } - - if($this->isContributor($member)) { - return _t('Blog.CONTRIBUTOR', 'Contributor'); - } - - return null; - } - - /** - * Check if this member is a writer of the blog. - * - * @param Member $member - * - * @return bool - */ - 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 bool - */ - public function isContributor($member) { - $isContributor = $this->isMemberOf($member, $this->Contributors()); - $this->extend('updateIsContributor', $isContributor, $member); - - return $isContributor; - } - - /** - * {@inheritdoc} - */ - public function canAddChildren($member = null) { - $member = $this->getMember($member); - - if($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) { - return true; - } - - return parent::canAddChildren($member); - } - - /** - * {@inheritdoc} - */ - public function getSettingsFields() { - $fields = parent::getSettingsFields(); - - $fields->addFieldToTab('Root.Settings', - NumericField::create('PostsPerPage', _t('Blog.PostsPerPage', 'Posts Per Page')) - ); - - $members = $this->getCandidateUsers()->map()->toArray(); - - $editorField = ListboxField::create('Editors', 'Editors', $members) - ->setMultiple(true) - ->setRightTitle('help') - ->setDescription(' - An editor has control over specific Blogs, and all posts included within it. Short of being able to assign other editors to a blog, they are able to handle most changes to their assigned blog.
-
- 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 - '); - - if(!$this->canEditEditors()) { - $editorField = $editorField->performDisabledTransformation(); - } - - $writerField = ListboxField::create('Writers', 'Writers', $members) - ->setMultiple(true) - ->setRightTitle('help') - ->setDescription(' - A writer has full control over creating, editing and publishing BlogPosts they have authored or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.
-
- Writers have these permissions:
-
- Update or publish any BlogPost they have authored or have been assigned to
- Assign/unassign any member as an author of a particular BlogPost they have authored or have been assigned to - '); - - if(!$this->canEditWriters()) { - $writerField = $writerField->performDisabledTransformation(); - } - - $contributorField = ListboxField::create('Contributors', 'Contributors', $members) - ->setMultiple(true) - ->setRightTitle('help') - ->setDescription(' - 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 any BlogPost they have authored or have been assigned to - '); - - if(!$this->canEditContributors()) { - $contributorField = $contributorField->performDisabledTransformation(); - } - - $fields->addFieldsToTab('Root.Users', array( - $editorField, - $writerField, - $contributorField - )); - - return $fields; - } - - /** - * 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) { - $list = Member::get(); - $this->extend('updateCandidateUsers', $list); - return $list; - } else { - return Permission::get_members_by_permission( - $this->config()->grant_user_permission - ); - } - } - - /** - * Determine if this user can edit the editors list. - * - * @param int|Member $member - * - * @return bool - */ - public function canEditEditors($member = null) { - $member = $this->getMember($member); - - $extended = $this->extendedCan('canEditEditors', $member); - - if($extended !== null) { - return $extended; - } - - return Permission::checkMember($member, self::MANAGE_USERS); - } - - /** - * Determine if this user can edit writers list. - * - * @param int|Member $member - * - * @return boolean - */ - public function canEditWriters($member = null) { - $member = $this->getMember($member); - - $extended = $this->extendedCan('canEditWriters', $member); - - if($extended !== null) { - return $extended; - } - - if($this->isEditor($member)) { - return true; - } - - return Permission::checkMember($member, self::MANAGE_USERS); - } - - /** - * Determines if this user can edit the contributors list. - * - * @param int|Member $member - * - * @return boolean - */ - public function canEditContributors($member = null) { - $member = $this->getMember($member); - - $extended = $this->extendedCan('canEditContributors', $member); - - if($extended !== null) { - return $extended; - } - - if($this->isEditor($member)) { - return true; - } - - return Permission::checkMember($member, self::MANAGE_USERS); - } - - /** - * Returns BlogPosts for a given date period. - * - * @param int $year - * @param null|int $month - * @param null|int $day - * - * @return DataList - */ - public function getArchivedBlogPosts($year, $month = null, $day = null) { - $query = $this->getBlogPosts()->dataQuery(); - - $stage = $query->getQueryParam('Versioned.stage'); - - if($stage) { - $stage = '_' . $stage; - } - - $query->innerJoin('BlogPost', sprintf('"SiteTree%s"."ID" = "BlogPost%s"."ID"', $stage, $stage)); - - $query->where(sprintf('YEAR("PublishDate") = \'%s\'', Convert::raw2sql($year))); - - if($month) { - $query->where(sprintf('MONTH("PublishDate") = \'%s\'', Convert::raw2sql($month))); - - if($day) { - $query->where(sprintf('DAY("PublishDate") = \'%s\'', Convert::raw2sql($day))); - } - } - - return $this->getBlogPosts()->setDataQuery($query); - } - - /** - * Return blog posts. - * - * @return DataList of BlogPost objects - */ - public function getBlogPosts() { - $blogPosts = BlogPost::get()->filter('ParentID', $this->ID); - - $this->extend('updateGetBlogPosts', $blogPosts); - - return $blogPosts; - } - - /** - * Get a link to a Member profile. - * - * @param string $urlSegment - * - * @return string - */ - public function ProfileLink($urlSegment) { - return Controller::join_links($this->Link(), 'profile', $urlSegment); - } - - /** - * This sets the title for our gridfield. - * - * @return string - */ - public function getLumberjackTitle() { - return _t('Blog.LumberjackTitle', 'Blog Posts'); - } - - /** - * This overwrites lumberjacks default gridfield config. - * - * @return GridFieldConfig - */ - public function getLumberjackGridFieldConfig() { - return GridFieldConfig_BlogPost::create(); - } - - /** - * {@inheritdoc} - */ - 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 - ) - ); - } - - /** - * {@inheritdoc} - */ - protected function onBeforeWrite() { - parent::onBeforeWrite(); - $this->assignGroup(); - } - - /** - * Assign users as necessary to the blog group. - */ - protected function assignGroup() { - if(!$this->config()->grant_user_access) { - return; - } - - $group = $this->getUserGroup(); - - // Must check if the method exists or else an error occurs when changing page type - if ($this->hasMethod('Editors')) { - foreach(array($this->Editors(), $this->Writers(), $this->Contributors()) as $levels) { - foreach($levels as $user) { - if(!$user->inGroup($group)) { - $user->Groups()->add($group); - } - } - } - } - } - - /** - * 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; - } - - $group = new Group(); - $group->Title = 'Blog users'; - $group->Code = $code; - - $group->write(); - - $permission = new Permission(); - $permission->Code = $this->config()->grant_user_permission; - - $group->Permissions()->add($permission); - - return $group; - } -} - -/** - * @package silverstripe - * @subpackage blog - */ -class Blog_Controller extends Page_Controller { - /** - * @var array - */ - private static $allowed_actions = array( - 'archive', - 'tag', - 'category', - 'rss', - 'profile', - ); - - /** - * @var array - */ - private static $url_handlers = array( - 'tag/$Tag!' => 'tag', - 'category/$Category!' => 'category', - 'archive/$Year!/$Month/$Day' => 'archive', - 'profile/$URLSegment!' => 'profile', - ); - - /** - * @var array - */ - private static $casting = array( - 'MetaTitle' => 'Text', - 'FilterDescription' => 'Text', - ); - - /** - * The current Blog Post DataList query. - * - * @var DataList - */ - protected $blogPosts; - - /** - * @return string - */ - public function index() { - /** - * @var Blog $dataRecord - */ - $dataRecord = $this->dataRecord; - - $this->blogPosts = $dataRecord->getBlogPosts(); - - return $this->render(); - } - - /** - * Renders a Blog Member's profile. - * - * @return SS_HTTPResponse - */ - public function profile() { - $profile = $this->getCurrentProfile(); - - if(!$profile) { - return $this->httpError(404, 'Not Found'); - } - - $this->blogPosts = $this->getCurrentProfilePosts(); - - return $this->render(); - } - - /** - * Get the Member associated with the current URL segment. - * - * @return null|Member - */ - public function getCurrentProfile() { - $urlSegment = $this->request->param('URLSegment'); - - if($urlSegment) { - return Member::get() - ->filter('URLSegment', $urlSegment) - ->first(); - } - - return null; - } - - /** - * Get posts related to the current Member profile. - * - * @return null|DataList - */ - public function getCurrentProfilePosts() { - $profile = $this->getCurrentProfile(); - - if($profile) { - return $profile->BlogPosts()->filter('ParentID', $this->ID); - } - - return null; - } - - /** - * Renders an archive for a specified date. This can be by year or year/month. - * - * @return null|SS_HTTPResponse - */ - public function archive() { - /** - * @var Blog $dataRecord - */ - $dataRecord = $this->dataRecord; - - $year = $this->getArchiveYear(); - $month = $this->getArchiveMonth(); - $day = $this->getArchiveDay(); - - if($this->request->param('Month') && !$month) { - $this->httpError(404, 'Not Found'); - } - - if($month && $this->request->param('Day') && !$day) { - $this->httpError(404, 'Not Found'); - } - - if($year) { - $this->blogPosts = $dataRecord->getArchivedBlogPosts($year, $month, $day); - - return $this->render(); - } - - $this->httpError(404, 'Not Found'); - - return null; - } - - /** - * Fetches the archive year from the url. - * - * @return int - */ - public function getArchiveYear() { - - if($this->request->param('Year')){ - - if(preg_match('/^[0-9]{4}$/', $year = $this->request->param('Year'))) { - return (int) $year; - } - } elseif($this->request->param('Action') == 'archive') { - return SS_Datetime::now()->Year(); - } - - return null; - } - - /** - * Fetches the archive money from the url. - * - * @return null|int - */ - public function getArchiveMonth() { - $month = $this->request->param('Month'); - - if(preg_match('/^[0-9]{1,2}$/', $month)) { - if($month > 0 && $month < 13) { - if(checkdate($month, 01, $this->getArchiveYear())) { - return (int) $month; - } - } - } - - return null; - } - - /** - * Fetches the archive day from the url. - * - * @return null|int - */ - public function getArchiveDay() { - $day = $this->request->param('Day'); - - if(preg_match('/^[0-9]{1,2}$/', $day)) { - if(checkdate($this->getArchiveMonth(), $day, $this->getArchiveYear())) { - return (int) $day; - } - } - - return null; - } - - /** - * Renders the blog posts for a given tag. - * - * @return null|SS_HTTPResponse - */ - public function tag() { - $tag = $this->getCurrentTag(); - - if($tag) { - $this->blogPosts = $tag->BlogPosts(); - return $this->render(); - } - - $this->httpError(404, 'Not Found'); - - return null; - } - - /** - * Tag Getter for use in templates. - * - * @return null|BlogTag - */ - public function getCurrentTag() { - /** - * @var Blog $dataRecord - */ - $dataRecord = $this->dataRecord; - $tag = $this->request->param('Tag'); - if($tag) { - return $dataRecord->Tags() - ->filter('URLSegment', array($tag, rawurlencode($tag))) - ->first(); - } - return null; - } - - /** - * Renders the blog posts for a given category. - * - * @return null|SS_HTTPResponse - */ - public function category() { - $category = $this->getCurrentCategory(); - - if($category) { - $this->blogPosts = $category->BlogPosts(); - - return $this->render(); - } - - $this->httpError(404, 'Not Found'); - - return null; - } - - /** - * Category Getter for use in templates. - * - * @return null|BlogCategory - */ - public function getCurrentCategory() { - /** - * @var Blog $dataRecord - */ - $dataRecord = $this->dataRecord; - $category = $this->request->param('Category'); - if($category) { - return $dataRecord->Categories() - ->filter('URLSegment', array($category, rawurlencode($category))) - ->first(); - } - return null; - } - - /** - * Get the meta title for the current action. - * - * @return string - */ - public function getMetaTitle() { - $title = $this->data()->getTitle(); - $filter = $this->getFilterDescription(); - - if($filter) { - $title = sprintf('%s - %s', $title, $filter); - } - - $this->extend('updateMetaTitle', $title); - - return $title; - } - - /** - * Returns a description of the current filter. - * - * @return string - */ - public function getFilterDescription() { - $items = array(); - - $list = $this->PaginatedList(); - $currentPage = $list->CurrentPage(); - - if($currentPage > 1) { - $items[] = _t( - 'Blog.FILTERDESCRIPTION_PAGE', - 'Page {page}', - null, - array( - 'page' => $currentPage, - ) - ); - } - - if($author = $this->getCurrentProfile()) { - $items[] = _t( - 'Blog.FILTERDESCRIPTION_AUTHOR', - 'By {author}', - null, - array( - 'author' => $author->Title, - ) - ); - } - - if($tag = $this->getCurrentTag()) { - $items[] = _t( - 'Blog.FILTERDESCRIPTION_TAG', - 'Tagged with {tag}', - null, - array( - 'tag' => $tag->Title, - ) - ); - } - - if($category = $this->getCurrentCategory()) { - $items[] = _t( - 'Blog.FILTERDESCRIPTION_CATEGORY', - 'In category {category}', - null, - array( - 'category' => $category->Title, - ) - ); - } - - if($this->owner->getArchiveYear()) { - if($this->owner->getArchiveDay()) { - $date = $this->owner->getArchiveDate()->Nice(); - } elseif($this->owner->getArchiveMonth()) { - $date = $this->owner->getArchiveDate()->format('F, Y'); - } else { - $date = $this->owner->getArchiveDate()->format('Y'); - } - - $items[] = _t( - 'Blog.FILTERDESCRIPTION_DATE', - 'In {date}', - null, - array( - 'date' => $date, - ) - ); - } - - $result = ''; - - if($items) { - $result = implode(', ', $items); - } - - $this->extend('updateFilterDescription', $result); - - return $result; - } - - /** - * Returns a list of paginated blog posts based on the BlogPost dataList. - * - * @return PaginatedList - */ - public function PaginatedList() { - $allPosts = $this->blogPosts ?: new ArrayList(); - - $posts = new PaginatedList($allPosts); - - // Set appropriate page size - if($this->PostsPerPage > 0) { - $pageSize = $this->PostsPerPage; - } elseif($count = $allPosts->count()) { - $pageSize = $count; - } else { - $pageSize = 99999; - } - $posts->setPageLength($pageSize); - - // Set current page - $start = $this->request->getVar($posts->getPaginationGetVar()); - $posts->setPageStart($start); - - return $posts; - } - - /** - * Displays an RSS feed of blog posts. - * - * @return string - */ - public function rss() { - /** - * @var Blog $dataRecord - */ - $dataRecord = $this->dataRecord; - - $this->blogPosts = $dataRecord->getBlogPosts(); - - $rss = new RSSFeed($this->blogPosts, $this->Link(), $this->MetaTitle, $this->MetaDescription); - - $this->extend('updateRss', $rss); - - return $rss->outputToBrowser(); - } - - /** - * Returns the current archive date. - * - * @return null|Date - */ - public function getArchiveDate() { - $year = $this->getArchiveYear(); - $month = $this->getArchiveMonth(); - $day = $this->getArchiveDay(); - - if($year) { - if($month) { - $date = sprintf('%s-%s-01', $year, $month); - - if($day) { - $date = sprintf('%s-%s-%s', $year, $month, $day); - } - } else { - $date = sprintf('%s-01-01', $year); - } - - return DBField::create_field('Date', $date); - } - - return null; - } - - /** - * Returns a link to the RSS feed. - * - * @return string - */ - public function getRSSLink() { - return $this->Link('rss'); - } -} + 'Int', + ); + + /** + * @var array + */ + private static $has_many = array( + 'Tags' => 'BlogTag', + 'Categories' => 'BlogCategory', + ); + + /** + * @var array + */ + private static $many_many = array( + 'Editors' => 'Member', + 'Writers' => 'Member', + 'Contributors' => 'Member', + ); + + /** + * @var array + */ + private static $allowed_children = array( + 'BlogPost', + ); + + /** + * @var array + */ + private static $extensions = array( + 'BlogFilter', + ); + + /** + * @var array + */ + private static $defaults = array( + 'ProvideComments' => false, + 'PostsPerPage' => 10, + ); + + /** + * @var string + */ + private static $description = 'Adds a blog to your website.'; + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + Requirements::css(BLOGGER_DIR . '/css/cms.css'); + Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); + + $self =& $this; + + $this->beforeUpdateCMSFields(function ($fields) use ($self) { + if (!$self->canEdit()) { + return; + } + + $categories = GridField::create( + 'Categories', + _t('Blog.Categories', 'Categories'), + $self->Categories(), + GridFieldCategorisationConfig::create(15, $self->Categories()->sort('Title'), 'BlogCategory', 'Categories', 'BlogPosts') + ); + + $tags = GridField::create( + 'Tags', + _t('Blog.Tags', 'Tags'), + $self->Tags(), + GridFieldCategorisationConfig::create(15, $self->Tags()->sort('Title'), 'BlogTag', 'Tags', 'BlogPosts') + ); + + /** + * @var FieldList $fields + */ + $fields->addFieldsToTab('Root.Categorisation', array( + $categories, + $tags + )); + + $fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation'); + }); + + return parent::getCMSFields(); + } + + /** + * {@inheritdoc} + */ + public function canEdit($member = null) + { + $member = $this->getMember($member); + + if ($this->isEditor($member)) { + return true; + } + + return parent::canEdit($member); + } + + /** + * @param null|int|Member $member + * + * @return null|Member + */ + protected function getMember($member = null) + { + if (!$member) { + $member = Member::currentUser(); + } + + if (is_numeric($member)) { + $member = Member::get()->byID($member); + } + + return $member; + } + + /** + * Check if this member is an editor of the blog. + * + * @param Member $member + * + * @return bool + */ + public function isEditor($member) + { + $isEditor = $this->isMemberOf($member, $this->Editors()); + $this->extend('updateIsEditor', $isEditor, $member); + + return $isEditor; + } + + /** + * Determine if the given member belongs to the given relation. + * + * @param Member $member + * @param DataList $relation + * + * @return bool + */ + protected function isMemberOf($member, $relation) + { + if (!$member || !$member->exists()) { + return false; + } + + if ($relation instanceof UnsavedRelationList) { + return in_array($member->ID, $relation->getIDList()); + } + + return $relation->byID($member->ID) !== null; + } + + /** + * Determine the role of the given member. + * + * Call be called via template to determine the current user. + * + * @example "Hello $RoleOf($CurrentMember.ID)" + * + * @param int|Member $member + * + * @return null|string + */ + public function RoleOf($member) + { + if (is_numeric($member)) { + $member = DataObject::get_by_id('Member', $member); + } + + if (!$member) { + return null; + } + + if ($this->isEditor($member)) { + return _t('Blog.EDITOR', 'Editor'); + } + + if ($this->isWriter($member)) { + return _t('Blog.WRITER', 'Writer'); + } + + if ($this->isContributor($member)) { + return _t('Blog.CONTRIBUTOR', 'Contributor'); + } + + return null; + } + + /** + * Check if this member is a writer of the blog. + * + * @param Member $member + * + * @return bool + */ + 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 bool + */ + public function isContributor($member) + { + $isContributor = $this->isMemberOf($member, $this->Contributors()); + $this->extend('updateIsContributor', $isContributor, $member); + + return $isContributor; + } + + /** + * {@inheritdoc} + */ + public function canAddChildren($member = null) + { + $member = $this->getMember($member); + + if ($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) { + return true; + } + + return parent::canAddChildren($member); + } + + /** + * {@inheritdoc} + */ + public function getSettingsFields() + { + $fields = parent::getSettingsFields(); + + $fields->addFieldToTab('Root.Settings', + NumericField::create('PostsPerPage', _t('Blog.PostsPerPage', 'Posts Per Page')) + ); + + $members = $this->getCandidateUsers()->map()->toArray(); + + $editorField = ListboxField::create('Editors', 'Editors', $members) + ->setMultiple(true) + ->setRightTitle('help') + ->setDescription(' + An editor has control over specific Blogs, and all posts included within it. Short of being able to assign other editors to a blog, they are able to handle most changes to their assigned blog.
+
+ 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 + '); + + if (!$this->canEditEditors()) { + $editorField = $editorField->performDisabledTransformation(); + } + + $writerField = ListboxField::create('Writers', 'Writers', $members) + ->setMultiple(true) + ->setRightTitle('help') + ->setDescription(' + A writer has full control over creating, editing and publishing BlogPosts they have authored or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.
+
+ Writers have these permissions:
+
+ Update or publish any BlogPost they have authored or have been assigned to
+ Assign/unassign any member as an author of a particular BlogPost they have authored or have been assigned to + '); + + if (!$this->canEditWriters()) { + $writerField = $writerField->performDisabledTransformation(); + } + + $contributorField = ListboxField::create('Contributors', 'Contributors', $members) + ->setMultiple(true) + ->setRightTitle('help') + ->setDescription(' + 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 any BlogPost they have authored or have been assigned to + '); + + if (!$this->canEditContributors()) { + $contributorField = $contributorField->performDisabledTransformation(); + } + + $fields->addFieldsToTab('Root.Users', array( + $editorField, + $writerField, + $contributorField + )); + + return $fields; + } + + /** + * 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) { + $list = Member::get(); + $this->extend('updateCandidateUsers', $list); + return $list; + } else { + return Permission::get_members_by_permission( + $this->config()->grant_user_permission + ); + } + } + + /** + * Determine if this user can edit the editors list. + * + * @param int|Member $member + * + * @return bool + */ + public function canEditEditors($member = null) + { + $member = $this->getMember($member); + + $extended = $this->extendedCan('canEditEditors', $member); + + if ($extended !== null) { + return $extended; + } + + return Permission::checkMember($member, self::MANAGE_USERS); + } + + /** + * Determine if this user can edit writers list. + * + * @param int|Member $member + * + * @return boolean + */ + public function canEditWriters($member = null) + { + $member = $this->getMember($member); + + $extended = $this->extendedCan('canEditWriters', $member); + + if ($extended !== null) { + return $extended; + } + + if ($this->isEditor($member)) { + return true; + } + + return Permission::checkMember($member, self::MANAGE_USERS); + } + + /** + * Determines if this user can edit the contributors list. + * + * @param int|Member $member + * + * @return boolean + */ + public function canEditContributors($member = null) + { + $member = $this->getMember($member); + + $extended = $this->extendedCan('canEditContributors', $member); + + if ($extended !== null) { + return $extended; + } + + if ($this->isEditor($member)) { + return true; + } + + return Permission::checkMember($member, self::MANAGE_USERS); + } + + /** + * Returns BlogPosts for a given date period. + * + * @param int $year + * @param null|int $month + * @param null|int $day + * + * @return DataList + */ + public function getArchivedBlogPosts($year, $month = null, $day = null) + { + $query = $this->getBlogPosts()->dataQuery(); + + $stage = $query->getQueryParam('Versioned.stage'); + + if ($stage) { + $stage = '_' . $stage; + } + + $query->innerJoin('BlogPost', sprintf('"SiteTree%s"."ID" = "BlogPost%s"."ID"', $stage, $stage)); + + $query->where(sprintf('YEAR("PublishDate") = \'%s\'', Convert::raw2sql($year))); + + if ($month) { + $query->where(sprintf('MONTH("PublishDate") = \'%s\'', Convert::raw2sql($month))); + + if ($day) { + $query->where(sprintf('DAY("PublishDate") = \'%s\'', Convert::raw2sql($day))); + } + } + + return $this->getBlogPosts()->setDataQuery($query); + } + + /** + * Return blog posts. + * + * @return DataList of BlogPost objects + */ + public function getBlogPosts() + { + $blogPosts = BlogPost::get()->filter('ParentID', $this->ID); + + $this->extend('updateGetBlogPosts', $blogPosts); + + return $blogPosts; + } + + /** + * Get a link to a Member profile. + * + * @param string $urlSegment + * + * @return string + */ + public function ProfileLink($urlSegment) + { + return Controller::join_links($this->Link(), 'profile', $urlSegment); + } + + /** + * This sets the title for our gridfield. + * + * @return string + */ + public function getLumberjackTitle() + { + return _t('Blog.LumberjackTitle', 'Blog Posts'); + } + + /** + * This overwrites lumberjacks default gridfield config. + * + * @return GridFieldConfig + */ + public function getLumberjackGridFieldConfig() + { + return GridFieldConfig_BlogPost::create(); + } + + /** + * {@inheritdoc} + */ + 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 + ) + ); + } + + /** + * {@inheritdoc} + */ + protected function onBeforeWrite() + { + parent::onBeforeWrite(); + $this->assignGroup(); + } + + /** + * Assign users as necessary to the blog group. + */ + protected function assignGroup() + { + if (!$this->config()->grant_user_access) { + return; + } + + $group = $this->getUserGroup(); + + // Must check if the method exists or else an error occurs when changing page type + if ($this->hasMethod('Editors')) { + foreach (array($this->Editors(), $this->Writers(), $this->Contributors()) as $levels) { + foreach ($levels as $user) { + if (!$user->inGroup($group)) { + $user->Groups()->add($group); + } + } + } + } + } + + /** + * 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; + } + + $group = new Group(); + $group->Title = 'Blog users'; + $group->Code = $code; + + $group->write(); + + $permission = new Permission(); + $permission->Code = $this->config()->grant_user_permission; + + $group->Permissions()->add($permission); + + return $group; + } +} + +/** + * @package silverstripe + * @subpackage blog + */ +class Blog_Controller extends Page_Controller +{ + /** + * @var array + */ + private static $allowed_actions = array( + 'archive', + 'tag', + 'category', + 'rss', + 'profile', + ); + + /** + * @var array + */ + private static $url_handlers = array( + 'tag/$Tag!' => 'tag', + 'category/$Category!' => 'category', + 'archive/$Year!/$Month/$Day' => 'archive', + 'profile/$URLSegment!' => 'profile', + ); + + /** + * @var array + */ + private static $casting = array( + 'MetaTitle' => 'Text', + 'FilterDescription' => 'Text', + ); + + /** + * The current Blog Post DataList query. + * + * @var DataList + */ + protected $blogPosts; + + /** + * @return string + */ + public function index() + { + /** + * @var Blog $dataRecord + */ + $dataRecord = $this->dataRecord; + + $this->blogPosts = $dataRecord->getBlogPosts(); + + return $this->render(); + } + + /** + * Renders a Blog Member's profile. + * + * @return SS_HTTPResponse + */ + public function profile() + { + $profile = $this->getCurrentProfile(); + + if (!$profile) { + return $this->httpError(404, 'Not Found'); + } + + $this->blogPosts = $this->getCurrentProfilePosts(); + + return $this->render(); + } + + /** + * Get the Member associated with the current URL segment. + * + * @return null|Member + */ + public function getCurrentProfile() + { + $urlSegment = $this->request->param('URLSegment'); + + if ($urlSegment) { + return Member::get() + ->filter('URLSegment', $urlSegment) + ->first(); + } + + return null; + } + + /** + * Get posts related to the current Member profile. + * + * @return null|DataList + */ + public function getCurrentProfilePosts() + { + $profile = $this->getCurrentProfile(); + + if ($profile) { + return $profile->BlogPosts()->filter('ParentID', $this->ID); + } + + return null; + } + + /** + * Renders an archive for a specified date. This can be by year or year/month. + * + * @return null|SS_HTTPResponse + */ + public function archive() + { + /** + * @var Blog $dataRecord + */ + $dataRecord = $this->dataRecord; + + $year = $this->getArchiveYear(); + $month = $this->getArchiveMonth(); + $day = $this->getArchiveDay(); + + if ($this->request->param('Month') && !$month) { + $this->httpError(404, 'Not Found'); + } + + if ($month && $this->request->param('Day') && !$day) { + $this->httpError(404, 'Not Found'); + } + + if ($year) { + $this->blogPosts = $dataRecord->getArchivedBlogPosts($year, $month, $day); + + return $this->render(); + } + + $this->httpError(404, 'Not Found'); + + return null; + } + + /** + * Fetches the archive year from the url. + * + * @return int + */ + public function getArchiveYear() + { + if ($this->request->param('Year')) { + if (preg_match('/^[0-9]{4}$/', $year = $this->request->param('Year'))) { + return (int) $year; + } + } elseif ($this->request->param('Action') == 'archive') { + return SS_Datetime::now()->Year(); + } + + return null; + } + + /** + * Fetches the archive money from the url. + * + * @return null|int + */ + public function getArchiveMonth() + { + $month = $this->request->param('Month'); + + if (preg_match('/^[0-9]{1,2}$/', $month)) { + if ($month > 0 && $month < 13) { + if (checkdate($month, 01, $this->getArchiveYear())) { + return (int) $month; + } + } + } + + return null; + } + + /** + * Fetches the archive day from the url. + * + * @return null|int + */ + public function getArchiveDay() + { + $day = $this->request->param('Day'); + + if (preg_match('/^[0-9]{1,2}$/', $day)) { + if (checkdate($this->getArchiveMonth(), $day, $this->getArchiveYear())) { + return (int) $day; + } + } + + return null; + } + + /** + * Renders the blog posts for a given tag. + * + * @return null|SS_HTTPResponse + */ + public function tag() + { + $tag = $this->getCurrentTag(); + + if ($tag) { + $this->blogPosts = $tag->BlogPosts(); + return $this->render(); + } + + $this->httpError(404, 'Not Found'); + + return null; + } + + /** + * Tag Getter for use in templates. + * + * @return null|BlogTag + */ + public function getCurrentTag() + { + /** + * @var Blog $dataRecord + */ + $dataRecord = $this->dataRecord; + $tag = $this->request->param('Tag'); + if ($tag) { + return $dataRecord->Tags() + ->filter('URLSegment', array($tag, rawurlencode($tag))) + ->first(); + } + return null; + } + + /** + * Renders the blog posts for a given category. + * + * @return null|SS_HTTPResponse + */ + public function category() + { + $category = $this->getCurrentCategory(); + + if ($category) { + $this->blogPosts = $category->BlogPosts(); + + return $this->render(); + } + + $this->httpError(404, 'Not Found'); + + return null; + } + + /** + * Category Getter for use in templates. + * + * @return null|BlogCategory + */ + public function getCurrentCategory() + { + /** + * @var Blog $dataRecord + */ + $dataRecord = $this->dataRecord; + $category = $this->request->param('Category'); + if ($category) { + return $dataRecord->Categories() + ->filter('URLSegment', array($category, rawurlencode($category))) + ->first(); + } + return null; + } + + /** + * Get the meta title for the current action. + * + * @return string + */ + public function getMetaTitle() + { + $title = $this->data()->getTitle(); + $filter = $this->getFilterDescription(); + + if ($filter) { + $title = sprintf('%s - %s', $title, $filter); + } + + $this->extend('updateMetaTitle', $title); + + return $title; + } + + /** + * Returns a description of the current filter. + * + * @return string + */ + public function getFilterDescription() + { + $items = array(); + + $list = $this->PaginatedList(); + $currentPage = $list->CurrentPage(); + + if ($currentPage > 1) { + $items[] = _t( + 'Blog.FILTERDESCRIPTION_PAGE', + 'Page {page}', + null, + array( + 'page' => $currentPage, + ) + ); + } + + if ($author = $this->getCurrentProfile()) { + $items[] = _t( + 'Blog.FILTERDESCRIPTION_AUTHOR', + 'By {author}', + null, + array( + 'author' => $author->Title, + ) + ); + } + + if ($tag = $this->getCurrentTag()) { + $items[] = _t( + 'Blog.FILTERDESCRIPTION_TAG', + 'Tagged with {tag}', + null, + array( + 'tag' => $tag->Title, + ) + ); + } + + if ($category = $this->getCurrentCategory()) { + $items[] = _t( + 'Blog.FILTERDESCRIPTION_CATEGORY', + 'In category {category}', + null, + array( + 'category' => $category->Title, + ) + ); + } + + if ($this->owner->getArchiveYear()) { + if ($this->owner->getArchiveDay()) { + $date = $this->owner->getArchiveDate()->Nice(); + } elseif ($this->owner->getArchiveMonth()) { + $date = $this->owner->getArchiveDate()->format('F, Y'); + } else { + $date = $this->owner->getArchiveDate()->format('Y'); + } + + $items[] = _t( + 'Blog.FILTERDESCRIPTION_DATE', + 'In {date}', + null, + array( + 'date' => $date, + ) + ); + } + + $result = ''; + + if ($items) { + $result = implode(', ', $items); + } + + $this->extend('updateFilterDescription', $result); + + return $result; + } + + /** + * Returns a list of paginated blog posts based on the BlogPost dataList. + * + * @return PaginatedList + */ + public function PaginatedList() + { + $allPosts = $this->blogPosts ?: new ArrayList(); + + $posts = new PaginatedList($allPosts); + + // Set appropriate page size + if ($this->PostsPerPage > 0) { + $pageSize = $this->PostsPerPage; + } elseif ($count = $allPosts->count()) { + $pageSize = $count; + } else { + $pageSize = 99999; + } + $posts->setPageLength($pageSize); + + // Set current page + $start = $this->request->getVar($posts->getPaginationGetVar()); + $posts->setPageStart($start); + + return $posts; + } + + /** + * Displays an RSS feed of blog posts. + * + * @return string + */ + public function rss() + { + /** + * @var Blog $dataRecord + */ + $dataRecord = $this->dataRecord; + + $this->blogPosts = $dataRecord->getBlogPosts(); + + $rss = new RSSFeed($this->blogPosts, $this->Link(), $this->MetaTitle, $this->MetaDescription); + + $this->extend('updateRss', $rss); + + return $rss->outputToBrowser(); + } + + /** + * Returns the current archive date. + * + * @return null|Date + */ + public function getArchiveDate() + { + $year = $this->getArchiveYear(); + $month = $this->getArchiveMonth(); + $day = $this->getArchiveDay(); + + if ($year) { + if ($month) { + $date = sprintf('%s-%s-01', $year, $month); + + if ($day) { + $date = sprintf('%s-%s-%s', $year, $month, $day); + } + } else { + $date = sprintf('%s-01-01', $year); + } + + return DBField::create_field('Date', $date); + } + + return null; + } + + /** + * Returns a link to the RSS feed. + * + * @return string + */ + public function getRSSLink() + { + return $this->Link('rss'); + } +} diff --git a/code/model/BlogCategory.php b/code/model/BlogCategory.php index d8a1fe4..3dce22f 100644 --- a/code/model/BlogCategory.php +++ b/code/model/BlogCategory.php @@ -1,145 +1,153 @@ - 'Varchar(255)', - ); - - /** - * @var array - */ - private static $has_one = array( - 'Blog' => 'Blog', - ); - - /** - * @var array - */ - private static $belongs_many_many = array( - 'BlogPosts' => 'BlogPost', - ); - - /** - * @var array - */ - private static $extensions = array( - 'URLSegmentExtension', - ); - - /** - * @return DataList - */ - public function BlogPosts() { - $blogPosts = parent::BlogPosts(); - - $this->extend("updateGetBlogPosts", $blogPosts); - - return $blogPosts; - } - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - $fields = new FieldList( - TextField::create('Title', _t('BlogCategory.Title', 'Title')) - ); - - $this->extend('updateCMSFields', $fields); - - return $fields; - } - - /** - * Returns a relative link to this category. - * - * @return string - */ - public function getLink() { - return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment); - } - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canView($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); - - if($extended !== null) { - return $extended; - } - - return $this->Blog()->canView($member); - } - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canCreate($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); - - if($extended !== null) { - return $extended; - } - - $permission = Blog::config()->grant_user_permission; - - return Permission::checkMember($member, $permission); - } - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canDelete($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); - - if($extended !== null) { - return $extended; - } - - return $this->Blog()->canEdit($member); - } - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canEdit($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); - - if($extended !== null) { - return $extended; - } - - return $this->Blog()->canEdit($member); - } -} + 'Varchar(255)', + ); + + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); + + /** + * @var array + */ + private static $belongs_many_many = array( + 'BlogPosts' => 'BlogPost', + ); + + /** + * @var array + */ + private static $extensions = array( + 'URLSegmentExtension', + ); + + /** + * @return DataList + */ + public function BlogPosts() + { + $blogPosts = parent::BlogPosts(); + + $this->extend("updateGetBlogPosts", $blogPosts); + + return $blogPosts; + } + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + $fields = new FieldList( + TextField::create('Title', _t('BlogCategory.Title', 'Title')) + ); + + $this->extend('updateCMSFields', $fields); + + return $fields; + } + + /** + * Returns a relative link to this category. + * + * @return string + */ + public function getLink() + { + return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment); + } + + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canView($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); + + if ($extended !== null) { + return $extended; + } + + return $this->Blog()->canView($member); + } + + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canCreate($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); + + if ($extended !== null) { + return $extended; + } + + $permission = Blog::config()->grant_user_permission; + + return Permission::checkMember($member, $permission); + } + + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canDelete($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); + + if ($extended !== null) { + return $extended; + } + + return $this->Blog()->canEdit($member); + } + + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canEdit($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); + + if ($extended !== null) { + return $extended; + } + + return $this->Blog()->canEdit($member); + } +} diff --git a/code/model/BlogPost.php b/code/model/BlogPost.php index 6427f89..7e98f2f 100644 --- a/code/model/BlogPost.php +++ b/code/model/BlogPost.php @@ -1,686 +1,707 @@ - 'SS_Datetime', - 'AuthorNames' => 'Varchar(1024)', - 'Summary' => 'HTMLText', - ); - - /** - * @var array - */ - private static $has_one = array( - 'FeaturedImage' => 'Image', - ); - - /** - * @var array - */ - private static $many_many = array( - 'Categories' => 'BlogCategory', - 'Tags' => 'BlogTag', - 'Authors' => 'Member', - ); - - /** - * @var array - */ - private static $defaults = array( - 'ShowInMenus' => false, - 'InheritSideBar' => true, - 'ProvideComments' => true, - ); - - /** - * @var array - */ - private static $extensions = array( - 'BlogPostFilter', - ); - - /** - * @var array - */ - private static $searchable_fields = array( - 'Title', - ); - - /** - * @var array - */ - private static $summary_fields = array( - 'Title', - ); - - /** - * @var array - */ - private static $casting = array( - 'Excerpt' => 'Text', - ); - - /** - * @var array - */ - private static $allowed_children = array(); - - /** - * The default sorting lists BlogPosts with an empty PublishDate at the top. - * - * @var string - */ - private static $default_sort = '"PublishDate" IS NULL DESC, "PublishDate" DESC'; - - /** - * @var bool - */ - private static $can_be_root = false; - - /** - * This will display or hide the current class from the SiteTree. This variable can be - * configured using YAML. - * - * @var bool - */ - private static $show_in_sitetree = false; - - /** - * Determine the role of the given member. - * - * Call be called via template to determine the current user. - * - * @example "Hello $RoleOf($CurrentMember.ID)" - * - * @param null|int|Member $member - * - * @return null|string - */ - public function RoleOf($member = null) { - $member = $this->getMember($member); - - if(!$member) { - return null; - } - - if($this->isAuthor($member)) { - return _t('BlogPost.AUTHOR', 'Author'); - } - - $parent = $this->Parent(); - - if($parent instanceof Blog) { - return $parent->RoleOf($member); - } - - return null; - } - - /** - * Determine if the given member is an author of this post. - * - * @param null|Member $member - * - * @return bool - */ - public function isAuthor($member = null) { - 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; - } - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - Requirements::css(BLOGGER_DIR . '/css/cms.css'); - Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); - - $self =& $this; - - $this->beforeUpdateCMSFields(function ($fields) use ($self) { - $uploadField = UploadField::create('FeaturedImage', _t('BlogPost.FeaturedImage', 'Banner Image')); - $uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif')); - - /** - * @var FieldList $fields - */ - $fields->insertAfter($uploadField, 'Content'); - - $summary = HtmlEditorField::create('Summary', false); - $summary->setRows(5); - $summary->setDescription(_t( - 'BlogPost.SUMMARY_DESCRIPTION', - 'If no summary is specified the first 30 words will be used.' - )); - - $summaryHolder = ToggleCompositeField::create( - 'CustomSummary', - _t('BlogPost.CUSTOMSUMMARY', 'Add A Custom Summary'), - array( - $summary, - ) - ); - $summaryHolder->setHeadingLevel(4); - $summaryHolder->addExtraClass('custom-summary'); - - $fields->insertAfter($summaryHolder, 'FeaturedImage'); - - $fields->push(HiddenField::create('MenuTitle')); - - $urlSegment = $fields->dataFieldByName('URLSegment'); - $urlSegment->setURLPrefix($self->Parent()->RelativeLink()); - - $fields->removeFieldsFromTab('Root.Main', array( - 'MenuTitle', - 'URLSegment', - )); - - $authorField = ListboxField::create( - 'Authors', - _t('BlogPost.Authors', 'Authors'), - $this->getCandidateAuthors()->map()->toArray() - )->setMultiple(true); - - $authorNames = TextField::create( - 'AuthorNames', - _t('BlogPost.AdditionalCredits', 'Additional Credits'), - null, - 1024 - )->setDescription(_t( - 'BlogPost.AdditionalCredits_Description', - 'If some authors of this post don\'t have CMS access, enter their name(s) here. You can separate multiple names with a comma.') - ); - - if(!$self->canEditAuthors()) { - $authorField = $authorField->performDisabledTransformation(); - $authorNames = $authorNames->performDisabledTransformation(); - } - - $publishDate = DatetimeField::create('PublishDate', _t('BlogPost.PublishDate', 'Publish Date')); - $publishDate->getDateField()->setConfig('showcalendar', true); - if(!$self->PublishDate) { - $publishDate->setDescription(_t( - 'BlogPost.PublishDate_Description', - 'Will be set to "now" if published without a value.') - ); - } - - // Get categories and tags - $parent = $self->Parent(); - $categories = $parent instanceof Blog - ? $parent->Categories() - : BlogCategory::get(); - $tags = $parent instanceof Blog - ? $parent->Tags() - : BlogTag::get(); - - $options = BlogAdminSidebar::create( - $publishDate, - $urlSegment, - TagField::create( - 'Categories', - _t('BlogPost.Categories', 'Categories'), - $categories, - $self->Categories() - ) - ->setCanCreate($self->canCreateCategories()) - ->setShouldLazyLoad(true), - TagField::create( - 'Tags', - _t('BlogPost.Tags', 'Tags'), - $tags, - $self->Tags() - ) - ->setCanCreate($self->canCreateTags()) - ->setShouldLazyLoad(true), - $authorField, - $authorNames - )->setTitle('Post Options'); - - $options->setName('blog-admin-sidebar'); - - $fields->insertBefore($options, 'Root'); - }); - - $fields = parent::getCMSFields(); - - $fields->fieldByName('Root')->setTemplate('TabSet_holder'); - - 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. - * - * @param null|int|Member $member - * - * @return bool - */ - public function canEditAuthors($member = null) { - $member = $this->getMember($member); - - $extended = $this->extendedCan('canEditAuthors', $member); - - if($extended !== null) { - return $extended; - } - - $parent = $this->Parent(); - - if($parent instanceof Blog && $parent->exists()) { - if($parent->isEditor($member)) { - return true; - } - - if($parent->isWriter($member) && $this->isAuthor($member)) { - return true; - } - } - - return Permission::checkMember($member, Blog::MANAGE_USERS); - } - - /** - * @param null|int|Member $member - * - * @return null|Member - */ - protected function getMember($member = null) { - if(!$member) { - $member = Member::currentUser(); - } - - if(is_numeric($member)) { - $member = Member::get()->byID($member); - } - - return $member; - } - - /** - * Determine whether user can create new categories. - * - * @param null|int|Member $member - * - * @return bool - */ - public function canCreateCategories($member = null) { - $member = $this->getMember($member); - - $parent = $this->Parent(); - - if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { - return false; - } - - if($parent->isEditor($member)) { - return true; - } - - return Permission::checkMember($member, 'ADMIN'); - } - - /** - * Determine whether user can create new tags. - * - * @param null|int|Member $member - * - * @return bool - */ - public function canCreateTags($member = null) { - $member = $this->getMember($member); - - $parent = $this->Parent(); - - if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { - return false; - } - - if($parent->isEditor($member)) { - return true; - } - - if($parent->isWriter($member)) { - return true; - } - - return Permission::checkMember($member, 'ADMIN'); - } - - /** - * {@inheritdoc} - * - * Update the PublishDate to now if the BlogPost would otherwise be published without a date. - */ - public function onBeforePublish() { - /** - * @var SS_Datetime $publishDate - */ - $publishDate = $this->dbObject('PublishDate'); - - if(!$publishDate->getValue()) { - $this->PublishDate = SS_Datetime::now()->getValue(); - $this->write(); - } - } - - /** - * {@inheritdoc} - * - * Sets blog relationship on all categories and tags assigned to this post. - */ - public function onAfterWrite() { - parent::onAfterWrite(); - - foreach($this->Categories() as $category) { - /** - * @var BlogCategory $category - */ - $category->BlogID = $this->ParentID; - $category->write(); - } - - foreach($this->Tags() as $tag) { - /** - * @var BlogTag $tag - */ - $tag->BlogID = $this->ParentID; - $tag->write(); - } - } - - /** - * {@inheritdoc} - */ - public function canView($member = null) { - $member = $this->getMember($member); - - if(!parent::canView($member)) { - return false; - } - - /** - * @var SS_Datetime $publishDate - */ - $publishDate = $this->dbObject('PublishDate'); - - // Show past posts - if(!$publishDate->exists() || !$publishDate->InFuture()) { - return true; - } - - // Anyone that can edit this page can view it - return $this->canEdit($member); - } - - /** - * {@inheritdoc} - */ - public function canPublish($member = null) { - $member = $this->getMember($member); - - if(Permission::checkMember($member, 'ADMIN')) { - return true; - } - - $extended = $this->extendedCan('canPublish', $member); - - if($extended !== null) { - return $extended; - } - - $parent = $this->Parent(); - - if($parent instanceof Blog && $parent->exists()) { - if($parent->isEditor($member)) { - return true; - } - - if($parent->isWriter($member) && $this->isAuthor($member)) { - return true; - } - - if($parent->isContributor($member)) { - return parent::canEdit($member); - } - } - - return $this->canEdit($member); - } - - /** - * {@inheritdoc} - */ - public function canEdit($member = null) { - $member = $this->getMember($member); - - if(parent::canEdit($member)) { - return true; - } - - $parent = $this->Parent(); - - if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { - return false; - } - - if($parent->isEditor($member)) { - return true; - } - - if(!$parent->isWriter($member) && !$parent->isContributor($member)) { - return false; - } - - return $this->isAuthor($member); - } - - /** - * Returns the post excerpt. - * - * @param int $wordsToDisplay - * - * @return string - */ - public function Excerpt($wordsToDisplay = 30) { - /** - * @var Text $content - */ - $content = $this->dbObject('Content'); - - return $content->Summary($wordsToDisplay); - } - - /** - * Returns a monthly archive link for the current blog post. - * - * @param string $type - * - * @return string - */ - public function getMonthlyArchiveLink($type = 'day') { - /** - * @var SS_Datetime $date - */ - $date = $this->dbObject('PublishDate'); - - if($type != 'year') { - if($type == 'day') { - return Controller::join_links( - $this->Parent()->Link('archive'), - $date->format('Y'), - $date->format('m'), - $date->format('d') - ); - } - - return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y'), $date->format('m')); - } - - return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); - } - - /** - * Returns a yearly archive link for the current blog post. - * - * @return string - */ - public function getYearlyArchiveLink() { - /** - * @var SS_Datetime $date - */ - $date = $this->dbObject('PublishDate'); - - return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); - } - - /** - * Resolves static and dynamic authors linked to this post. - * - * @return ArrayList - */ - public function getCredits() { - $list = new ArrayList(); - - $list->merge($this->getDynamicCredits()); - $list->merge($this->getStaticCredits()); - - return $list->sort('Name'); - } - - /** - * Resolves dynamic authors linked to this post. - * - * @return ArrayList - */ - protected function getDynamicCredits() { - // Find best page to host user profiles - $parent = $this->Parent(); - if(! ($parent instanceof Blog) ) { - $parent = Blog::get()->first(); - } - - // If there is no parent blog, return list undecorated - if(!$parent) { - $items = $this->Authors()->toArray(); - return new ArrayList($items); - } - - // Update all authors - $items = new ArrayList(); - foreach($this->Authors() as $author) { - // Add link for each author - $author = $author->customise(array( - 'URL' => $parent->ProfileLink($author->URLSegment), - )); - $items->push($author); - } - - return $items; - } - - /** - * Resolves static authors linked to this post. - * - * @return ArrayList - */ - protected function getStaticCredits() { - $items = new ArrayList(); - - $authors = array_filter(preg_split('/\s*,\s*/', $this->AuthorNames)); - - foreach($authors as $author) { - $item = new ArrayData(array( - 'Name' => $author, - )); - - $items->push($item); - } - - return $items; - } - - /** - * Sets the label for BlogPost.Title to 'Post Title' (Rather than 'Page name'). - * - * @param bool $includeRelations - * - * @return array - */ - public function fieldLabels($includeRelations = true) { - $labels = parent::fieldLabels($includeRelations); - - $labels['Title'] = _t('BlogPost.PageTitleLabel', 'Post Title'); - - return $labels; - } - - /** - * {@inheritdoc} - */ - protected function onBeforeWrite() { - parent::onBeforeWrite(); - - if(!$this->exists() && ($member = Member::currentUser())) { - $this->Authors()->add($member); - } - } -} - -/** - * @package silverstripe - * @subpackage blog - */ -class BlogPost_Controller extends Page_Controller { - -} + 'SS_Datetime', + 'AuthorNames' => 'Varchar(1024)', + 'Summary' => 'HTMLText', + ); + + /** + * @var array + */ + private static $has_one = array( + 'FeaturedImage' => 'Image', + ); + + /** + * @var array + */ + private static $many_many = array( + 'Categories' => 'BlogCategory', + 'Tags' => 'BlogTag', + 'Authors' => 'Member', + ); + + /** + * @var array + */ + private static $defaults = array( + 'ShowInMenus' => false, + 'InheritSideBar' => true, + 'ProvideComments' => true, + ); + + /** + * @var array + */ + private static $extensions = array( + 'BlogPostFilter', + ); + + /** + * @var array + */ + private static $searchable_fields = array( + 'Title', + ); + + /** + * @var array + */ + private static $summary_fields = array( + 'Title', + ); + + /** + * @var array + */ + private static $casting = array( + 'Excerpt' => 'Text', + ); + + /** + * @var array + */ + private static $allowed_children = array(); + + /** + * The default sorting lists BlogPosts with an empty PublishDate at the top. + * + * @var string + */ + private static $default_sort = '"PublishDate" IS NULL DESC, "PublishDate" DESC'; + + /** + * @var bool + */ + private static $can_be_root = false; + + /** + * This will display or hide the current class from the SiteTree. This variable can be + * configured using YAML. + * + * @var bool + */ + private static $show_in_sitetree = false; + + /** + * Determine the role of the given member. + * + * Call be called via template to determine the current user. + * + * @example "Hello $RoleOf($CurrentMember.ID)" + * + * @param null|int|Member $member + * + * @return null|string + */ + public function RoleOf($member = null) + { + $member = $this->getMember($member); + + if (!$member) { + return null; + } + + if ($this->isAuthor($member)) { + return _t('BlogPost.AUTHOR', 'Author'); + } + + $parent = $this->Parent(); + + if ($parent instanceof Blog) { + return $parent->RoleOf($member); + } + + return null; + } + + /** + * Determine if the given member is an author of this post. + * + * @param null|Member $member + * + * @return bool + */ + public function isAuthor($member = null) + { + 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; + } + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + Requirements::css(BLOGGER_DIR . '/css/cms.css'); + Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); + + $self =& $this; + + $this->beforeUpdateCMSFields(function ($fields) use ($self) { + $uploadField = UploadField::create('FeaturedImage', _t('BlogPost.FeaturedImage', 'Banner Image')); + $uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif')); + + /** + * @var FieldList $fields + */ + $fields->insertAfter($uploadField, 'Content'); + + $summary = HtmlEditorField::create('Summary', false); + $summary->setRows(5); + $summary->setDescription(_t( + 'BlogPost.SUMMARY_DESCRIPTION', + 'If no summary is specified the first 30 words will be used.' + )); + + $summaryHolder = ToggleCompositeField::create( + 'CustomSummary', + _t('BlogPost.CUSTOMSUMMARY', 'Add A Custom Summary'), + array( + $summary, + ) + ); + $summaryHolder->setHeadingLevel(4); + $summaryHolder->addExtraClass('custom-summary'); + + $fields->insertAfter($summaryHolder, 'FeaturedImage'); + + $fields->push(HiddenField::create('MenuTitle')); + + $urlSegment = $fields->dataFieldByName('URLSegment'); + $urlSegment->setURLPrefix($self->Parent()->RelativeLink()); + + $fields->removeFieldsFromTab('Root.Main', array( + 'MenuTitle', + 'URLSegment', + )); + + $authorField = ListboxField::create( + 'Authors', + _t('BlogPost.Authors', 'Authors'), + $this->getCandidateAuthors()->map()->toArray() + )->setMultiple(true); + + $authorNames = TextField::create( + 'AuthorNames', + _t('BlogPost.AdditionalCredits', 'Additional Credits'), + null, + 1024 + )->setDescription(_t( + 'BlogPost.AdditionalCredits_Description', + 'If some authors of this post don\'t have CMS access, enter their name(s) here. You can separate multiple names with a comma.') + ); + + if (!$self->canEditAuthors()) { + $authorField = $authorField->performDisabledTransformation(); + $authorNames = $authorNames->performDisabledTransformation(); + } + + $publishDate = DatetimeField::create('PublishDate', _t('BlogPost.PublishDate', 'Publish Date')); + $publishDate->getDateField()->setConfig('showcalendar', true); + if (!$self->PublishDate) { + $publishDate->setDescription(_t( + 'BlogPost.PublishDate_Description', + 'Will be set to "now" if published without a value.') + ); + } + + // Get categories and tags + $parent = $self->Parent(); + $categories = $parent instanceof Blog + ? $parent->Categories() + : BlogCategory::get(); + $tags = $parent instanceof Blog + ? $parent->Tags() + : BlogTag::get(); + + $options = BlogAdminSidebar::create( + $publishDate, + $urlSegment, + TagField::create( + 'Categories', + _t('BlogPost.Categories', 'Categories'), + $categories, + $self->Categories() + ) + ->setCanCreate($self->canCreateCategories()) + ->setShouldLazyLoad(true), + TagField::create( + 'Tags', + _t('BlogPost.Tags', 'Tags'), + $tags, + $self->Tags() + ) + ->setCanCreate($self->canCreateTags()) + ->setShouldLazyLoad(true), + $authorField, + $authorNames + )->setTitle('Post Options'); + + $options->setName('blog-admin-sidebar'); + + $fields->insertBefore($options, 'Root'); + }); + + $fields = parent::getCMSFields(); + + $fields->fieldByName('Root')->setTemplate('TabSet_holder'); + + 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. + * + * @param null|int|Member $member + * + * @return bool + */ + public function canEditAuthors($member = null) + { + $member = $this->getMember($member); + + $extended = $this->extendedCan('canEditAuthors', $member); + + if ($extended !== null) { + return $extended; + } + + $parent = $this->Parent(); + + if ($parent instanceof Blog && $parent->exists()) { + if ($parent->isEditor($member)) { + return true; + } + + if ($parent->isWriter($member) && $this->isAuthor($member)) { + return true; + } + } + + return Permission::checkMember($member, Blog::MANAGE_USERS); + } + + /** + * @param null|int|Member $member + * + * @return null|Member + */ + protected function getMember($member = null) + { + if (!$member) { + $member = Member::currentUser(); + } + + if (is_numeric($member)) { + $member = Member::get()->byID($member); + } + + return $member; + } + + /** + * Determine whether user can create new categories. + * + * @param null|int|Member $member + * + * @return bool + */ + public function canCreateCategories($member = null) + { + $member = $this->getMember($member); + + $parent = $this->Parent(); + + if (!$parent || !$parent->exists() || !($parent instanceof Blog)) { + return false; + } + + if ($parent->isEditor($member)) { + return true; + } + + return Permission::checkMember($member, 'ADMIN'); + } + + /** + * Determine whether user can create new tags. + * + * @param null|int|Member $member + * + * @return bool + */ + public function canCreateTags($member = null) + { + $member = $this->getMember($member); + + $parent = $this->Parent(); + + if (!$parent || !$parent->exists() || !($parent instanceof Blog)) { + return false; + } + + if ($parent->isEditor($member)) { + return true; + } + + if ($parent->isWriter($member)) { + return true; + } + + return Permission::checkMember($member, 'ADMIN'); + } + + /** + * {@inheritdoc} + * + * Update the PublishDate to now if the BlogPost would otherwise be published without a date. + */ + public function onBeforePublish() + { + /** + * @var SS_Datetime $publishDate + */ + $publishDate = $this->dbObject('PublishDate'); + + if (!$publishDate->getValue()) { + $this->PublishDate = SS_Datetime::now()->getValue(); + $this->write(); + } + } + + /** + * {@inheritdoc} + * + * Sets blog relationship on all categories and tags assigned to this post. + */ + public function onAfterWrite() + { + parent::onAfterWrite(); + + foreach ($this->Categories() as $category) { + /** + * @var BlogCategory $category + */ + $category->BlogID = $this->ParentID; + $category->write(); + } + + foreach ($this->Tags() as $tag) { + /** + * @var BlogTag $tag + */ + $tag->BlogID = $this->ParentID; + $tag->write(); + } + } + + /** + * {@inheritdoc} + */ + public function canView($member = null) + { + $member = $this->getMember($member); + + if (!parent::canView($member)) { + return false; + } + + /** + * @var SS_Datetime $publishDate + */ + $publishDate = $this->dbObject('PublishDate'); + + // Show past posts + if (!$publishDate->exists() || !$publishDate->InFuture()) { + return true; + } + + // Anyone that can edit this page can view it + return $this->canEdit($member); + } + + /** + * {@inheritdoc} + */ + public function canPublish($member = null) + { + $member = $this->getMember($member); + + if (Permission::checkMember($member, 'ADMIN')) { + return true; + } + + $extended = $this->extendedCan('canPublish', $member); + + if ($extended !== null) { + return $extended; + } + + $parent = $this->Parent(); + + if ($parent instanceof Blog && $parent->exists()) { + if ($parent->isEditor($member)) { + return true; + } + + if ($parent->isWriter($member) && $this->isAuthor($member)) { + return true; + } + + if ($parent->isContributor($member)) { + return parent::canEdit($member); + } + } + + return $this->canEdit($member); + } + + /** + * {@inheritdoc} + */ + public function canEdit($member = null) + { + $member = $this->getMember($member); + + if (parent::canEdit($member)) { + return true; + } + + $parent = $this->Parent(); + + if (!$parent || !$parent->exists() || !($parent instanceof Blog)) { + return false; + } + + if ($parent->isEditor($member)) { + return true; + } + + if (!$parent->isWriter($member) && !$parent->isContributor($member)) { + return false; + } + + return $this->isAuthor($member); + } + + /** + * Returns the post excerpt. + * + * @param int $wordsToDisplay + * + * @return string + */ + public function Excerpt($wordsToDisplay = 30) + { + /** + * @var Text $content + */ + $content = $this->dbObject('Content'); + + return $content->Summary($wordsToDisplay); + } + + /** + * Returns a monthly archive link for the current blog post. + * + * @param string $type + * + * @return string + */ + public function getMonthlyArchiveLink($type = 'day') + { + /** + * @var SS_Datetime $date + */ + $date = $this->dbObject('PublishDate'); + + if ($type != 'year') { + if ($type == 'day') { + return Controller::join_links( + $this->Parent()->Link('archive'), + $date->format('Y'), + $date->format('m'), + $date->format('d') + ); + } + + return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y'), $date->format('m')); + } + + return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); + } + + /** + * Returns a yearly archive link for the current blog post. + * + * @return string + */ + public function getYearlyArchiveLink() + { + /** + * @var SS_Datetime $date + */ + $date = $this->dbObject('PublishDate'); + + return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); + } + + /** + * Resolves static and dynamic authors linked to this post. + * + * @return ArrayList + */ + public function getCredits() + { + $list = new ArrayList(); + + $list->merge($this->getDynamicCredits()); + $list->merge($this->getStaticCredits()); + + return $list->sort('Name'); + } + + /** + * Resolves dynamic authors linked to this post. + * + * @return ArrayList + */ + protected function getDynamicCredits() + { + // Find best page to host user profiles + $parent = $this->Parent(); + if (! ($parent instanceof Blog)) { + $parent = Blog::get()->first(); + } + + // If there is no parent blog, return list undecorated + if (!$parent) { + $items = $this->Authors()->toArray(); + return new ArrayList($items); + } + + // Update all authors + $items = new ArrayList(); + foreach ($this->Authors() as $author) { + // Add link for each author + $author = $author->customise(array( + 'URL' => $parent->ProfileLink($author->URLSegment), + )); + $items->push($author); + } + + return $items; + } + + /** + * Resolves static authors linked to this post. + * + * @return ArrayList + */ + protected function getStaticCredits() + { + $items = new ArrayList(); + + $authors = array_filter(preg_split('/\s*,\s*/', $this->AuthorNames)); + + foreach ($authors as $author) { + $item = new ArrayData(array( + 'Name' => $author, + )); + + $items->push($item); + } + + return $items; + } + + /** + * Sets the label for BlogPost.Title to 'Post Title' (Rather than 'Page name'). + * + * @param bool $includeRelations + * + * @return array + */ + public function fieldLabels($includeRelations = true) + { + $labels = parent::fieldLabels($includeRelations); + + $labels['Title'] = _t('BlogPost.PageTitleLabel', 'Post Title'); + + return $labels; + } + + /** + * {@inheritdoc} + */ + protected function onBeforeWrite() + { + parent::onBeforeWrite(); + + if (!$this->exists() && ($member = Member::currentUser())) { + $this->Authors()->add($member); + } + } +} + +/** + * @package silverstripe + * @subpackage blog + */ +class BlogPost_Controller extends Page_Controller +{ +} diff --git a/code/model/BlogTag.php b/code/model/BlogTag.php index d9f0aac..c5b7376 100644 --- a/code/model/BlogTag.php +++ b/code/model/BlogTag.php @@ -12,135 +12,143 @@ * @property string $URLSegment * @property int $BlogID */ -class BlogTag extends DataObject implements CategorisationObject { - /** - * @var array - */ - private static $db = array( - 'Title' => 'Varchar(255)', - ); +class BlogTag extends DataObject implements CategorisationObject +{ + /** + * @var array + */ + private static $db = array( + 'Title' => 'Varchar(255)', + ); - /** - * @var array - */ - private static $has_one = array( - 'Blog' => 'Blog', - ); + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); - /** - * @var array - */ - private static $belongs_many_many = array( - 'BlogPosts' => 'BlogPost', - ); + /** + * @var array + */ + private static $belongs_many_many = array( + 'BlogPosts' => 'BlogPost', + ); - /** - * @var array - */ - private static $extensions = array( - 'URLSegmentExtension', - ); + /** + * @var array + */ + private static $extensions = array( + 'URLSegmentExtension', + ); - /** - * @return DataList - */ - public function BlogPosts() { - $blogPosts = parent::BlogPosts(); + /** + * @return DataList + */ + public function BlogPosts() + { + $blogPosts = parent::BlogPosts(); - $this->extend("updateGetBlogPosts", $blogPosts); + $this->extend("updateGetBlogPosts", $blogPosts); - return $blogPosts; - } + return $blogPosts; + } - /** - * {@inheritdoc} - */ - public function getCMSFields() { - $fields = new FieldList( - TextField::create('Title', _t('BlogTag.Title', 'Title')) - ); + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + $fields = new FieldList( + TextField::create('Title', _t('BlogTag.Title', 'Title')) + ); - $this->extend('updateCMSFields', $fields); + $this->extend('updateCMSFields', $fields); - return $fields; - } + return $fields; + } - /** - * Returns a relative URL for the tag link. - * - * @return string - */ - public function getLink() { - return Controller::join_links($this->Blog()->Link(), 'tag', $this->URLSegment); - } + /** + * Returns a relative URL for the tag link. + * + * @return string + */ + public function getLink() + { + return Controller::join_links($this->Blog()->Link(), 'tag', $this->URLSegment); + } - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canView($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canView($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); - if($extended !== null) { - return $extended; - } + if ($extended !== null) { + return $extended; + } - return $this->Blog()->canView($member); - } + return $this->Blog()->canView($member); + } - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canCreate($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canCreate($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); - if($extended !== null) { - return $extended; - } + if ($extended !== null) { + return $extended; + } - $permission = Blog::config()->grant_user_permission; + $permission = Blog::config()->grant_user_permission; - return Permission::checkMember($member, $permission); - } + return Permission::checkMember($member, $permission); + } - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canDelete($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canDelete($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); - if($extended !== null) { - return $extended; - } + if ($extended !== null) { + return $extended; + } - return $this->Blog()->canEdit($member); - } + return $this->Blog()->canEdit($member); + } - /** - * Inherits from the parent blog or can be overwritten using a DataExtension. - * - * @param null|Member $member - * - * @return bool - */ - public function canEdit($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); + /** + * Inherits from the parent blog or can be overwritten using a DataExtension. + * + * @param null|Member $member + * + * @return bool + */ + public function canEdit($member = null) + { + $extended = $this->extendedCan(__FUNCTION__, $member); - if($extended !== null) { - return $extended; - } + if ($extended !== null) { + return $extended; + } - return $this->Blog()->canEdit($member); - } + return $this->Blog()->canEdit($member); + } } diff --git a/code/model/CategorisationObject.php b/code/model/CategorisationObject.php index 5528478..811419e 100644 --- a/code/model/CategorisationObject.php +++ b/code/model/CategorisationObject.php @@ -3,6 +3,6 @@ /** * @method ManyManyList BlogPosts */ -interface CategorisationObject { - +interface CategorisationObject +{ } diff --git a/code/widgets/BlogArchiveWidget.php b/code/widgets/BlogArchiveWidget.php index e210430..07ecd7c 100644 --- a/code/widgets/BlogArchiveWidget.php +++ b/code/widgets/BlogArchiveWidget.php @@ -1,135 +1,138 @@ - 'Int', - 'ArchiveType' => 'Enum(\'Monthly,Yearly\', \'Monthly\')', - ); - - /** - * @var array - */ - private static $defaults = array( - 'NumberOfMonths' => 12, - ); - - /** - * @var array - */ - private static $has_one = array( - 'Blog' => 'Blog', - ); - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - $self =& $this; - - $this->beforeUpdateCMSFields(function ($fields) use ($self) { - /** - * @var Enum $archiveType - */ - $archiveType = $self->dbObject('ArchiveType'); - - $type = $archiveType->enumValues(); - - foreach($type as $k => $v) { - $type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v); - } - - /** - * @var FieldList $fields - */ - $fields->merge(array( - DropdownField::create('BlogID', _t('BlogArchiveWidget.Blog', 'Blog'), Blog::get()->map()), - DropdownField::create('ArchiveType', _t('BlogArchiveWidget.ArchiveType', 'ArchiveType'), $type), - NumericField::create('NumberToDisplay', _t('BlogArchiveWidget.NumberToDisplay', 'No. to Display')) - )); - }); - - return parent::getCMSFields(); - } - - /** - * Returns a list of months where blog posts are present. - * - * @return DataList - */ - public function getArchive() { - $query = $this->Blog()->getBlogPosts()->dataQuery(); - - if($this->ArchiveType == 'Yearly') { - $query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')'); - } else { - $query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')'); - } - - $posts = $this->Blog()->getBlogPosts()->setDataQuery($query); - - if($this->NumberToDisplay > 0) { - $posts = $posts->limit($this->NumberToDisplay); - } - - $archive = new ArrayList(); - - if($posts->count() > 0) { - foreach($posts as $post) { - /** - * @var BlogPost $post - */ - $date = Date::create(); - $date->setValue($post->PublishDate); - - if($this->ArchiveType == 'Yearly') { - $year = $date->FormatI18N("%Y"); - $month = null; - $title = $year; - } else { - $year = $date->FormatI18N("%Y"); - $month = $date->FormatI18N("%m"); - $title = $date->FormatI18N("%B %Y"); - } - - $archive->push(new ArrayData(array( - 'Title' => $title, - 'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month) - ))); - } - } - - return $archive; - } -} - -class BlogArchiveWidget_Controller extends Widget_Controller { - -} + 'Int', + 'ArchiveType' => 'Enum(\'Monthly,Yearly\', \'Monthly\')', + ); + + /** + * @var array + */ + private static $defaults = array( + 'NumberOfMonths' => 12, + ); + + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + $self =& $this; + + $this->beforeUpdateCMSFields(function ($fields) use ($self) { + /** + * @var Enum $archiveType + */ + $archiveType = $self->dbObject('ArchiveType'); + + $type = $archiveType->enumValues(); + + foreach ($type as $k => $v) { + $type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v); + } + + /** + * @var FieldList $fields + */ + $fields->merge(array( + DropdownField::create('BlogID', _t('BlogArchiveWidget.Blog', 'Blog'), Blog::get()->map()), + DropdownField::create('ArchiveType', _t('BlogArchiveWidget.ArchiveType', 'ArchiveType'), $type), + NumericField::create('NumberToDisplay', _t('BlogArchiveWidget.NumberToDisplay', 'No. to Display')) + )); + }); + + return parent::getCMSFields(); + } + + /** + * Returns a list of months where blog posts are present. + * + * @return DataList + */ + public function getArchive() + { + $query = $this->Blog()->getBlogPosts()->dataQuery(); + + if ($this->ArchiveType == 'Yearly') { + $query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')'); + } else { + $query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')'); + } + + $posts = $this->Blog()->getBlogPosts()->setDataQuery($query); + + if ($this->NumberToDisplay > 0) { + $posts = $posts->limit($this->NumberToDisplay); + } + + $archive = new ArrayList(); + + if ($posts->count() > 0) { + foreach ($posts as $post) { + /** + * @var BlogPost $post + */ + $date = Date::create(); + $date->setValue($post->PublishDate); + + if ($this->ArchiveType == 'Yearly') { + $year = $date->FormatI18N("%Y"); + $month = null; + $title = $year; + } else { + $year = $date->FormatI18N("%Y"); + $month = $date->FormatI18N("%m"); + $title = $date->FormatI18N("%B %Y"); + } + + $archive->push(new ArrayData(array( + 'Title' => $title, + 'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month) + ))); + } + } + + return $archive; + } +} + +class BlogArchiveWidget_Controller extends Widget_Controller +{ +} diff --git a/code/widgets/BlogCategoriesWidget.php b/code/widgets/BlogCategoriesWidget.php index 929fd7d..14944df 100644 --- a/code/widgets/BlogCategoriesWidget.php +++ b/code/widgets/BlogCategoriesWidget.php @@ -1,97 +1,100 @@ - 'Int', - 'Order' => 'Varchar', - 'Direction' => 'Varchar', - ); - - /** - * @var array - */ - private static $has_one = array( - 'Blog' => 'Blog', - ); - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - $this->beforeUpdateCMSFields(function (FieldList $fields) { - $fields[] = DropdownField::create( - 'BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map() - ); - - $fields[] = NumericField::create( - 'Limit', _t('BlogCategoriesWidget.Limit.Label', 'Limit'), 0 - ) - ->setDescription(_t('BlogCategoriesWidget.Limit.Description', 'Limit the number of categories shown by this widget (set to 0 to show all categories).')) - ->setMaxLength(3); - - $fields[] = DropdownField::create( - 'Order', _t('BlogCategoriesWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated') - ) - ->setDescription(_t('BlogCategoriesWidget.Sort.Description', 'Change the order of categories shown by this widget.')); - - $fields[] = DropdownField::create( - 'Direction', _t('BlogCategoriesWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending') - ) - ->setDescription(_t('BlogCategoriesWidget.Direction.Description', 'Change the direction of ordering of categories shown by this widget.')); - }); - - return parent::getCMSFields(); - } - - /** - * @return DataList - */ - public function getCategories() { - $blog = $this->Blog(); - - if (!$blog) { - return array(); - } - - $query = $blog->Categories(); - - if ($this->Limit) { - $query = $query->limit(Convert::raw2sql($this->Limit)); - } - - if ($this->Order && $this->Direction) { - $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); - } - - return $query; - } -} - -class BlogCategoriesWidget_Controller extends Widget_Controller { - -} + 'Int', + 'Order' => 'Varchar', + 'Direction' => 'Varchar', + ); + + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + $this->beforeUpdateCMSFields(function (FieldList $fields) { + $fields[] = DropdownField::create( + 'BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map() + ); + + $fields[] = NumericField::create( + 'Limit', _t('BlogCategoriesWidget.Limit.Label', 'Limit'), 0 + ) + ->setDescription(_t('BlogCategoriesWidget.Limit.Description', 'Limit the number of categories shown by this widget (set to 0 to show all categories).')) + ->setMaxLength(3); + + $fields[] = DropdownField::create( + 'Order', _t('BlogCategoriesWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated') + ) + ->setDescription(_t('BlogCategoriesWidget.Sort.Description', 'Change the order of categories shown by this widget.')); + + $fields[] = DropdownField::create( + 'Direction', _t('BlogCategoriesWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending') + ) + ->setDescription(_t('BlogCategoriesWidget.Direction.Description', 'Change the direction of ordering of categories shown by this widget.')); + }); + + return parent::getCMSFields(); + } + + /** + * @return DataList + */ + public function getCategories() + { + $blog = $this->Blog(); + + if (!$blog) { + return array(); + } + + $query = $blog->Categories(); + + if ($this->Limit) { + $query = $query->limit(Convert::raw2sql($this->Limit)); + } + + if ($this->Order && $this->Direction) { + $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); + } + + return $query; + } +} + +class BlogCategoriesWidget_Controller extends Widget_Controller +{ +} diff --git a/code/widgets/BlogRecentPostsWidget.php b/code/widgets/BlogRecentPostsWidget.php index 4e52ac5..2456cb4 100644 --- a/code/widgets/BlogRecentPostsWidget.php +++ b/code/widgets/BlogRecentPostsWidget.php @@ -1,77 +1,80 @@ - 'Int', - ); - - /** - * @var array - */ - private static $has_one = array( - 'Blog' => 'Blog', - ); - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - $this->beforeUpdateCMSFields(function ($fields) { - /** - * @var FieldList $fields - */ - $fields->merge(array( - DropdownField::create('BlogID', _t('BlogRecentPostsWidget.Blog', 'Blog'), Blog::get()->map()), - NumericField::create('NumberOfPosts', _t('BlogRecentPostsWidget.NumberOfPosts', 'Number of Posts')) - )); - }); - - return parent::getCMSFields(); - } - - /** - * @return array - */ - public function getPosts() { - $blog = $this->Blog(); - - if($blog) { - return $blog->getBlogPosts() - ->sort('"PublishDate" DESC') - ->limit($this->NumberOfPosts); - } - - return array(); - } -} - -class BlogRecentPostsWidget_Controller extends Widget_Controller { - -} + 'Int', + ); + + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + $this->beforeUpdateCMSFields(function ($fields) { + /** + * @var FieldList $fields + */ + $fields->merge(array( + DropdownField::create('BlogID', _t('BlogRecentPostsWidget.Blog', 'Blog'), Blog::get()->map()), + NumericField::create('NumberOfPosts', _t('BlogRecentPostsWidget.NumberOfPosts', 'Number of Posts')) + )); + }); + + return parent::getCMSFields(); + } + + /** + * @return array + */ + public function getPosts() + { + $blog = $this->Blog(); + + if ($blog) { + return $blog->getBlogPosts() + ->sort('"PublishDate" DESC') + ->limit($this->NumberOfPosts); + } + + return array(); + } +} + +class BlogRecentPostsWidget_Controller extends Widget_Controller +{ +} diff --git a/code/widgets/BlogTagsWidget.php b/code/widgets/BlogTagsWidget.php index 5f4dfc3..a5ac177 100644 --- a/code/widgets/BlogTagsWidget.php +++ b/code/widgets/BlogTagsWidget.php @@ -1,97 +1,100 @@ - 'Int', - 'Order' => 'Varchar', - 'Direction' => 'Varchar', - ); - - /** - * @var array - */ - private static $has_one = array( - 'Blog' => 'Blog', - ); - - /** - * {@inheritdoc} - */ - public function getCMSFields() { - $this->beforeUpdateCMSFields(function (Fieldlist $fields) { - $fields[] = DropdownField::create( - 'BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map() - ); - - $fields[] = NumericField::create( - 'Limit', _t('BlogTagsWidget.Limit.Label', 'Limit'), 0 - ) - ->setDescription(_t('BlogTagsWidget.Limit.Description', 'Limit the number of tags shown by this widget (set to 0 to show all tags).')) - ->setMaxLength(3); - - $fields[] = DropdownField::create( - 'Order', _t('BlogTagsWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated') - ) - ->setDescription(_t('BlogTagsWidget.Sort.Description', 'Change the order of tags shown by this widget.')); - - $fields[] = DropdownField::create( - 'Direction', _t('BlogTagsWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending') - ) - ->setDescription(_t('BlogTagsWidget.Direction.Description', 'Change the direction of ordering of tags shown by this widget.')); - }); - - return parent::getCMSFields(); - } - - /** - * @return DataList - */ - public function getTags() { - $blog = $this->Blog(); - - if (!$blog) { - return array(); - } - - $query = $blog->Tags(); - - if ($this->Limit) { - $query = $query->limit(Convert::raw2sql($this->Limit)); - } - - if ($this->Order && $this->Direction) { - $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); - } - - return $query; - } -} - -class BlogTagsWidget_Controller extends Widget_Controller { - -} + 'Int', + 'Order' => 'Varchar', + 'Direction' => 'Varchar', + ); + + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); + + /** + * {@inheritdoc} + */ + public function getCMSFields() + { + $this->beforeUpdateCMSFields(function (Fieldlist $fields) { + $fields[] = DropdownField::create( + 'BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map() + ); + + $fields[] = NumericField::create( + 'Limit', _t('BlogTagsWidget.Limit.Label', 'Limit'), 0 + ) + ->setDescription(_t('BlogTagsWidget.Limit.Description', 'Limit the number of tags shown by this widget (set to 0 to show all tags).')) + ->setMaxLength(3); + + $fields[] = DropdownField::create( + 'Order', _t('BlogTagsWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated') + ) + ->setDescription(_t('BlogTagsWidget.Sort.Description', 'Change the order of tags shown by this widget.')); + + $fields[] = DropdownField::create( + 'Direction', _t('BlogTagsWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending') + ) + ->setDescription(_t('BlogTagsWidget.Direction.Description', 'Change the direction of ordering of tags shown by this widget.')); + }); + + return parent::getCMSFields(); + } + + /** + * @return DataList + */ + public function getTags() + { + $blog = $this->Blog(); + + if (!$blog) { + return array(); + } + + $query = $blog->Tags(); + + if ($this->Limit) { + $query = $query->limit(Convert::raw2sql($this->Limit)); + } + + if ($this->Order && $this->Direction) { + $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); + } + + return $query; + } +} + +class BlogTagsWidget_Controller extends Widget_Controller +{ +} diff --git a/tests/BlogCategoryTest.php b/tests/BlogCategoryTest.php index 27d4d69..db0564f 100755 --- a/tests/BlogCategoryTest.php +++ b/tests/BlogCategoryTest.php @@ -3,116 +3,124 @@ /** * @mixin PHPUnit_Framework_TestCase */ -class BlogCategoryTest extends FunctionalTest { - /** - * @var string - */ - static $fixture_file = 'blog.yml'; +class BlogCategoryTest extends FunctionalTest +{ + /** + * @var string + */ + public static $fixture_file = 'blog.yml'; - /** - * {@inheritdoc} - */ - public function setUp() { - parent::setUp(); + /** + * {@inheritdoc} + */ + public function setUp() + { + parent::setUp(); - SS_Datetime::set_mock_now('2013-10-10 20:00:00'); - } + SS_Datetime::set_mock_now('2013-10-10 20:00:00'); + } - /** - * {@inheritdoc} - */ - public function tearDown() { - SS_Datetime::clear_mock_now(); + /** + * {@inheritdoc} + */ + public function tearDown() + { + SS_Datetime::clear_mock_now(); - parent::tearDown(); - } + parent::tearDown(); + } - /** - * Tests that any blog posts returned from $category->BlogPosts() many_many are published, - * both by normal 'save & publish' functionality and by publish date. - */ - public function testBlogPosts() { - $member = Member::currentUser(); + /** + * Tests that any blog posts returned from $category->BlogPosts() many_many are published, + * both by normal 'save & publish' functionality and by publish date. + */ + public function testBlogPosts() + { + $member = Member::currentUser(); - if($member) { - $member->logout(); - } + if ($member) { + $member->logout(); + } - $this->objFromFixture('BlogPost', 'FirstBlogPost'); + $this->objFromFixture('BlogPost', 'FirstBlogPost'); - /** - * @var BlogCategory $category - */ - $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); + /** + * @var BlogCategory $category + */ + $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); - $this->assertEquals(1, $category->BlogPosts()->count(), 'Category blog post count'); - } + $this->assertEquals(1, $category->BlogPosts()->count(), 'Category blog post count'); + } - public function testCanView() { - $this->useDraftSite(); + public function testCanView() + { + $this->useDraftSite(); - $this->objFromFixture('Member', 'Admin'); + $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); - $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); + $editor = $this->objFromFixture('Member', 'Editor'); + $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); - $this->assertFalse($category->canView($editor), 'Editor should not be able to view category.'); - } + $this->assertFalse($category->canView($editor), 'Editor should not be able to view category.'); + } - /** - * The first blog can be viewed by anybody. - */ - public function testCanEdit() { - $this->useDraftSite(); + /** + * The first blog can be viewed by anybody. + */ + public function testCanEdit() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); + $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); - $this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.'); - $this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); + $this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.'); + $this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); - $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); + $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); - $this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.'); - $this->assertFalse($category->canEdit($editor), 'Editor should not be able to edit category.'); + $this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.'); + $this->assertFalse($category->canEdit($editor), 'Editor should not be able to edit category.'); - $category = $this->objFromFixture('BlogCategory', 'ThirdCategory'); + $category = $this->objFromFixture('BlogCategory', 'ThirdCategory'); - $this->assertTrue($category->canEdit($admin), 'Admin should always be able to edit category.'); - $this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); - } + $this->assertTrue($category->canEdit($admin), 'Admin should always be able to edit category.'); + $this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); + } - public function testCanCreate() { - $this->useDraftSite(); + public function testCanCreate() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $category = singleton('BlogCategory'); + $category = singleton('BlogCategory'); - $this->assertTrue($category->canCreate($admin), 'Admin should be able to create category.'); - $this->assertTrue($category->canCreate($editor), 'Editor should be able to create category.'); - } + $this->assertTrue($category->canCreate($admin), 'Admin should be able to create category.'); + $this->assertTrue($category->canCreate($editor), 'Editor should be able to create category.'); + } - public function testCanDelete() { - $this->useDraftSite(); + public function testCanDelete() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); + $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); - $this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.'); - $this->assertTrue($category->canDelete($editor), 'Editor should be able to category category.'); + $this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.'); + $this->assertTrue($category->canDelete($editor), 'Editor should be able to category category.'); - $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); - $this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.'); - $this->assertFalse($category->canDelete($editor), 'Editor should not be able to delete category.'); + $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); + $this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.'); + $this->assertFalse($category->canDelete($editor), 'Editor should not be able to delete category.'); - $category = $this->objFromFixture('BlogCategory', 'ThirdCategory'); - $this->assertTrue($category->canDelete($admin), 'Admin should always be able to delete category.'); - $this->assertTrue($category->canDelete($editor), 'Editor should be able to delete category.'); - } + $category = $this->objFromFixture('BlogCategory', 'ThirdCategory'); + $this->assertTrue($category->canDelete($admin), 'Admin should always be able to delete category.'); + $this->assertTrue($category->canDelete($editor), 'Editor should be able to delete category.'); + } } diff --git a/tests/BlogPostFilterTest.php b/tests/BlogPostFilterTest.php index 95d4114..e878e40 100755 --- a/tests/BlogPostFilterTest.php +++ b/tests/BlogPostFilterTest.php @@ -3,40 +3,44 @@ /** * @mixin PHPUnit_Framework_TestCase */ -class BlogPostFilterTest extends SapphireTest { - /** - * @var string - */ - static $fixture_file = 'blog.yml'; +class BlogPostFilterTest extends SapphireTest +{ + /** + * @var string + */ + public static $fixture_file = 'blog.yml'; - public function setUp() { - parent::setUp(); + public function setUp() + { + parent::setUp(); - SS_Datetime::set_mock_now('2013-10-10 20:00:00'); - } + SS_Datetime::set_mock_now('2013-10-10 20:00:00'); + } - public function tearDown() { - SS_Datetime::clear_mock_now(); + public function tearDown() + { + SS_Datetime::clear_mock_now(); - parent::tearDown(); - } + parent::tearDown(); + } - public function testFilter() { - $member = Member::currentUser(); + public function testFilter() + { + $member = Member::currentUser(); - if($member) { - $member->logout(); - } + if ($member) { + $member->logout(); + } - /** - * @var Blog $blog - */ - $blog = $this->objFromFixture('Blog', 'FirstBlog'); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - $this->assertEquals(3, $blog->AllChildren()->Count(), 'Filtered blog posts'); + $this->assertEquals(3, $blog->AllChildren()->Count(), 'Filtered blog posts'); - SS_Datetime::set_mock_now('2020-01-01 00:00:00'); + SS_Datetime::set_mock_now('2020-01-01 00:00:00'); - $this->assertEquals(5, $blog->AllChildren()->Count(), 'Unfiltered blog posts'); - } + $this->assertEquals(5, $blog->AllChildren()->Count(), 'Unfiltered blog posts'); + } } diff --git a/tests/BlogPostTest.php b/tests/BlogPostTest.php index 7e02336..6b10635 100644 --- a/tests/BlogPostTest.php +++ b/tests/BlogPostTest.php @@ -1,79 +1,82 @@ objFromFixture('Member', $user); - $pageRecord = $this->objFromFixture('BlogPost', $page); - SS_Datetime::set_mock_now($date); - $this->assertEquals($canView, $pageRecord->canView($userRecord)); - } - - public function canViewProvider() { - $someFutureDate = '2013-10-10 20:00:00'; - $somePastDate = '2009-10-10 20:00:00'; - return array( - // Check this post given the date has passed - array($someFutureDate, 'Editor', 'PostA', true), - array($someFutureDate, 'Contributor', 'PostA', true), - array($someFutureDate, 'BlogEditor', 'PostA', true), - array($someFutureDate, 'Writer', 'PostA', true), - - // Check unpublished pages - array($somePastDate, 'Editor', 'PostA', true), - array($somePastDate, 'Contributor', 'PostA', true), - array($somePastDate, 'BlogEditor', 'PostA', true), - array($somePastDate, 'Writer', 'PostA', true), - - // Test a page that was authored by another user - - // Check this post given the date has passed - array($someFutureDate, 'Editor', 'FirstBlogPost', true), - array($someFutureDate, 'Contributor', 'FirstBlogPost', true), - array($someFutureDate, 'BlogEditor', 'FirstBlogPost', true), - array($someFutureDate, 'Writer', 'FirstBlogPost', true), - - // Check future pages - non-editors shouldn't be able to see this - array($somePastDate, 'Editor', 'FirstBlogPost', true), - array($somePastDate, 'Contributor', 'FirstBlogPost', false), - array($somePastDate, 'BlogEditor', 'FirstBlogPost', false), - array($somePastDate, 'Writer', 'FirstBlogPost', false), - ); - } + /** + * @dataProvider canViewProvider + */ + public function testCanView($date, $user, $page, $canView) + { + $userRecord = $this->objFromFixture('Member', $user); + $pageRecord = $this->objFromFixture('BlogPost', $page); + SS_Datetime::set_mock_now($date); + $this->assertEquals($canView, $pageRecord->canView($userRecord)); + } + + public function canViewProvider() + { + $someFutureDate = '2013-10-10 20:00:00'; + $somePastDate = '2009-10-10 20:00:00'; + return array( + // Check this post given the date has passed + array($someFutureDate, 'Editor', 'PostA', true), + array($someFutureDate, 'Contributor', 'PostA', true), + array($someFutureDate, 'BlogEditor', 'PostA', true), + array($someFutureDate, 'Writer', 'PostA', true), + + // Check unpublished pages + array($somePastDate, 'Editor', 'PostA', true), + array($somePastDate, 'Contributor', 'PostA', true), + array($somePastDate, 'BlogEditor', 'PostA', true), + array($somePastDate, 'Writer', 'PostA', true), + + // Test a page that was authored by another user - public function testCandidateAuthors() { - $blogpost = $this->objFromFixture('BlogPost', 'PostC'); + // Check this post given the date has passed + array($someFutureDate, 'Editor', 'FirstBlogPost', true), + array($someFutureDate, 'Contributor', 'FirstBlogPost', true), + array($someFutureDate, 'BlogEditor', 'FirstBlogPost', true), + array($someFutureDate, 'Writer', 'FirstBlogPost', true), + + // Check future pages - non-editors shouldn't be able to see this + array($somePastDate, 'Editor', 'FirstBlogPost', true), + array($somePastDate, 'Contributor', 'FirstBlogPost', false), + array($somePastDate, 'BlogEditor', 'FirstBlogPost', false), + array($somePastDate, 'Writer', 'FirstBlogPost', false), + ); + } - $this->assertEquals(7, $blogpost->getCandidateAuthors()->count()); + public function testCandidateAuthors() + { + $blogpost = $this->objFromFixture('BlogPost', 'PostC'); - //Set the group to draw Members from - Config::inst()->update('BlogPost', 'restrict_authors_to_group','BlogUsers'); + $this->assertEquals(7, $blogpost->getCandidateAuthors()->count()); - $this->assertEquals(3, $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()); + } } diff --git a/tests/BlogTagTest.php b/tests/BlogTagTest.php index b9ed9e3..7f4eca7 100755 --- a/tests/BlogTagTest.php +++ b/tests/BlogTagTest.php @@ -3,124 +3,132 @@ /** * @mixin PHPUnit_Framework_TestCase */ -class BlogTagTest extends FunctionalTest { - /** - * @var string - */ - static $fixture_file = 'blog.yml'; +class BlogTagTest extends FunctionalTest +{ + /** + * @var string + */ + public static $fixture_file = 'blog.yml'; - /** - * {@inheritdoc} - */ - public function setUp() { - parent::setUp(); + /** + * {@inheritdoc} + */ + public function setUp() + { + parent::setUp(); - SS_Datetime::set_mock_now('2013-10-10 20:00:00'); - } + SS_Datetime::set_mock_now('2013-10-10 20:00:00'); + } - /** - * {@inheritdoc} - */ - public function tearDown() { - SS_Datetime::clear_mock_now(); + /** + * {@inheritdoc} + */ + public function tearDown() + { + SS_Datetime::clear_mock_now(); - parent::tearDown(); - } + parent::tearDown(); + } - /** - * Tests that any blog posts returned from $tag->BlogPosts() many_many are published, both by - * normal 'save & publish' functionality and by publish date. - */ - public function testBlogPosts() { - $member = Member::currentUser(); + /** + * Tests that any blog posts returned from $tag->BlogPosts() many_many are published, both by + * normal 'save & publish' functionality and by publish date. + */ + public function testBlogPosts() + { + $member = Member::currentUser(); - if($member) { - $member->logout(); - } + if ($member) { + $member->logout(); + } - $this->objFromFixture('BlogPost', 'FirstBlogPost'); + $this->objFromFixture('BlogPost', 'FirstBlogPost'); - /** - * @var BlogTag $tag - */ - $tag = $this->objFromFixture('BlogTag', 'FirstTag'); + /** + * @var BlogTag $tag + */ + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $this->assertEquals(1, $tag->BlogPosts()->count(), 'Tag blog post count'); - } + $this->assertEquals(1, $tag->BlogPosts()->count(), 'Tag blog post count'); + } - /** - * The first blog can be viewed by anybody. - */ - public function testCanView() { - $this->useDraftSite(); + /** + * The first blog can be viewed by anybody. + */ + public function testCanView() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $tag = $this->objFromFixture('BlogTag', 'FirstTag'); + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.'); - $this->assertTrue($tag->canView($editor), 'Editor should be able to view tag.'); + $this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.'); + $this->assertTrue($tag->canView($editor), 'Editor should be able to view tag.'); - $tag = $this->objFromFixture('BlogTag', 'SecondTag'); + $tag = $this->objFromFixture('BlogTag', 'SecondTag'); - $this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.'); - $this->assertFalse($tag->canView($editor), 'Editor should not be able to view tag.'); - } + $this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.'); + $this->assertFalse($tag->canView($editor), 'Editor should not be able to view tag.'); + } - public function testCanEdit() { - $this->useDraftSite(); + public function testCanEdit() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $tag = $this->objFromFixture('BlogTag', 'FirstTag'); + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.'); - $this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); + $this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.'); + $this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); - $tag = $this->objFromFixture('BlogTag', 'SecondTag'); + $tag = $this->objFromFixture('BlogTag', 'SecondTag'); - $this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.'); - $this->assertFalse($tag->canEdit($editor), 'Editor should not be able to edit tag.'); + $this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.'); + $this->assertFalse($tag->canEdit($editor), 'Editor should not be able to edit tag.'); - $tag = $this->objFromFixture('BlogTag', 'ThirdTag'); + $tag = $this->objFromFixture('BlogTag', 'ThirdTag'); - $this->assertTrue($tag->canEdit($admin), 'Admin should always be able to edit tags.'); - $this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); - } + $this->assertTrue($tag->canEdit($admin), 'Admin should always be able to edit tags.'); + $this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); + } - public function testCanCreate() { - $this->useDraftSite(); + public function testCanCreate() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $tag = singleton('BlogTag'); + $tag = singleton('BlogTag'); - $this->assertTrue($tag->canCreate($admin), 'Admin should be able to create tag.'); - $this->assertTrue($tag->canCreate($editor), 'Editor should be able to create tag.'); - } + $this->assertTrue($tag->canCreate($admin), 'Admin should be able to create tag.'); + $this->assertTrue($tag->canCreate($editor), 'Editor should be able to create tag.'); + } - public function testCanDelete() { - $this->useDraftSite(); + public function testCanDelete() + { + $this->useDraftSite(); - $admin = $this->objFromFixture('Member', 'Admin'); - $editor = $this->objFromFixture('Member', 'Editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - $tag = $this->objFromFixture('BlogTag', 'FirstTag'); + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.'); - $this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); + $this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.'); + $this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); - $tag = $this->objFromFixture('BlogTag', 'SecondTag'); + $tag = $this->objFromFixture('BlogTag', 'SecondTag'); - $this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.'); - $this->assertFalse($tag->canDelete($editor), 'Editor should not be able to delete tag.'); + $this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.'); + $this->assertFalse($tag->canDelete($editor), 'Editor should not be able to delete tag.'); - $tag = $this->objFromFixture('BlogTag', 'ThirdTag'); + $tag = $this->objFromFixture('BlogTag', 'ThirdTag'); - $this->assertTrue($tag->canDelete($admin), 'Admin should always be able to delete tags.'); - $this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); - } + $this->assertTrue($tag->canDelete($admin), 'Admin should always be able to delete tags.'); + $this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); + } } diff --git a/tests/BlogTest.php b/tests/BlogTest.php index 860d93c..bfe63fb 100755 --- a/tests/BlogTest.php +++ b/tests/BlogTest.php @@ -3,332 +3,347 @@ /** * @mixin PHPUnit_Framework_TestCase */ -class BlogTest extends SapphireTest { - /** - * @var string - */ - static $fixture_file = 'blog.yml'; +class BlogTest extends SapphireTest +{ + /** + * @var string + */ + public static $fixture_file = 'blog.yml'; - /** - * {@inheritdoc} - */ - public function setUp() { - parent::setUp(); + /** + * {@inheritdoc} + */ + public function setUp() + { + parent::setUp(); - Config::nest(); - SS_Datetime::set_mock_now('2013-10-10 20:00:00'); + Config::nest(); + SS_Datetime::set_mock_now('2013-10-10 20:00:00'); - /** - * @var Blog $blog - */ - $blog = $this->objFromFixture('Blog', 'FirstBlog'); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - $blog->publish('Stage', 'Live'); - } + $blog->publish('Stage', 'Live'); + } - /** - * {@inheritdoc} - */ - public function tearDown() { - SS_Datetime::clear_mock_now(); - Config::unnest(); + /** + * {@inheritdoc} + */ + public function tearDown() + { + SS_Datetime::clear_mock_now(); + Config::unnest(); - parent::tearDown(); - } + parent::tearDown(); + } - public function testGetExcludedSiteTreeClassNames() { - $member = Member::currentUser(); + public function testGetExcludedSiteTreeClassNames() + { + $member = Member::currentUser(); - if($member) { - $member->logout(); - } + if ($member) { + $member->logout(); + } - /** - * @var Blog $blog - */ - $blog = $this->objFromFixture('Blog', 'FirstBlog'); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - Config::inst()->update('BlogPost', 'show_in_sitetree', true); - $classes = $blog->getExcludedSiteTreeClassNames(); + Config::inst()->update('BlogPost', 'show_in_sitetree', true); + $classes = $blog->getExcludedSiteTreeClassNames(); - $this->assertNotContains('BlogPost', $classes, 'BlogPost class should be hidden.'); + $this->assertNotContains('BlogPost', $classes, 'BlogPost class should be hidden.'); - Config::inst()->update('BlogPost', 'show_in_sitetree', false); - $classes = $blog->getExcludedSiteTreeClassNames(); + Config::inst()->update('BlogPost', 'show_in_sitetree', false); + $classes = $blog->getExcludedSiteTreeClassNames(); - $this->assertContains('BlogPost', $classes, 'BlogPost class should be hidden.'); - } + $this->assertContains('BlogPost', $classes, 'BlogPost class should be hidden.'); + } - public function testGetArchivedBlogPosts() { - $member = Member::currentUser(); + public function testGetArchivedBlogPosts() + { + $member = Member::currentUser(); - if($member) { - $member->logout(); - } + if ($member) { + $member->logout(); + } - /** - * @var Blog $blog - */ - $blog = $this->objFromFixture('Blog', 'FirstBlog'); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - $archive = $blog->getArchivedBlogPosts(2013); + $archive = $blog->getArchivedBlogPosts(2013); - $this->assertEquals(2, $archive->count(), 'Incorrect Yearly Archive count for 2013'); - $this->assertEquals('First Post', $archive->first()->Title, 'Incorrect First Blog post'); - $this->assertEquals('Second Post', $archive->last()->Title, 'Incorrect Last Blog post'); + $this->assertEquals(2, $archive->count(), 'Incorrect Yearly Archive count for 2013'); + $this->assertEquals('First Post', $archive->first()->Title, 'Incorrect First Blog post'); + $this->assertEquals('Second Post', $archive->last()->Title, 'Incorrect Last Blog post'); - $archive = $blog->getArchivedBlogPosts(2013, 10); + $archive = $blog->getArchivedBlogPosts(2013, 10); - $this->assertEquals(1, $archive->count(), 'Incorrect monthly archive count.'); + $this->assertEquals(1, $archive->count(), 'Incorrect monthly archive count.'); - $archive = $blog->getArchivedBlogPosts(2013, 10, 01); + $archive = $blog->getArchivedBlogPosts(2013, 10, 01); - $this->assertEquals(1, $archive->count(), 'Incorrect daily archive count.'); - } + $this->assertEquals(1, $archive->count(), 'Incorrect daily archive count.'); + } - public function testArchiveLinks() { - /** - * @var Blog $blog - */ - $blog = $this->objFromFixture('Blog', 'FirstBlog'); + public function testArchiveLinks() + { + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - $link = Controller::join_links($blog->Link('archive'), '2013', '10', '01'); + $link = Controller::join_links($blog->Link('archive'), '2013', '10', '01'); - $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - $link = Controller::join_links($blog->Link('archive'), '2013', '10'); + $link = Controller::join_links($blog->Link('archive'), '2013', '10'); - $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - $link = Controller::join_links($blog->Link('archive'), '2013'); + $link = Controller::join_links($blog->Link('archive'), '2013'); - $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - $link = Controller::join_links($blog->Link('archive'), '2011', '10', '01'); + $link = Controller::join_links($blog->Link('archive'), '2011', '10', '01'); - $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - $link = Controller::join_links($blog->Link('archive')); - $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); + $link = Controller::join_links($blog->Link('archive')); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - $link = Controller::join_links($blog->Link('archive'), 'invalid-year'); + $link = Controller::join_links($blog->Link('archive'), 'invalid-year'); - $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); - - $link = Controller::join_links($blog->Link('archive'), '2013', '99'); - - $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); - - $link = Controller::join_links($blog->Link('archive'), '2013', '10', '99'); - - $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); - - } - - /* - * Test archive year - */ - public function testArchiveYear(){ - $blog = $this->objFromFixture('Blog', 'FirstBlog'); - $controller = new Blog_Controller($blog); - $this->requestURL($controller, 'first-post/archive/'); - $this->assertEquals(2013, $controller->getArchiveYear(), 'getArchiveYear should return 2013'); - } - - /** - * @param string $link - * - * @return int - */ - protected function getStatusOf($link) { - return Director::test($link)->getStatusCode(); - } - - public function testRoles() { - /** - * @var Blog $firstBlog - */ - $firstBlog = $this->objFromFixture('Blog', 'FirstBlog'); - - /** - * @var Blog $fourthBlog - */ - $fourthBlog = $this->objFromFixture('Blog', 'FourthBlog'); - - /** - * @var BlogPost $postA - */ - $postA = $this->objFromFixture('BlogPost', 'PostA'); - - /** - * @var BlogPost $postB - */ - $postB = $this->objFromFixture('BlogPost', 'PostB'); - - /** - * @var BlogPost $postC - */ - $postC = $this->objFromFixture('BlogPost', 'PostC'); - - /** - * @var Member $editor - */ - $editor = $this->objFromFixture('Member', 'BlogEditor'); - - /** - * @var Member $writer - */ - $writer = $this->objFromFixture('Member', 'Writer'); - - /** - * @var Member $contributor - */ - $contributor = $this->objFromFixture('Member', 'Contributor'); - - /** - * @var Member $visitor - */ - $visitor = $this->objFromFixture('Member', 'Visitor'); - - $this->assertEquals('Editor', $fourthBlog->RoleOf($editor)); - $this->assertEquals('Contributor', $fourthBlog->RoleOf($contributor)); - $this->assertEquals('Writer', $fourthBlog->RoleOf($writer)); - $this->assertEmpty($fourthBlog->RoleOf($visitor)); - $this->assertEquals('Author', $postA->RoleOf($writer)); - $this->assertEquals('Author', $postA->RoleOf($contributor)); - $this->assertEquals('Editor', $postA->RoleOf($editor)); - $this->assertEmpty($postA->RoleOf($visitor)); - - // Test RoleOf with string values given - $this->assertEquals('Editor', $fourthBlog->RoleOf((string)(int)$editor->ID)); - $this->assertEquals('Contributor', $fourthBlog->RoleOf((string)(int)$contributor->ID)); - $this->assertEquals('Writer', $fourthBlog->RoleOf((string)(int)$writer->ID)); - $this->assertEmpty($fourthBlog->RoleOf((string)(int)$visitor->ID)); - $this->assertEquals('Author', $postA->RoleOf((string)(int)$writer->ID)); - $this->assertEquals('Author', $postA->RoleOf((string)(int)$contributor->ID)); - $this->assertEquals('Editor', $postA->RoleOf((string)(int)$editor->ID)); - $this->assertEmpty($postA->RoleOf((string)(int)$visitor->ID)); - - // Test RoleOf with int values given - $this->assertEquals('Editor', $fourthBlog->RoleOf((int)$editor->ID)); - $this->assertEquals('Contributor', $fourthBlog->RoleOf((int)$contributor->ID)); - $this->assertEquals('Writer', $fourthBlog->RoleOf((int)$writer->ID)); - $this->assertEmpty($fourthBlog->RoleOf((int)$visitor->ID)); - $this->assertEquals('Author', $postA->RoleOf((int)$writer->ID)); - $this->assertEquals('Author', $postA->RoleOf((int)$contributor->ID)); - $this->assertEquals('Editor', $postA->RoleOf((int)$editor->ID)); - $this->assertEmpty($postA->RoleOf((int)$visitor->ID)); - - $this->assertTrue($fourthBlog->canEdit($editor)); - $this->assertFalse($firstBlog->canEdit($editor)); - $this->assertTrue($fourthBlog->canAddChildren($editor)); - $this->assertFalse($firstBlog->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)); - - $this->assertFalse($fourthBlog->canEdit($writer)); - $this->assertFalse($firstBlog->canEdit($writer)); - $this->assertTrue($fourthBlog->canAddChildren($writer)); - $this->assertFalse($firstBlog->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)); - - $this->assertFalse($fourthBlog->canEdit($contributor)); - $this->assertFalse($firstBlog->canEdit($contributor)); - $this->assertTrue($fourthBlog->canAddChildren($contributor)); - $this->assertFalse($firstBlog->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)); - - $this->assertFalse($fourthBlog->canEdit($visitor)); - $this->assertFalse($firstBlog->canEdit($visitor)); - $this->assertFalse($fourthBlog->canAddChildren($visitor)); - $this->assertFalse($firstBlog->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)); - } - - public function testFilteredCategories() { - $blog = $this->objFromFixture('Blog', 'FirstBlog'); - $controller = new Blog_Controller($blog); - - // Root url - $this->requestURL($controller, 'first-post'); - $this->assertIDsEquals( - $blog->AllChildren()->column('ID'), - $controller->PaginatedList()->column('ID') - ); - - - // RSS - $this->requestURL($controller, 'first-post/rss'); - $this->assertIDsEquals( - $blog->AllChildren()->column('ID'), - $controller->PaginatedList()->column('ID') - ); - - // Posts - $firstPostID = $this->idFromFixture('BlogPost', 'FirstBlogPost'); - $secondPostID = $this->idFromFixture('BlogPost', 'SecondBlogPost'); - $firstFuturePostID = $this->idFromFixture('BlogPost', 'FirstFutureBlogPost'); - $secondFuturePostID = $this->idFromFixture('BlogPost', 'SecondFutureBlogPost'); - - // Request first tag - $this->requestURL($controller, 'first-post/tag/first-tag'); - $this->assertIDsEquals( - array($firstPostID, $firstFuturePostID, $secondFuturePostID), - $controller->PaginatedList() - ); - - // Request 2013 posts - $this->requestURL($controller, 'first-post/archive/2013'); - $this->assertIDsEquals( - array($firstPostID, $secondPostID, $secondFuturePostID), - $controller->PaginatedList() - ); - } - - /** - * Mock a request against a given controller - * - * @param ContentController $controller - * @param string $url - */ - protected function requestURL(ContentController $controller, $url) { - $request = new SS_HTTPRequest('get', $url); - $request->match('$URLSegment//$Action/$ID/$OtherID'); - $request->shift(); - $controller->init(); - $controller->handleRequest($request, new DataModel()); - } - - /** - * Assert these id lists match - * - * @param array|SS_List $left - * @param array|SS_List $right - */ - protected function assertIDsEquals($left, $right) { - if($left instanceof SS_List) $left = $left->column('ID'); - if($right instanceof SS_List) $right = $right->column('ID'); - asort($left); - asort($right); - $this->assertEquals(array_values($left), array_values($right)); - } + $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); + + $link = Controller::join_links($blog->Link('archive'), '2013', '99'); + + $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); + + $link = Controller::join_links($blog->Link('archive'), '2013', '10', '99'); + + $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); + } + + /* + * Test archive year + */ + public function testArchiveYear() + { + $blog = $this->objFromFixture('Blog', 'FirstBlog'); + $controller = new Blog_Controller($blog); + $this->requestURL($controller, 'first-post/archive/'); + $this->assertEquals(2013, $controller->getArchiveYear(), 'getArchiveYear should return 2013'); + } + + /** + * @param string $link + * + * @return int + */ + protected function getStatusOf($link) + { + return Director::test($link)->getStatusCode(); + } + + public function testRoles() + { + /** + * @var Blog $firstBlog + */ + $firstBlog = $this->objFromFixture('Blog', 'FirstBlog'); + + /** + * @var Blog $fourthBlog + */ + $fourthBlog = $this->objFromFixture('Blog', 'FourthBlog'); + + /** + * @var BlogPost $postA + */ + $postA = $this->objFromFixture('BlogPost', 'PostA'); + + /** + * @var BlogPost $postB + */ + $postB = $this->objFromFixture('BlogPost', 'PostB'); + + /** + * @var BlogPost $postC + */ + $postC = $this->objFromFixture('BlogPost', 'PostC'); + + /** + * @var Member $editor + */ + $editor = $this->objFromFixture('Member', 'BlogEditor'); + + /** + * @var Member $writer + */ + $writer = $this->objFromFixture('Member', 'Writer'); + + /** + * @var Member $contributor + */ + $contributor = $this->objFromFixture('Member', 'Contributor'); + + /** + * @var Member $visitor + */ + $visitor = $this->objFromFixture('Member', 'Visitor'); + + $this->assertEquals('Editor', $fourthBlog->RoleOf($editor)); + $this->assertEquals('Contributor', $fourthBlog->RoleOf($contributor)); + $this->assertEquals('Writer', $fourthBlog->RoleOf($writer)); + $this->assertEmpty($fourthBlog->RoleOf($visitor)); + $this->assertEquals('Author', $postA->RoleOf($writer)); + $this->assertEquals('Author', $postA->RoleOf($contributor)); + $this->assertEquals('Editor', $postA->RoleOf($editor)); + $this->assertEmpty($postA->RoleOf($visitor)); + + // Test RoleOf with string values given + $this->assertEquals('Editor', $fourthBlog->RoleOf((string)(int)$editor->ID)); + $this->assertEquals('Contributor', $fourthBlog->RoleOf((string)(int)$contributor->ID)); + $this->assertEquals('Writer', $fourthBlog->RoleOf((string)(int)$writer->ID)); + $this->assertEmpty($fourthBlog->RoleOf((string)(int)$visitor->ID)); + $this->assertEquals('Author', $postA->RoleOf((string)(int)$writer->ID)); + $this->assertEquals('Author', $postA->RoleOf((string)(int)$contributor->ID)); + $this->assertEquals('Editor', $postA->RoleOf((string)(int)$editor->ID)); + $this->assertEmpty($postA->RoleOf((string)(int)$visitor->ID)); + + // Test RoleOf with int values given + $this->assertEquals('Editor', $fourthBlog->RoleOf((int)$editor->ID)); + $this->assertEquals('Contributor', $fourthBlog->RoleOf((int)$contributor->ID)); + $this->assertEquals('Writer', $fourthBlog->RoleOf((int)$writer->ID)); + $this->assertEmpty($fourthBlog->RoleOf((int)$visitor->ID)); + $this->assertEquals('Author', $postA->RoleOf((int)$writer->ID)); + $this->assertEquals('Author', $postA->RoleOf((int)$contributor->ID)); + $this->assertEquals('Editor', $postA->RoleOf((int)$editor->ID)); + $this->assertEmpty($postA->RoleOf((int)$visitor->ID)); + + $this->assertTrue($fourthBlog->canEdit($editor)); + $this->assertFalse($firstBlog->canEdit($editor)); + $this->assertTrue($fourthBlog->canAddChildren($editor)); + $this->assertFalse($firstBlog->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)); + + $this->assertFalse($fourthBlog->canEdit($writer)); + $this->assertFalse($firstBlog->canEdit($writer)); + $this->assertTrue($fourthBlog->canAddChildren($writer)); + $this->assertFalse($firstBlog->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)); + + $this->assertFalse($fourthBlog->canEdit($contributor)); + $this->assertFalse($firstBlog->canEdit($contributor)); + $this->assertTrue($fourthBlog->canAddChildren($contributor)); + $this->assertFalse($firstBlog->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)); + + $this->assertFalse($fourthBlog->canEdit($visitor)); + $this->assertFalse($firstBlog->canEdit($visitor)); + $this->assertFalse($fourthBlog->canAddChildren($visitor)); + $this->assertFalse($firstBlog->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)); + } + + public function testFilteredCategories() + { + $blog = $this->objFromFixture('Blog', 'FirstBlog'); + $controller = new Blog_Controller($blog); + + // Root url + $this->requestURL($controller, 'first-post'); + $this->assertIDsEquals( + $blog->AllChildren()->column('ID'), + $controller->PaginatedList()->column('ID') + ); + + + // RSS + $this->requestURL($controller, 'first-post/rss'); + $this->assertIDsEquals( + $blog->AllChildren()->column('ID'), + $controller->PaginatedList()->column('ID') + ); + + // Posts + $firstPostID = $this->idFromFixture('BlogPost', 'FirstBlogPost'); + $secondPostID = $this->idFromFixture('BlogPost', 'SecondBlogPost'); + $firstFuturePostID = $this->idFromFixture('BlogPost', 'FirstFutureBlogPost'); + $secondFuturePostID = $this->idFromFixture('BlogPost', 'SecondFutureBlogPost'); + + // Request first tag + $this->requestURL($controller, 'first-post/tag/first-tag'); + $this->assertIDsEquals( + array($firstPostID, $firstFuturePostID, $secondFuturePostID), + $controller->PaginatedList() + ); + + // Request 2013 posts + $this->requestURL($controller, 'first-post/archive/2013'); + $this->assertIDsEquals( + array($firstPostID, $secondPostID, $secondFuturePostID), + $controller->PaginatedList() + ); + } + + /** + * Mock a request against a given controller + * + * @param ContentController $controller + * @param string $url + */ + protected function requestURL(ContentController $controller, $url) + { + $request = new SS_HTTPRequest('get', $url); + $request->match('$URLSegment//$Action/$ID/$OtherID'); + $request->shift(); + $controller->init(); + $controller->handleRequest($request, new DataModel()); + } + + /** + * Assert these id lists match + * + * @param array|SS_List $left + * @param array|SS_List $right + */ + protected function assertIDsEquals($left, $right) + { + if ($left instanceof SS_List) { + $left = $left->column('ID'); + } + if ($right instanceof SS_List) { + $right = $right->column('ID'); + } + asort($left); + asort($right); + $this->assertEquals(array_values($left), array_values($right)); + } }