mirror of
https://github.com/silverstripe/silverstripe-blog
synced 2024-10-22 11:05:58 +02:00
commit
a64f6f0a81
@ -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();
|
||||
}
|
||||
));
|
||||
|
@ -16,8 +16,7 @@ class GridFieldFormAction extends GridField_FormAction {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
public function getAttributes() {
|
||||
$attributes = parent::getAttributes();
|
||||
|
||||
return array_merge(
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,34 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Description of BlogMigrationTask
|
||||
*
|
||||
* @author dmooyman
|
||||
*/
|
||||
class BlogMigrationTask extends MigrationTask {
|
||||
|
||||
/**
|
||||
* Should this task be invoked automatically via dev/build?
|
||||
*
|
||||
* @config
|
||||
* @var boolean
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $run_during_dev_build = true;
|
||||
|
||||
protected function message($text) {
|
||||
if(Controller::curr() instanceof DatabaseAdmin) {
|
||||
DB::alteration_message($text, 'obsolete');
|
||||
} else {
|
||||
Debug::message($text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function up() {
|
||||
$classes = ClassInfo::implementorsOf('MigratableObject');
|
||||
|
||||
$this->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');
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
<?php
|
||||
|
||||
interface MigratableObject {
|
||||
|
||||
/**
|
||||
* Migrate the object up to the current version
|
||||
* Migrate the object up to the current version.
|
||||
*/
|
||||
public function up();
|
||||
}
|
||||
|
@ -1,27 +1,49 @@
|
||||
<?php
|
||||
|
||||
if(!class_exists('Widget')) return;
|
||||
if(!class_exists('Widget')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 2.0
|
||||
*
|
||||
* @property string $DisplayMode
|
||||
* @property string $ArchiveType
|
||||
*/
|
||||
class ArchiveWidget extends BlogArchiveWidget implements MigratableObject {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array(
|
||||
'DisplayMode' => '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();
|
||||
}
|
||||
|
@ -1,29 +1,43 @@
|
||||
<?php
|
||||
|
||||
if(! class_exists('Widget')) return;
|
||||
if(!class_exists('Widget')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of tags associated with blog posts
|
||||
* A list of tags associated with blog posts.
|
||||
*
|
||||
* @package blog
|
||||
*/
|
||||
class TagCloudWidget extends BlogTagsWidget implements MigratableObject {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array(
|
||||
"Title" => "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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Adds Blog specific behaviour to Comment
|
||||
* Extends {@see Comment}
|
||||
* Adds Blog specific behaviour to Comment.
|
||||
*/
|
||||
class BlogCommentExtension extends DataExtension {
|
||||
|
||||
/**
|
||||
* Extra CSS classes for styling different comment types.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExtraClass() {
|
||||
$blogPost = $this->owner->getParent();
|
||||
|
||||
// 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 '';
|
||||
}
|
||||
}
|
||||
|
@ -1,89 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class is responsible for filtering the SiteTree when necessary and also
|
||||
* overlaps into filtering only published posts.
|
||||
* This class is responsible for filtering the SiteTree when necessary and also overlaps into
|
||||
* filtering only published posts.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
*
|
||||
**/
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is responsible for filtering only published posts to users who do not have
|
||||
* permission to view non-published posts.
|
||||
* This is responsible for filtering only published posts to users who do not have permission to
|
||||
* view non-published posts.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Customise blog post to support comment notifications
|
||||
* Extends {@see BlogPost} with extensions to {@see CommentNotifiable}
|
||||
* Customise blog post to support comment notifications.
|
||||
*
|
||||
* Extends {@see BlogPost} with extensions to {@see CommentNotifiable}.
|
||||
*/
|
||||
class BlogPostNotifications extends DataExtension {
|
||||
|
||||
/**
|
||||
* Notify all authors of notifications
|
||||
* Notify all authors of notifications.
|
||||
*
|
||||
* @param type $list
|
||||
* @param type $comment
|
||||
* @param SS_List $list
|
||||
* @param mixed $comment
|
||||
*/
|
||||
public function updateNotificationRecipients(&$list, &$comment) {
|
||||
// Notify all authors
|
||||
$list = $this->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);
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Adds URLSegment functionality to Tags & Categories
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Adds URLSegment functionality to Tags & Categories.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*/
|
||||
class URLSegmentExtension extends DataExtension {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array(
|
||||
'URLSegment' => '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;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
<?php
|
||||
|
||||
class BlogAdminSidebar extends FieldGroup {
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOpen() {
|
||||
$sidebar = Cookie::get('blog-admin-sidebar');
|
||||
|
||||
if($sidebar == 1 || is_null($sidebar)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,168 +5,181 @@
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Provides a component to the {@link GridField} which tells the user whether or not a
|
||||
* blog post has been published and when.
|
||||
* Provides a component to the {@link GridField} which tells the user whether or not a blog post
|
||||
* has been published and when.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
*/
|
||||
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 = "<span class='modified'>" . _t("GridFieldBlogPostState.Modified") . "</span>";
|
||||
$modifiedLabel = '<span class="modified">' . _t('GridFieldBlogPostState.Modified') . '</span>';
|
||||
}
|
||||
|
||||
$published = $record->isPublished();
|
||||
if(!$published) {
|
||||
if(!$record->isPublished()) {
|
||||
return _t(
|
||||
"GridFieldBlogPostState.Draft",
|
||||
'GridFieldBlogPostState.Draft',
|
||||
'<i class="btn-icon gridfield-icon btn-icon-pencil"></i> 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',
|
||||
'<i class="gridfield-icon blog-icon-timer"></i> 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",
|
||||
'<i class="btn-icon gridfield-icon btn-icon-accept"></i> 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',
|
||||
'<i class="btn-icon gridfield-icon btn-icon-accept"></i> 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,15 @@
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <mstrong@silverstripe.org>
|
||||
**/
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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 <github@michaelstrong.co.uk>
|
||||
**/
|
||||
*/
|
||||
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('<a class="toggle-description">help</a>')
|
||||
@ -304,7 +309,6 @@ class Blog extends Page implements PermissionProvider {
|
||||
$editorField = $editorField->performDisabledTransformation();
|
||||
}
|
||||
|
||||
// Writers
|
||||
$writerField = ListboxField::create('Writers', 'Writers', $members)
|
||||
->setMultiple(true)
|
||||
->setRightTitle('<a class="toggle-description">help</a>')
|
||||
@ -321,7 +325,6 @@ class Blog extends Page implements PermissionProvider {
|
||||
$writerField = $writerField->performDisabledTransformation();
|
||||
}
|
||||
|
||||
// Contributors
|
||||
$contributorField = ListboxField::create('Contributors', 'Contributors', $members)
|
||||
->setMultiple(true)
|
||||
->setRightTitle('<a class="toggle-description">help</a>')
|
||||
@ -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 <github@michaelstrong.co.uk>
|
||||
**/
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,127 +1,135 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A blog category fo generalising blog posts.
|
||||
* A blog category for generalising blog posts.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* An indivisual blog post.
|
||||
* An individual blog post.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
@ -9,74 +9,145 @@
|
||||
* @method ManyManyList Categories()
|
||||
* @method ManyManyList Tags()
|
||||
* @method ManyManyList Authors()
|
||||
* @method Blog Parent()
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
* @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 <github@michaelstrong.co.uk>
|
||||
**/
|
||||
*/
|
||||
class BlogPost_Controller extends Page_Controller {
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,119 +1,136 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A blog tag for keyword descriptions of a Blog post
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @author Michael Strong <github@michaelstrong.co.uk>
|
||||
**/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A blog tag for keyword descriptions of a blog post.
|
||||
*
|
||||
* @package silverstripe
|
||||
* @subpackage blog
|
||||
*
|
||||
* @method Blog Blog()
|
||||
* @method ManyManyList BlogPosts
|
||||
*
|
||||
* @property string $Title
|
||||
* @property string $URLSegment
|
||||
* @property int $BlogID
|
||||
*/
|
||||
class BlogTag extends DataObject implements CategorisationObject {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array(
|
||||
'Title' => 'Varchar(255)',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $has_one = array(
|
||||
'Blog' => 'Blog',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $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);
|
||||
}
|
||||
}
|
||||
|
8
code/model/CategorisationObject.php
Normal file
8
code/model/CategorisationObject.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @method ManyManyList BlogPosts
|
||||
*/
|
||||
interface CategorisationObject {
|
||||
|
||||
}
|
@ -1,88 +1,125 @@
|
||||
<?php
|
||||
|
||||
if(class_exists("Widget")) {
|
||||
if(!class_exists('Widget')) {
|
||||
return;
|
||||
}
|
||||
|
||||
class BlogArchiveWidget extends Widget {
|
||||
|
||||
private static $title = "Archive";
|
||||
/**
|
||||
* @method Blog Blog()
|
||||
*
|
||||
* @property string $ArchiveType
|
||||
* @property int $NumberToDisplay
|
||||
*/
|
||||
class BlogArchiveWidget extends Widget {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $title = 'Archive';
|
||||
|
||||
private static $cmsTitle = "Archive";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $cmsTitle = 'Archive';
|
||||
|
||||
private static $description = "Displays an archive list of posts.";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $description = 'Displays an archive list of posts.';
|
||||
|
||||
private static $db = array(
|
||||
"NumberToDisplay" => "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 {
|
||||
|
||||
}
|
||||
|
@ -1,42 +1,67 @@
|
||||
<?php
|
||||
|
||||
if(class_exists("Widget")) {
|
||||
if(!class_exists("Widget")) {
|
||||
return;
|
||||
}
|
||||
|
||||
class BlogCategoriesWidget extends Widget {
|
||||
|
||||
private static $title = "Categories";
|
||||
/**
|
||||
* @method Blog Blog()
|
||||
*/
|
||||
class BlogCategoriesWidget extends Widget {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $title = 'Categories';
|
||||
|
||||
private static $cmsTitle = "Blog Categories";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $cmsTitle = 'Blog Categories';
|
||||
|
||||
private static $description = "Displays a list of blog categories.";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $description = 'Displays a list of blog categories.';
|
||||
|
||||
private static $db = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array();
|
||||
|
||||
private static $has_one = array(
|
||||
"Blog" => "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 {
|
||||
|
||||
}
|
||||
|
@ -1,47 +1,74 @@
|
||||
<?php
|
||||
|
||||
if(class_exists("Widget")) {
|
||||
if(!class_exists("Widget")) {
|
||||
return;
|
||||
}
|
||||
|
||||
class BlogRecentPostsWidget extends Widget {
|
||||
|
||||
private static $title = "Recent Posts";
|
||||
/**
|
||||
* @method Blog Blog()
|
||||
*
|
||||
* @property int $NumberOfPosts
|
||||
*/
|
||||
class BlogRecentPostsWidget extends Widget {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $title = 'Recent Posts';
|
||||
|
||||
private static $cmsTitle = "Recent Posts";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $cmsTitle = 'Recent Posts';
|
||||
|
||||
private static $description = "Displays a list of recent blog posts.";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $description = 'Displays a list of recent blog posts.';
|
||||
|
||||
private static $db = array(
|
||||
"NumberOfPosts" => "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();
|
||||
|
||||
}
|
||||
if($blog) {
|
||||
return $blog->getBlogPosts()
|
||||
->sort('PublishDate DESC')
|
||||
->limit($this->NumberOfPosts);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
class BlogRecentPostsWidget_Controller extends Widget_Controller {
|
||||
|
||||
}
|
||||
|
@ -1,40 +1,65 @@
|
||||
<?php
|
||||
|
||||
if(class_exists("Widget")) {
|
||||
if(!class_exists("Widget")) {
|
||||
return;
|
||||
}
|
||||
|
||||
class BlogTagsWidget extends Widget {
|
||||
|
||||
private static $title = "Tags";
|
||||
/**
|
||||
* @method Blog Blog()
|
||||
*/
|
||||
class BlogTagsWidget extends Widget {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $title = 'Tags';
|
||||
|
||||
private static $cmsTitle = "Blog Tags";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $cmsTitle = 'Blog Tags';
|
||||
|
||||
private static $description = "Displays a list of blog tags.";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $description = 'Displays a list of blog tags.';
|
||||
|
||||
private static $db = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array();
|
||||
|
||||
private static $has_one = array(
|
||||
"Blog" => "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();
|
||||
|
||||
}
|
||||
if($blog) {
|
||||
return $blog->Tags();
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
class BlogTagsWidget_Controller extends Widget_Controller {
|
||||
|
||||
}
|
||||
|
@ -1,107 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @mixin PHPUnit_Framework_TestCase
|
||||
*/
|
||||
class BlogCategoryTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = "blog.yml";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'blog.yml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
SS_Datetime::set_mock_now("2013-10-10 20:00:00");
|
||||
parent::setUp();
|
||||
|
||||
SS_Datetime::set_mock_now('2013-10-10 20:00:00');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function tearDown() {
|
||||
SS_Datetime::clear_mock_now();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that any blog posts returned from $category->BlogPosts() many_many are published,
|
||||
* both by normal 'save & publish' functionality and by publish date.
|
||||
**/
|
||||
*/
|
||||
public function testBlogPosts() {
|
||||
// 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.');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,31 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @mixin PHPUnit_Framework_TestCase
|
||||
*/
|
||||
class BlogPostFilterTest extends SapphireTest {
|
||||
|
||||
static $fixture_file = "blog.yml";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'blog.yml';
|
||||
|
||||
public function setUp() {
|
||||
SS_Datetime::set_mock_now("2013-10-10 20:00:00");
|
||||
parent::setUp();
|
||||
|
||||
SS_Datetime::set_mock_now('2013-10-10 20:00:00');
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
SS_Datetime::clear_mock_now();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testFilter() {
|
||||
$member = Member::currentUser();
|
||||
if($member) $member->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');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,107 +1,126 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @mixin PHPUnit_Framework_TestCase
|
||||
*/
|
||||
class BlogTagTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = "blog.yml";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'blog.yml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
SS_Datetime::set_mock_now("2013-10-10 20:00:00");
|
||||
parent::setUp();
|
||||
|
||||
SS_Datetime::set_mock_now('2013-10-10 20:00:00');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function tearDown() {
|
||||
SS_Datetime::clear_mock_now();
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that any blog posts returned from $tag->BlogPosts() many_many are published,
|
||||
* both by normal 'save & publish' functionality and by publish date.
|
||||
**/
|
||||
* 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.');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,129 +1,198 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @mixin PHPUnit_Framework_TestCase
|
||||
*/
|
||||
class BlogTest extends SapphireTest {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'blog.yml';
|
||||
|
||||
static $fixture_file = "blog.yml";
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
Config::nest();
|
||||
SS_Datetime::set_mock_now("2013-10-10 20:00:00");
|
||||
$this->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));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
154
tests/blog.yml
154
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
|
||||
|
Loading…
Reference in New Issue
Block a user