From 787c02a19d2491ace59948630795e5bc6da40bf0 Mon Sep 17 00:00:00 2001 From: Christopher Pitt Date: Sun, 10 May 2015 02:33:12 +1200 Subject: [PATCH] Clean up --- code/admin/GridFieldCategorisationConfig.php | 9 +- code/admin/GridFieldFormAction.php | 3 +- code/admin/GridFieldMergeAction.php | 4 +- code/compat/pages/BlogEntry.php | 70 +- code/compat/pages/BlogHolder.php | 23 +- code/compat/pages/BlogTree.php | 17 +- code/compat/tasks/BlogMigrationTask.php | 74 +- code/compat/tasks/MigratableObject.php | 3 +- code/compat/widgets/ArchiveWidget.php | 36 +- code/compat/widgets/TagCloudWidget.php | 32 +- code/extensions/BlogCommentExtension.php | 18 +- code/extensions/BlogFilter.php | 89 +- code/extensions/BlogMemberExtension.php | 55 +- code/extensions/BlogPostFilter.php | 36 +- code/extensions/BlogPostNotifications.php | 17 +- code/extensions/URLSegmentExtension.php | 109 ++- code/forms/BlogAdminSidebar.php | 9 +- .../forms/gridfield/GridFieldAddByDBField.php | 193 ++-- .../gridfield/GridFieldBlogPostState.php | 85 +- .../gridfield/GridFieldConfig_BlogPost.php | 12 +- code/model/Blog.php | 887 ++++++++++-------- code/model/BlogCategory.php | 100 +- code/model/BlogPost.php | 587 +++++++----- code/model/BlogTag.php | 255 ++--- code/model/CategorisationObject.php | 8 + code/widgets/BlogArchiveWidget.php | 175 ++-- code/widgets/BlogCategoriesWidget.php | 81 +- code/widgets/BlogRecentPostsWidget.php | 97 +- code/widgets/BlogTagsWidget.php | 81 +- tests/BlogCategoryTest.php | 123 +-- tests/BlogPostFilterTest.php | 33 +- tests/BlogTagTest.php | 137 +-- tests/BlogTest.php | 243 +++-- tests/blog.yml | 154 ++- 34 files changed, 2249 insertions(+), 1606 deletions(-) create mode 100644 code/model/CategorisationObject.php diff --git a/code/admin/GridFieldCategorisationConfig.php b/code/admin/GridFieldCategorisationConfig.php index d629228..423a34e 100644 --- a/code/admin/GridFieldCategorisationConfig.php +++ b/code/admin/GridFieldCategorisationConfig.php @@ -11,20 +11,23 @@ class GridFieldCategorisationConfig extends GridFieldConfig_RecordEditor { public function __construct($itemsPerPage = 15, $mergeRecords, $parentType, $parentMethod, $childMethod) { parent::__construct($itemsPerPage); - $this->removeComponentsByType("GridFieldAddNewButton"); + $this->removeComponentsByType('GridFieldAddNewButton'); $this->addComponent( - new GridFieldAddByDBField("buttons-before-left") + new GridFieldAddByDBField('buttons-before-left') ); $this->addComponent( new GridFieldMergeAction($mergeRecords, $parentType, $parentMethod, $childMethod) ); + /** + * @var GridFieldDataColumns $columns + */ $columns = $this->getComponentByType('GridFieldDataColumns'); $columns->setFieldFormatting(array( - 'BlogPostsCount' => function($value, &$item) { + 'BlogPostsCount' => function ($value, CategorisationObject $item) { return $item->BlogPosts()->Count(); } )); diff --git a/code/admin/GridFieldFormAction.php b/code/admin/GridFieldFormAction.php index 1020fb3..6632722 100644 --- a/code/admin/GridFieldFormAction.php +++ b/code/admin/GridFieldFormAction.php @@ -16,8 +16,7 @@ class GridFieldFormAction extends GridField_FormAction { /** * @return array */ - public function getAttributes() - { + public function getAttributes() { $attributes = parent::getAttributes(); return array_merge( diff --git a/code/admin/GridFieldMergeAction.php b/code/admin/GridFieldMergeAction.php index 6901609..073d44f 100644 --- a/code/admin/GridFieldMergeAction.php +++ b/code/admin/GridFieldMergeAction.php @@ -66,7 +66,7 @@ class GridFieldMergeAction implements GridField_ColumnProvider, GridField_Action 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()); - + $prefix = strtolower($this->parentMethod . '-' . $this->childMethod); $action = GridFieldFormAction::create( @@ -129,7 +129,7 @@ class GridFieldMergeAction implements GridField_ColumnProvider, GridField_Action $posts = $fromParent->{$this->childMethod}(); - foreach ($posts as $post) { + foreach($posts as $post) { $relationship = $post->{$this->parentMethod}(); $relationship->remove($fromParent); diff --git a/code/compat/pages/BlogEntry.php b/code/compat/pages/BlogEntry.php index 1d78954..a80a7bf 100644 --- a/code/compat/pages/BlogEntry.php +++ b/code/compat/pages/BlogEntry.php @@ -2,59 +2,82 @@ /** * @deprecated since version 2.0 + * + * @property int $ParentID + * @property string $Date + * @property string $PublishDate + * @property string $Tags */ 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" + 'Date' => 'SS_Datetime', + 'Author' => 'Text', + 'Tags' => 'Text', ); /** - * Safely split and parse all distinct tags assigned to this BlogEntry - * - * @return array Associative array of lowercase tag to native case tags - * @deprecated since version 2.0 + * {@inheritdoc} */ - public function TagNames() { - $tags = preg_split("/\s*,\s*/", trim($this->Tags)); - $results = array(); - foreach($tags as $tag) { - if($tag) $results[mb_strtolower($tag)] = $tag; - } - return $results; - } - public function canCreate($member = null) { - // Deprecated return false; } + /** + * {@inheritdoc} + */ public function up() { - // Migrate tags foreach($this->TagNames() as $tag) { - // Skip if tag already assigned - if($this->Tags()->filter('Title', $tag)->count()) continue; + if($this->Tags()->filter('Title', $tag)->count()) { + continue; + } - // Create tag $tagObject = new BlogTag(); $tagObject->Title = $tag; $tagObject->BlogID = $this->ParentID; + $tagObject->write(); + $this->Tags()->add($tagObject); } - // Update fields $this->PublishDate = $this->Date; + if($this->ClassName === 'BlogEntry') { $this->ClassName = 'BlogPost'; $this->write(); } } + /** + * 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(); + + foreach($tags as $tag) { + if($tag) $results[mb_strtolower($tag)] = $tag; + } + + return $results; + } + + /** + * {@inheritdoc} + */ public function requireDefaultRecords() { parent::requireDefaultRecords(); @@ -69,4 +92,5 @@ class BlogEntry extends BlogPost implements MigratableObject { * @deprecated since version 2.0 */ class BlogEntry_Controller extends BlogPost_Controller { + } diff --git a/code/compat/pages/BlogHolder.php b/code/compat/pages/BlogHolder.php index a3cd43e..714d7ad 100644 --- a/code/compat/pages/BlogHolder.php +++ b/code/compat/pages/BlogHolder.php @@ -4,23 +4,36 @@ * @deprecated since version 2.0 */ 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 $has_one = array( 'Owner' => 'Member', ); + /** + * {@inheritdoc} + */ public function canCreate($member = null) { - // Deprecated return false; } + /** + * {@inheritdoc} + */ public function up() { if($this->ClassName === 'BlogHolder') { $this->ClassName = 'Blog'; @@ -33,5 +46,5 @@ class BlogHolder extends BlogTree implements MigratableObject { * @deprecated since version 2.0 */ class BlogHolder_Controller extends BlogTree_Controller { - -} \ No newline at end of file + +} diff --git a/code/compat/pages/BlogTree.php b/code/compat/pages/BlogTree.php index 0c29d67..f62b026 100644 --- a/code/compat/pages/BlogTree.php +++ b/code/compat/pages/BlogTree.php @@ -4,19 +4,29 @@ * @deprecated since version 2.0 */ class BlogTree extends Page implements MigratableObject { - + /** + * @var string + */ private static $hide_ancestor = 'BlogTree'; + /** + * @var array + */ private static $db = array( 'Name' => 'Varchar(255)', 'LandingPageFreshness' => 'Varchar', ); + /** + * {@inheritdoc} + */ public function canCreate($member = null) { - // Deprecated return false; } + /** + * {@inheritdoc} + */ public function up() { if($this->ClassName === 'BlogTree') { $this->ClassName = 'Page'; @@ -29,4 +39,5 @@ class BlogTree extends Page implements MigratableObject { * @deprecated since version 2.0 */ class BlogTree_Controller extends Page_Controller { -} \ No newline at end of file + +} diff --git a/code/compat/tasks/BlogMigrationTask.php b/code/compat/tasks/BlogMigrationTask.php index 4e786e5..fd636a3 100644 --- a/code/compat/tasks/BlogMigrationTask.php +++ b/code/compat/tasks/BlogMigrationTask.php @@ -1,34 +1,24 @@ message('Migrating legacy blog records'); foreach($classes as $class) { - // migrate objects in each stage if(is_subclass_of($class, 'SiteTree')) { foreach(array('Stage', 'Live') as $stage) { $oldMode = Versioned::get_reading_mode(); @@ -37,40 +27,66 @@ class BlogMigrationTask extends MigrationTask { Versioned::set_reading_mode($oldMode); } } else { - // Migrate object $this->upClass($class); } } } - public function down() { - $this->message('BlogMigrationTask::down() not implemented'); + /** + * @param string $text + */ + protected function message($text) { + if(Controller::curr() instanceof DatabaseAdmin) { + DB::alteration_message($text, 'obsolete'); + } else { + Debug::message($text); + } } /** * Migrate records of a single class * - * @param type $class - * @param type $stage + * @param string $class + * @param null|string $stage */ protected function upClass($class, $stage = null) { - if(!class_exists($class)) return; + if(!class_exists($class)) { + return; + } - // Migrate all records $items = $class::get(); if($count = $items->count()) { - $stageMessage = " in stage {$stage}"; - $this->message("Migrating {$count} legacy {$class} records{$stageMessage}."); + $this->message( + sprintf( + 'Migrating %s legacy %s records in stage %s.', + $count, + $class, + $stage + ) + ); + foreach($items as $item) { - // Cancel if onBeforeUp returns false $cancel = $item->extend('onBeforeUp'); - if($cancel && min($cancel) === false) continue; - // Up + + if($cancel && min($cancel) === false) { + continue; + } + + /** + * @var MigratableObject $item + */ $item->up(); - // Post extensions + $item->extend('onAfterUp'); } } } + + /** + * {@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 7870c04..59af4ae 100644 --- a/code/compat/tasks/MigratableObject.php +++ b/code/compat/tasks/MigratableObject.php @@ -1,9 +1,8 @@ 'Varchar' + 'DisplayMode' => 'Varchar', ); - private static $only_available_in = array('none'); + /** + * @var array + */ + private static $only_available_in = array( + 'none', + ); + /** + * {@inheritdoc} + */ public function canCreate($member = null) { - // Deprecated return false; } - + + /** + * {@inheritdoc} + */ public function up() { if($this->DisplayMode) { - $this->ArchiveType = ($this->DisplayMode === 'year') ? 'Yearly' : 'Monthly'; + $this->ArchiveType = 'Monthly'; + + if($this->DisplayMode === 'year') { + $this->ArchiveType = 'Yearly'; + } } + $this->ClassName = 'BlogArchiveWidget'; $this->write(); } diff --git a/code/compat/widgets/TagCloudWidget.php b/code/compat/widgets/TagCloudWidget.php index cf9d55a..7ee3d57 100644 --- a/code/compat/widgets/TagCloudWidget.php +++ b/code/compat/widgets/TagCloudWidget.php @@ -1,29 +1,43 @@ "Varchar", - "Limit" => "Int", - "Sortby" => "Varchar" + 'Title' => 'Varchar', + 'Limit' => 'Int', + 'Sortby' => 'Varchar', ); - private static $only_available_in = array('none'); + /** + * @var array + */ + private static $only_available_in = array( + 'none', + ); + /** + * {@inheritdoc} + */ public function canCreate($member = null) { - // Deprecated return false; } + /** + * {@inheritdoc} + */ public function up() { $this->ClassName = 'BlogTagsWidget'; $this->write(); } -} \ No newline at end of file +} diff --git a/code/extensions/BlogCommentExtension.php b/code/extensions/BlogCommentExtension.php index 8b2db4a..7431e4d 100644 --- a/code/extensions/BlogCommentExtension.php +++ b/code/extensions/BlogCommentExtension.php @@ -1,23 +1,23 @@ owner->getParent(); - - // Make sure we're dealing with a BlogPost. - if ( ($blogPost instanceof BlogPost) - && $blogPost->isAuthor($this->owner->Author()) - ) { - return 'author-comment'; + + if($blogPost instanceof BlogPost) { + if($blogPost->isAuthor($this->owner->Author())) { + return 'author-comment'; + } } + + return ''; } } diff --git a/code/extensions/BlogFilter.php b/code/extensions/BlogFilter.php index 0aa04f0..b7e9781 100644 --- a/code/extensions/BlogFilter.php +++ b/code/extensions/BlogFilter.php @@ -1,89 +1,106 @@ - * - **/ + */ class BlogFilter extends Lumberjack { - /** - * Augments (@link Hierarchy::stageChildren()} - * - * @param $staged DataList - * @param $showAll boolean - **/ + * {@inheritdoc} + */ public function stageChildren($showAll = false) { $staged = parent::stageChildren($showAll); - if(!$this->shouldFilter() - && in_array(get_class($this->owner), ClassInfo::subClassesFor("Blog")) - && !Permission::check("VIEW_DRAFT_CONTENT") - ) { - - // Get the current stage. + if(!$this->shouldFilter() && $this->subclassForBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { $stage = Versioned::current_stage(); - if($stage == "Stage") $stage = ""; - elseif($stage) $stage = "_{$stage}"; - // Filter published posts + if($stage == 'Stage') { + $stage = ''; + } elseif($stage) { + $stage = '_' . $stage; + } + $dataQuery = $staged->dataQuery() - ->innerJoin("BlogPost", '"BlogPost' . $stage . '"."ID" = "SiteTree' . $stage . '"."ID"') - ->where('"PublishDate" < \'' . Convert::raw2sql(SS_Datetime::now()) . '\''); + ->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->owner instanceof Blog - && !Permission::check("VIEW_DRAFT_CONTENT") - ) { - // Filter publish posts + if(!$this->shouldFilter() && $this->isBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { $dataQuery = $staged->dataQuery() - ->innerJoin("BlogPost", '"BlogPost_Live"."ID" = "SiteTree_Live"."ID"') - ->where('"BlogPost"."PublishDate" < \'' . Convert::raw2sql(SS_Datetime::now()->getValue()) . '\''); + ->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 = SiteTree::get()->filter(array( 'ParentID' => $this->owner->ID, 'ClassName' => $excluded - ))->sort('"SiteTree"."Created" DESC'); + ))->sort('SiteTree.Created DESC'); + $gridField = new BlogFilter_GridField( - "ChildPages", + '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 + * Enables children of non-editable pages to be edited. */ class BlogFilter_GridField extends GridField { - public function transform(FormTransformation $trans) { - // Don't allow parent object transformations to propegate automatically to child records + /** + * @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 8c33ba0..04507f2 100644 --- a/code/extensions/BlogMemberExtension.php +++ b/code/extensions/BlogMemberExtension.php @@ -5,25 +5,34 @@ * * @package silverstripe * @subpackage blog - * - **/ + */ class BlogMemberExtension extends DataExtension { - + /** + * @var array + */ private static $db = array( 'URLSegment' => 'Varchar', - 'BlogProfileSummary' => 'Text' + 'BlogProfileSummary' => 'Text', ); + /** + * @var array + */ private static $has_one = array( - 'BlogProfileImage' => 'Image' + 'BlogProfileImage' => 'Image', ); + /** + * @var array + */ private static $belongs_many_many = array( - 'AuthoredPosts' => 'BlogPost' + 'AuthoredPosts' => 'BlogPost', ); + /** + * {@inheritdoc} + */ public function onBeforeWrite() { - // Generate a unique URL segment for the Member. $count = 1; $this->owner->URLSegment = $this->generateURLSegment(); @@ -34,45 +43,45 @@ class BlogMemberExtension extends DataExtension { } } - public function updateCMSFields(FieldList $fields) { - $fields->removeByName('URLSegment'); - - return $fields; - } - /** * Generate a unique URL segment based on the Member's name. - * - * @return string Generated URL segment. + * + * @return string */ public function generateURLSegment() { $filter = URLSegmentFilter::create(); $name = $this->owner->FirstName . ' ' . $this->owner->Surname; $urlSegment = $filter->filter($name); - // Fallback to generic profile name if path is empty (= no valid, convertable characters) if(!$urlSegment || $urlSegment == '-' || $urlSegment == '-1') { - $urlSegment = "profile-".$this->owner->ID; + $urlSegment = 'profile-' . $this->owner->ID; } return $urlSegment; } /** - * Returns TRUE if this object has a URL segment value that does not conflict with any other objects. - * + * Returns TRUE if this object has a URL segment value that does not conflict with any other + * objects. + * * @return bool */ - public function validURLSegment() { + public function validURLSegment() { $conflict = Member::get()->filter('URLSegment', $this->owner->URLSegment); - // If the Member we're checking against is saved, exclude them from the check. - // i.e. don't conflict against yourself. - if ($this->owner->ID) { + if($this->owner->ID) { $conflict = $conflict->exclude('ID', $this->owner->ID); } return $conflict->count() == 0; } + /** + * {@inheritdoc} + */ + public function updateCMSFields(FieldList $fields) { + $fields->removeByName('URLSegment'); + + return $fields; + } } diff --git a/code/extensions/BlogPostFilter.php b/code/extensions/BlogPostFilter.php index 79d64d3..d71e62a 100644 --- a/code/extensions/BlogPostFilter.php +++ b/code/extensions/BlogPostFilter.php @@ -1,36 +1,38 @@ -**/ + */ class BlogPostFilter extends DataExtension { - /** * Augment queries so that we don't fetch unpublished articles. - **/ + * + * @param SQLQuery $query + */ public function augmentSQL(SQLQuery &$query) { $stage = Versioned::current_stage(); - if($stage == 'Live' || !Permission::check("VIEW_DRAFT_CONTENT")) { - $query->addWhere("PublishDate < '" . Convert::raw2sql(SS_Datetime::now()) . "'"); + + if($stage == 'Live' || !Permission::check('VIEW_DRAFT_CONTENT')) { + $query->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. + * 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) { - // Ensures that we're joining the BlogPost table which holds required db fields. - $dataQuery->innerJoin("BlogPost", "`SiteTree`.`ID` = `BlogPost`.`ID`"); + $dataQuery->innerJoin('BlogPost', 'SiteTree.ID = BlogPost.ID'); } - -} \ No newline at end of file +} diff --git a/code/extensions/BlogPostNotifications.php b/code/extensions/BlogPostNotifications.php index 66757b1..0d4d8ee 100644 --- a/code/extensions/BlogPostNotifications.php +++ b/code/extensions/BlogPostNotifications.php @@ -1,30 +1,29 @@ owner->Authors(); } /** - * Update comment to include the page 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 = "A new comment has been posted on " . $this->owner->Title; + $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 83f148e..f6f6105 100644 --- a/code/extensions/URLSegmentExtension.php +++ b/code/extensions/URLSegmentExtension.php @@ -1,48 +1,61 @@ - -**/ -class URLSegmentExtension extends DataExtension { - - private static $db = array( - "URLSegment" => "Varchar(255)" - ); - - public function onBeforeWrite() { - $this->owner->generateURLSegment(); - } - - - - /** - * Generates a unique URLSegment from the title. - * - * @param $increment - * - * @return string URLSegment - **/ - public function generateURLSegment($increment = null) { - $filter = new URLSegmentFilter(); - $this->owner->URLSegment = $filter->filter($this->owner->Title); - if(is_int($increment)) $this->owner->URLSegment .= '-' . $increment; - - // Check to see if the URLSegment already exists - $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($duplicate->count() > 0) { - $increment = is_int($increment) ? $increment + 1 : 0; - $this->owner->generateURLSegment((int) $increment); - } - return $this->owner->URLSegment; - } - -} \ No newline at end of file + 'Varchar(255)', + ); + + /** + * {@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(); + + $this->owner->URLSegment = $filter->filter($this->owner->Title); + + if(is_int($increment)) { + $this->owner->URLSegment .= '-' . $increment; + } + + $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($duplicate->count() > 0) { + if(is_int($increment)) { + $increment += 1; + } else { + $increment = 0; + } + + $this->owner->generateURLSegment((int) $increment); + } + + return $this->owner->URLSegment; + } +} diff --git a/code/forms/BlogAdminSidebar.php b/code/forms/BlogAdminSidebar.php index 3c506b4..ea812a3 100644 --- a/code/forms/BlogAdminSidebar.php +++ b/code/forms/BlogAdminSidebar.php @@ -1,13 +1,16 @@ -**/ + */ class GridFieldAddByDBField implements GridField_ActionProvider, GridField_HTMLProvider { - /** * HTML Fragment to render the field. * * @var string - **/ + */ protected $targetFragment; - - /** - * Default field to create the dataobject by should be Title. + * Default field to create the DataObject by should be Title. * * @var string - **/ - protected $dataObjectField = "Title"; - - + */ + protected $dataObjectField = 'Title'; /** * Creates a text field and add button which allows the user to directly create a new * DataObject by just entering the title. * - * @param $targetFragment string - **/ - public function __construct($targetFragment = 'before', $dataObjectField = "Title") { + * @param string $targetFragment + * @param string $dataObjectField + */ + public function __construct($targetFragment = 'before', $dataObjectField = 'Title') { $this->targetFragment = $targetFragment; $this->dataObjectField = (string) $dataObjectField; } - - /** * Provide actions to this component. * - * @param $gridField GridField + * @param GridField $gridField * * @return array - **/ + */ public function getActions($gridField) { - return array("add"); + return array( + 'add', + ); } - - /** - * Handles the add action for the given DataObject + * Handles the add action for the given DataObject. * - * @param $gridFIeld GridFIeld + * @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") { + if($actionName == 'add') { $dbField = $this->getDataObjectField(); $objClass = $gridField->getModelClass(); + $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" + $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.", + 'GridFieldAddByDBField.PermissionFail', + 'You don\'t have permission to create a {class}.', + 'Unable to add the DataObject.', array( - "class" => get_class($obj) + 'class' => get_class($obj) ) ) ); } } else { - throw new UnexpectedValueException("Invalid field (" . $dbField . ") on " . $obj->ClassName . "."); + throw new UnexpectedValueException( + sprintf( + 'Invalid field (%s) on %s.', + $dbField, + $obj->ClassName + ) + ); } } + + return null; } - - - /** - * Renders the TextField and add button to the GridField. - * - * @param $girdField GridField - * - * @return string HTML - **/ - public function getHTMLFragments($gridField) { - $dataClass = $gridField->getList()->dataClass(); - $obj = singleton($dataClass); - if(!$obj->canCreate()) return ""; - - $dbField = $this->getDataObjectField(); - - $textField = TextField::create( - "gridfieldaddbydbfield[" . $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'); - - // Start thinking about rending this back to the GF - $forTemplate = new ArrayData(array()); - $forTemplate->Fields = new ArrayList(); - - $forTemplate->Fields->push($textField); - $forTemplate->Fields->push($addAction); - - return array( - $this->targetFragment => $forTemplate->renderWith("GridFieldAddByDBField") - ); - } - - - /** * 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; } -} \ No newline at end of file + /** + * Renders the TextField and add button to the GridField. + * + * @param $gridField GridField + * + * @return string + */ + public function getHTMLFragments($gridField) { + $dataClass = $gridField->getList()->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 c4af614..dde0a05 100644 --- a/code/forms/gridfield/GridFieldBlogPostState.php +++ b/code/forms/gridfield/GridFieldBlogPostState.php @@ -1,74 +1,85 @@ - **/ + */ class GridFieldBlogPostState extends GridFieldSiteTreeState { - + /** + * {@inheritdoc} + */ public function getColumnContent($gridField, $record, $columnName) { - if($columnName == "State") { + if($columnName == 'State') { Requirements::css(BLOGGER_DIR . '/css/cms.css'); - if($record->hasMethod("isPublished")) { - $modifiedLabel = ""; + if($record->hasMethod('isPublished')) { + $modifiedLabel = ''; + if($record->isModifiedOnStage) { - $modifiedLabel = "" . _t("GridFieldBlogPostState.Modified") . ""; + $modifiedLabel = '' . _t('GridFieldBlogPostState.Modified') . ''; } - $published = $record->isPublished(); - if(!$published) { + if(!$record->isPublished()) { return _t( - "GridFieldBlogPostState.Draft", + 'GridFieldBlogPostState.Draft', ' Saved as Draft on {date}', - "State for when a post is saved.", + 'State for when a post is saved.', array( - "date" => $record->dbObject("LastEdited")->Nice() + 'date' => $record->dbObject('LastEdited')->Nice(), ) ); - } else if (strtotime($record->PublishDate) > time()) { + } + + if(strtotime($record->PublishDate) > time()) { return _t( - "GridFieldBlogPostState.Timer", + 'GridFieldBlogPostState.Timer', ' Publish at {date}', - "State for when a post is published.", + 'State for when a post is published.', array( - "date" => $record->dbObject("PublishDate")->Nice() - ) - ) . $modifiedLabel; - } else { - return _t( - "GridFieldBlogPostState.Published", - ' Published on {date}', - "State for when a post is published.", - array( - "date" => $record->dbObject("PublishDate")->Nice() + 'date' => $record->dbObject('PublishDate')->Nice(), ) ) . $modifiedLabel; } + + return _t( + 'GridFieldBlogPostState.Published', + ' Published on {date}', + 'State for when a post is published.', + array( + 'date' => $record->dbObject('PublishDate')->Nice(), + ) + ) . $modifiedLabel; } } + + return ''; } + /** + * {@inheritdoc} + */ public function getColumnAttributes($gridField, $record, $columnName) { - if($columnName == "State") { - if($record->hasMethod("isPublished")) { + if($columnName == 'State') { + if($record->hasMethod('isPublished')) { $published = $record->isPublished(); + if(!$published) { - $class = "gridfield-icon draft"; - } else if (strtotime($record->PublishDate) > time()) { - $class = "gridfield-icon timer"; + $class = 'gridfield-icon draft'; + } else if(strtotime($record->PublishDate) > time()) { + $class = 'gridfield-icon timer'; } else { - $class = "gridfield-icon published"; + $class = 'gridfield-icon published'; } - return array("class" => $class); + + return array( + 'class' => $class, + ); } } + return array(); } - -} \ No newline at end of file +} diff --git a/code/forms/gridfield/GridFieldConfig_BlogPost.php b/code/forms/gridfield/GridFieldConfig_BlogPost.php index 776449c..9383559 100644 --- a/code/forms/gridfield/GridFieldConfig_BlogPost.php +++ b/code/forms/gridfield/GridFieldConfig_BlogPost.php @@ -5,15 +5,15 @@ * * @package silverstripe * @subpackage blog - * - * @author Michael Strong -**/ + */ class GridFieldConfig_BlogPost extends GridFieldConfig_Lumberjack { - + /** + * @param null|int $itemsPerPage + */ public function __construct($itemsPerPage = null) { parent::__construct($itemsPerPage); + $this->removeComponentsByType('GridFieldSiteTreeState'); $this->addComponent(new GridFieldBlogPostState()); } - -} \ No newline at end of file +} diff --git a/code/model/Blog.php b/code/model/Blog.php index 9c5ad90..68b2271 100644 --- a/code/model/Blog.php +++ b/code/model/Blog.php @@ -11,73 +11,97 @@ * @method ManyManyList Editors() List of editors * @method ManyManyList Writers() List of writers * @method ManyManyList Contributors() List of contributors - * - * @author Michael Strong - **/ + */ class Blog extends Page implements PermissionProvider { - /** - * Permission for user management + * Permission for user management. * * @var string */ const MANAGE_USERS = 'BLOG_MANAGE_USERS'; /** - * If true, users assigned as editor, writer, or contributor will be automatically - * granted CMS_ACCESS_CMSMain permission. If false, only users with this permission - * already may be assigned. + * If true, users assigned as editor, writer, or contributor will be automatically granted + * CMS_ACCESS_CMSMain permission. If false, only users with this permission already may be + * assigned. + * + * @config * * @var boolean - * @config */ private static $grant_user_access = true; /** - * Permission to either require, or grant to users assigned to work on this blog + * Permission to either require, or grant to users assigned to work on this blog. + * + * @config * * @var string - * @config */ private static $grant_user_permission = 'CMS_ACCESS_CMSMain'; /** - * Group code to assign newly granted users toh + * Group code to assign newly granted users to. + * + * @config * * @var string - * @config */ private static $grant_user_group = 'blog-users'; + /** + * @var array + */ private static $db = array( - "PostsPerPage" => "Int", + 'PostsPerPage' => 'Int', ); + /** + * @var array + */ private static $has_many = array( - "Tags" => "BlogTag", - "Categories" => "BlogCategory", + '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", + 'BlogPost', ); + /** + * @var array + */ private static $extensions = array( - "BlogFilter", + 'BlogFilter', ); + /** + * @var array + */ private static $defaults = array( - "ProvideComments" => false, + 'ProvideComments' => false, ); + /** + * @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'); @@ -90,183 +114,163 @@ class Blog extends Page implements PermissionProvider { } $categories = GridField::create( - "Categories", - _t("Blog.Categories", "Categories"), + 'Categories', + _t('Blog.Categories', 'Categories'), $self->Categories(), GridFieldCategorisationConfig::create(15, $self->Categories(), 'BlogCategory', 'Categories', 'BlogPosts') ); $tags = GridField::create( - "Tags", - _t("Blog.Tags", "Tags"), + 'Tags', + _t('Blog.Tags', 'Tags'), $self->Tags(), GridFieldCategorisationConfig::create(15, $self->Tags(), 'BlogTag', 'Tags', 'BlogPosts') ); - $fields->addFieldsToTab("Root.Categorisation", array( + $fields->addFieldsToTab('Root.Categorisation', array( $categories, $tags )); - $fields->findOrMakeTab("Root.Categorisation")->addExtraClass('blog-cms-categorisation'); + + $fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation'); }); - $fields = parent::getCMSFields(); - - return $fields; + return parent::getCMSFields(); } /** - * Check if this member is an editor of the blog - * - * @param Member $member - * - * @return boolean + * {@inheritdoc} */ - public function isEditor($member) { - $isEditor = $this->isMemberOf($member, $this->Editors()); - $this->extend('updateIsEditor', $isEditor, $member); - return $isEditor; - } - - /** - * Check if this member is a writer of the blog - * - * @param Member $member - * - * @return boolean - */ - public function isWriter($member) { - $isWriter = $this->isMemberOf($member, $this->Writers()); - $this->extend('updateIsWriter', $isWriter, $member); - return $isWriter; - } - - /** - * Check if this member is a contributor of the blog - * - * @param Member $member - * - * @return boolean - */ - public function isContributor($member) { - $isContributor = $this->isMemberOf($member, $this->Contributors()); - $this->extend('updateIsContributor', $isContributor, $member); - return $isContributor; - } - - /** - * Determine the role of the given member - * Call be called via template to determine the current user - * - * E.g. `Hello $RoleOf($CurrentMember.ID)` - * - * @param Member|integer $member - * - * @return string|null Author, Editor, Writer, Contributor, or null if no role - */ - public function RoleOf($member) { - if(is_numeric($member)) $member = DataObject::get_by_id('Member', $member); - if(!$member) return null; - - // Check each role - 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'); - } - - /** - * Determine if the given member belongs to the given subrelation - * - * @param Member $member - * @param DataList $list Relation to check - * - * @return boolean - */ - protected function isMemberOf($member, $list) { - if(!$member || !$member->exists()) return false; - - if($list instanceof UnsavedRelationList) { - return in_array($member->ID, $list->getIDList()); - } - - return $list->byID($member->ID) !== null; - } - - public function canEdit($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + $member = $this->getMember($member); - // Allow editors to edit this page - if($this->isEditor($member)) return true; + if($this->isEditor($member)) { + return true; + } return parent::canEdit($member); } /** - * Determine if this user can edit the editors list + * @param null|int|Member $member * - * @param Member $member - * - * @return boolean + * @return null|Member */ - public function canEditEditors($member = null) { - $member = $member ?: Member::currentUser(); + protected function getMember($member = null) { + if(!$member) { + $member = Member::currentUser(); + } - $extended = $this->extendedCan('canEditEditors', $member); - if($extended !== null) return $extended; + if(is_int($member)) { + $member = Member::get()->byID($member); + } - // Check permission - return Permission::checkMember($member, self::MANAGE_USERS); + return $member; } /** - * Determine if this user can edit writers list + * Check if this member is an editor of the blog. * * @param Member $member * - * @return boolean + * @return bool */ - public function canEditWriters($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + public function isEditor($member) { + $isEditor = $this->isMemberOf($member, $this->Editors()); + $this->extend('updateIsEditor', $isEditor, $member); - $extended = $this->extendedCan('canEditWriters', $member); - if($extended !== null) return $extended; - - // Editors can edit writers - if($this->isEditor($member)) return true; - - // Check permission - return Permission::checkMember($member, self::MANAGE_USERS); + return $isEditor; } /** - * Determines if this user can edit the contributors list + * Determine if the given member belongs to the given relation. * - * @param type $member + * @param Member $member + * @param DataList $relation * - * @return boolean + * @return bool */ - public function canEditContributors($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + protected function isMemberOf($member, $relation) { + if(!$member || !$member->exists()) { + return false; + } - $extended = $this->extendedCan('canEditContributors', $member); - if($extended !== null) return $extended; + if($relation instanceof UnsavedRelationList) { + return in_array($member->ID, $relation->getIDList()); + } - // Editors can edit writers - if($this->isEditor($member)) return true; - - // Check permission - return Permission::checkMember($member, self::MANAGE_USERS); + 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 = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + $member = $this->getMember($member); - // Editors, Writers and Contributors can add children if($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) { return true; } @@ -274,17 +278,18 @@ class Blog extends Page implements PermissionProvider { return parent::canAddChildren($member); } - + /** + * {@inheritdoc} + */ public function getSettingsFields() { $fields = parent::getSettingsFields(); - $fields->addFieldToTab("Root.Settings", - NumericField::create("PostsPerPage", _t("Blog.PostsPerPage", "Posts Per Page")) + + $fields->addFieldToTab('Root.Settings', + NumericField::create('PostsPerPage', _t('Blog.PostsPerPage', 'Posts Per Page')) ); - // Roles and Permissions $members = $this->getCandidateUsers()->map()->toArray(); - // Editors $editorField = ListboxField::create('Editors', 'Editors', $members) ->setMultiple(true) ->setRightTitle('help') @@ -304,7 +309,6 @@ class Blog extends Page implements PermissionProvider { $editorField = $editorField->performDisabledTransformation(); } - // Writers $writerField = ListboxField::create('Writers', 'Writers', $members) ->setMultiple(true) ->setRightTitle('help') @@ -321,7 +325,6 @@ class Blog extends Page implements PermissionProvider { $writerField = $writerField->performDisabledTransformation(); } - // Contributors $contributorField = ListboxField::create('Contributors', 'Contributors', $members) ->setMultiple(true) ->setRightTitle('help') @@ -346,62 +349,145 @@ class Blog extends Page implements PermissionProvider { return $fields; } - /** - * Return blog posts + * Gets the list of user candidates to be assigned to assist with this blog. * - * @return DataList of BlogPost objects - **/ - public function getBlogPosts() { - $blogPosts = BlogPost::get()->filter("ParentID", $this->ID); - //Allow decorators to manipulate list - $this->extend('updateGetBlogPosts', $blogPosts); - return $blogPosts; + * @return SS_List + */ + protected function getCandidateUsers() { + if($this->config()->grant_user_access) { + return Member::get(); + } 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); + } /** - * Returns blogs posts for a given date period. + * Determine if this user can edit writers list. * - * @param $year int - * @param $month int - * @param $day int + * @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 = '_' . Convert::raw2sql($stage); + $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))); - $query->innerJoin("BlogPost", "`SiteTree" . $stage . "`.`ID` = `BlogPost" . $stage . "`.`ID`"); - $query->where("YEAR(PublishDate) = '" . Convert::raw2sql($year) . "'"); if($month) { - $query->where("MONTH(PublishDate) = '" . Convert::raw2sql($month) . "'"); + $query->where(sprintf('MONTH(PublishDate) = \'%s\'', Convert::raw2sql($month))); + if($day) { - $query->where("DAY(PublishDate) = '" . Convert::raw2sql($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 urlSegment + * @param string $urlSegment * - * @return String + * @return string */ public function ProfileLink($urlSegment) { return Controller::join_links($this->Link(), 'profile', $urlSegment); } - /** - * This sets the title for our gridfield + * This sets the title for our gridfield. * * @return string */ @@ -409,7 +495,6 @@ class Blog extends Page implements PermissionProvider { return _t('Blog.LumberjackTitle', 'Blog Posts'); } - /** * This overwrites lumberjacks default gridfield config. * @@ -419,6 +504,9 @@ class Blog extends Page implements PermissionProvider { return GridFieldConfig_BlogPost::create(); } + /** + * {@inheritdoc} + */ public function providePermissions() { return array( Blog::MANAGE_USERS => array( @@ -437,112 +525,109 @@ class Blog extends Page implements PermissionProvider { } /** - * Gets the list of user candidates to be assigned to assist with this blog - * - * @return SS_List + * {@inheritdoc} */ - protected function getCandidateUsers() { - if($this->config()->grant_user_access) { - // If we are allowed to grant CMS access, all users are candidates - return Member::get(); - } else { - // If access cannot be granted, limit users to those who can access the CMS - // This is useful for more secure sites - $permission = $this->config()->grant_user_permission; - return Permission::get_members_by_permission($permission); - } - } - - /** - * Gets or creates the group used to assign CMS access - * - * @return Group - */ - protected function getUserGroup() { - $code = $this->config()->grant_user_group; - $group = Group::get()->filter('Code', $code)->first(); - if($group) return $group; - - // Create new group - $group = new Group(); - $group->Title = 'Blog users'; - $group->Code = $code; - $group->write(); - - // Add permission - $permission = new Permission(); - $permission->Code = $this->config()->grant_user_permission; - $group->Permissions()->add($permission); - - return $group; - } - protected function onBeforeWrite() { parent::onBeforeWrite(); $this->assignGroup(); } /** - * Assign users as necessary to the blog group + * Assign users as necessary to the blog group. */ protected function assignGroup() { - // Ensure that any user granted editor, writer, or contributor have CMS_ACCESS_CMSMain access - if(!$this->config()->grant_user_access) return; + if(!$this->config()->grant_user_access) { + return; + } - // Generate or retrieve the group $group = $this->getUserGroup(); - foreach(array($this->Editors(), $this->Writers(), $this->Contributors()) as $userlist) { - foreach($userlist as $user) { - // Ensure user exists in the group - if(!$user->inGroup($group)) $user->Groups()->add($group); + + 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; + } + } - /** - * Blog Controller - * * @package silverstripe * @subpackage blog - * - * @author Michael Strong - **/ + */ class Blog_Controller extends Page_Controller { - + /** + * @var array + */ private static $allowed_actions = array( 'archive', 'tag', 'category', 'rss', - 'profile' + 'profile', ); + /** + * @var array + */ private static $url_handlers = array( 'tag/$Tag!' => 'tag', 'category/$Category!' => 'category', 'archive/$Year!/$Month/$Day' => 'archive', - 'profile/$URLSegment!' => 'profile' + 'profile/$URLSegment!' => 'profile', ); + /** + * @var array + */ private static $casting = array( 'MetaTitle' => 'Text', - 'FilterDescription' => 'Text' + 'FilterDescription' => 'Text', ); - /** * The current Blog Post DataList query. * * @var DataList - **/ + */ protected $blogPosts; - + /** + * @return string + */ public function index() { $this->blogPosts = $this->getBlogPosts(); + return $this->render(); } @@ -550,7 +635,7 @@ class Blog_Controller extends Page_Controller { * Renders a Blog Member's profile. * * @return SS_HTTPResponse - **/ + */ public function profile() { $profile = $this->getCurrentProfile(); @@ -566,8 +651,8 @@ class Blog_Controller extends Page_Controller { /** * Get the Member associated with the current URL segment. * - * @return Member|null - **/ + * @return null|Member + */ public function getCurrentProfile() { $urlSegment = $this->request->param('URLSegment'); @@ -581,10 +666,10 @@ class Blog_Controller extends Page_Controller { } /** - * Get posts related to the current Member profile + * Get posts related to the current Member profile. * - * @return DataList|null - **/ + * @return null|DataList + */ public function getCurrentProfilePosts() { $profile = $this->getCurrentProfile(); @@ -596,279 +681,297 @@ class Blog_Controller extends Page_Controller { } /** - * Renders an archive for a specificed date. This can be by year or year/month + * Renders an archive for a specified date. This can be by year or year/month. * * @return SS_HTTPResponse - **/ + */ public function archive() { $year = $this->getArchiveYear(); $month = $this->getArchiveMonth(); $day = $this->getArchiveDay(); - // If an invalid month has been passed, we can return a 404. - if($this->request->param("Month") && !$month) { - return $this->httpError(404, "Not Found"); + if($this->request->param('Month') && !$month) { + return $this->httpError(404, 'Not Found'); } - // Check for valid day - if($month && $this->request->param("Day") && !$day) { - return $this->httpError(404, "Not Found"); + if($month && $this->request->param('Day') && !$day) { + return $this->httpError(404, 'Not Found'); } if($year) { $this->blogPosts = $this->getArchivedBlogPosts($year, $month, $day); + return $this->render(); } - return $this->httpError(404, "Not Found"); + + return $this->httpError(404, 'Not Found'); } + /** + * Fetches the archive year from the url. + * + * @return null|int + */ + public function getArchiveYear() { + $year = $this->request->param('Year'); + + if(preg_match('/^[0-9]{4}$/', $year)) { + return (int) $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 SS_HTTPResponse - **/ + */ public function tag() { $tag = $this->getCurrentTag(); + if($tag) { $this->blogPosts = $tag->BlogPosts(); return $this->render(); } - return $this->httpError(404, "Not Found"); + + return $this->httpError(404, 'Not Found'); } + /** + * Tag Getter for use in templates. + * + * @return null|BlogTag + */ + public function getCurrentTag() { + $tag = $this->request->param('Tag'); + + if($tag) { + return $this->dataRecord->Tags() + ->filter('URLSegment', $tag) + ->first(); + } + + return null; + } /** - * Renders the blog posts for a given category + * Renders the blog posts for a given category. * * @return SS_HTTPResponse - **/ + */ public function category() { $category = $this->getCurrentCategory(); + if($category) { $this->blogPosts = $category->BlogPosts(); return $this->render(); } - return $this->httpError(404, "Not Found"); + + return $this->httpError(404, 'Not Found'); } /** - * Get the meta title for the current action + * Category Getter for use in templates. + * + * @return null|BlogCategory + */ + public function getCurrentCategory() { + $category = $this->request->param('Category'); + + if($category) { + return $this->dataRecord->Categories() + ->filter('URLSegment', $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 = "{$title} - {$filter}"; + $title = sprintf('%s - $s', $title, $filter); } $this->extend('updateMetaTitle', $title); + return $title; } /** - * Returns a description of the current filter + * Returns a description of the current filter. * * @return string */ public function getFilterDescription() { $items = array(); - // Check current page $list = $this->PaginatedList(); $currentPage = $list->CurrentPage(); - // Build title if($currentPage > 1) { $items[] = _t( 'Blog.FILTERDESCRIPTION_PAGE', - "Page {page}", + 'Page {page}', null, - array('page' => $currentPage) + array( + 'page' => $currentPage, + ) ); } - // Check author if($author = $this->getCurrentProfile()) { $items[] = _t( 'Blog.FILTERDESCRIPTION_AUTHOR', - "By {author}", + 'By {author}', null, - array('author' => $author->Title) + array( + 'author' => $author->Title, + ) ); } - // Check tag if($tag = $this->getCurrentTag()) { $items[] = _t( 'Blog.FILTERDESCRIPTION_TAG', - "Tagged with {tag}", + 'Tagged with {tag}', null, - array('tag' => $tag->Title) + array( + 'tag' => $tag->Title, + ) ); } - // Check category if($category = $this->getCurrentCategory()) { $items[] = _t( 'Blog.FILTERDESCRIPTION_CATEGORY', - "In category {category}", + 'In category {category}', null, - array('category' => $category->Title) + array( + 'category' => $category->Title, + ) ); } - // Check archive if($this->owner->getArchiveYear()) { if($this->owner->getArchiveDay()) { $date = $this->owner->getArchiveDate()->Nice(); } elseif($this->owner->getArchiveMonth()) { - $date = $this->owner->getArchiveDate()->format("F, Y"); + $date = $this->owner->getArchiveDate()->format('F, Y'); } else { - $date = $this->owner->getArchiveDate()->format("Y"); + $date = $this->owner->getArchiveDate()->format('Y'); } + $items[] = _t( 'Blog.FILTERDESCRIPTION_DATE', - "In {date}", + 'In {date}', null, - array('date' => $date) + array( + 'date' => $date, + ) ); } $result = ''; - if($items) $result = implode(', ', $items); - // Allow extension + if($items) { + $result = implode(', ', $items); + } + $this->extend('updateFilterDescription', $result); + return $result; } - /** - * Displays an RSS feed of blog posts - * - * @return string HTML - **/ - public function rss() { - $rss = new RSSFeed($this->getBlogPosts(), $this->Link(), $this->MetaTitle, $this->MetaDescription); - $this->extend('updateRss', $rss); - return $rss->outputToBrowser(); - } - - - /** - * Returns a list of paginated blog posts based on the blogPost dataList + * Returns a list of paginated blog posts based on the BlogPost dataList. * * @return PaginatedList - **/ + */ public function PaginatedList() { $posts = new PaginatedList($this->blogPosts); - // If pagination is set to '0' then no pagination will be shown. if($this->PostsPerPage > 0) { $posts->setPageLength($this->PostsPerPage); } else { - $pageSize = $this->getBlogPosts()->count() ?: 99999; + $pageSize = 99999; + + if($count = $this->getBlogPosts()->count()) { + $pageSize = $count; + } + $posts->setPageLength($pageSize); } $start = $this->request->getVar($posts->getPaginationGetVar()); + $posts->setPageStart($start); return $posts; } - /** - * Tag Getter for use in templates. + * Displays an RSS feed of blog posts. * - * @return BlogTag|null - **/ - public function getCurrentTag() { - $tag = $this->request->param("Tag"); - if($tag) { - return $this->dataRecord->Tags() - ->filter("URLSegment", $tag) - ->first(); - } - return null; + * @return string + */ + public function rss() { + $rss = new RSSFeed($this->getBlogPosts(), $this->Link(), $this->MetaTitle, $this->MetaDescription); + + $this->extend('updateRss', $rss); + + return $rss->outputToBrowser(); } - - /** - * Category Getter for use in templates. - * - * @return BlogCategory|null - **/ - public function getCurrentCategory() { - $category = $this->request->param("Category"); - if($category) { - return $this->dataRecord->Categories() - ->filter("URLSegment", $category) - ->first(); - } - return null; - } - - - /** - * Fetches the archive year from the url - * - * @return int|null - **/ - public function getArchiveYear() { - $year = $this->request->param("Year"); - if(preg_match("/^[0-9]{4}$/", $year)) { - return (int) $year; - } - return null; - } - - - /** - * Fetches the archive money from the url. - * - * @return int|null - **/ - public function getArchiveMonth() { - $month = $this->request->param("Month"); - if(preg_match("/^[0-9]{1,2}$/", $month)) { - if($month > 0 && $month < 13) { - // Check that we have a valid date. - if(checkdate($month, 01, $this->getArchiveYear())) { - return (int) $month; - } - } - } - return null; - } - - - /** - * Fetches the archive day from the url - * - * @return int|null - **/ - public function getArchiveDay() { - $day = $this->request->param("Day"); - if(preg_match("/^[0-9]{1,2}$/", $day)) { - - // Check that we have a valid date - if(checkdate($this->getArchiveMonth(), $day, $this->getArchiveYear())) { - return (int) $day; - } - } - return null; - } - - /** * Returns the current archive date. * - * @return Date - **/ + * @return null|Date + */ public function getArchiveDate() { $year = $this->getArchiveYear(); $month = $this->getArchiveMonth(); @@ -876,25 +979,27 @@ class Blog_Controller extends Page_Controller { if($year) { if($month) { - $date = $year . '-' . $month . '-01'; + $date = sprintf('%s-%s-01', $year, $month); + if($day) { - $date = $year . '-' . $month . '-' . $day; + $date = sprintf('%s-%s-%s', $year, $month, $day); } } else { - $date = $year . '-01-01'; + $date = sprintf('%s-01-01', $year); } - return DBField::create_field("Date", $date); - } - } + return DBField::create_field('Date', $date); + } + + return null; + } /** * Returns a link to the RSS feed. * - * @return string URL - **/ + * @return string + */ public function getRSSLink() { - return $this->Link("rss"); + return $this->Link('rss'); } - } diff --git a/code/model/BlogCategory.php b/code/model/BlogCategory.php index 8f63efc..5eb434b 100644 --- a/code/model/BlogCategory.php +++ b/code/model/BlogCategory.php @@ -1,127 +1,135 @@ -**/ -class BlogCategory extends DataObject { - + * @method Blog Blog() + * @method ManyManyList BlogPosts() + * + * @property string $URLSegment + * @property int $BlogID + */ +class BlogCategory extends DataObject implements CategorisationObject { + /** + * @var array + */ private static $db = array( - "Title" => "Varchar(255)", + 'Title' => 'Varchar(255)', ); - - + /** + * @var array + */ private static $has_one = array( - "Blog" => "Blog", + 'Blog' => 'Blog', ); - - + /** + * @var array + */ private static $belongs_many_many = array( - "BlogPosts" => "BlogPost", + 'BlogPosts' => 'BlogPost', ); - - + /** + * @var array + */ private static $extensions = array( - "URLSegmentExtension", + 'URLSegmentExtension', ); - - + /** + * {@inheritdoc} + */ public function getCMSFields() { $fields = new FieldList( - TextField::create("Title", _t("BlogCategory.Title", "Title")) + TextField::create('Title', _t('BlogCategory.Title', 'Title')) ); - $this->extend("updateCMSFields", $fields); + + $this->extend('updateCMSFields', $fields); + return $fields; } - - /** * Returns a relative link to this category. * - * @return string URL - **/ + * @return string + */ public function getLink() { - return Controller::join_links($this->Blog()->Link(), "category", $this->URLSegment); + return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment); } - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension + * Inherits from the parent blog or can be overwritten using a DataExtension. * - * @param $member Member + * @param null|Member $member * - * @return boolean + * @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 + * Inherits from the parent blog or can be overwritten using a DataExtension. * - * @param $member Member + * @param null|Member $member * - * @return boolean + * @return bool */ public function canCreate($member = null) { $extended = $this->extendedCan(__FUNCTION__, $member); + if($extended !== null) { return $extended; } - // Since there is no parent yet, need to make a best guess $permission = Blog::config()->grant_user_permission; + return Permission::checkMember($member, $permission); } - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension + * Inherits from the parent blog or can be overwritten using a DataExtension. * - * @param $member Member + * @param null|Member $member * - * @return boolean + * @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 + * Inherits from the parent blog or can be overwritten using a DataExtension. * - * @param $member Member + * @param null|Member $member * - * @return boolean + * @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 95634c8..48f109d 100644 --- a/code/model/BlogPost.php +++ b/code/model/BlogPost.php @@ -1,7 +1,7 @@ -**/ + * @property string $PublishDate + * @property string $AuthorNames + * @property int $ParentID + */ class BlogPost extends Page { - + /** + * @var array + */ private static $db = array( - "PublishDate" => "SS_Datetime", - "AuthorNames" => "Varchar(1024)", - "Summary" => "HTMLText", + 'PublishDate' => 'SS_Datetime', + 'AuthorNames' => 'Varchar(1024)', + 'Summary' => 'HTMLText', ); + /** + * @var array + */ private static $has_one = array( - "FeaturedImage" => "Image", + 'FeaturedImage' => 'Image', ); + /** + * @var array + */ private static $many_many = array( - "Categories" => "BlogCategory", - "Tags" => "BlogTag", - "Authors" => "Member", + 'Categories' => 'BlogCategory', + 'Tags' => 'BlogTag', + 'Authors' => 'Member', ); + /** + * @var array + */ private static $defaults = array( - "ShowInMenus" => false, - "InheritSideBar" => true, // Support for widgets - "ProvideComments" => true, // Support for comments + 'ShowInMenus' => false, + 'InheritSideBar' => true, + 'ProvideComments' => true, ); + /** + * @var array + */ private static $extensions = array( - "BlogPostFilter", + 'BlogPostFilter', ); + /** + * @var array + */ private static $searchable_fields = array( - "Title", + 'Title', ); + /** + * @var array + */ private static $summary_fields = array( - "Title", + 'Title', ); + /** + * @var array + */ private static $casting = array( - 'Excerpt' => 'Text' + 'Excerpt' => 'Text', ); + /** + * @var array + */ private static $allowed_children = array(); - private static $default_sort = "PublishDate DESC"; + /** + * @var string + */ + private static $default_sort = '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. + * This will display or hide the current class from the SiteTree. This variable can be + * configured using YAML. * - * @var boolean - **/ + * @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) { + if(is_int($member)) { + $member = DataObject::get_by_id('Member', $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 + * Determine if the given member is an author of this post. * - * @param Member $member - * @return boolean + * @param null|Member $member + * + * @return bool */ - public function isAuthor($member) { - if(!$member || !$member->exists()) return false; + 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()); } @@ -85,92 +156,80 @@ class BlogPost extends Page { } /** - * Determine the role of the given member - * Call be called via template to determine the current user - * - * E.g. `Hello $RoleOf($CurrentMember.ID)` - * - * @param Member|integer $member - * @return string|null Author, Editor, Writer, Contributor, or null if no role + * {@inheritdoc} */ - public function RoleOf($member) { - if(is_numeric($member)) $member = DataObject::get_by_id('Member', $member); - if(!$member) return null; - - // Check if this member is an author - if($this->isAuthor($member)) return _t("BlogPost.AUTHOR", "Author"); - - // Check parent role - $parent = $this->Parent(); - if($parent instanceof Blog) return $parent->RoleOf($member); - } - - 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) { - // Add blog summary + $this->beforeUpdateCMSFields(function ($fields) use ($self) { + /** + * @var FieldList $fields + */ + + $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 = HtmlEditorField::create("Summary", false) + $summary, ) - ) - ->setHeadingLevel(4) - ->addExtraClass('custom-summary'); - $summary->setRows(5); - $summary->setDescription(_t( - 'BlogPost.SUMMARY_DESCRIPTION', - "If no summary is specified the first 30 words will be used." - )); + ); + $summaryHolder->setHeadingLevel(4); + $summaryHolder->addExtraClass('custom-summary'); + $fields->insertBefore($summaryHolder, 'Content'); - // Add featured image - $fields->insertAfter( - $uploadField = UploadField::create("FeaturedImage", _t("BlogPost.FeaturedImage", "Featured Image")), - "Content" - ); + $uploadField = UploadField::create('FeaturedImage', _t('BlogPost.FeaturedImage', 'Featured Image')); $uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif')); - // We're going to hide MenuTitle - Its not needed in blog posts. + $fields->insertAfter( + $uploadField, + 'Content' + ); + $fields->push(HiddenField::create('MenuTitle')); - // We're going to add the url segment to sidebar so we're making it a little lighter $urlSegment = $fields->dataFieldByName('URLSegment'); $urlSegment->setURLPrefix($self->Parent()->RelativeLink()); - // Remove the MenuTitle and URLSegment from the main tab $fields->removeFieldsFromTab('Root.Main', array( 'MenuTitle', 'URLSegment', )); - // Author field $authorField = ListboxField::create( - "Authors", - _t("BlogPost.Authors", "Authors"), + 'Authors', + _t('BlogPost.Authors', 'Authors'), Member::get()->map()->toArray() )->setMultiple(true); $authorNames = TextField::create( - "AuthorNames", - _t("BlogPost.AdditionalCredits", "Additional Credits"), + 'AuthorNames', + _t('BlogPost.AdditionalCredits', 'Additional Credits'), null, 1024 - )->setDescription('If some authors of this post don\'t have CMS access, enter their name(s) here. You can separate multiple names with a comma.'); + ); + $authorNames->setDescription('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(); } - // Build up our sidebar + $publishDate = DatetimeField::create('PublishDate', _t('BlogPost.PublishDate', 'Publish Date')); + $publishDate->getDateField()->setConfig('showcalendar', true); + $options = BlogAdminSidebar::create( - $publishDate = DatetimeField::create("PublishDate", _t("BlogPost.PublishDate", "Publish Date")), + $publishDate, $urlSegment, TagField::create( 'Categories', @@ -189,36 +248,84 @@ class BlogPost extends Page { $authorField, $authorNames )->setTitle('Post Options'); - $publishDate->getDateField()->setConfig("showcalendar", true); - // Insert it before the TabSet $fields->insertBefore($options, 'Root'); }); $fields = parent::getCMSFields(); - // We need to render an outer template to deal with our custom layout $fields->fieldByName('Root')->setTemplate('TabSet_holder'); return $fields; } + /** + * 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_int($member)) { + $member = Member::get()->byID($member); + } + + return $member; + } + /** * Determine whether user can create new categories. * - * @param int|Member|null $member + * @param null|int|Member $member * * @return bool */ public function canCreateCategories($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + $member = $member = $this->getMember($member); $parent = $this->Parent(); - if(!$parent || !$parent->exists() || !($parent instanceof Blog)) return false; + if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { + return false; + } - if($parent->isEditor($member)) return true; + if($parent->isEditor($member)) { + return true; + } return Permission::checkMember($member, 'ADMIN'); } @@ -226,212 +333,214 @@ class BlogPost extends Page { /** * Determine whether user can create new tags. * - * @param int|Member|null $member + * @param null|int|Member $member * * @return bool */ public function canCreateTags($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + $member = $member = $this->getMember($member); $parent = $this->Parent(); - if(!$parent || !$parent->exists() || !($parent instanceof Blog)) return false; + if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { + return false; + } - if($parent->isEditor($member)) return true; + if($parent->isEditor($member)) { + return true; + } - if($parent->isWriter($member)) return true; + if($parent->isWriter($member)) { + return true; + } return Permission::checkMember($member, 'ADMIN'); } - protected function onBeforeWrite() { - parent::onBeforeWrite(); - - // If no publish date is set, set the date to now. - if(!$this->PublishDate) $this->PublishDate = SS_Datetime::now()->getValue(); - - // If creating a new entry, assign the current member as an author - // This allows writers and contributors to then edit their new post - if(!$this->exists() && ($member = Member::currentUser())) { - $this->Authors()->add($member); - } - } - - - /** - * Update the PublishDate to now, if being published for the first time, and the date hasn't been set to the future. - **/ + * {@inheritdoc} + * + * Update the PublishDate to now, if being published for the first time, and the date hasn't + * been set to the future. + */ public function onBeforePublish() { - if ($this->dbObject('PublishDate')->InPast() && !$this->isPublished()) { + /** + * @var SS_Datetime $publishDate + */ + $publishDate = $this->dbObject('PublishDate'); + + if($publishDate->InPast() && !$this->isPublished()) { $this->PublishDate = SS_Datetime::now()->getValue(); $this->write(); } } /** - * Sets blog relationship on all categories and tags assigned to this post. + * {@inheritdoc} * - * @throws ValidationException + * Sets blog relationship on all categories and tags assigned to this post. */ - public function onAfterWrite() - { + public function onAfterWrite() { parent::onAfterWrite(); - foreach ($this->Categories() as $category) { + foreach($this->Categories() as $category) { + /** + * @var BlogCategory $category + */ $category->BlogID = $this->ParentID; $category->write(); } - foreach ($this->Tags() as $tag) { + foreach($this->Tags() as $tag) { + /** + * @var BlogTag $tag + */ $tag->BlogID = $this->ParentID; $tag->write(); } } /** - * Checks the publish date to see if the blog post has actually been published. - * - * @param $member Member|null - * - * @return boolean - **/ + * {@inheritdoc} + */ public function canView($member = null) { - if(!parent::canView($member)) return false; + if(!parent::canView($member)) { + return false; + } if($this->PublishDate) { - $publishDate = $this->dbObject("PublishDate"); - if($publishDate->InFuture() && !Permission::checkMember($member, "VIEW_DRAFT_CONTENT")) { + /** + * @var SS_Datetime $publishDate + */ + $publishDate = $this->dbObject('PublishDate'); + + if($publishDate->InFuture() && !Permission::checkMember($member, 'VIEW_DRAFT_CONTENT')) { return false; } } + return true; } - public function canEdit($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); + /** + * {@inheritdoc} + */ + public function canPublish($member = null) { + $member = $this->getMember($member); - // Inherit permission - if(parent::canEdit($member)) return true; + if(Permission::checkMember($member, 'ADMIN')) { + return true; + } + + $extended = $this->extendedCan('canPublish', $member); + + if($extended !== null) { + return $extended; + } - // Check if assigned to a blog $parent = $this->Parent(); - if(!$parent || !$parent->exists() || !($parent instanceof Blog)) return false; - // Editors have full control - if($parent->isEditor($member)) return true; + if($parent instanceof Blog && $parent->exists()) { + if($parent->isEditor($member)) { + return true; + } - // Only writers or contributors can edit - if(!$parent->isWriter($member) && !$parent->isContributor($member)) return false; + 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; + } - // And only if they are also authors return $this->isAuthor($member); } - /** - * Determine if this user can edit the authors list - * - * @param Member $member - * @return boolean - */ - public function canEditAuthors($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); - - $extended = $this->extendedCan('canEditAuthors', $member); - if($extended !== null) return $extended; - - // Check blog roles - $parent = $this->Parent(); - if($parent instanceof Blog && $parent->exists()) { - // Editors can do anything - if($parent->isEditor($member)) return true; - - // Writers who are also authors can edit authors - if($parent->isWriter($member) && $this->isAuthor($member)) return true; - } - - // Check permission - return Permission::checkMember($member, Blog::MANAGE_USERS); - } - - public function canPublish($member = null) { - $member = $member ?: Member::currentUser(); - if(is_numeric($member)) $member = Member::get()->byID($member); - - if(Permission::checkMember($member, "ADMIN")) return true; - - // Standard mechanism for accepting permission changes from extensions - $extended = $this->extendedCan('canPublish', $member); - if($extended !== null) return $extended; - - // Check blog roles - $parent = $this->Parent(); - if($parent instanceof Blog && $parent->exists()) { - // Editors can do anything - if($parent->isEditor($member)) return true; - - // Writers who are also authors can edit authors - if($parent->isWriter($member) && $this->isAuthor($member)) return true; - - // Contributors can ONLY publish this page if they somehow have global publish permissions - // In this case defer to old canEdit implementation - if($parent->isContributor($member)) return parent::canEdit($member); - } - - // Normal case - fail over to canEdit() - return $this->canEdit($member); - } - - /** * Returns the post excerpt. * - * @param $wordCount int - number of words to display + * @param int $wordsToDisplay * * @return string - **/ - public function Excerpt($wordCount = 30) { - return $this->dbObject("Content")->LimitWordCount($wordCount); + */ + public function Excerpt($wordsToDisplay = 30) { + /** + * @var Text $content + */ + $content = $this->dbObject('Content'); + + return $content->LimitWordCount($wordsToDisplay); } - - /** * Returns a monthly archive link for the current blog post. * - * @param $type string day|month|year + * @param string $type * - * @return string URL - **/ - public function getMonthlyArchiveLink($type = "day") { - $date = $this->dbObject("PublishDate"); - if($type != "year") { - if($type == "day") { + * @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") + $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'), $date->format('m')); } - return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y")); + + return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); } - - /** * Returns a yearly archive link for the current blog post. * - * @return string URL - **/ + * @return string + */ public function getYearlyArchiveLink() { - $date = $this->dbObject("PublishDate"); - return Controller::join_links($this->Parent()->Link("archive"), $date->format("Y")); + /** + * @var SS_Datetime $date + */ + $date = $this->dbObject('PublishDate'); + + return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); } /** @@ -439,8 +548,7 @@ class BlogPost extends Page { * * @return ArrayList */ - public function getCredits() - { + public function getCredits() { $list = new ArrayList(); $list->merge($this->getDynamicCredits()); @@ -454,8 +562,7 @@ class BlogPost extends Page { * * @return ArrayList */ - protected function getDynamicCredits() - { + protected function getDynamicCredits() { $items = new ArrayList(); foreach($this->Authors() as $author) { @@ -474,13 +581,12 @@ class BlogPost extends Page { * * @return ArrayList */ - protected function getStaticCredits() - { + protected function getStaticCredits() { $items = new ArrayList(); $authors = array_filter(preg_split('/\s*,\s*/', $this->AuthorNames)); - foreach ($authors as $author) { + foreach($authors as $author) { $item = new ArrayData(array( 'Name' => $author, )); @@ -492,27 +598,40 @@ class BlogPost extends Page { } /** - * Sets the label for BlogPost.Title to 'Post Title' (Rather than 'Page name') + * 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"); + */ + 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->PublishDate) { + $this->PublishDate = SS_Datetime::now()->getValue(); + } + + if(!$this->exists() && ($member = Member::currentUser())) { + $this->Authors()->add($member); + } + } +} /** - * Blog Post controller - * * @package silverstripe * @subpackage blog - * - * @author Michael Strong -**/ + */ class BlogPost_Controller extends Page_Controller { - + } diff --git a/code/model/BlogTag.php b/code/model/BlogTag.php index 9dbaf69..0afafa6 100644 --- a/code/model/BlogTag.php +++ b/code/model/BlogTag.php @@ -1,119 +1,136 @@ - -**/ -class BlogTag extends DataObject { - - private static $db = array( - "Title" => "Varchar(255)", - ); - - private static $has_one = array( - "Blog" => "Blog", - ); - - private static $belongs_many_many = array( - "BlogPosts" => "BlogPost", - ); - - private static $extensions = array( - "URLSegmentExtension", - ); - - - public function getCMSFields() { - $fields = new FieldList( - TextField::create("Title", _t("BlogTag.Title", "Title")) - ); - $this->extend("updateCMSFields", $fields); - return $fields; - } - - - /** - * Returns a relative URL for the tag link. - * - * @return string URL - **/ - 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 $member Member - * - * @return boolean - */ - 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 $member Member - * - * @return boolean - */ - public function canCreate($member = null) { - $extended = $this->extendedCan(__FUNCTION__, $member); - if($extended !== null) { - return $extended; - } - - // Since there is no parent yet, need to make a best guess - $permission = Blog::config()->grant_user_permission; - return Permission::checkMember($member, $permission); - } - - - - /** - * Inherits from the parent blog or can be overwritten using a DataExtension - * - * @param $member Member - * - * @return boolean - */ - 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 $member Member - * - * @return boolean - */ - 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', + ); + + /** + * {@inheritdoc} + */ + public function getCMSFields() { + $fields = new FieldList( + TextField::create('Title', _t('BlogTag.Title', 'Title')) + ); + + $this->extend('updateCMSFields', $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); + } + + /** + * 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/CategorisationObject.php b/code/model/CategorisationObject.php new file mode 100644 index 0000000..5528478 --- /dev/null +++ b/code/model/CategorisationObject.php @@ -0,0 +1,8 @@ + "Int", - "ArchiveType" => "Enum('Monthly,Yearly', 'Monthly')" - ); + /** + * @var array + */ + private static $db = array( + 'NumberToDisplay' => 'Int', + 'ArchiveType' => 'Enum("Monthly,Yearly", "Monthly")', + ); - private static $defaults = array( - "NumberOfMonths" => 12 - ); + /** + * @var array + */ + private static $defaults = array( + 'NumberOfMonths' => 12, + ); - private static $has_one = array( - "Blog" => "Blog", - ); + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); - public function getCMSFields() { - $self = $this; - $this->beforeUpdateCMSFields(function($fields) use ($self) { - $type = $self->dbObject("ArchiveType")->enumValues(); - foreach($type as $k => $v) { - $type[$k] = _t("BlogArchiveWidget." . ucfirst(strtolower($v)), $v); - } + /** + * {@inheritdoc} + */ + public function getCMSFields() { + $self = &$this; - $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(); - } + $this->beforeUpdateCMSFields(function ($fields) use ($self) { + $type = $self->dbObject('ArchiveType')->enumValues(); - - /** - * 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')"); + foreach($type as $k => $v) { + $type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v); } - $articles = $this->Blog()->getBlogPosts()->setDataQuery($query); - if($this->NumberToDisplay > 0) $articles = $articles->limit($this->NumberToDisplay); - - $archive = new ArrayList(); - if($articles->count() > 0) { - foreach($articles as $article) { - if($this->ArchiveType == "Yearly") { - $year = date('Y', strtotime($article->PublishDate)); - $month = null; - $title = $year; - } else { - $year = date('Y', strtotime($article->PublishDate)); - $month = date('m', strtotime($article->PublishDate)); - $title = date('F Y', strtotime($article->PublishDate)); - } - $archive->push(new ArrayData(array( - "Title" => $title, - "Link" => Controller::join_links($this->Blog()->Link("archive"), $year, $month) - ))); - } - } - return $archive; + $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); - class BlogArchiveWidget_Controller extends Widget_Controller { - + if($this->NumberToDisplay > 0) { + $posts = $posts->limit($this->NumberToDisplay); + } + + $archive = new ArrayList(); + + if($posts->count() > 0) { + foreach($posts as $post) { + /** + * @var BlogPost $post + */ + + if($this->ArchiveType == 'Yearly') { + $year = date('Y', strtotime($post->PublishDate)); + $month = null; + $title = $year; + } else { + $year = date('Y', strtotime($post->PublishDate)); + $month = date('m', strtotime($post->PublishDate)); + $title = date('F Y', strtotime($post->PublishDate)); + } + + $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 930dd4b..ce07580 100644 --- a/code/widgets/BlogCategoriesWidget.php +++ b/code/widgets/BlogCategoriesWidget.php @@ -1,42 +1,67 @@ "Blog", - ); + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); - public function getCMSFields() { - $this->beforeUpdateCMSFields(function($fields) { - $fields->push( - DropdownField::create("BlogID", _t("BlogCategoriesWidget.Blog", "Blog"), Blog::get()->map()) - ); - }); - return parent::getCMSFields(); - } - - public function getCategories() { - $blog = $this->Blog(); - if($blog) { - return $blog->Categories(); - } - return array(); - } + /** + * {@inheritdoc} + */ + public function getCMSFields() { + $this->beforeUpdateCMSFields(function ($fields) { + $fields->push( + DropdownField::create('BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map()) + ); + }); + return parent::getCMSFields(); } - class BlogCategoriesWidget_Controller extends Widget_Controller { - + /** + * @return array + */ + public function getCategories() { + $blog = $this->Blog(); + + if($blog) { + return $blog->Categories(); + } + + return array(); } +} + +class BlogCategoriesWidget_Controller extends Widget_Controller { } diff --git a/code/widgets/BlogRecentPostsWidget.php b/code/widgets/BlogRecentPostsWidget.php index 72fbe29..7886d16 100644 --- a/code/widgets/BlogRecentPostsWidget.php +++ b/code/widgets/BlogRecentPostsWidget.php @@ -1,47 +1,74 @@ "Int", - ); + /** + * @var array + */ + private static $db = array( + 'NumberOfPosts' => 'Int', + ); - private static $has_one = array( - "Blog" => "Blog", - ); + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); - public function getCMSFields() { - $this->beforeUpdateCMSFields(function($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(); - } - - public function getPosts() { - $blog = $this->Blog(); - if($blog) { - return $blog->getBlogPosts() - ->sort("PublishDate DESC") - ->limit($this->NumberOfPosts); - } - return array(); - } + /** + * {@inheritdoc} + */ + public function getCMSFields() { + $this->beforeUpdateCMSFields(function ($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(); } - class BlogRecentPostsWidget_Controller extends Widget_Controller { - - } + /** + * @return array + */ + public function getPosts() { + $blog = $this->Blog(); -} \ No newline at end of file + 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 ce854bb..5efed18 100644 --- a/code/widgets/BlogTagsWidget.php +++ b/code/widgets/BlogTagsWidget.php @@ -1,40 +1,65 @@ "Blog", - ); + /** + * @var array + */ + private static $has_one = array( + 'Blog' => 'Blog', + ); - public function getCMSFields() { - $this->beforeUpdateCMSFields(function($fields) { - $fields->push(DropdownField::create("BlogID", _t("BlogTagsWidget.Blog", "Blog"), Blog::get()->map())); - }); - return parent::getCMSFields(); - } - - public function getTags() { - $blog = $this->Blog(); - if($blog) { - return $blog->Tags(); - } - return array(); - } + /** + * {@inheritdoc} + */ + public function getCMSFields() { + $this->beforeUpdateCMSFields(function ($fields) { + $fields->push(DropdownField::create('BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map())); + }); + return parent::getCMSFields(); } - class BlogTagsWidget_Controller extends Widget_Controller { - - } + /** + * @return array + */ + public function getTags() { + $blog = $this->Blog(); -} \ No newline at end of file + if($blog) { + return $blog->Tags(); + } + + return array(); + } +} + +class BlogTagsWidget_Controller extends Widget_Controller { + +} diff --git a/tests/BlogCategoryTest.php b/tests/BlogCategoryTest.php index 428a442..27d4d69 100755 --- a/tests/BlogCategoryTest.php +++ b/tests/BlogCategoryTest.php @@ -1,107 +1,118 @@ BlogPosts() many_many are published, * both by normal 'save & publish' functionality and by publish date. - **/ + */ public function testBlogPosts() { - // Ensure the user is not logged in as admin (or anybody) $member = Member::currentUser(); - if($member) $member->logout(); - $post = $this->objFromFixture("BlogPost", "blogpost1"); - $category = $this->objFromFixture("BlogCategory", "firstcategory"); - $this->assertEquals(1, $category->BlogPosts()->count(), "Category blog post count"); + if($member) { + $member->logout(); + } + + $this->objFromFixture('BlogPost', 'FirstBlogPost'); + + /** + * @var BlogCategory $category + */ + $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); + + $this->assertEquals(1, $category->BlogPosts()->count(), 'Category blog post count'); } - - public function testCanView() { $this->useDraftSite(); - $admin = $this->objFromFixture("Member", "admin"); - $editor = $this->objFromFixture('Member', 'editor'); + $this->objFromFixture('Member', 'Admin'); - // The first blog can bew viewed by anybody - // $category = $this->objFromFixture("BlogCategory", "firstcategory"); - // $this->assertTrue($category->canView($admin), "Admin should be able to view category."); - // $this->assertTrue($category->canView($editor), "Editor should be able to view category."); + $editor = $this->objFromFixture('Member', 'Editor'); + $category = $this->objFromFixture('BlogCategory', 'SecondCategory'); - $category = $this->objFromFixture("BlogCategory", "secondcategory"); - // $this->assertTrue($category->canView($admin), "Admin should be able to view category."); - $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(); - $admin = $this->objFromFixture("Member", "admin"); - $editor = $this->objFromFixture('Member', 'editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - // The first blog can bew viewed by anybody - $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."); + $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); - $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->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); - $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."); + $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.'); + + $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.'); } - - 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'); - // The first blog can bew viewed by anybody $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(); - $admin = $this->objFromFixture("Member", "admin"); - $editor = $this->objFromFixture('Member', 'editor'); + $admin = $this->objFromFixture('Member', 'Admin'); + $editor = $this->objFromFixture('Member', 'Editor'); - // The first blog can bew viewed by anybody - $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."); + $category = $this->objFromFixture('BlogCategory', 'FirstCategory'); - $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."); + $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", "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', '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.'); } - } diff --git a/tests/BlogPostFilterTest.php b/tests/BlogPostFilterTest.php index d66236f..95d4114 100755 --- a/tests/BlogPostFilterTest.php +++ b/tests/BlogPostFilterTest.php @@ -1,31 +1,42 @@ logout(); - $blog = $this->objFromFixture('Blog', 'firstblog'); + if($member) { + $member->logout(); + } - $count = $blog->AllChildren()->Count(); - $this->assertEquals(3, $count, "Filtered blog posts"); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - SS_Datetime::set_mock_now("2020-01-01 00:00:00"); - $count = $blog->AllChildren()->Count(); - $this->assertEquals(5, $count, "Unfiltered blog posts"); + $this->assertEquals(3, $blog->AllChildren()->Count(), 'Filtered blog posts'); + + SS_Datetime::set_mock_now('2020-01-01 00:00:00'); + + $this->assertEquals(5, $blog->AllChildren()->Count(), 'Unfiltered blog posts'); } - } diff --git a/tests/BlogTagTest.php b/tests/BlogTagTest.php index e7da478..b9ed9e3 100755 --- a/tests/BlogTagTest.php +++ b/tests/BlogTagTest.php @@ -1,107 +1,126 @@ BlogPosts() many_many are published, - * both by normal 'save & publish' functionality and by publish date. - **/ + * 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() { - // Ensure the user is not logged in as admin (or anybody) $member = Member::currentUser(); - if($member) $member->logout(); - $post = $this->objFromFixture("BlogPost", "blogpost1"); - $tag = $this->objFromFixture("BlogTag", "firsttag"); - $this->assertEquals(1, $tag->BlogPosts()->count(), "Tag blog post count"); + if($member) { + $member->logout(); + } + + $this->objFromFixture('BlogPost', 'FirstBlogPost'); + + /** + * @var BlogTag $tag + */ + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); + + $this->assertEquals(1, $tag->BlogPosts()->count(), 'Tag blog post count'); } - - + /** + * 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'); - // The first blog can bew viewed by anybody - $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."); + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $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->assertTrue($tag->canView($editor), 'Editor should be able to view tag.'); + + $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.'); } - - 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'); - // The first blog can bew viewed by anybody - $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."); + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $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->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); - $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."); + $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.'); + + $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.'); } - - 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'); - // The first blog can bew viewed by anybody - $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."); + $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.'); } - - 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'); - // The first blog can bew viewed by anybody - $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."); + $tag = $this->objFromFixture('BlogTag', 'FirstTag'); - $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->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); - $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."); + $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.'); + + $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.'); } - } diff --git a/tests/BlogTest.php b/tests/BlogTest.php index 55cdb4e..27dc573 100755 --- a/tests/BlogTest.php +++ b/tests/BlogTest.php @@ -1,129 +1,198 @@ objFromFixture("Blog", "firstblog")->publish("Stage", "Live"); + SS_Datetime::set_mock_now('2013-10-10 20:00:00'); + + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); + + $blog->publish('Stage', 'Live'); } + /** + * {@inheritdoc} + */ public function tearDown() { SS_Datetime::clear_mock_now(); Config::unnest(); + parent::tearDown(); } - + public function testGetExcludedSiteTreeClassNames() { $member = Member::currentUser(); - if($member) $member->logout(); - $blog = $this->objFromFixture("Blog", 'firstblog'); + if($member) { + $member->logout(); + } - Config::inst()->update("BlogPost", "show_in_sitetree", true); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); + + Config::inst()->update('BlogPost', 'show_in_sitetree', true); $classes = $blog->getExcludedSiteTreeClassNames(); - $this->assertNotContains('BlogPost', $classes, "BlogPost class should be hidden."); - Config::inst()->update("BlogPost", "show_in_sitetree", false); + $this->assertNotContains('BlogPost', $classes, 'BlogPost class should be hidden.'); + + 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(); - if($member) $member->logout(); - $blog = $this->objFromFixture("Blog", "firstblog"); + if($member) { + $member->logout(); + } + + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - // Test yearly $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"); - // Test monthly + $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); - $this->assertEquals(1, $archive->count(), "Incorrect monthly acrhive count."); - // Test daily + $this->assertEquals(1, $archive->count(), 'Incorrect monthly archive count.'); + $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() { - $blog = $this->objFromFixture("Blog", "firstblog"); + /** + * @var Blog $blog + */ + $blog = $this->objFromFixture('Blog', 'FirstBlog'); - // Test valid links - $archiveLink = Controller::join_links($blog->Link("archive"), 2013, 10, 01); - $response = Director::test($archiveLink); - $this->assertEquals(200, $response->getStatusCode(), "HTTP Status should be 200"); + $link = Controller::join_links($blog->Link('archive'), '2013', '10', '01'); - $archiveLink = Controller::join_links($blog->Link("archive"), 2013, 10); - $response = Director::test($archiveLink); - $this->assertEquals(200, $response->getStatusCode(), "HTTP Status should be 200"); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - $archiveLink = Controller::join_links($blog->Link("archive"), 2013); - $response = Director::test($archiveLink); - $this->assertEquals(200, $response->getStatusCode(), "HTTP Status should be 200"); + $link = Controller::join_links($blog->Link('archive'), '2013', '10'); - $archiveLink = Controller::join_links($blog->Link("archive"), 2011, 10, 01); - $response = Director::test($archiveLink); // No posts on this date, but a valid entry. - $this->assertEquals(200, $response->getStatusCode(), "HTTP Status should be 200"); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); + $link = Controller::join_links($blog->Link('archive'), '2013'); - // Test invalid links & dates - $response = Director::test($blog->Link("archive")); // 404 when no date is set - $this->assertEquals(404, $response->getStatusCode(), "HTTP Status should be 404"); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - // Invalid year - $archiveLink = Controller::join_links($blog->Link("archive"), "invalid-year"); - $response = Director::test($archiveLink); // 404 when an invalid yer is set - $this->assertEquals(404, $response->getStatusCode(), "HTTP Status should be 404"); + $link = Controller::join_links($blog->Link('archive'), '2011', '10', '01'); - // Invalid month - $archiveLink = Controller::join_links($blog->Link("archive"), "2013", "99"); - $response = Director::test($archiveLink); // 404 when an invalid month is set - $this->assertEquals(404, $response->getStatusCode(), "HTTP Status should be 404"); + $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); - // Invalid day - $archiveLink = Controller::join_links($blog->Link("archive"), "2013", "10", "99"); - $response = Director::test($archiveLink); // 404 when an invalid day is set - $this->assertEquals(404, $response->getStatusCode(), "HTTP Status should be 404"); + $link = Controller::join_links($blog->Link('archive')); + $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); + + $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'); + } + + /** + * @param string $link + * + * @return int + */ + protected function getStatusOf($link) { + return Director::test($link)->getStatusCode(); } public function testRoles() { - $blog = $this->objFromFixture('Blog', 'fourthblog'); - $blog2 = $this->objFromFixture('Blog', 'firstblog'); - $postA = $this->objFromFixture('BlogPost', 'post-a'); - $postB = $this->objFromFixture('BlogPost', 'post-b'); - $postC = $this->objFromFixture('BlogPost', 'post-c'); - $editor = $this->objFromFixture('Member', 'blogeditor'); - $writer = $this->objFromFixture('Member', 'writer'); - $contributor = $this->objFromFixture('Member', 'contributor'); - $visitor = $this->objFromFixture('Member', 'visitor'); + /** + * @var Blog $firstBlog + */ + $firstBlog = $this->objFromFixture('Blog', 'FirstBlog'); - // Check roleof - $this->assertEquals('Editor', $blog->RoleOf($editor)); - $this->assertEquals('Contributor', $blog->RoleOf($contributor)); - $this->assertEquals('Writer', $blog->RoleOf($writer)); - $this->assertEmpty($blog->RoleOf($visitor)); + /** + * @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)); - // Check that editors have all permissions on their own blog - $this->assertTrue($blog->canEdit($editor)); - $this->assertFalse($blog2->canEdit($editor)); - $this->assertTrue($blog->canAddChildren($editor)); - $this->assertFalse($blog2->canAddChildren($editor)); + $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)); @@ -131,11 +200,10 @@ class BlogTest extends SapphireTest { $this->assertTrue($postB->canPublish($editor)); $this->assertTrue($postC->canPublish($editor)); - // check rights of writers - $this->assertFalse($blog->canEdit($writer)); - $this->assertFalse($blog2->canEdit($writer)); - $this->assertTrue($blog->canAddChildren($writer)); - $this->assertFalse($blog2->canAddChildren($writer)); + $this->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)); @@ -143,11 +211,10 @@ class BlogTest extends SapphireTest { $this->assertFalse($postB->canPublish($writer)); $this->assertTrue($postC->canPublish($writer)); - // Check rights of contributors - $this->assertFalse($blog->canEdit($contributor)); - $this->assertFalse($blog2->canEdit($contributor)); - $this->assertTrue($blog->canAddChildren($contributor)); - $this->assertFalse($blog2->canAddChildren($contributor)); + $this->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)); @@ -155,11 +222,10 @@ class BlogTest extends SapphireTest { $this->assertFalse($postB->canPublish($contributor)); $this->assertFalse($postC->canPublish($contributor)); - // Check rights of non-cms user - $this->assertFalse($blog->canEdit($visitor)); - $this->assertFalse($blog2->canEdit($visitor)); - $this->assertFalse($blog->canAddChildren($visitor)); - $this->assertFalse($blog2->canAddChildren($visitor)); + $this->assertFalse($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)); @@ -167,5 +233,4 @@ class BlogTest extends SapphireTest { $this->assertFalse($postB->canPublish($visitor)); $this->assertFalse($postC->canPublish($visitor)); } - -} \ No newline at end of file +} diff --git a/tests/blog.yml b/tests/blog.yml index 7defbc8..b4be745 100755 --- a/tests/blog.yml +++ b/tests/blog.yml @@ -1,150 +1,148 @@ -##################################################### # Mock date is set to 2013-10-01 20:00:00 -##################################################### + Group: - admins: + Administrators: Title: Administrators - editors: + Editors: Title: Editors - blog-users: + BlogUsers: Title: Blog Users - Code: blog-users + Code: BlogUsers Permission: - admins: + Administrators: Code: ADMIN - Group: =>Group.admins - editors: + Group: =>Group.Administrators + Editors: Code: CMS_ACCESS_CMSMain - Group: =>Group.editors - blog-users: + Group: =>Group.Editors + BlogUsers: Code: CMS_ACCESS_CMSMain - Group: =>Group.blog-users - - + Group: =>Group.BlogUsers + SiteConfig: - default: + Default: CanEditType: 'OnlyTheseUsers' CanCreateTopLevelType: 'OnlyTheseUsers' - EditorGroups: =>Group.admins,=>Group.editors - CreateTopLevelGroups: =>Group.admins,=>Group.editors + EditorGroups: =>Group.Administrators,=>Group.Editors + CreateTopLevelGroups: =>Group.Administrators,=>Group.Editors Member: - admin: + Admin: FirstName: Test Surname: Administrator - Groups: =>Group.admins - editor: + Groups: =>Group.Administrators + Editor: FirstName: Test Surname: Editor - Groups: =>Group.editors - blogeditor: + Groups: =>Group.Editors + BlogEditor: FirstName: Blog Surname: Editor - Groups: =>Group.blog-users - writer: + Groups: =>Group.BlogUsers + Writer: FirstName: Blog Surname: Writer - Groups: =>Group.blog-users - contributor: + Groups: =>Group.BlogUsers + Contributor: FirstName: Blog Surname: Contributor - Groups: =>Group.blog-users - visitor: + Groups: =>Group.BlogUsers + Visitor: FirstName: Blog Surname: Visitor Blog: - firstblog: + FirstBlog: Title: 'First Blog' - secondblog: + SecondBlog: Title: 'Second Blog' CanViewType: 'OnlyTheseUsers' CanEditType: 'OnlyTheseUsers' - ViewerGroups: =>Group.admins - EditorGroups: =>Group.admins - thirdblog: + ViewerGroups: =>Group.Administrators + EditorGroups: =>Group.Administrators + ThirdBlog: Title: 'Third Blog' CanEditType: 'OnlyTheseUsers' - EditorGroups: =>Group.editors - fourthblog: + EditorGroups: =>Group.Editors + FourthBlog: Title: 'Fourth Blog' - Editors: =>Member.blogeditor - Writers: =>Member.writer - Contributors: =>Member.contributor + Editors: =>Member.BlogEditor + Writers: =>Member.Writer + Contributors: =>Member.Contributor BlogTag: - firsttag: + FirstTag: Title: 'First Tag' URLSegment: 'first-tag' - Blog: =>Blog.firstblog - secondtag: + Blog: =>Blog.FirstBlog + SecondTag: Title: 'Second Tag' URLSegment: 'second-tag' - Blog: =>Blog.secondblog - thirdtag: + Blog: =>Blog.SecondBlog + ThirdTag: Title: 'Third Tag' URLSegment: 'third-tag' - Blog: =>Blog.thirdblog + Blog: =>Blog.ThirdBlog BlogCategory: - firstcategory: + FirstCategory: Title: 'First Category' URLSegment: 'first-category' - Blog: =>Blog.firstblog - secondcategory: + Blog: =>Blog.FirstBlog + SecondCategory: Title: 'Second Category' URLSegment: 'second-category' - Blog: =>Blog.secondblog - thirdcategory: + Blog: =>Blog.SecondBlog + ThirdCategory: Title: 'Third Category' URLSegment: 'third-category' - Blog: =>Blog.thirdblog + Blog: =>Blog.ThirdBlog BlogPost: - blogpost1: - Title: 'First post' + FirstBlogPost: + Title: 'First Post' URLSegment: first-post PublishDate: '2013-10-01 15:00:00' - Parent: =>Blog.firstblog - Tags: =>BlogTag.firsttag - Categories: =>BlogCategory.firstcategory - blogpost2: - Title: 'Second post' + Parent: =>Blog.FirstBlog + Tags: =>BlogTag.FirstTag + Categories: =>BlogCategory.FirstCategory + SecondBlogPost: + Title: 'Second Post' URLSegment: second-post PublishDate: '2013-09-01 15:00:00' - Parent: =>Blog.firstblog - blogpost3: - Title: 'Old post' + Parent: =>Blog.FirstBlog + ThirdBlogPost: + Title: 'Old Post' URLSegment: old-post PublishDate: '2012-01-09 15:00:00' - Parent: =>Blog.firstblog - futurepost: + Parent: =>Blog.FirstBlog + FirstFutureBlogPost: Title: 'Future Post' URLSegment: future-post PublishDate: '2015-01-01 00:00:00' - Tags: =>BlogTag.firsttag - Categories: =>BlogCategory.firstcategory - Parent: =>Blog.firstblog - futurepost2: + Tags: =>BlogTag.FirstTag + Categories: =>BlogCategory.FirstCategory + Parent: =>Blog.FirstBlog + SecondFutureBlogPost: Title: 'Future Post 2' URLSegment: future-post-2 PublishDate: '2013-11-01 00:00:00' - Tags: =>BlogTag.firsttag - Categories: =>BlogCategory.firstcategory - Parent: =>Blog.firstblog - post-a: + Tags: =>BlogTag.FirstTag + Categories: =>BlogCategory.FirstCategory + Parent: =>Blog.FirstBlog + PostA: Title: 'One Post' PublishDate: '2012-01-09 15:00:00' - Parent: =>Blog.fourthblog - Authors: =>Member.writer,=>Member.contributor - post-b: + Parent: =>Blog.FourthBlog + Authors: =>Member.Writer,=>Member.Contributor + PostB: Title: 'Second Post' PublishDate: '2012-01-09 15:00:00' - Parent: =>Blog.fourthblog - Authors: =>Member.blogeditor - post-c: + Parent: =>Blog.FourthBlog + Authors: =>Member.BlogEditor + PostC: Title: 'Third Post' PublishDate: '2012-01-09 15:00:00' - Parent: =>Blog.fourthblog - Authors: =>Member.blogeditor,=>Member.writer,=>Member.contributor + Parent: =>Blog.FourthBlog + Authors: =>Member.BlogEditor,=>Member.Writer,=>Member.Contributor