Converted to PSR-2

This commit is contained in:
helpfulrobot 2015-11-21 19:17:29 +13:00
parent 4785ad0123
commit f82825d9a6
34 changed files with 4276 additions and 4078 deletions

View File

@ -1,54 +1,57 @@
<?php <?php
class GridFieldCategorisationConfig extends GridFieldConfig_RecordEditor { class GridFieldCategorisationConfig extends GridFieldConfig_RecordEditor
/** {
* @param int $itemsPerPage /**
* @param array|SS_List $mergeRecords * @param int $itemsPerPage
* @param string $parentType * @param array|SS_List $mergeRecords
* @param string $parentMethod * @param string $parentType
* @param string $childMethod * @param string $parentMethod
*/ * @param string $childMethod
public function __construct($itemsPerPage = 15, $mergeRecords, $parentType, $parentMethod, $childMethod) { */
parent::__construct($itemsPerPage); public function __construct($itemsPerPage = 15, $mergeRecords, $parentType, $parentMethod, $childMethod)
{
parent::__construct($itemsPerPage);
$this->removeComponentsByType('GridFieldAddNewButton'); $this->removeComponentsByType('GridFieldAddNewButton');
$this->addComponent( $this->addComponent(
new GridFieldAddByDBField('buttons-before-left') new GridFieldAddByDBField('buttons-before-left')
); );
$this->addComponent( $this->addComponent(
new GridFieldMergeAction($mergeRecords, $parentType, $parentMethod, $childMethod) new GridFieldMergeAction($mergeRecords, $parentType, $parentMethod, $childMethod)
); );
/** /**
* @var GridFieldDataColumns $columns * @var GridFieldDataColumns $columns
*/ */
$columns = $this->getComponentByType('GridFieldDataColumns'); $columns = $this->getComponentByType('GridFieldDataColumns');
$columns->setFieldFormatting(array( $columns->setFieldFormatting(array(
'BlogPostsCount' => function ($value, CategorisationObject $item) { 'BlogPostsCount' => function ($value, CategorisationObject $item) {
return $item->BlogPosts()->Count(); return $item->BlogPosts()->Count();
} }
)); ));
$this->changeColumnOrder(); $this->changeColumnOrder();
} }
/** /**
* Reorders GridField columns so that Actions is last. * Reorders GridField columns so that Actions is last.
*/ */
protected function changeColumnOrder() { protected function changeColumnOrder()
/** {
* @var GridFieldDataColumns $columns /**
*/ * @var GridFieldDataColumns $columns
$columns = $this->getComponentByType('GridFieldDataColumns'); */
$columns = $this->getComponentByType('GridFieldDataColumns');
$columns->setDisplayFields(array( $columns->setDisplayFields(array(
'Title' => 'Title', 'Title' => 'Title',
'BlogPostsCount' => 'Posts', 'BlogPostsCount' => 'Posts',
'MergeAction' => 'MergeAction', 'MergeAction' => 'MergeAction',
'Actions' => 'Actions', 'Actions' => 'Actions',
)); ));
} }
} }

View File

@ -1,27 +1,30 @@
<?php <?php
class GridFieldFormAction extends GridField_FormAction { class GridFieldFormAction extends GridField_FormAction
/** {
* @var array /**
*/ * @var array
protected $extraAttributes = array(); */
protected $extraAttributes = array();
/** /**
* @param array $attributes * @param array $attributes
*/ */
public function setExtraAttributes(array $attributes) { public function setExtraAttributes(array $attributes)
$this->extraAttributes = $attributes; {
} $this->extraAttributes = $attributes;
}
/** /**
* @return array * @return array
*/ */
public function getAttributes() { public function getAttributes()
$attributes = parent::getAttributes(); {
$attributes = parent::getAttributes();
return array_merge( return array_merge(
$attributes, $attributes,
$this->extraAttributes $this->extraAttributes
); );
} }
} }

View File

@ -1,140 +1,149 @@
<?php <?php
class GridFieldMergeAction implements GridField_ColumnProvider, GridField_ActionProvider { class GridFieldMergeAction implements GridField_ColumnProvider, GridField_ActionProvider
/** {
* List of records to show in the MergeAction column. /**
* * List of records to show in the MergeAction column.
* @var array|SS_List *
*/ * @var array|SS_List
protected $records; */
protected $records;
/** /**
* Type of parent DataObject (i.e BlogTag, BlogCategory). * Type of parent DataObject (i.e BlogTag, BlogCategory).
* *
* @var string * @var string
*/ */
protected $parentType; protected $parentType;
/** /**
* Relationship method to reference parent (i.e BlogTags). * Relationship method to reference parent (i.e BlogTags).
* *
* @var string * @var string
*/ */
protected $parentMethod; protected $parentMethod;
/** /**
* Relationship method to reference child (i.e BlogPosts). * Relationship method to reference child (i.e BlogPosts).
* *
* @var string * @var string
*/ */
protected $childMethod; protected $childMethod;
/** /**
* @param array|SS_List $records * @param array|SS_List $records
* @param string $parentType * @param string $parentType
* @param string $parentMethod * @param string $parentMethod
* @param string $childMethod * @param string $childMethod
*/ */
public function __construct($records = array(), $parentType, $parentMethod, $childMethod) { public function __construct($records = array(), $parentType, $parentMethod, $childMethod)
$this->records = $records; {
$this->parentType = $parentType; $this->records = $records;
$this->parentMethod = $parentMethod; $this->parentType = $parentType;
$this->childMethod = $childMethod; $this->parentMethod = $parentMethod;
} $this->childMethod = $childMethod;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function augmentColumns($gridField, &$columns) { public function augmentColumns($gridField, &$columns)
if(!in_array('MergeAction', $columns)) { {
$columns[] = 'MergeAction'; if (!in_array('MergeAction', $columns)) {
} $columns[] = 'MergeAction';
}
return $columns; return $columns;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getColumnsHandled($gridField) { public function getColumnsHandled($gridField)
return array('MergeAction'); {
} return array('MergeAction');
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getColumnContent($gridField, $record, $columnName) { 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()); if ($columnName === 'MergeAction' && $record->{$this->childMethod}()->Count() > 0) {
$dropdown->setAttribute('id', 'Target_'.$record->ID); $dropdown = new DropdownField('Target', 'Target', $this->records->exclude('ID', $record->ID)->map());
$prefix = strtolower($this->parentMethod . '-' . $this->childMethod); $dropdown->setAttribute('id', 'Target_'.$record->ID);
$prefix = strtolower($this->parentMethod . '-' . $this->childMethod);
$action = GridFieldFormAction::create( $action = GridFieldFormAction::create(
$gridField, $gridField,
'MergeAction' . $record->ID, 'MergeAction' . $record->ID,
'Move', 'Move',
'merge', 'merge',
array( array(
'record' => $record->ID, 'record' => $record->ID,
'target' => $prefix . '-target-record-' . $record->ID, 'target' => $prefix . '-target-record-' . $record->ID,
) )
); );
$action->setExtraAttributes(array( $action->setExtraAttributes(array(
'data-target' => $prefix . '-target-record-' . $record->ID 'data-target' => $prefix . '-target-record-' . $record->ID
)); ));
return $dropdown->Field() . $action->Field() . '<a title="Move posts to" class="MergeActionReveal">move posts to</a>'; return $dropdown->Field() . $action->Field() . '<a title="Move posts to" class="MergeActionReveal">move posts to</a>';
} }
return null; return null;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getColumnAttributes($gridField, $record, $columnName) { public function getColumnAttributes($gridField, $record, $columnName)
return array('class' => 'MergeAction'); {
} return array('class' => 'MergeAction');
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getColumnMetadata($gridField, $columnName) { public function getColumnMetadata($gridField, $columnName)
return array('title' => 'Move posts to'); {
} return array('title' => 'Move posts to');
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getActions($gridField) { public function getActions($gridField)
return array('merge'); {
} return array('merge');
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function handleAction(GridField $gridField, $actionName, $arguments, $data) { public function handleAction(GridField $gridField, $actionName, $arguments, $data)
if($actionName === 'merge') { {
$controller = Controller::curr(); if ($actionName === 'merge') {
$controller = Controller::curr();
$request = $controller->getRequest(); $request = $controller->getRequest();
$target = $request->requestVar($arguments["target"]); $target = $request->requestVar($arguments["target"]);
$parentType = $this->parentType; $parentType = $this->parentType;
$fromParent = $parentType::get()->byId($arguments['record']); $fromParent = $parentType::get()->byId($arguments['record']);
$toParent = $parentType::get()->byId($target); $toParent = $parentType::get()->byId($target);
$posts = $fromParent->{$this->childMethod}(); $posts = $fromParent->{$this->childMethod}();
foreach($posts as $post) { foreach ($posts as $post) {
$relationship = $post->{$this->parentMethod}(); $relationship = $post->{$this->parentMethod}();
$relationship->remove($fromParent); $relationship->remove($fromParent);
$relationship->add($toParent); $relationship->add($toParent);
} }
} }
} }
} }

View File

@ -8,105 +8,106 @@
* @property string $PublishDate * @property string $PublishDate
* @property string $Tags * @property string $Tags
*/ */
class BlogEntry extends BlogPost implements MigratableObject { class BlogEntry extends BlogPost implements MigratableObject
/** {
* @var string /**
*/ * @var string
private static $hide_ancestor = 'BlogEntry'; */
private static $hide_ancestor = 'BlogEntry';
/** /**
* @var array * @var array
*/ */
private static $db = array( private static $db = array(
'Date' => 'SS_Datetime', 'Date' => 'SS_Datetime',
'Author' => 'Text', 'Author' => 'Text',
'Tags' => 'Text', 'Tags' => 'Text',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function canCreate($member = null) { public function canCreate($member = null)
return false; {
} return false;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function up() { public function up()
{
//Migrate comma separated tags into BlogTag objects.
foreach($this->TagNames() as $tag) { //Migrate comma separated tags into BlogTag objects.
foreach ($this->TagNames() as $tag) {
$existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); $existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID));
if($existingTag->count()) { if ($existingTag->count()) {
//if tag already exists we will simply add it to this post. //if tag already exists we will simply add it to this post.
$tagObject = $existingTag->First(); $tagObject = $existingTag->First();
} else {
} else {
//if the tag is now we create it and add it to this post. //if the tag is now we create it and add it to this post.
$tagObject = new BlogTag(); $tagObject = new BlogTag();
$tagObject->Title = $tag; $tagObject->Title = $tag;
$tagObject->BlogID = $this->ParentID; $tagObject->BlogID = $this->ParentID;
$tagObject->write(); $tagObject->write();
}
if ($tagObject) {
} $this->Tags()->add($tagObject);
}
}
if($tagObject){ //Store if the original entity was published or not (draft)
$this->Tags()->add($tagObject); $published = $this->IsPublished();
} // If a user has subclassed BlogEntry, it should not be turned into a BlogPost.
} if ($this->ClassName === 'BlogEntry') {
$this->ClassName = 'BlogPost';
$this->RecordClassName = 'BlogPost';
}
//Migrate these key data attributes
$this->PublishDate = $this->Date;
$this->AuthorNames = $this->Author;
$this->InheritSideBar = true;
//Write and additionally publish the item if it was published before.
$this->write();
if ($published) {
$this->publish('Stage', 'Live');
$message = "PUBLISHED: ";
} else {
$message = "DRAFT: ";
}
return $message . $this->Title;
}
//Store if the original entity was published or not (draft) /**
$published = $this->IsPublished(); * Safely split and parse all distinct tags assigned to this BlogEntry.
// If a user has subclassed BlogEntry, it should not be turned into a BlogPost. *
if($this->ClassName === 'BlogEntry') { * @deprecated since version 2.0
$this->ClassName = 'BlogPost'; *
$this->RecordClassName = 'BlogPost'; * @return array
} */
//Migrate these key data attributes public function TagNames()
$this->PublishDate = $this->Date; {
$this->AuthorNames = $this->Author; $tags = preg_split('/\s*,\s*/', trim($this->Tags));
$this->InheritSideBar = true;
//Write and additionally publish the item if it was published before.
$this->write();
if($published){
$this->publish('Stage','Live');
$message = "PUBLISHED: ";
} else {
$message = "DRAFT: ";
}
return $message . $this->Title;
}
/** $results = array();
* 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) {
foreach($tags as $tag) { $results[mb_strtolower($tag)] = $tag;
if($tag) $results[mb_strtolower($tag)] = $tag; }
} }
return $results;
}
return $results;
}
} }
/** /**
* @deprecated since version 2.0 * @deprecated since version 2.0
*/ */
class BlogEntry_Controller extends BlogPost_Controller { class BlogEntry_Controller extends BlogPost_Controller
{
} }

View File

@ -3,71 +3,75 @@
/** /**
* @deprecated since version 2.0 * @deprecated since version 2.0
*/ */
class BlogHolder extends BlogTree implements MigratableObject { class BlogHolder extends BlogTree implements MigratableObject
/** {
* @var string /**
*/ * @var string
private static $hide_ancestor = 'BlogHolder'; */
private static $hide_ancestor = 'BlogHolder';
/** /**
* @var array * @var array
*/ */
private static $db = array( private static $db = array(
'AllowCustomAuthors' => 'Boolean', 'AllowCustomAuthors' => 'Boolean',
'ShowFullEntry' => 'Boolean', 'ShowFullEntry' => 'Boolean',
); );
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'Owner' => 'Member', 'Owner' => 'Member',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function canCreate($member = null) { public function canCreate($member = null)
return false; {
} return false;
}
//Overload these to stop the Uncaught Exception: Object->__call(): the method 'parent' does not exist on 'BlogHolder' error. //Overload these to stop the Uncaught Exception: Object->__call(): the method 'parent' does not exist on 'BlogHolder' error.
public function validURLSegment() { public function validURLSegment()
return true; {
} return true;
public function syncLinkTracking() { }
return null; public function syncLinkTracking()
} {
return null;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function up() { public function up()
{
$published = $this->IsPublished();
$published = $this->IsPublished(); if ($this->ClassName === 'BlogHolder') {
$this->ClassName = 'Blog';
$this->RecordClassName = 'Blog';
$this->PostsPerPage = 10;
$this->write();
}
if($this->ClassName === 'BlogHolder') { if ($published) {
$this->ClassName = 'Blog'; $this->publish('Stage', 'Live');
$this->RecordClassName = 'Blog'; $message = "PUBLISHED: ";
$this->PostsPerPage = 10; } else {
$this->write(); $message = "DRAFT: ";
} }
if($published){ return $message . $this->Title;
$this->publish('Stage','Live'); }
$message = "PUBLISHED: ";
} else {
$message = "DRAFT: ";
}
return $message . $this->Title;
}
} }
/** /**
* @deprecated since version 2.0 * @deprecated since version 2.0
*/ */
class BlogHolder_Controller extends BlogTree_Controller { class BlogHolder_Controller extends BlogTree_Controller
{
} }

View File

@ -3,51 +3,54 @@
/** /**
* @deprecated since version 2.0 * @deprecated since version 2.0
*/ */
class BlogTree extends Page implements MigratableObject { class BlogTree extends Page implements MigratableObject
/** {
* @var string /**
*/ * @var string
private static $hide_ancestor = 'BlogTree'; */
private static $hide_ancestor = 'BlogTree';
/** /**
* @var array * @var array
*/ */
private static $db = array( private static $db = array(
'Name' => 'Varchar(255)', 'Name' => 'Varchar(255)',
'LandingPageFreshness' => 'Varchar', 'LandingPageFreshness' => 'Varchar',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function canCreate($member = null) { public function canCreate($member = null)
return false; {
} return false;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function up() { public function up()
$published = $this->IsPublished(); {
if($this->ClassName === 'BlogTree') { $published = $this->IsPublished();
$this->ClassName = 'Page'; if ($this->ClassName === 'BlogTree') {
$this->RecordClassName = 'Page'; $this->ClassName = 'Page';
$this->write(); $this->RecordClassName = 'Page';
} $this->write();
if($published){ }
$this->publish('Stage','Live'); if ($published) {
$message = "PUBLISHED: "; $this->publish('Stage', 'Live');
} else { $message = "PUBLISHED: ";
$message = "DRAFT: "; } else {
} $message = "DRAFT: ";
}
return $message . $this->Title;
} return $message . $this->Title;
}
} }
/** /**
* @deprecated since version 2.0 * @deprecated since version 2.0
*/ */
class BlogTree_Controller extends Page_Controller { class BlogTree_Controller extends Page_Controller
{
} }

View File

@ -1,89 +1,92 @@
<?php <?php
class BlogMigrationTask extends MigrationTask { class BlogMigrationTask extends MigrationTask
/** {
* Should this task be invoked automatically via dev/build? /**
* * Should this task be invoked automatically via dev/build?
* @config *
* * @config
* @var bool *
*/ * @var bool
private static $run_during_dev_build = true; */
private static $run_during_dev_build = true;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function up() { public function up()
$classes = ClassInfo::implementorsOf('MigratableObject'); {
$classes = ClassInfo::implementorsOf('MigratableObject');
$this->message('Migrating legacy blog records'); $this->message('Migrating legacy blog records');
foreach($classes as $class) { foreach ($classes as $class) {
$this->upClass($class);
$this->upClass($class); }
} }
}
/** /**
* @param string $text * @param string $text
*/ */
protected function message($text) { protected function message($text)
if(Controller::curr() instanceof DatabaseAdmin) { {
DB::alteration_message($text, 'obsolete'); if (Controller::curr() instanceof DatabaseAdmin) {
} else { DB::alteration_message($text, 'obsolete');
echo $text . "<br/>"; } else {
} echo $text . "<br/>";
} }
}
/** /**
* Migrate records of a single class * Migrate records of a single class
* *
* @param string $class * @param string $class
* @param null|string $stage * @param null|string $stage
*/ */
protected function upClass($class) { protected function upClass($class)
if(!class_exists($class)) { {
return; if (!class_exists($class)) {
} return;
}
if(is_subclass_of($class, 'SiteTree')) { if (is_subclass_of($class, 'SiteTree')) {
$items = SiteTree::get()->filter('ClassName', $class); $items = SiteTree::get()->filter('ClassName', $class);
} else { } else {
$items = $class::get(); $items = $class::get();
} }
if($count = $items->count()) { if ($count = $items->count()) {
$this->message( $this->message(
sprintf( sprintf(
'Migrating %s legacy %s records.', 'Migrating %s legacy %s records.',
$count, $count,
$class $class
) )
); );
foreach($items as $item) { foreach ($items as $item) {
$cancel = $item->extend('onBeforeUp'); $cancel = $item->extend('onBeforeUp');
if($cancel && min($cancel) === false) { if ($cancel && min($cancel) === false) {
continue; continue;
} }
/** /**
* @var MigratableObject $item * @var MigratableObject $item
*/ */
$result = $item->up(); $result = $item->up();
$this->message($result); $this->message($result);
$item->extend('onAfterUp'); $item->extend('onAfterUp');
} }
} }
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function down() { public function down()
$this->message('BlogMigrationTask::down() not implemented'); {
} $this->message('BlogMigrationTask::down() not implemented');
}
} }

View File

@ -1,8 +1,9 @@
<?php <?php
interface MigratableObject { interface MigratableObject
/** {
* Migrate the object up to the current version. /**
*/ * Migrate the object up to the current version.
public function up(); */
public function up();
} }

View File

@ -1,7 +1,7 @@
<?php <?php
if(!class_exists('Widget')) { if (!class_exists('Widget')) {
return; return;
} }
/** /**
@ -10,43 +10,45 @@ if(!class_exists('Widget')) {
* @property string $DisplayMode * @property string $DisplayMode
* @property string $ArchiveType * @property string $ArchiveType
*/ */
class ArchiveWidget extends BlogArchiveWidget implements MigratableObject { class ArchiveWidget extends BlogArchiveWidget implements MigratableObject
/** {
* @var array /**
*/ * @var array
private static $db = array( */
'DisplayMode' => 'Varchar', private static $db = array(
); 'DisplayMode' => 'Varchar',
);
/** /**
* @var array * @var array
*/ */
private static $only_available_in = array( private static $only_available_in = array(
'none', 'none',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function canCreate($member = null) { public function canCreate($member = null)
return false; {
} return false;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function up() { public function up()
if($this->DisplayMode) { {
$this->ArchiveType = 'Monthly'; if ($this->DisplayMode) {
$this->ArchiveType = 'Monthly';
if($this->DisplayMode === 'year') { if ($this->DisplayMode === 'year') {
$this->ArchiveType = 'Yearly'; $this->ArchiveType = 'Yearly';
} }
} }
$this->ClassName = 'BlogArchiveWidget'; $this->ClassName = 'BlogArchiveWidget';
$this->write(); $this->write();
return "Migrated " . $this->ArchiveType . " archive widget"; return "Migrated " . $this->ArchiveType . " archive widget";
}
}
} }

View File

@ -1,7 +1,7 @@
<?php <?php
if(!class_exists('Widget')) { if (!class_exists('Widget')) {
return; return;
} }
/** /**
@ -9,36 +9,39 @@ if(!class_exists('Widget')) {
* *
* @package blog * @package blog
*/ */
class TagCloudWidget extends BlogTagsWidget implements MigratableObject { class TagCloudWidget extends BlogTagsWidget implements MigratableObject
/** {
* @var array /**
*/ * @var array
private static $db = array( */
'Title' => 'Varchar', private static $db = array(
'Limit' => 'Int', 'Title' => 'Varchar',
'Sortby' => 'Varchar', 'Limit' => 'Int',
); 'Sortby' => 'Varchar',
);
/** /**
* @var array * @var array
*/ */
private static $only_available_in = array( private static $only_available_in = array(
'none', 'none',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function canCreate($member = null) { public function canCreate($member = null)
return false; {
} return false;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function up() { public function up()
$this->ClassName = 'BlogTagsWidget'; {
$this->write(); $this->ClassName = 'BlogTagsWidget';
return "Migrated " . $this->Title . " widget"; $this->write();
} return "Migrated " . $this->Title . " widget";
}
} }

View File

@ -3,21 +3,23 @@
/** /**
* Adds Blog specific behaviour to Comment. * Adds Blog specific behaviour to Comment.
*/ */
class BlogCommentExtension extends DataExtension { class BlogCommentExtension extends DataExtension
/** {
* Extra CSS classes for styling different comment types. /**
* * Extra CSS classes for styling different comment types.
* @return string *
*/ * @return string
public function getExtraClass() { */
$blogPost = $this->owner->getParent(); public function getExtraClass()
{
$blogPost = $this->owner->getParent();
if($blogPost instanceof BlogPost) { if ($blogPost instanceof BlogPost) {
if($blogPost->isAuthor($this->owner->Author())) { if ($blogPost->isAuthor($this->owner->Author())) {
return 'author-comment'; return 'author-comment';
} }
} }
return ''; return '';
} }
} }

View File

@ -1,106 +1,114 @@
<?php <?php
/** /**
* This class is responsible for filtering the SiteTree when necessary and also overlaps into * This class is responsible for filtering the SiteTree when necessary and also overlaps into
* filtering only published posts. * filtering only published posts.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class BlogFilter extends Lumberjack { class BlogFilter extends Lumberjack
/** {
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function stageChildren($showAll = false) { */
$staged = parent::stageChildren($showAll); public function stageChildren($showAll = false)
{
if(!$this->shouldFilter() && $this->subclassForBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { $staged = parent::stageChildren($showAll);
$stage = Versioned::current_stage();
if (!$this->shouldFilter() && $this->subclassForBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) {
if($stage == 'Stage') { $stage = Versioned::current_stage();
$stage = '';
} elseif($stage) { if ($stage == 'Stage') {
$stage = '_' . $stage; $stage = '';
} } elseif ($stage) {
$stage = '_' . $stage;
$dataQuery = $staged->dataQuery() }
->innerJoin('BlogPost', sprintf('"BlogPost%s"."ID" = "SiteTree%s"."ID"', $stage, $stage))
->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); $dataQuery = $staged->dataQuery()
->innerJoin('BlogPost', sprintf('"BlogPost%s"."ID" = "SiteTree%s"."ID"', $stage, $stage))
$staged = $staged->setDataQuery($dataQuery); ->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now())));
}
$staged = $staged->setDataQuery($dataQuery);
return $staged; }
}
return $staged;
/** }
* @return bool
*/ /**
protected function subclassForBlog() { * @return bool
return in_array(get_class($this->owner), ClassInfo::subClassesFor('Blog')); */
} 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); * {@inheritdoc}
*/
if(!$this->shouldFilter() && $this->isBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) { public function liveChildren($showAll = false, $onlyDeletedFromStage = false)
$dataQuery = $staged->dataQuery() {
->innerJoin('BlogPost', '"BlogPost_Live"."ID" = "SiteTree_Live"."ID"') $staged = parent::liveChildren($showAll, $onlyDeletedFromStage);
->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now())));
if (!$this->shouldFilter() && $this->isBlog() && !Permission::check('VIEW_DRAFT_CONTENT')) {
$staged = $staged->setDataQuery($dataQuery); $dataQuery = $staged->dataQuery()
} ->innerJoin('BlogPost', '"BlogPost_Live"."ID" = "SiteTree_Live"."ID"')
->where(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now())));
return $staged;
} $staged = $staged->setDataQuery($dataQuery);
}
/**
* @return bool return $staged;
*/ }
protected function isBlog() {
return $this->owner instanceof Blog; /**
} * @return bool
*/
/** protected function isBlog()
* {@inheritdoc} {
*/ return $this->owner instanceof Blog;
public function updateCMSFields(FieldList $fields) { }
$excluded = $this->owner->getExcludedSiteTreeClassNames();
/**
if(!empty($excluded)) { * {@inheritdoc}
$pages = BlogPost::get()->filter(array( */
'ParentID' => $this->owner->ID, public function updateCMSFields(FieldList $fields)
'ClassName' => $excluded {
)); $excluded = $this->owner->getExcludedSiteTreeClassNames();
$gridField = new BlogFilter_GridField( if (!empty($excluded)) {
'ChildPages', $pages = BlogPost::get()->filter(array(
$this->getLumberjackTitle(), 'ParentID' => $this->owner->ID,
$pages, 'ClassName' => $excluded
$this->getLumberjackGridFieldConfig() ));
);
$gridField = new BlogFilter_GridField(
$tab = new Tab('ChildPages', $this->getLumberjackTitle(), $gridField); 'ChildPages',
$this->getLumberjackTitle(),
$fields->insertBefore($tab, 'Main'); $pages,
} $this->getLumberjackGridFieldConfig()
} );
}
$tab = new Tab('ChildPages', $this->getLumberjackTitle(), $gridField);
/** $fields->insertBefore($tab, 'Main');
* Enables children of non-editable pages to be edited. }
*/ }
class BlogFilter_GridField extends GridField { }
/**
* @param FormTransformation $transformation
* /**
* @return $this * Enables children of non-editable pages to be edited.
*/ */
public function transform(FormTransformation $transformation) { class BlogFilter_GridField extends GridField
return $this; {
} /**
} * @param FormTransformation $transformation
*
* @return $this
*/
public function transform(FormTransformation $transformation)
{
return $this;
}
}

View File

@ -6,105 +6,110 @@
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class BlogMemberExtension extends DataExtension { class BlogMemberExtension extends DataExtension
/** {
* @var array /**
*/ * @var array
private static $db = array( */
'URLSegment' => 'Varchar', private static $db = array(
'BlogProfileSummary' => 'Text', 'URLSegment' => 'Varchar',
); 'BlogProfileSummary' => 'Text',
);
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'BlogProfileImage' => 'Image', 'BlogProfileImage' => 'Image',
); );
/** /**
* @var array * @var array
*/ */
private static $belongs_many_many = array( private static $belongs_many_many = array(
'BlogPosts' => 'BlogPost', 'BlogPosts' => 'BlogPost',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function onBeforeWrite() { public function onBeforeWrite()
$count = 1; {
$count = 1;
$this->owner->URLSegment = $this->generateURLSegment(); $this->owner->URLSegment = $this->generateURLSegment();
while(!$this->validURLSegment()) { while (!$this->validURLSegment()) {
$this->owner->URLSegment = preg_replace('/-[0-9]+$/', null, $this->owner->URLSegment) . '-' . $count; $this->owner->URLSegment = preg_replace('/-[0-9]+$/', null, $this->owner->URLSegment) . '-' . $count;
$count++; $count++;
} }
} }
/** /**
* Generate a unique URL segment based on the Member's name. * Generate a unique URL segment based on the Member's name.
* *
* @return string * @return string
*/ */
public function generateURLSegment() { public function generateURLSegment()
$filter = URLSegmentFilter::create(); {
$name = $this->owner->FirstName . ' ' . $this->owner->Surname; $filter = URLSegmentFilter::create();
$urlSegment = $filter->filter($name); $name = $this->owner->FirstName . ' ' . $this->owner->Surname;
$urlSegment = $filter->filter($name);
if(!$urlSegment || $urlSegment == '-' || $urlSegment == '-1') { if (!$urlSegment || $urlSegment == '-' || $urlSegment == '-1') {
$urlSegment = 'profile-' . $this->owner->ID; $urlSegment = 'profile-' . $this->owner->ID;
} }
return $urlSegment; return $urlSegment;
} }
/** /**
* Returns TRUE if this object has a URL segment value that does not conflict with any other * Returns TRUE if this object has a URL segment value that does not conflict with any other
* objects. * objects.
* *
* @return bool * @return bool
*/ */
public function validURLSegment() { public function validURLSegment()
$conflict = Member::get()->filter('URLSegment', $this->owner->URLSegment); {
$conflict = Member::get()->filter('URLSegment', $this->owner->URLSegment);
if($this->owner->ID) { if ($this->owner->ID) {
$conflict = $conflict->exclude('ID', $this->owner->ID); $conflict = $conflict->exclude('ID', $this->owner->ID);
} }
return $conflict->count() == 0; return $conflict->count() == 0;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function updateCMSFields(FieldList $fields) { public function updateCMSFields(FieldList $fields)
$fields->removeByName('URLSegment'); {
$fields->removeByName('URLSegment');
// Remove the automatically-generated posts tab. // Remove the automatically-generated posts tab.
$fields->removeFieldFromTab('Root', 'BlogPosts'); $fields->removeFieldFromTab('Root', 'BlogPosts');
// Construct a better posts tab. // Construct a better posts tab.
Requirements::css(BLOGGER_DIR . '/css/cms.css'); Requirements::css(BLOGGER_DIR . '/css/cms.css');
Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); Requirements::javascript(BLOGGER_DIR . '/js/cms.js');
$tab = new Tab('BlogPosts', 'Blog Posts'); $tab = new Tab('BlogPosts', 'Blog Posts');
$gridField = new GridField( $gridField = new GridField(
'BlogPosts', 'BlogPosts',
'Blog Posts', 'Blog Posts',
$this->owner->BlogPosts(), $this->owner->BlogPosts(),
new GridFieldConfig_BlogPost() new GridFieldConfig_BlogPost()
); );
$tab->Fields()->add($gridField); $tab->Fields()->add($gridField);
$fields->addFieldToTab('Root', $tab); $fields->addFieldToTab('Root', $tab);
return $fields; return $fields;
} }
} }

View File

@ -1,42 +1,45 @@
<?php <?php
/** /**
* This is responsible for filtering only published posts to users who do not have permission to * This is responsible for filtering only published posts to users who do not have permission to
* view non-published posts. * view non-published posts.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class BlogPostFilter extends DataExtension { class BlogPostFilter extends DataExtension
/** {
* Augment queries so that we don't fetch unpublished articles. /**
* * Augment queries so that we don't fetch unpublished articles.
* @param SQLQuery $query *
*/ * @param SQLQuery $query
public function augmentSQL(SQLQuery &$query) { */
$stage = Versioned::current_stage(); public function augmentSQL(SQLQuery &$query)
{
if (Controller::curr() instanceof LeftAndMain) { $stage = Versioned::current_stage();
return;
} if (Controller::curr() instanceof LeftAndMain) {
return;
if($stage == 'Live' || !Permission::check('VIEW_DRAFT_CONTENT')) { }
$query->addWhere(sprintf('"PublishDate" < \'%s\'', 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
* @see https://github.com/silverstripe/silverstripe-framework/issues/1682 * PublishDate causes an error.
* *
* @param SQLQuery $query * @see https://github.com/silverstripe/silverstripe-framework/issues/1682
* @param mixed $dataQuery *
* @param mixed $parent * @param SQLQuery $query
*/ * @param mixed $dataQuery
public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent) { * @param mixed $parent
$dataQuery->innerJoin('BlogPost', '"SiteTree"."ID" = "BlogPost"."ID"'); */
} public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent)
} {
$dataQuery->innerJoin('BlogPost', '"SiteTree"."ID" = "BlogPost"."ID"');
}
}

View File

@ -5,25 +5,28 @@
* *
* Extends {@see BlogPost} with extensions to {@see CommentNotifiable}. * Extends {@see BlogPost} with extensions to {@see CommentNotifiable}.
*/ */
class BlogPostNotifications extends DataExtension { class BlogPostNotifications extends DataExtension
/** {
* Notify all authors of notifications. /**
* * Notify all authors of notifications.
* @param SS_List $list *
* @param mixed $comment * @param SS_List $list
*/ * @param mixed $comment
public function updateNotificationRecipients(&$list, &$comment) { */
$list = $this->owner->Authors(); public function updateNotificationRecipients(&$list, &$comment)
} {
$list = $this->owner->Authors();
}
/** /**
* Update comment to include the page title. * Update comment to include the page title.
* *
* @param string $subject * @param string $subject
* @param Comment $comment * @param Comment $comment
* @param Member|string $recipient * @param Member|string $recipient
*/ */
public function updateNotificationSubject(&$subject, &$comment, &$recipient) { public function updateNotificationSubject(&$subject, &$comment, &$recipient)
$subject = sprintf('A new comment has been posted on ', $this->owner->Title); {
} $subject = sprintf('A new comment has been posted on ', $this->owner->Title);
}
} }

View File

@ -6,56 +6,59 @@
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class URLSegmentExtension extends DataExtension { class URLSegmentExtension extends DataExtension
/** {
* @var array /**
*/ * @var array
private static $db = array( */
'URLSegment' => 'Varchar(255)', private static $db = array(
); 'URLSegment' => 'Varchar(255)',
);
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function onBeforeWrite() { public function onBeforeWrite()
$this->owner->generateURLSegment(); {
} $this->owner->generateURLSegment();
}
/** /**
* Generates a unique URLSegment from the title. * Generates a unique URLSegment from the title.
* *
* @param int $increment * @param int $increment
* *
* @return string * @return string
*/ */
public function generateURLSegment($increment = null) { public function generateURLSegment($increment = null)
$filter = new URLSegmentFilter(); {
$filter = new URLSegmentFilter();
$this->owner->URLSegment = $filter->filter($this->owner->Title); $this->owner->URLSegment = $filter->filter($this->owner->Title);
if(is_int($increment)) { if (is_int($increment)) {
$this->owner->URLSegment .= '-' . $increment; $this->owner->URLSegment .= '-' . $increment;
} }
$duplicate = DataList::create($this->owner->ClassName)->filter(array( $duplicate = DataList::create($this->owner->ClassName)->filter(array(
'URLSegment' => $this->owner->URLSegment, 'URLSegment' => $this->owner->URLSegment,
'BlogID' => $this->owner->BlogID, 'BlogID' => $this->owner->BlogID,
)); ));
if($this->owner->ID) { if ($this->owner->ID) {
$duplicate = $duplicate->exclude('ID', $this->owner->ID); $duplicate = $duplicate->exclude('ID', $this->owner->ID);
} }
if($duplicate->count() > 0) { if ($duplicate->count() > 0) {
if(is_int($increment)) { if (is_int($increment)) {
$increment += 1; $increment += 1;
} else { } else {
$increment = 0; $increment = 0;
} }
$this->owner->generateURLSegment((int) $increment); $this->owner->generateURLSegment((int) $increment);
} }
return $this->owner->URLSegment; return $this->owner->URLSegment;
} }
} }

View File

@ -1,16 +1,18 @@
<?php <?php
class BlogAdminSidebar extends FieldGroup { class BlogAdminSidebar extends FieldGroup
/** {
* @return bool /**
*/ * @return bool
public function isOpen() { */
$sidebar = Cookie::get('blog-admin-sidebar'); public function isOpen()
{
if($sidebar == 1 || is_null($sidebar)) { $sidebar = Cookie::get('blog-admin-sidebar');
return true;
} if ($sidebar == 1 || is_null($sidebar)) {
return true;
return false; }
}
} return false;
}
}

View File

@ -1,193 +1,200 @@
<?php <?php
/** /**
* Adds a component which allows a user to add a new DataObject by database field. * Adds a component which allows a user to add a new DataObject by database field.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class GridFieldAddByDBField implements GridField_ActionProvider, GridField_HTMLProvider { class GridFieldAddByDBField implements GridField_ActionProvider, GridField_HTMLProvider
/** {
* HTML Fragment to render the field. /**
* * HTML Fragment to render the field.
* @var string *
*/ * @var string
protected $targetFragment; */
protected $targetFragment;
/**
* Default field to create the DataObject by should be Title. /**
* * Default field to create the DataObject by should be Title.
* @var string *
*/ * @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. * Creates a text field and add button which allows the user to directly create a new
* * DataObject by just entering the title.
* @param string $targetFragment *
* @param string $dataObjectField * @param string $targetFragment
*/ * @param string $dataObjectField
public function __construct($targetFragment = 'before', $dataObjectField = 'Title') { */
$this->targetFragment = $targetFragment; public function __construct($targetFragment = 'before', $dataObjectField = 'Title')
$this->dataObjectField = (string) $dataObjectField; {
} $this->targetFragment = $targetFragment;
$this->dataObjectField = (string) $dataObjectField;
/** }
* Provide actions to this component.
* /**
* @param GridField $gridField * Provide actions to this component.
* *
* @return array * @param GridField $gridField
*/ *
public function getActions($gridField) { * @return array
return array( */
'add', public function getActions($gridField)
); {
} return array(
'add',
/** );
* Handles the add action for the given DataObject. }
*
* @param $gridField GridField /**
* @param $actionName string * Handles the add action for the given DataObject.
* @param $arguments mixed *
* @param $data array * @param $gridField GridField
* * @param $actionName string
* @return null|SS_HTTPResponse * @param $arguments mixed
* * @param $data array
* @throws UnexpectedValueException *
*/ * @return null|SS_HTTPResponse
public function handleAction(GridField $gridField, $actionName, $arguments, $data) { *
if($actionName == 'add') { * @throws UnexpectedValueException
$dbField = $this->getDataObjectField(); */
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
$objClass = $gridField->getModelClass(); {
if ($actionName == 'add') {
/** $dbField = $this->getDataObjectField();
* @var DataObject $obj
*/ $objClass = $gridField->getModelClass();
$obj = new $objClass();
/**
if($obj->hasField($dbField)) { * @var DataObject $obj
$obj->setCastedField($dbField, $data['gridfieldaddbydbfield'][$obj->ClassName][$dbField]); */
$obj = new $objClass();
if($obj->canCreate()) {
$id = $gridField->getList()->add($obj); if ($obj->hasField($dbField)) {
if(!$id) { $obj->setCastedField($dbField, $data['gridfieldaddbydbfield'][$obj->ClassName][$dbField]);
$gridField->setError(
_t( if ($obj->canCreate()) {
'GridFieldAddByDBField.AddFail', $id = $gridField->getList()->add($obj);
'Unable to save {class} to the database.', if (!$id) {
'Unable to add the DataObject.', $gridField->setError(
array( _t(
'class' => get_class($obj), 'GridFieldAddByDBField.AddFail',
) 'Unable to save {class} to the database.',
), 'Unable to add the DataObject.',
'error' array(
); 'class' => get_class($obj),
} )
} else { ),
return Security::permissionFailure( 'error'
Controller::curr(), );
_t( }
'GridFieldAddByDBField.PermissionFail', } else {
'You don\'t have permission to create a {class}.', return Security::permissionFailure(
'Unable to add the DataObject.', Controller::curr(),
array( _t(
'class' => get_class($obj) 'GridFieldAddByDBField.PermissionFail',
) 'You don\'t have permission to create a {class}.',
) 'Unable to add the DataObject.',
); array(
} 'class' => get_class($obj)
} else { )
throw new UnexpectedValueException( )
sprintf( );
'Invalid field (%s) on %s.', }
$dbField, } else {
$obj->ClassName throw new UnexpectedValueException(
) sprintf(
); 'Invalid field (%s) on %s.',
} $dbField,
} $obj->ClassName
)
return null; );
} }
}
/**
* Returns the database field for which we'll add the new data object. return null;
* }
* @return string
*/ /**
public function getDataObjectField() { * Returns the database field for which we'll add the new data object.
return $this->dataObjectField; *
} * @return string
*/
/** public function getDataObjectField()
* Set the database field. {
* return $this->dataObjectField;
* @param $field string }
*/
public function setDataObjectField($field) { /**
$this->dataObjectField = (string) $field; * Set the database field.
} *
* @param $field string
/** */
* Renders the TextField and add button to the GridField. public function setDataObjectField($field)
* {
* @param $gridField GridField $this->dataObjectField = (string) $field;
* }
* @return string
*/ /**
public function getHTMLFragments($gridField) { * Renders the TextField and add button to the GridField.
/** *
* @var DataList $dataList * @param $gridField GridField
*/ *
$dataList = $gridField->getList(); * @return string
*/
$dataClass = $dataList->dataClass(); public function getHTMLFragments($gridField)
{
$obj = singleton($dataClass); /**
* @var DataList $dataList
if(!$obj->canCreate()) { */
return ""; $dataList = $gridField->getList();
}
$dataClass = $dataList->dataClass();
$dbField = $this->getDataObjectField();
$obj = singleton($dataClass);
$textField = TextField::create(
sprintf( if (!$obj->canCreate()) {
"gridfieldaddbydbfield[%s][%s]", return "";
$obj->ClassName, }
Convert::raw2htmlatt($dbField)
) $dbField = $this->getDataObjectField();
)
->setAttribute('placeholder', $obj->fieldLabel($dbField)) $textField = TextField::create(
->addExtraClass('no-change-track'); sprintf(
"gridfieldaddbydbfield[%s][%s]",
$addAction = new GridField_FormAction( $obj->ClassName,
$gridField, Convert::raw2htmlatt($dbField)
'add', )
_t('GridFieldAddByDBField.Add', )
'Add {name}', "Add button text", ->setAttribute('placeholder', $obj->fieldLabel($dbField))
array( ->addExtraClass('no-change-track');
'name' => $obj->i18n_singular_name(),
) $addAction = new GridField_FormAction(
), $gridField,
'add', 'add',
'add' _t('GridFieldAddByDBField.Add',
); 'Add {name}', "Add button text",
array(
$addAction->setAttribute('data-icon', 'add'); 'name' => $obj->i18n_singular_name(),
)
$forTemplate = new ArrayData(array()); ),
'add',
$forTemplate->Fields = new ArrayList(); 'add'
$forTemplate->Fields->push($textField); );
$forTemplate->Fields->push($addAction);
$addAction->setAttribute('data-icon', 'add');
return array(
$this->targetFragment => $forTemplate->renderWith('GridFieldAddByDBField') $forTemplate = new ArrayData(array());
);
} $forTemplate->Fields = new ArrayList();
} $forTemplate->Fields->push($textField);
$forTemplate->Fields->push($addAction);
return array(
$this->targetFragment => $forTemplate->renderWith('GridFieldAddByDBField')
);
}
}

View File

@ -1,94 +1,97 @@
<?php <?php
/** /**
* Provides a component to the {@link GridField} which tells the user whether or not a blog post * Provides a component to the {@link GridField} which tells the user whether or not a blog post
* has been published and when. * has been published and when.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class GridFieldBlogPostState extends GridFieldSiteTreeState { class GridFieldBlogPostState extends GridFieldSiteTreeState
/** {
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function getColumnContent($gridField, $record, $columnName) { */
if($columnName == 'State') { public function getColumnContent($gridField, $record, $columnName)
Requirements::css(BLOGGER_DIR . '/css/cms.css'); {
if($record instanceof BlogPost) { if ($columnName == 'State') {
$modifiedLabel = ''; Requirements::css(BLOGGER_DIR . '/css/cms.css');
if ($record instanceof BlogPost) {
if($record->isModifiedOnStage) { $modifiedLabel = '';
$modifiedLabel = '<span class="modified">' . _t('GridFieldBlogPostState.Modified') . '</span>';
} if ($record->isModifiedOnStage) {
$modifiedLabel = '<span class="modified">' . _t('GridFieldBlogPostState.Modified') . '</span>';
if(!$record->isPublished()) { }
/**
* @var SS_Datetime $lastEdited if (!$record->isPublished()) {
*/ /**
$lastEdited = $record->dbObject('LastEdited'); * @var SS_Datetime $lastEdited
*/
return _t( $lastEdited = $record->dbObject('LastEdited');
'GridFieldBlogPostState.Draft',
'<i class="btn-icon gridfield-icon btn-icon-pencil"></i> Saved as Draft on {date}', return _t(
'State for when a post is saved.', 'GridFieldBlogPostState.Draft',
array( '<i class="btn-icon gridfield-icon btn-icon-pencil"></i> Saved as Draft on {date}',
'date' => $lastEdited->Nice(), 'State for when a post is saved.',
) array(
); 'date' => $lastEdited->Nice(),
} )
);
/** }
* @var SS_Datetime $publishDate
*/ /**
$publishDate = $record->dbObject('PublishDate'); * @var SS_Datetime $publishDate
*/
if(strtotime($record->PublishDate) > time()) { $publishDate = $record->dbObject('PublishDate');
return _t(
'GridFieldBlogPostState.Timer', if (strtotime($record->PublishDate) > time()) {
'<i class="gridfield-icon blog-icon-timer"></i> Publish at {date}', return _t(
'State for when a post is published.', 'GridFieldBlogPostState.Timer',
array( '<i class="gridfield-icon blog-icon-timer"></i> Publish at {date}',
'date' => $publishDate->Nice(), 'State for when a post is published.',
) array(
) . $modifiedLabel; 'date' => $publishDate->Nice(),
} )
) . $modifiedLabel;
return _t( }
'GridFieldBlogPostState.Published',
'<i class="btn-icon gridfield-icon btn-icon-accept"></i> Published on {date}', return _t(
'State for when a post is published.', 'GridFieldBlogPostState.Published',
array( '<i class="btn-icon gridfield-icon btn-icon-accept"></i> Published on {date}',
'date' => $publishDate->Nice(), 'State for when a post is published.',
) array(
) . $modifiedLabel; 'date' => $publishDate->Nice(),
} )
} ) . $modifiedLabel;
}
return ''; }
}
return '';
/** }
* {@inheritdoc}
*/ /**
public function getColumnAttributes($gridField, $record, $columnName) { * {@inheritdoc}
if($columnName == 'State') { */
if($record instanceof BlogPost) { public function getColumnAttributes($gridField, $record, $columnName)
$published = $record->isPublished(); {
if ($columnName == 'State') {
if(!$published) { if ($record instanceof BlogPost) {
$class = 'gridfield-icon draft'; $published = $record->isPublished();
} else if(strtotime($record->PublishDate) > time()) {
$class = 'gridfield-icon timer'; if (!$published) {
} else { $class = 'gridfield-icon draft';
$class = 'gridfield-icon published'; } elseif (strtotime($record->PublishDate) > time()) {
} $class = 'gridfield-icon timer';
} else {
return array( $class = 'gridfield-icon published';
'class' => $class, }
);
} return array(
} 'class' => $class,
);
return array(); }
} }
}
return array();
}
}

View File

@ -1,19 +1,21 @@
<?php <?php
/** /**
* GridField config necessary for managing a SiteTree object. * GridField config necessary for managing a SiteTree object.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class GridFieldConfig_BlogPost extends GridFieldConfig_Lumberjack { class GridFieldConfig_BlogPost extends GridFieldConfig_Lumberjack
/** {
* @param null|int $itemsPerPage /**
*/ * @param null|int $itemsPerPage
public function __construct($itemsPerPage = null) { */
parent::__construct($itemsPerPage); public function __construct($itemsPerPage = null)
{
$this->removeComponentsByType('GridFieldSiteTreeState'); parent::__construct($itemsPerPage);
$this->addComponent(new GridFieldBlogPostState());
} $this->removeComponentsByType('GridFieldSiteTreeState');
} $this->addComponent(new GridFieldBlogPostState());
}
}

View File

@ -1,1045 +1,1086 @@
<?php <?php
/** /**
* Blog Holder * Blog Holder
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
* *
* @method HasManyList Tags() List of tags in this blog * @method HasManyList Tags() List of tags in this blog
* @method HasManyList Categories() List of categories in this blog * @method HasManyList Categories() List of categories in this blog
* @method ManyManyList Editors() List of editors * @method ManyManyList Editors() List of editors
* @method ManyManyList Writers() List of writers * @method ManyManyList Writers() List of writers
* @method ManyManyList Contributors() List of contributors * @method ManyManyList Contributors() List of contributors
*/ */
class Blog extends Page implements PermissionProvider { class Blog extends Page implements PermissionProvider
/** {
* Permission for user management. /**
* * Permission for user management.
* @var string *
*/ * @var string
const MANAGE_USERS = 'BLOG_MANAGE_USERS'; */
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 * If true, users assigned as editor, writer, or contributor will be automatically granted
* assigned. * CMS_ACCESS_CMSMain permission. If false, only users with this permission already may be
* * assigned.
* @config *
* * @config
* @var boolean *
*/ * @var boolean
private static $grant_user_access = true; */
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 *
* * @config
* @var string *
*/ * @var string
private static $grant_user_permission = 'CMS_ACCESS_CMSMain'; */
private static $grant_user_permission = 'CMS_ACCESS_CMSMain';
/**
* Group code to assign newly granted users to. /**
* * Group code to assign newly granted users to.
* @config *
* * @config
* @var string *
*/ * @var string
private static $grant_user_group = 'blog-users'; */
private static $grant_user_group = 'blog-users';
/**
* @var array /**
*/ * @var array
private static $db = array( */
'PostsPerPage' => 'Int', private static $db = array(
); 'PostsPerPage' => 'Int',
);
/**
* @var array /**
*/ * @var array
private static $has_many = array( */
'Tags' => 'BlogTag', private static $has_many = array(
'Categories' => 'BlogCategory', 'Tags' => 'BlogTag',
); 'Categories' => 'BlogCategory',
);
/**
* @var array /**
*/ * @var array
private static $many_many = array( */
'Editors' => 'Member', private static $many_many = array(
'Writers' => 'Member', 'Editors' => 'Member',
'Contributors' => 'Member', 'Writers' => 'Member',
); 'Contributors' => 'Member',
);
/**
* @var array /**
*/ * @var array
private static $allowed_children = array( */
'BlogPost', private static $allowed_children = array(
); 'BlogPost',
);
/**
* @var array /**
*/ * @var array
private static $extensions = array( */
'BlogFilter', private static $extensions = array(
); 'BlogFilter',
);
/**
* @var array /**
*/ * @var array
private static $defaults = array( */
'ProvideComments' => false, private static $defaults = array(
'PostsPerPage' => 10, 'ProvideComments' => false,
); 'PostsPerPage' => 10,
);
/**
* @var string /**
*/ * @var string
private static $description = 'Adds a blog to your website.'; */
private static $description = 'Adds a blog to your website.';
/**
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function getCMSFields() { */
Requirements::css(BLOGGER_DIR . '/css/cms.css'); public function getCMSFields()
Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); {
Requirements::css(BLOGGER_DIR . '/css/cms.css');
$self =& $this; Requirements::javascript(BLOGGER_DIR . '/js/cms.js');
$this->beforeUpdateCMSFields(function ($fields) use ($self) { $self =& $this;
if(!$self->canEdit()) {
return; $this->beforeUpdateCMSFields(function ($fields) use ($self) {
} if (!$self->canEdit()) {
return;
$categories = GridField::create( }
'Categories',
_t('Blog.Categories', 'Categories'), $categories = GridField::create(
$self->Categories(), 'Categories',
GridFieldCategorisationConfig::create(15, $self->Categories()->sort('Title'), 'BlogCategory', 'Categories', 'BlogPosts') _t('Blog.Categories', 'Categories'),
); $self->Categories(),
GridFieldCategorisationConfig::create(15, $self->Categories()->sort('Title'), 'BlogCategory', 'Categories', 'BlogPosts')
$tags = GridField::create( );
'Tags',
_t('Blog.Tags', 'Tags'), $tags = GridField::create(
$self->Tags(), 'Tags',
GridFieldCategorisationConfig::create(15, $self->Tags()->sort('Title'), 'BlogTag', 'Tags', 'BlogPosts') _t('Blog.Tags', 'Tags'),
); $self->Tags(),
GridFieldCategorisationConfig::create(15, $self->Tags()->sort('Title'), 'BlogTag', 'Tags', 'BlogPosts')
/** );
* @var FieldList $fields
*/ /**
$fields->addFieldsToTab('Root.Categorisation', array( * @var FieldList $fields
$categories, */
$tags $fields->addFieldsToTab('Root.Categorisation', array(
)); $categories,
$tags
$fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation'); ));
});
$fields->findOrMakeTab('Root.Categorisation')->addExtraClass('blog-cms-categorisation');
return parent::getCMSFields(); });
}
return parent::getCMSFields();
/** }
* {@inheritdoc}
*/ /**
public function canEdit($member = null) { * {@inheritdoc}
$member = $this->getMember($member); */
public function canEdit($member = null)
if($this->isEditor($member)) { {
return true; $member = $this->getMember($member);
}
if ($this->isEditor($member)) {
return parent::canEdit($member); return true;
} }
/** return parent::canEdit($member);
* @param null|int|Member $member }
*
* @return null|Member /**
*/ * @param null|int|Member $member
protected function getMember($member = null) { *
if(!$member) { * @return null|Member
$member = Member::currentUser(); */
} protected function getMember($member = null)
{
if(is_numeric($member)) { if (!$member) {
$member = Member::get()->byID($member); $member = Member::currentUser();
} }
return $member; if (is_numeric($member)) {
} $member = Member::get()->byID($member);
}
/**
* Check if this member is an editor of the blog. return $member;
* }
* @param Member $member
* /**
* @return bool * Check if this member is an editor of the blog.
*/ *
public function isEditor($member) { * @param Member $member
$isEditor = $this->isMemberOf($member, $this->Editors()); *
$this->extend('updateIsEditor', $isEditor, $member); * @return bool
*/
return $isEditor; public function isEditor($member)
} {
$isEditor = $this->isMemberOf($member, $this->Editors());
/** $this->extend('updateIsEditor', $isEditor, $member);
* Determine if the given member belongs to the given relation.
* return $isEditor;
* @param Member $member }
* @param DataList $relation
* /**
* @return bool * Determine if the given member belongs to the given relation.
*/ *
protected function isMemberOf($member, $relation) { * @param Member $member
if(!$member || !$member->exists()) { * @param DataList $relation
return false; *
} * @return bool
*/
if($relation instanceof UnsavedRelationList) { protected function isMemberOf($member, $relation)
return in_array($member->ID, $relation->getIDList()); {
} if (!$member || !$member->exists()) {
return false;
return $relation->byID($member->ID) !== null; }
}
if ($relation instanceof UnsavedRelationList) {
/** return in_array($member->ID, $relation->getIDList());
* Determine the role of the given member. }
*
* Call be called via template to determine the current user. return $relation->byID($member->ID) !== null;
* }
* @example "Hello $RoleOf($CurrentMember.ID)"
* /**
* @param int|Member $member * Determine the role of the given member.
* *
* @return null|string * Call be called via template to determine the current user.
*/ *
public function RoleOf($member) { * @example "Hello $RoleOf($CurrentMember.ID)"
if(is_numeric($member)) { *
$member = DataObject::get_by_id('Member', $member); * @param int|Member $member
} *
* @return null|string
if(!$member) { */
return null; public function RoleOf($member)
} {
if (is_numeric($member)) {
if($this->isEditor($member)) { $member = DataObject::get_by_id('Member', $member);
return _t('Blog.EDITOR', 'Editor'); }
}
if (!$member) {
if($this->isWriter($member)) { return null;
return _t('Blog.WRITER', 'Writer'); }
}
if ($this->isEditor($member)) {
if($this->isContributor($member)) { return _t('Blog.EDITOR', 'Editor');
return _t('Blog.CONTRIBUTOR', 'Contributor'); }
}
if ($this->isWriter($member)) {
return null; return _t('Blog.WRITER', 'Writer');
} }
/** if ($this->isContributor($member)) {
* Check if this member is a writer of the blog. return _t('Blog.CONTRIBUTOR', 'Contributor');
* }
* @param Member $member
* return null;
* @return bool }
*/
public function isWriter($member) { /**
$isWriter = $this->isMemberOf($member, $this->Writers()); * Check if this member is a writer of the blog.
$this->extend('updateIsWriter', $isWriter, $member); *
* @param Member $member
return $isWriter; *
} * @return bool
*/
/** public function isWriter($member)
* Check if this member is a contributor of the blog. {
* $isWriter = $this->isMemberOf($member, $this->Writers());
* @param Member $member $this->extend('updateIsWriter', $isWriter, $member);
*
* @return bool return $isWriter;
*/ }
public function isContributor($member) {
$isContributor = $this->isMemberOf($member, $this->Contributors()); /**
$this->extend('updateIsContributor', $isContributor, $member); * Check if this member is a contributor of the blog.
*
return $isContributor; * @param Member $member
} *
* @return bool
/** */
* {@inheritdoc} public function isContributor($member)
*/ {
public function canAddChildren($member = null) { $isContributor = $this->isMemberOf($member, $this->Contributors());
$member = $this->getMember($member); $this->extend('updateIsContributor', $isContributor, $member);
if($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) { return $isContributor;
return true; }
}
/**
return parent::canAddChildren($member); * {@inheritdoc}
} */
public function canAddChildren($member = null)
/** {
* {@inheritdoc} $member = $this->getMember($member);
*/
public function getSettingsFields() { if ($this->isEditor($member) || $this->isWriter($member) || $this->isContributor($member)) {
$fields = parent::getSettingsFields(); return true;
}
$fields->addFieldToTab('Root.Settings',
NumericField::create('PostsPerPage', _t('Blog.PostsPerPage', 'Posts Per Page')) return parent::canAddChildren($member);
); }
$members = $this->getCandidateUsers()->map()->toArray(); /**
* {@inheritdoc}
$editorField = ListboxField::create('Editors', 'Editors', $members) */
->setMultiple(true) public function getSettingsFields()
->setRightTitle('<a class="toggle-description">help</a>') {
->setDescription(' $fields = parent::getSettingsFields();
An editor has control over specific Blogs, and all posts included within it. Short of being able to assign other editors to a blog, they are able to handle most changes to their assigned blog.<br />
<br /> $fields->addFieldToTab('Root.Settings',
Editors have these permissions:<br /> NumericField::create('PostsPerPage', _t('Blog.PostsPerPage', 'Posts Per Page'))
<br /> );
Update or publish any BlogPost in their Blog<br />
Update or publish their Blog<br /> $members = $this->getCandidateUsers()->map()->toArray();
Assign/unassign writers to their Blog<br />
Assign/unassign contributors to their Blog<br /> $editorField = ListboxField::create('Editors', 'Editors', $members)
Assign/unassign any member as an author of a particular BlogPost ->setMultiple(true)
'); ->setRightTitle('<a class="toggle-description">help</a>')
->setDescription('
if(!$this->canEditEditors()) { An editor has control over specific Blogs, and all posts included within it. Short of being able to assign other editors to a blog, they are able to handle most changes to their assigned blog.<br />
$editorField = $editorField->performDisabledTransformation(); <br />
} Editors have these permissions:<br />
<br />
$writerField = ListboxField::create('Writers', 'Writers', $members) Update or publish any BlogPost in their Blog<br />
->setMultiple(true) Update or publish their Blog<br />
->setRightTitle('<a class="toggle-description">help</a>') Assign/unassign writers to their Blog<br />
->setDescription(' Assign/unassign contributors to their Blog<br />
A writer has full control over creating, editing and publishing BlogPosts they have authored or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.<br /> Assign/unassign any member as an author of a particular BlogPost
<br /> ');
Writers have these permissions:<br />
<br /> if (!$this->canEditEditors()) {
Update or publish any BlogPost they have authored or have been assigned to<br /> $editorField = $editorField->performDisabledTransformation();
Assign/unassign any member as an author of a particular BlogPost they have authored or have been assigned to }
');
$writerField = ListboxField::create('Writers', 'Writers', $members)
if(!$this->canEditWriters()) { ->setMultiple(true)
$writerField = $writerField->performDisabledTransformation(); ->setRightTitle('<a class="toggle-description">help</a>')
} ->setDescription('
A writer has full control over creating, editing and publishing BlogPosts they have authored or have been assigned to. Writers are unable to edit BlogPosts to which they are not assigned.<br />
$contributorField = ListboxField::create('Contributors', 'Contributors', $members) <br />
->setMultiple(true) Writers have these permissions:<br />
->setRightTitle('<a class="toggle-description">help</a>') <br />
->setDescription(' Update or publish any BlogPost they have authored or have been assigned to<br />
Contributors have the ability to create or edit BlogPosts, but are unable to publish without authorisation of an editor. They are also unable to assign other contributing authors to any of their BlogPosts.<br /> Assign/unassign any member as an author of a particular BlogPost they have authored or have been assigned to
<br /> ');
Contributors have these permissions:<br />
<br /> if (!$this->canEditWriters()) {
Update any BlogPost they have authored or have been assigned to $writerField = $writerField->performDisabledTransformation();
'); }
if(!$this->canEditContributors()) { $contributorField = ListboxField::create('Contributors', 'Contributors', $members)
$contributorField = $contributorField->performDisabledTransformation(); ->setMultiple(true)
} ->setRightTitle('<a class="toggle-description">help</a>')
->setDescription('
$fields->addFieldsToTab('Root.Users', array( Contributors have the ability to create or edit BlogPosts, but are unable to publish without authorisation of an editor. They are also unable to assign other contributing authors to any of their BlogPosts.<br />
$editorField, <br />
$writerField, Contributors have these permissions:<br />
$contributorField <br />
)); Update any BlogPost they have authored or have been assigned to
');
return $fields;
} if (!$this->canEditContributors()) {
$contributorField = $contributorField->performDisabledTransformation();
/** }
* Gets the list of user candidates to be assigned to assist with this blog.
* $fields->addFieldsToTab('Root.Users', array(
* @return SS_List $editorField,
*/ $writerField,
protected function getCandidateUsers() { $contributorField
if($this->config()->grant_user_access) { ));
$list = Member::get();
$this->extend('updateCandidateUsers', $list); return $fields;
return $list; }
} else {
return Permission::get_members_by_permission( /**
$this->config()->grant_user_permission * Gets the list of user candidates to be assigned to assist with this blog.
); *
} * @return SS_List
} */
protected function getCandidateUsers()
/** {
* Determine if this user can edit the editors list. if ($this->config()->grant_user_access) {
* $list = Member::get();
* @param int|Member $member $this->extend('updateCandidateUsers', $list);
* return $list;
* @return bool } else {
*/ return Permission::get_members_by_permission(
public function canEditEditors($member = null) { $this->config()->grant_user_permission
$member = $this->getMember($member); );
}
$extended = $this->extendedCan('canEditEditors', $member); }
if($extended !== null) { /**
return $extended; * Determine if this user can edit the editors list.
} *
* @param int|Member $member
return Permission::checkMember($member, self::MANAGE_USERS); *
} * @return bool
*/
/** public function canEditEditors($member = null)
* Determine if this user can edit writers list. {
* $member = $this->getMember($member);
* @param int|Member $member
* $extended = $this->extendedCan('canEditEditors', $member);
* @return boolean
*/ if ($extended !== null) {
public function canEditWriters($member = null) { return $extended;
$member = $this->getMember($member); }
$extended = $this->extendedCan('canEditWriters', $member); return Permission::checkMember($member, self::MANAGE_USERS);
}
if($extended !== null) {
return $extended; /**
} * Determine if this user can edit writers list.
*
if($this->isEditor($member)) { * @param int|Member $member
return true; *
} * @return boolean
*/
return Permission::checkMember($member, self::MANAGE_USERS); public function canEditWriters($member = null)
} {
$member = $this->getMember($member);
/**
* Determines if this user can edit the contributors list. $extended = $this->extendedCan('canEditWriters', $member);
*
* @param int|Member $member if ($extended !== null) {
* return $extended;
* @return boolean }
*/
public function canEditContributors($member = null) { if ($this->isEditor($member)) {
$member = $this->getMember($member); return true;
}
$extended = $this->extendedCan('canEditContributors', $member);
return Permission::checkMember($member, self::MANAGE_USERS);
if($extended !== null) { }
return $extended;
} /**
* Determines if this user can edit the contributors list.
if($this->isEditor($member)) { *
return true; * @param int|Member $member
} *
* @return boolean
return Permission::checkMember($member, self::MANAGE_USERS); */
} public function canEditContributors($member = null)
{
/** $member = $this->getMember($member);
* Returns BlogPosts for a given date period.
* $extended = $this->extendedCan('canEditContributors', $member);
* @param int $year
* @param null|int $month if ($extended !== null) {
* @param null|int $day return $extended;
* }
* @return DataList
*/ if ($this->isEditor($member)) {
public function getArchivedBlogPosts($year, $month = null, $day = null) { return true;
$query = $this->getBlogPosts()->dataQuery(); }
$stage = $query->getQueryParam('Versioned.stage'); return Permission::checkMember($member, self::MANAGE_USERS);
}
if($stage) {
$stage = '_' . $stage; /**
} * Returns BlogPosts for a given date period.
*
$query->innerJoin('BlogPost', sprintf('"SiteTree%s"."ID" = "BlogPost%s"."ID"', $stage, $stage)); * @param int $year
* @param null|int $month
$query->where(sprintf('YEAR("PublishDate") = \'%s\'', Convert::raw2sql($year))); * @param null|int $day
*
if($month) { * @return DataList
$query->where(sprintf('MONTH("PublishDate") = \'%s\'', Convert::raw2sql($month))); */
public function getArchivedBlogPosts($year, $month = null, $day = null)
if($day) { {
$query->where(sprintf('DAY("PublishDate") = \'%s\'', Convert::raw2sql($day))); $query = $this->getBlogPosts()->dataQuery();
}
} $stage = $query->getQueryParam('Versioned.stage');
return $this->getBlogPosts()->setDataQuery($query); if ($stage) {
} $stage = '_' . $stage;
}
/**
* Return blog posts. $query->innerJoin('BlogPost', sprintf('"SiteTree%s"."ID" = "BlogPost%s"."ID"', $stage, $stage));
*
* @return DataList of BlogPost objects $query->where(sprintf('YEAR("PublishDate") = \'%s\'', Convert::raw2sql($year)));
*/
public function getBlogPosts() { if ($month) {
$blogPosts = BlogPost::get()->filter('ParentID', $this->ID); $query->where(sprintf('MONTH("PublishDate") = \'%s\'', Convert::raw2sql($month)));
$this->extend('updateGetBlogPosts', $blogPosts); if ($day) {
$query->where(sprintf('DAY("PublishDate") = \'%s\'', Convert::raw2sql($day)));
return $blogPosts; }
} }
/** return $this->getBlogPosts()->setDataQuery($query);
* Get a link to a Member profile. }
*
* @param string $urlSegment /**
* * Return blog posts.
* @return string *
*/ * @return DataList of BlogPost objects
public function ProfileLink($urlSegment) { */
return Controller::join_links($this->Link(), 'profile', $urlSegment); public function getBlogPosts()
} {
$blogPosts = BlogPost::get()->filter('ParentID', $this->ID);
/**
* This sets the title for our gridfield. $this->extend('updateGetBlogPosts', $blogPosts);
*
* @return string return $blogPosts;
*/ }
public function getLumberjackTitle() {
return _t('Blog.LumberjackTitle', 'Blog Posts'); /**
} * Get a link to a Member profile.
*
/** * @param string $urlSegment
* This overwrites lumberjacks default gridfield config. *
* * @return string
* @return GridFieldConfig */
*/ public function ProfileLink($urlSegment)
public function getLumberjackGridFieldConfig() { {
return GridFieldConfig_BlogPost::create(); return Controller::join_links($this->Link(), 'profile', $urlSegment);
} }
/** /**
* {@inheritdoc} * This sets the title for our gridfield.
*/ *
public function providePermissions() { * @return string
return array( */
Blog::MANAGE_USERS => array( public function getLumberjackTitle()
'name' => _t( {
'Blog.PERMISSION_MANAGE_USERS_DESCRIPTION', return _t('Blog.LumberjackTitle', 'Blog Posts');
'Manage users for individual blogs' }
),
'help' => _t( /**
'Blog.PERMISSION_MANAGE_USERS_HELP', * This overwrites lumberjacks default gridfield config.
'Allow assignment of Editors, Writers, or Contributors to blogs' *
), * @return GridFieldConfig
'category' => _t('Blog.PERMISSIONS_CATEGORY', 'Blog permissions'), */
'sort' => 100 public function getLumberjackGridFieldConfig()
) {
); return GridFieldConfig_BlogPost::create();
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function onBeforeWrite() { public function providePermissions()
parent::onBeforeWrite(); {
$this->assignGroup(); return array(
} Blog::MANAGE_USERS => array(
'name' => _t(
/** 'Blog.PERMISSION_MANAGE_USERS_DESCRIPTION',
* Assign users as necessary to the blog group. 'Manage users for individual blogs'
*/ ),
protected function assignGroup() { 'help' => _t(
if(!$this->config()->grant_user_access) { 'Blog.PERMISSION_MANAGE_USERS_HELP',
return; 'Allow assignment of Editors, Writers, or Contributors to blogs'
} ),
'category' => _t('Blog.PERMISSIONS_CATEGORY', 'Blog permissions'),
$group = $this->getUserGroup(); 'sort' => 100
)
// Must check if the method exists or else an error occurs when changing page type );
if ($this->hasMethod('Editors')) { }
foreach(array($this->Editors(), $this->Writers(), $this->Contributors()) as $levels) {
foreach($levels as $user) { /**
if(!$user->inGroup($group)) { * {@inheritdoc}
$user->Groups()->add($group); */
} protected function onBeforeWrite()
} {
} parent::onBeforeWrite();
} $this->assignGroup();
} }
/** /**
* Gets or creates the group used to assign CMS access. * Assign users as necessary to the blog group.
* */
* @return Group protected function assignGroup()
*/ {
protected function getUserGroup() { if (!$this->config()->grant_user_access) {
$code = $this->config()->grant_user_group; return;
}
$group = Group::get()->filter('Code', $code)->first();
$group = $this->getUserGroup();
if($group) {
return $group; // Must check if the method exists or else an error occurs when changing page type
} if ($this->hasMethod('Editors')) {
foreach (array($this->Editors(), $this->Writers(), $this->Contributors()) as $levels) {
$group = new Group(); foreach ($levels as $user) {
$group->Title = 'Blog users'; if (!$user->inGroup($group)) {
$group->Code = $code; $user->Groups()->add($group);
}
$group->write(); }
}
$permission = new Permission(); }
$permission->Code = $this->config()->grant_user_permission; }
$group->Permissions()->add($permission); /**
* Gets or creates the group used to assign CMS access.
return $group; *
} * @return Group
} */
protected function getUserGroup()
/** {
* @package silverstripe $code = $this->config()->grant_user_group;
* @subpackage blog
*/ $group = Group::get()->filter('Code', $code)->first();
class Blog_Controller extends Page_Controller {
/** if ($group) {
* @var array return $group;
*/ }
private static $allowed_actions = array(
'archive', $group = new Group();
'tag', $group->Title = 'Blog users';
'category', $group->Code = $code;
'rss',
'profile', $group->write();
);
$permission = new Permission();
/** $permission->Code = $this->config()->grant_user_permission;
* @var array
*/ $group->Permissions()->add($permission);
private static $url_handlers = array(
'tag/$Tag!' => 'tag', return $group;
'category/$Category!' => 'category', }
'archive/$Year!/$Month/$Day' => 'archive', }
'profile/$URLSegment!' => 'profile',
); /**
* @package silverstripe
/** * @subpackage blog
* @var array */
*/ class Blog_Controller extends Page_Controller
private static $casting = array( {
'MetaTitle' => 'Text', /**
'FilterDescription' => 'Text', * @var array
); */
private static $allowed_actions = array(
/** 'archive',
* The current Blog Post DataList query. 'tag',
* 'category',
* @var DataList 'rss',
*/ 'profile',
protected $blogPosts; );
/** /**
* @return string * @var array
*/ */
public function index() { private static $url_handlers = array(
/** 'tag/$Tag!' => 'tag',
* @var Blog $dataRecord 'category/$Category!' => 'category',
*/ 'archive/$Year!/$Month/$Day' => 'archive',
$dataRecord = $this->dataRecord; 'profile/$URLSegment!' => 'profile',
);
$this->blogPosts = $dataRecord->getBlogPosts();
/**
return $this->render(); * @var array
} */
private static $casting = array(
/** 'MetaTitle' => 'Text',
* Renders a Blog Member's profile. 'FilterDescription' => 'Text',
* );
* @return SS_HTTPResponse
*/ /**
public function profile() { * The current Blog Post DataList query.
$profile = $this->getCurrentProfile(); *
* @var DataList
if(!$profile) { */
return $this->httpError(404, 'Not Found'); protected $blogPosts;
}
/**
$this->blogPosts = $this->getCurrentProfilePosts(); * @return string
*/
return $this->render(); public function index()
} {
/**
/** * @var Blog $dataRecord
* Get the Member associated with the current URL segment. */
* $dataRecord = $this->dataRecord;
* @return null|Member
*/ $this->blogPosts = $dataRecord->getBlogPosts();
public function getCurrentProfile() {
$urlSegment = $this->request->param('URLSegment'); return $this->render();
}
if($urlSegment) {
return Member::get() /**
->filter('URLSegment', $urlSegment) * Renders a Blog Member's profile.
->first(); *
} * @return SS_HTTPResponse
*/
return null; public function profile()
} {
$profile = $this->getCurrentProfile();
/**
* Get posts related to the current Member profile. if (!$profile) {
* return $this->httpError(404, 'Not Found');
* @return null|DataList }
*/
public function getCurrentProfilePosts() { $this->blogPosts = $this->getCurrentProfilePosts();
$profile = $this->getCurrentProfile();
return $this->render();
if($profile) { }
return $profile->BlogPosts()->filter('ParentID', $this->ID);
} /**
* Get the Member associated with the current URL segment.
return null; *
} * @return null|Member
*/
/** public function getCurrentProfile()
* Renders an archive for a specified date. This can be by year or year/month. {
* $urlSegment = $this->request->param('URLSegment');
* @return null|SS_HTTPResponse
*/ if ($urlSegment) {
public function archive() { return Member::get()
/** ->filter('URLSegment', $urlSegment)
* @var Blog $dataRecord ->first();
*/ }
$dataRecord = $this->dataRecord;
return null;
$year = $this->getArchiveYear(); }
$month = $this->getArchiveMonth();
$day = $this->getArchiveDay(); /**
* Get posts related to the current Member profile.
if($this->request->param('Month') && !$month) { *
$this->httpError(404, 'Not Found'); * @return null|DataList
} */
public function getCurrentProfilePosts()
if($month && $this->request->param('Day') && !$day) { {
$this->httpError(404, 'Not Found'); $profile = $this->getCurrentProfile();
}
if ($profile) {
if($year) { return $profile->BlogPosts()->filter('ParentID', $this->ID);
$this->blogPosts = $dataRecord->getArchivedBlogPosts($year, $month, $day); }
return $this->render(); return null;
} }
$this->httpError(404, 'Not Found'); /**
* Renders an archive for a specified date. This can be by year or year/month.
return null; *
} * @return null|SS_HTTPResponse
*/
/** public function archive()
* Fetches the archive year from the url. {
* /**
* @return int * @var Blog $dataRecord
*/ */
public function getArchiveYear() { $dataRecord = $this->dataRecord;
if($this->request->param('Year')){ $year = $this->getArchiveYear();
$month = $this->getArchiveMonth();
if(preg_match('/^[0-9]{4}$/', $year = $this->request->param('Year'))) { $day = $this->getArchiveDay();
return (int) $year;
} if ($this->request->param('Month') && !$month) {
} elseif($this->request->param('Action') == 'archive') { $this->httpError(404, 'Not Found');
return SS_Datetime::now()->Year(); }
}
if ($month && $this->request->param('Day') && !$day) {
return null; $this->httpError(404, 'Not Found');
} }
/** if ($year) {
* Fetches the archive money from the url. $this->blogPosts = $dataRecord->getArchivedBlogPosts($year, $month, $day);
*
* @return null|int return $this->render();
*/ }
public function getArchiveMonth() {
$month = $this->request->param('Month'); $this->httpError(404, 'Not Found');
if(preg_match('/^[0-9]{1,2}$/', $month)) { return null;
if($month > 0 && $month < 13) { }
if(checkdate($month, 01, $this->getArchiveYear())) {
return (int) $month; /**
} * Fetches the archive year from the url.
} *
} * @return int
*/
return null; public function getArchiveYear()
} {
if ($this->request->param('Year')) {
/** if (preg_match('/^[0-9]{4}$/', $year = $this->request->param('Year'))) {
* Fetches the archive day from the url. return (int) $year;
* }
* @return null|int } elseif ($this->request->param('Action') == 'archive') {
*/ return SS_Datetime::now()->Year();
public function getArchiveDay() { }
$day = $this->request->param('Day');
return null;
if(preg_match('/^[0-9]{1,2}$/', $day)) { }
if(checkdate($this->getArchiveMonth(), $day, $this->getArchiveYear())) {
return (int) $day; /**
} * Fetches the archive money from the url.
} *
* @return null|int
return null; */
} public function getArchiveMonth()
{
/** $month = $this->request->param('Month');
* Renders the blog posts for a given tag.
* if (preg_match('/^[0-9]{1,2}$/', $month)) {
* @return null|SS_HTTPResponse if ($month > 0 && $month < 13) {
*/ if (checkdate($month, 01, $this->getArchiveYear())) {
public function tag() { return (int) $month;
$tag = $this->getCurrentTag(); }
}
if($tag) { }
$this->blogPosts = $tag->BlogPosts();
return $this->render(); return null;
} }
$this->httpError(404, 'Not Found'); /**
* Fetches the archive day from the url.
return null; *
} * @return null|int
*/
/** public function getArchiveDay()
* Tag Getter for use in templates. {
* $day = $this->request->param('Day');
* @return null|BlogTag
*/ if (preg_match('/^[0-9]{1,2}$/', $day)) {
public function getCurrentTag() { if (checkdate($this->getArchiveMonth(), $day, $this->getArchiveYear())) {
/** return (int) $day;
* @var Blog $dataRecord }
*/ }
$dataRecord = $this->dataRecord;
$tag = $this->request->param('Tag'); return null;
if($tag) { }
return $dataRecord->Tags()
->filter('URLSegment', array($tag, rawurlencode($tag))) /**
->first(); * Renders the blog posts for a given tag.
} *
return null; * @return null|SS_HTTPResponse
} */
public function tag()
/** {
* Renders the blog posts for a given category. $tag = $this->getCurrentTag();
*
* @return null|SS_HTTPResponse if ($tag) {
*/ $this->blogPosts = $tag->BlogPosts();
public function category() { return $this->render();
$category = $this->getCurrentCategory(); }
if($category) { $this->httpError(404, 'Not Found');
$this->blogPosts = $category->BlogPosts();
return null;
return $this->render(); }
}
/**
$this->httpError(404, 'Not Found'); * Tag Getter for use in templates.
*
return null; * @return null|BlogTag
} */
public function getCurrentTag()
/** {
* Category Getter for use in templates. /**
* * @var Blog $dataRecord
* @return null|BlogCategory */
*/ $dataRecord = $this->dataRecord;
public function getCurrentCategory() { $tag = $this->request->param('Tag');
/** if ($tag) {
* @var Blog $dataRecord return $dataRecord->Tags()
*/ ->filter('URLSegment', array($tag, rawurlencode($tag)))
$dataRecord = $this->dataRecord; ->first();
$category = $this->request->param('Category'); }
if($category) { return null;
return $dataRecord->Categories() }
->filter('URLSegment', array($category, rawurlencode($category)))
->first(); /**
} * Renders the blog posts for a given category.
return null; *
} * @return null|SS_HTTPResponse
*/
/** public function category()
* Get the meta title for the current action. {
* $category = $this->getCurrentCategory();
* @return string
*/ if ($category) {
public function getMetaTitle() { $this->blogPosts = $category->BlogPosts();
$title = $this->data()->getTitle();
$filter = $this->getFilterDescription(); return $this->render();
}
if($filter) {
$title = sprintf('%s - %s', $title, $filter); $this->httpError(404, 'Not Found');
}
return null;
$this->extend('updateMetaTitle', $title); }
return $title; /**
} * Category Getter for use in templates.
*
/** * @return null|BlogCategory
* Returns a description of the current filter. */
* public function getCurrentCategory()
* @return string {
*/ /**
public function getFilterDescription() { * @var Blog $dataRecord
$items = array(); */
$dataRecord = $this->dataRecord;
$list = $this->PaginatedList(); $category = $this->request->param('Category');
$currentPage = $list->CurrentPage(); if ($category) {
return $dataRecord->Categories()
if($currentPage > 1) { ->filter('URLSegment', array($category, rawurlencode($category)))
$items[] = _t( ->first();
'Blog.FILTERDESCRIPTION_PAGE', }
'Page {page}', return null;
null, }
array(
'page' => $currentPage, /**
) * Get the meta title for the current action.
); *
} * @return string
*/
if($author = $this->getCurrentProfile()) { public function getMetaTitle()
$items[] = _t( {
'Blog.FILTERDESCRIPTION_AUTHOR', $title = $this->data()->getTitle();
'By {author}', $filter = $this->getFilterDescription();
null,
array( if ($filter) {
'author' => $author->Title, $title = sprintf('%s - %s', $title, $filter);
) }
);
} $this->extend('updateMetaTitle', $title);
if($tag = $this->getCurrentTag()) { return $title;
$items[] = _t( }
'Blog.FILTERDESCRIPTION_TAG',
'Tagged with {tag}', /**
null, * Returns a description of the current filter.
array( *
'tag' => $tag->Title, * @return string
) */
); public function getFilterDescription()
} {
$items = array();
if($category = $this->getCurrentCategory()) {
$items[] = _t( $list = $this->PaginatedList();
'Blog.FILTERDESCRIPTION_CATEGORY', $currentPage = $list->CurrentPage();
'In category {category}',
null, if ($currentPage > 1) {
array( $items[] = _t(
'category' => $category->Title, 'Blog.FILTERDESCRIPTION_PAGE',
) 'Page {page}',
); null,
} array(
'page' => $currentPage,
if($this->owner->getArchiveYear()) { )
if($this->owner->getArchiveDay()) { );
$date = $this->owner->getArchiveDate()->Nice(); }
} elseif($this->owner->getArchiveMonth()) {
$date = $this->owner->getArchiveDate()->format('F, Y'); if ($author = $this->getCurrentProfile()) {
} else { $items[] = _t(
$date = $this->owner->getArchiveDate()->format('Y'); 'Blog.FILTERDESCRIPTION_AUTHOR',
} 'By {author}',
null,
$items[] = _t( array(
'Blog.FILTERDESCRIPTION_DATE', 'author' => $author->Title,
'In {date}', )
null, );
array( }
'date' => $date,
) if ($tag = $this->getCurrentTag()) {
); $items[] = _t(
} 'Blog.FILTERDESCRIPTION_TAG',
'Tagged with {tag}',
$result = ''; null,
array(
if($items) { 'tag' => $tag->Title,
$result = implode(', ', $items); )
} );
}
$this->extend('updateFilterDescription', $result);
if ($category = $this->getCurrentCategory()) {
return $result; $items[] = _t(
} 'Blog.FILTERDESCRIPTION_CATEGORY',
'In category {category}',
/** null,
* Returns a list of paginated blog posts based on the BlogPost dataList. array(
* 'category' => $category->Title,
* @return PaginatedList )
*/ );
public function PaginatedList() { }
$allPosts = $this->blogPosts ?: new ArrayList();
if ($this->owner->getArchiveYear()) {
$posts = new PaginatedList($allPosts); if ($this->owner->getArchiveDay()) {
$date = $this->owner->getArchiveDate()->Nice();
// Set appropriate page size } elseif ($this->owner->getArchiveMonth()) {
if($this->PostsPerPage > 0) { $date = $this->owner->getArchiveDate()->format('F, Y');
$pageSize = $this->PostsPerPage; } else {
} elseif($count = $allPosts->count()) { $date = $this->owner->getArchiveDate()->format('Y');
$pageSize = $count; }
} else {
$pageSize = 99999; $items[] = _t(
} 'Blog.FILTERDESCRIPTION_DATE',
$posts->setPageLength($pageSize); 'In {date}',
null,
// Set current page array(
$start = $this->request->getVar($posts->getPaginationGetVar()); 'date' => $date,
$posts->setPageStart($start); )
);
return $posts; }
}
$result = '';
/**
* Displays an RSS feed of blog posts. if ($items) {
* $result = implode(', ', $items);
* @return string }
*/
public function rss() { $this->extend('updateFilterDescription', $result);
/**
* @var Blog $dataRecord return $result;
*/ }
$dataRecord = $this->dataRecord;
/**
$this->blogPosts = $dataRecord->getBlogPosts(); * Returns a list of paginated blog posts based on the BlogPost dataList.
*
$rss = new RSSFeed($this->blogPosts, $this->Link(), $this->MetaTitle, $this->MetaDescription); * @return PaginatedList
*/
$this->extend('updateRss', $rss); public function PaginatedList()
{
return $rss->outputToBrowser(); $allPosts = $this->blogPosts ?: new ArrayList();
}
$posts = new PaginatedList($allPosts);
/**
* Returns the current archive date. // Set appropriate page size
* if ($this->PostsPerPage > 0) {
* @return null|Date $pageSize = $this->PostsPerPage;
*/ } elseif ($count = $allPosts->count()) {
public function getArchiveDate() { $pageSize = $count;
$year = $this->getArchiveYear(); } else {
$month = $this->getArchiveMonth(); $pageSize = 99999;
$day = $this->getArchiveDay(); }
$posts->setPageLength($pageSize);
if($year) {
if($month) { // Set current page
$date = sprintf('%s-%s-01', $year, $month); $start = $this->request->getVar($posts->getPaginationGetVar());
$posts->setPageStart($start);
if($day) {
$date = sprintf('%s-%s-%s', $year, $month, $day); return $posts;
} }
} else {
$date = sprintf('%s-01-01', $year); /**
} * Displays an RSS feed of blog posts.
*
return DBField::create_field('Date', $date); * @return string
} */
public function rss()
return null; {
} /**
* @var Blog $dataRecord
/** */
* Returns a link to the RSS feed. $dataRecord = $this->dataRecord;
*
* @return string $this->blogPosts = $dataRecord->getBlogPosts();
*/
public function getRSSLink() { $rss = new RSSFeed($this->blogPosts, $this->Link(), $this->MetaTitle, $this->MetaDescription);
return $this->Link('rss');
} $this->extend('updateRss', $rss);
}
return $rss->outputToBrowser();
}
/**
* Returns the current archive date.
*
* @return null|Date
*/
public function getArchiveDate()
{
$year = $this->getArchiveYear();
$month = $this->getArchiveMonth();
$day = $this->getArchiveDay();
if ($year) {
if ($month) {
$date = sprintf('%s-%s-01', $year, $month);
if ($day) {
$date = sprintf('%s-%s-%s', $year, $month, $day);
}
} else {
$date = sprintf('%s-01-01', $year);
}
return DBField::create_field('Date', $date);
}
return null;
}
/**
* Returns a link to the RSS feed.
*
* @return string
*/
public function getRSSLink()
{
return $this->Link('rss');
}
}

View File

@ -1,145 +1,153 @@
<?php <?php
/** /**
* A blog category for generalising blog posts. * A blog category for generalising blog posts.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
* *
* @method Blog Blog() * @method Blog Blog()
* *
* @property string $URLSegment * @property string $URLSegment
* @property int $BlogID * @property int $BlogID
*/ */
class BlogCategory extends DataObject implements CategorisationObject { class BlogCategory extends DataObject implements CategorisationObject
/** {
* @var array /**
*/ * @var array
private static $db = array( */
'Title' => 'Varchar(255)', private static $db = array(
); 'Title' => 'Varchar(255)',
);
/**
* @var array /**
*/ * @var array
private static $has_one = array( */
'Blog' => 'Blog', private static $has_one = array(
); 'Blog' => 'Blog',
);
/**
* @var array /**
*/ * @var array
private static $belongs_many_many = array( */
'BlogPosts' => 'BlogPost', private static $belongs_many_many = array(
); 'BlogPosts' => 'BlogPost',
);
/**
* @var array /**
*/ * @var array
private static $extensions = array( */
'URLSegmentExtension', private static $extensions = array(
); 'URLSegmentExtension',
);
/**
* @return DataList /**
*/ * @return DataList
public function BlogPosts() { */
$blogPosts = parent::BlogPosts(); public function BlogPosts()
{
$this->extend("updateGetBlogPosts", $blogPosts); $blogPosts = parent::BlogPosts();
return $blogPosts; $this->extend("updateGetBlogPosts", $blogPosts);
}
return $blogPosts;
/** }
* {@inheritdoc}
*/ /**
public function getCMSFields() { * {@inheritdoc}
$fields = new FieldList( */
TextField::create('Title', _t('BlogCategory.Title', 'Title')) public function getCMSFields()
); {
$fields = new FieldList(
$this->extend('updateCMSFields', $fields); TextField::create('Title', _t('BlogCategory.Title', 'Title'))
);
return $fields;
} $this->extend('updateCMSFields', $fields);
/** return $fields;
* Returns a relative link to this category. }
*
* @return string /**
*/ * Returns a relative link to this category.
public function getLink() { *
return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment); * @return string
} */
public function getLink()
/** {
* Inherits from the parent blog or can be overwritten using a DataExtension. return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment);
* }
* @param null|Member $member
* /**
* @return bool * Inherits from the parent blog or can be overwritten using a DataExtension.
*/ *
public function canView($member = null) { * @param null|Member $member
$extended = $this->extendedCan(__FUNCTION__, $member); *
* @return bool
if($extended !== null) { */
return $extended; public function canView($member = null)
} {
$extended = $this->extendedCan(__FUNCTION__, $member);
return $this->Blog()->canView($member);
} if ($extended !== null) {
return $extended;
/** }
* Inherits from the parent blog or can be overwritten using a DataExtension.
* return $this->Blog()->canView($member);
* @param null|Member $member }
*
* @return bool /**
*/ * Inherits from the parent blog or can be overwritten using a DataExtension.
public function canCreate($member = null) { *
$extended = $this->extendedCan(__FUNCTION__, $member); * @param null|Member $member
*
if($extended !== null) { * @return bool
return $extended; */
} public function canCreate($member = null)
{
$permission = Blog::config()->grant_user_permission; $extended = $this->extendedCan(__FUNCTION__, $member);
return Permission::checkMember($member, $permission); if ($extended !== null) {
} return $extended;
}
/**
* Inherits from the parent blog or can be overwritten using a DataExtension. $permission = Blog::config()->grant_user_permission;
*
* @param null|Member $member return Permission::checkMember($member, $permission);
* }
* @return bool
*/ /**
public function canDelete($member = null) { * Inherits from the parent blog or can be overwritten using a DataExtension.
$extended = $this->extendedCan(__FUNCTION__, $member); *
* @param null|Member $member
if($extended !== null) { *
return $extended; * @return bool
} */
public function canDelete($member = null)
return $this->Blog()->canEdit($member); {
} $extended = $this->extendedCan(__FUNCTION__, $member);
/** if ($extended !== null) {
* Inherits from the parent blog or can be overwritten using a DataExtension. return $extended;
* }
* @param null|Member $member
* return $this->Blog()->canEdit($member);
* @return bool }
*/
public function canEdit($member = null) { /**
$extended = $this->extendedCan(__FUNCTION__, $member); * Inherits from the parent blog or can be overwritten using a DataExtension.
*
if($extended !== null) { * @param null|Member $member
return $extended; *
} * @return bool
*/
return $this->Blog()->canEdit($member); public function canEdit($member = null)
} {
} $extended = $this->extendedCan(__FUNCTION__, $member);
if ($extended !== null) {
return $extended;
}
return $this->Blog()->canEdit($member);
}
}

View File

@ -1,686 +1,707 @@
<?php <?php
/** /**
* An individual blog post. * An individual blog post.
* *
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
* *
* @method ManyManyList Categories() * @method ManyManyList Categories()
* @method ManyManyList Tags() * @method ManyManyList Tags()
* @method ManyManyList Authors() * @method ManyManyList Authors()
* @method Blog Parent() * @method Blog Parent()
* *
* @property string $PublishDate * @property string $PublishDate
* @property string $AuthorNames * @property string $AuthorNames
* @property int $ParentID * @property int $ParentID
*/ */
class BlogPost extends Page { class BlogPost extends Page
{
/** /**
* Same as above, but for list of users that can be * Same as above, but for list of users that can be
* given credit in the author field for blog posts * given credit in the author field for blog posts
* @var string|bool false or group code * @var string|bool false or group code
*/ */
private static $restrict_authors_to_group = false; private static $restrict_authors_to_group = false;
/** /**
* @var array * @var array
*/ */
private static $db = array( private static $db = array(
'PublishDate' => 'SS_Datetime', 'PublishDate' => 'SS_Datetime',
'AuthorNames' => 'Varchar(1024)', 'AuthorNames' => 'Varchar(1024)',
'Summary' => 'HTMLText', 'Summary' => 'HTMLText',
); );
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'FeaturedImage' => 'Image', 'FeaturedImage' => 'Image',
); );
/** /**
* @var array * @var array
*/ */
private static $many_many = array( private static $many_many = array(
'Categories' => 'BlogCategory', 'Categories' => 'BlogCategory',
'Tags' => 'BlogTag', 'Tags' => 'BlogTag',
'Authors' => 'Member', 'Authors' => 'Member',
); );
/** /**
* @var array * @var array
*/ */
private static $defaults = array( private static $defaults = array(
'ShowInMenus' => false, 'ShowInMenus' => false,
'InheritSideBar' => true, 'InheritSideBar' => true,
'ProvideComments' => true, 'ProvideComments' => true,
); );
/** /**
* @var array * @var array
*/ */
private static $extensions = array( private static $extensions = array(
'BlogPostFilter', 'BlogPostFilter',
); );
/** /**
* @var array * @var array
*/ */
private static $searchable_fields = array( private static $searchable_fields = array(
'Title', 'Title',
); );
/** /**
* @var array * @var array
*/ */
private static $summary_fields = array( private static $summary_fields = array(
'Title', 'Title',
); );
/** /**
* @var array * @var array
*/ */
private static $casting = array( private static $casting = array(
'Excerpt' => 'Text', 'Excerpt' => 'Text',
); );
/** /**
* @var array * @var array
*/ */
private static $allowed_children = array(); private static $allowed_children = array();
/** /**
* The default sorting lists BlogPosts with an empty PublishDate at the top. * The default sorting lists BlogPosts with an empty PublishDate at the top.
* *
* @var string * @var string
*/ */
private static $default_sort = '"PublishDate" IS NULL DESC, "PublishDate" DESC'; private static $default_sort = '"PublishDate" IS NULL DESC, "PublishDate" DESC';
/** /**
* @var bool * @var bool
*/ */
private static $can_be_root = false; private static $can_be_root = false;
/** /**
* This will display or hide the current class from the SiteTree. This variable can be * This will display or hide the current class from the SiteTree. This variable can be
* configured using YAML. * configured using YAML.
* *
* @var bool * @var bool
*/ */
private static $show_in_sitetree = false; private static $show_in_sitetree = false;
/** /**
* Determine the role of the given member. * Determine the role of the given member.
* *
* Call be called via template to determine the current user. * Call be called via template to determine the current user.
* *
* @example "Hello $RoleOf($CurrentMember.ID)" * @example "Hello $RoleOf($CurrentMember.ID)"
* *
* @param null|int|Member $member * @param null|int|Member $member
* *
* @return null|string * @return null|string
*/ */
public function RoleOf($member = null) { public function RoleOf($member = null)
$member = $this->getMember($member); {
$member = $this->getMember($member);
if(!$member) {
return null; if (!$member) {
} return null;
}
if($this->isAuthor($member)) {
return _t('BlogPost.AUTHOR', 'Author'); if ($this->isAuthor($member)) {
} return _t('BlogPost.AUTHOR', 'Author');
}
$parent = $this->Parent();
$parent = $this->Parent();
if($parent instanceof Blog) {
return $parent->RoleOf($member); if ($parent instanceof Blog) {
} return $parent->RoleOf($member);
}
return null;
} 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 null|Member $member *
* * @param null|Member $member
* @return bool *
*/ * @return bool
public function isAuthor($member = null) { */
if(!$member || !$member->exists()) { public function isAuthor($member = null)
return false; {
} if (!$member || !$member->exists()) {
return false;
$list = $this->Authors(); }
if($list instanceof UnsavedRelationList) { $list = $this->Authors();
return in_array($member->ID, $list->getIDList());
} if ($list instanceof UnsavedRelationList) {
return in_array($member->ID, $list->getIDList());
return $list->byID($member->ID) !== null; }
}
return $list->byID($member->ID) !== null;
/** }
* {@inheritdoc}
*/ /**
public function getCMSFields() { * {@inheritdoc}
Requirements::css(BLOGGER_DIR . '/css/cms.css'); */
Requirements::javascript(BLOGGER_DIR . '/js/cms.js'); public function getCMSFields()
{
$self =& $this; Requirements::css(BLOGGER_DIR . '/css/cms.css');
Requirements::javascript(BLOGGER_DIR . '/js/cms.js');
$this->beforeUpdateCMSFields(function ($fields) use ($self) {
$uploadField = UploadField::create('FeaturedImage', _t('BlogPost.FeaturedImage', 'Banner Image')); $self =& $this;
$uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
$this->beforeUpdateCMSFields(function ($fields) use ($self) {
/** $uploadField = UploadField::create('FeaturedImage', _t('BlogPost.FeaturedImage', 'Banner Image'));
* @var FieldList $fields $uploadField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'png', 'gif'));
*/
$fields->insertAfter($uploadField, 'Content'); /**
* @var FieldList $fields
$summary = HtmlEditorField::create('Summary', false); */
$summary->setRows(5); $fields->insertAfter($uploadField, 'Content');
$summary->setDescription(_t(
'BlogPost.SUMMARY_DESCRIPTION', $summary = HtmlEditorField::create('Summary', false);
'If no summary is specified the first 30 words will be used.' $summary->setRows(5);
)); $summary->setDescription(_t(
'BlogPost.SUMMARY_DESCRIPTION',
$summaryHolder = ToggleCompositeField::create( 'If no summary is specified the first 30 words will be used.'
'CustomSummary', ));
_t('BlogPost.CUSTOMSUMMARY', 'Add A Custom Summary'),
array( $summaryHolder = ToggleCompositeField::create(
$summary, 'CustomSummary',
) _t('BlogPost.CUSTOMSUMMARY', 'Add A Custom Summary'),
); array(
$summaryHolder->setHeadingLevel(4); $summary,
$summaryHolder->addExtraClass('custom-summary'); )
);
$fields->insertAfter($summaryHolder, 'FeaturedImage'); $summaryHolder->setHeadingLevel(4);
$summaryHolder->addExtraClass('custom-summary');
$fields->push(HiddenField::create('MenuTitle'));
$fields->insertAfter($summaryHolder, 'FeaturedImage');
$urlSegment = $fields->dataFieldByName('URLSegment');
$urlSegment->setURLPrefix($self->Parent()->RelativeLink()); $fields->push(HiddenField::create('MenuTitle'));
$fields->removeFieldsFromTab('Root.Main', array( $urlSegment = $fields->dataFieldByName('URLSegment');
'MenuTitle', $urlSegment->setURLPrefix($self->Parent()->RelativeLink());
'URLSegment',
)); $fields->removeFieldsFromTab('Root.Main', array(
'MenuTitle',
$authorField = ListboxField::create( 'URLSegment',
'Authors', ));
_t('BlogPost.Authors', 'Authors'),
$this->getCandidateAuthors()->map()->toArray() $authorField = ListboxField::create(
)->setMultiple(true); 'Authors',
_t('BlogPost.Authors', 'Authors'),
$authorNames = TextField::create( $this->getCandidateAuthors()->map()->toArray()
'AuthorNames', )->setMultiple(true);
_t('BlogPost.AdditionalCredits', 'Additional Credits'),
null, $authorNames = TextField::create(
1024 'AuthorNames',
)->setDescription(_t( _t('BlogPost.AdditionalCredits', 'Additional Credits'),
'BlogPost.AdditionalCredits_Description', null,
'If some authors of this post don\'t have CMS access, enter their name(s) here. You can separate multiple names with a comma.') 1024
); )->setDescription(_t(
'BlogPost.AdditionalCredits_Description',
if(!$self->canEditAuthors()) { 'If some authors of this post don\'t have CMS access, enter their name(s) here. You can separate multiple names with a comma.')
$authorField = $authorField->performDisabledTransformation(); );
$authorNames = $authorNames->performDisabledTransformation();
} if (!$self->canEditAuthors()) {
$authorField = $authorField->performDisabledTransformation();
$publishDate = DatetimeField::create('PublishDate', _t('BlogPost.PublishDate', 'Publish Date')); $authorNames = $authorNames->performDisabledTransformation();
$publishDate->getDateField()->setConfig('showcalendar', true); }
if(!$self->PublishDate) {
$publishDate->setDescription(_t( $publishDate = DatetimeField::create('PublishDate', _t('BlogPost.PublishDate', 'Publish Date'));
'BlogPost.PublishDate_Description', $publishDate->getDateField()->setConfig('showcalendar', true);
'Will be set to "now" if published without a value.') if (!$self->PublishDate) {
); $publishDate->setDescription(_t(
} 'BlogPost.PublishDate_Description',
'Will be set to "now" if published without a value.')
// Get categories and tags );
$parent = $self->Parent(); }
$categories = $parent instanceof Blog
? $parent->Categories() // Get categories and tags
: BlogCategory::get(); $parent = $self->Parent();
$tags = $parent instanceof Blog $categories = $parent instanceof Blog
? $parent->Tags() ? $parent->Categories()
: BlogTag::get(); : BlogCategory::get();
$tags = $parent instanceof Blog
$options = BlogAdminSidebar::create( ? $parent->Tags()
$publishDate, : BlogTag::get();
$urlSegment,
TagField::create( $options = BlogAdminSidebar::create(
'Categories', $publishDate,
_t('BlogPost.Categories', 'Categories'), $urlSegment,
$categories, TagField::create(
$self->Categories() 'Categories',
) _t('BlogPost.Categories', 'Categories'),
->setCanCreate($self->canCreateCategories()) $categories,
->setShouldLazyLoad(true), $self->Categories()
TagField::create( )
'Tags', ->setCanCreate($self->canCreateCategories())
_t('BlogPost.Tags', 'Tags'), ->setShouldLazyLoad(true),
$tags, TagField::create(
$self->Tags() 'Tags',
) _t('BlogPost.Tags', 'Tags'),
->setCanCreate($self->canCreateTags()) $tags,
->setShouldLazyLoad(true), $self->Tags()
$authorField, )
$authorNames ->setCanCreate($self->canCreateTags())
)->setTitle('Post Options'); ->setShouldLazyLoad(true),
$authorField,
$options->setName('blog-admin-sidebar'); $authorNames
)->setTitle('Post Options');
$fields->insertBefore($options, 'Root');
}); $options->setName('blog-admin-sidebar');
$fields = parent::getCMSFields(); $fields->insertBefore($options, 'Root');
});
$fields->fieldByName('Root')->setTemplate('TabSet_holder');
$fields = parent::getCMSFields();
return $fields;
} $fields->fieldByName('Root')->setTemplate('TabSet_holder');
/** return $fields;
* Gets the list of author candidates to be assigned as authors of this blog post. }
*
* @return SS_List /**
*/ * Gets the list of author candidates to be assigned as authors of this blog post.
public function getCandidateAuthors() { *
if($this->config()->restrict_authors_to_group) { * @return SS_List
return Group::get()->filter('Code', $this->config()->restrict_authors_to_group)->first()->Members(); */
} else { public function getCandidateAuthors()
$list = Member::get(); {
$this->extend('updateCandidateAuthors', $list); if ($this->config()->restrict_authors_to_group) {
return $list; return Group::get()->filter('Code', $this->config()->restrict_authors_to_group)->first()->Members();
} } else {
} $list = Member::get();
$this->extend('updateCandidateAuthors', $list);
/** return $list;
* Determine if this user can edit the authors list. }
* }
* @param null|int|Member $member
* /**
* @return bool * Determine if this user can edit the authors list.
*/ *
public function canEditAuthors($member = null) { * @param null|int|Member $member
$member = $this->getMember($member); *
* @return bool
$extended = $this->extendedCan('canEditAuthors', $member); */
public function canEditAuthors($member = null)
if($extended !== null) { {
return $extended; $member = $this->getMember($member);
}
$extended = $this->extendedCan('canEditAuthors', $member);
$parent = $this->Parent();
if ($extended !== null) {
if($parent instanceof Blog && $parent->exists()) { return $extended;
if($parent->isEditor($member)) { }
return true;
} $parent = $this->Parent();
if($parent->isWriter($member) && $this->isAuthor($member)) { if ($parent instanceof Blog && $parent->exists()) {
return true; if ($parent->isEditor($member)) {
} return true;
} }
return Permission::checkMember($member, Blog::MANAGE_USERS); if ($parent->isWriter($member) && $this->isAuthor($member)) {
} return true;
}
/** }
* @param null|int|Member $member
* return Permission::checkMember($member, Blog::MANAGE_USERS);
* @return null|Member }
*/
protected function getMember($member = null) { /**
if(!$member) { * @param null|int|Member $member
$member = Member::currentUser(); *
} * @return null|Member
*/
if(is_numeric($member)) { protected function getMember($member = null)
$member = Member::get()->byID($member); {
} if (!$member) {
$member = Member::currentUser();
return $member; }
}
if (is_numeric($member)) {
/** $member = Member::get()->byID($member);
* Determine whether user can create new categories. }
*
* @param null|int|Member $member return $member;
* }
* @return bool
*/ /**
public function canCreateCategories($member = null) { * Determine whether user can create new categories.
$member = $this->getMember($member); *
* @param null|int|Member $member
$parent = $this->Parent(); *
* @return bool
if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { */
return false; public function canCreateCategories($member = null)
} {
$member = $this->getMember($member);
if($parent->isEditor($member)) {
return true; $parent = $this->Parent();
}
if (!$parent || !$parent->exists() || !($parent instanceof Blog)) {
return Permission::checkMember($member, 'ADMIN'); return false;
} }
/** if ($parent->isEditor($member)) {
* Determine whether user can create new tags. return true;
* }
* @param null|int|Member $member
* return Permission::checkMember($member, 'ADMIN');
* @return bool }
*/
public function canCreateTags($member = null) { /**
$member = $this->getMember($member); * Determine whether user can create new tags.
*
$parent = $this->Parent(); * @param null|int|Member $member
*
if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { * @return bool
return false; */
} public function canCreateTags($member = null)
{
if($parent->isEditor($member)) { $member = $this->getMember($member);
return true;
} $parent = $this->Parent();
if($parent->isWriter($member)) { if (!$parent || !$parent->exists() || !($parent instanceof Blog)) {
return true; return false;
} }
return Permission::checkMember($member, 'ADMIN'); if ($parent->isEditor($member)) {
} return true;
}
/**
* {@inheritdoc} if ($parent->isWriter($member)) {
* return true;
* Update the PublishDate to now if the BlogPost would otherwise be published without a date. }
*/
public function onBeforePublish() { return Permission::checkMember($member, 'ADMIN');
/** }
* @var SS_Datetime $publishDate
*/ /**
$publishDate = $this->dbObject('PublishDate'); * {@inheritdoc}
*
if(!$publishDate->getValue()) { * Update the PublishDate to now if the BlogPost would otherwise be published without a date.
$this->PublishDate = SS_Datetime::now()->getValue(); */
$this->write(); public function onBeforePublish()
} {
} /**
* @var SS_Datetime $publishDate
/** */
* {@inheritdoc} $publishDate = $this->dbObject('PublishDate');
*
* Sets blog relationship on all categories and tags assigned to this post. if (!$publishDate->getValue()) {
*/ $this->PublishDate = SS_Datetime::now()->getValue();
public function onAfterWrite() { $this->write();
parent::onAfterWrite(); }
}
foreach($this->Categories() as $category) {
/** /**
* @var BlogCategory $category * {@inheritdoc}
*/ *
$category->BlogID = $this->ParentID; * Sets blog relationship on all categories and tags assigned to this post.
$category->write(); */
} public function onAfterWrite()
{
foreach($this->Tags() as $tag) { parent::onAfterWrite();
/**
* @var BlogTag $tag foreach ($this->Categories() as $category) {
*/ /**
$tag->BlogID = $this->ParentID; * @var BlogCategory $category
$tag->write(); */
} $category->BlogID = $this->ParentID;
} $category->write();
}
/**
* {@inheritdoc} foreach ($this->Tags() as $tag) {
*/ /**
public function canView($member = null) { * @var BlogTag $tag
$member = $this->getMember($member); */
$tag->BlogID = $this->ParentID;
if(!parent::canView($member)) { $tag->write();
return false; }
} }
/** /**
* @var SS_Datetime $publishDate * {@inheritdoc}
*/ */
$publishDate = $this->dbObject('PublishDate'); public function canView($member = null)
{
// Show past posts $member = $this->getMember($member);
if(!$publishDate->exists() || !$publishDate->InFuture()) {
return true; if (!parent::canView($member)) {
} return false;
}
// Anyone that can edit this page can view it
return $this->canEdit($member); /**
} * @var SS_Datetime $publishDate
*/
/** $publishDate = $this->dbObject('PublishDate');
* {@inheritdoc}
*/ // Show past posts
public function canPublish($member = null) { if (!$publishDate->exists() || !$publishDate->InFuture()) {
$member = $this->getMember($member); return true;
}
if(Permission::checkMember($member, 'ADMIN')) {
return true; // Anyone that can edit this page can view it
} return $this->canEdit($member);
}
$extended = $this->extendedCan('canPublish', $member);
/**
if($extended !== null) { * {@inheritdoc}
return $extended; */
} public function canPublish($member = null)
{
$parent = $this->Parent(); $member = $this->getMember($member);
if($parent instanceof Blog && $parent->exists()) { if (Permission::checkMember($member, 'ADMIN')) {
if($parent->isEditor($member)) { return true;
return true; }
}
$extended = $this->extendedCan('canPublish', $member);
if($parent->isWriter($member) && $this->isAuthor($member)) {
return true; if ($extended !== null) {
} return $extended;
}
if($parent->isContributor($member)) {
return parent::canEdit($member); $parent = $this->Parent();
}
} if ($parent instanceof Blog && $parent->exists()) {
if ($parent->isEditor($member)) {
return $this->canEdit($member); return true;
} }
/** if ($parent->isWriter($member) && $this->isAuthor($member)) {
* {@inheritdoc} return true;
*/ }
public function canEdit($member = null) {
$member = $this->getMember($member); if ($parent->isContributor($member)) {
return parent::canEdit($member);
if(parent::canEdit($member)) { }
return true; }
}
return $this->canEdit($member);
$parent = $this->Parent(); }
if(!$parent || !$parent->exists() || !($parent instanceof Blog)) { /**
return false; * {@inheritdoc}
} */
public function canEdit($member = null)
if($parent->isEditor($member)) { {
return true; $member = $this->getMember($member);
}
if (parent::canEdit($member)) {
if(!$parent->isWriter($member) && !$parent->isContributor($member)) { return true;
return false; }
}
$parent = $this->Parent();
return $this->isAuthor($member);
} if (!$parent || !$parent->exists() || !($parent instanceof Blog)) {
return false;
/** }
* Returns the post excerpt.
* if ($parent->isEditor($member)) {
* @param int $wordsToDisplay return true;
* }
* @return string
*/ if (!$parent->isWriter($member) && !$parent->isContributor($member)) {
public function Excerpt($wordsToDisplay = 30) { return false;
/** }
* @var Text $content
*/ return $this->isAuthor($member);
$content = $this->dbObject('Content'); }
return $content->Summary($wordsToDisplay); /**
} * Returns the post excerpt.
*
/** * @param int $wordsToDisplay
* Returns a monthly archive link for the current blog post. *
* * @return string
* @param string $type */
* public function Excerpt($wordsToDisplay = 30)
* @return string {
*/ /**
public function getMonthlyArchiveLink($type = 'day') { * @var Text $content
/** */
* @var SS_Datetime $date $content = $this->dbObject('Content');
*/
$date = $this->dbObject('PublishDate'); return $content->Summary($wordsToDisplay);
}
if($type != 'year') {
if($type == 'day') { /**
return Controller::join_links( * Returns a monthly archive link for the current blog post.
$this->Parent()->Link('archive'), *
$date->format('Y'), * @param string $type
$date->format('m'), *
$date->format('d') * @return string
); */
} public function getMonthlyArchiveLink($type = 'day')
{
return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y'), $date->format('m')); /**
} * @var SS_Datetime $date
*/
return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y')); $date = $this->dbObject('PublishDate');
}
if ($type != 'year') {
/** if ($type == 'day') {
* Returns a yearly archive link for the current blog post. return Controller::join_links(
* $this->Parent()->Link('archive'),
* @return string $date->format('Y'),
*/ $date->format('m'),
public function getYearlyArchiveLink() { $date->format('d')
/** );
* @var SS_Datetime $date }
*/
$date = $this->dbObject('PublishDate'); 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'));
}
/**
* Resolves static and dynamic authors linked to this post. /**
* * Returns a yearly archive link for the current blog post.
* @return ArrayList *
*/ * @return string
public function getCredits() { */
$list = new ArrayList(); public function getYearlyArchiveLink()
{
$list->merge($this->getDynamicCredits()); /**
$list->merge($this->getStaticCredits()); * @var SS_Datetime $date
*/
return $list->sort('Name'); $date = $this->dbObject('PublishDate');
}
return Controller::join_links($this->Parent()->Link('archive'), $date->format('Y'));
/** }
* Resolves dynamic authors linked to this post.
* /**
* @return ArrayList * Resolves static and dynamic authors linked to this post.
*/ *
protected function getDynamicCredits() { * @return ArrayList
// Find best page to host user profiles */
$parent = $this->Parent(); public function getCredits()
if(! ($parent instanceof Blog) ) { {
$parent = Blog::get()->first(); $list = new ArrayList();
}
$list->merge($this->getDynamicCredits());
// If there is no parent blog, return list undecorated $list->merge($this->getStaticCredits());
if(!$parent) {
$items = $this->Authors()->toArray(); return $list->sort('Name');
return new ArrayList($items); }
}
/**
// Update all authors * Resolves dynamic authors linked to this post.
$items = new ArrayList(); *
foreach($this->Authors() as $author) { * @return ArrayList
// Add link for each author */
$author = $author->customise(array( protected function getDynamicCredits()
'URL' => $parent->ProfileLink($author->URLSegment), {
)); // Find best page to host user profiles
$items->push($author); $parent = $this->Parent();
} if (! ($parent instanceof Blog)) {
$parent = Blog::get()->first();
return $items; }
}
// If there is no parent blog, return list undecorated
/** if (!$parent) {
* Resolves static authors linked to this post. $items = $this->Authors()->toArray();
* return new ArrayList($items);
* @return ArrayList }
*/
protected function getStaticCredits() { // Update all authors
$items = new ArrayList(); $items = new ArrayList();
foreach ($this->Authors() as $author) {
$authors = array_filter(preg_split('/\s*,\s*/', $this->AuthorNames)); // Add link for each author
$author = $author->customise(array(
foreach($authors as $author) { 'URL' => $parent->ProfileLink($author->URLSegment),
$item = new ArrayData(array( ));
'Name' => $author, $items->push($author);
)); }
$items->push($item); return $items;
} }
return $items; /**
} * Resolves static authors linked to this post.
*
/** * @return ArrayList
* Sets the label for BlogPost.Title to 'Post Title' (Rather than 'Page name'). */
* protected function getStaticCredits()
* @param bool $includeRelations {
* $items = new ArrayList();
* @return array
*/ $authors = array_filter(preg_split('/\s*,\s*/', $this->AuthorNames));
public function fieldLabels($includeRelations = true) {
$labels = parent::fieldLabels($includeRelations); foreach ($authors as $author) {
$item = new ArrayData(array(
$labels['Title'] = _t('BlogPost.PageTitleLabel', 'Post Title'); 'Name' => $author,
));
return $labels;
} $items->push($item);
}
/**
* {@inheritdoc} return $items;
*/ }
protected function onBeforeWrite() {
parent::onBeforeWrite(); /**
* Sets the label for BlogPost.Title to 'Post Title' (Rather than 'Page name').
if(!$this->exists() && ($member = Member::currentUser())) { *
$this->Authors()->add($member); * @param bool $includeRelations
} *
} * @return array
} */
public function fieldLabels($includeRelations = true)
/** {
* @package silverstripe $labels = parent::fieldLabels($includeRelations);
* @subpackage blog
*/ $labels['Title'] = _t('BlogPost.PageTitleLabel', 'Post Title');
class BlogPost_Controller extends Page_Controller {
return $labels;
} }
/**
* {@inheritdoc}
*/
protected function onBeforeWrite()
{
parent::onBeforeWrite();
if (!$this->exists() && ($member = Member::currentUser())) {
$this->Authors()->add($member);
}
}
}
/**
* @package silverstripe
* @subpackage blog
*/
class BlogPost_Controller extends Page_Controller
{
}

View File

@ -12,135 +12,143 @@
* @property string $URLSegment * @property string $URLSegment
* @property int $BlogID * @property int $BlogID
*/ */
class BlogTag extends DataObject implements CategorisationObject { class BlogTag extends DataObject implements CategorisationObject
/** {
* @var array /**
*/ * @var array
private static $db = array( */
'Title' => 'Varchar(255)', private static $db = array(
); 'Title' => 'Varchar(255)',
);
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'Blog' => 'Blog', 'Blog' => 'Blog',
); );
/** /**
* @var array * @var array
*/ */
private static $belongs_many_many = array( private static $belongs_many_many = array(
'BlogPosts' => 'BlogPost', 'BlogPosts' => 'BlogPost',
); );
/** /**
* @var array * @var array
*/ */
private static $extensions = array( private static $extensions = array(
'URLSegmentExtension', 'URLSegmentExtension',
); );
/** /**
* @return DataList * @return DataList
*/ */
public function BlogPosts() { public function BlogPosts()
$blogPosts = parent::BlogPosts(); {
$blogPosts = parent::BlogPosts();
$this->extend("updateGetBlogPosts", $blogPosts); $this->extend("updateGetBlogPosts", $blogPosts);
return $blogPosts; return $blogPosts;
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getCMSFields() { public function getCMSFields()
$fields = new FieldList( {
TextField::create('Title', _t('BlogTag.Title', 'Title')) $fields = new FieldList(
); TextField::create('Title', _t('BlogTag.Title', 'Title'))
);
$this->extend('updateCMSFields', $fields); $this->extend('updateCMSFields', $fields);
return $fields; return $fields;
} }
/** /**
* Returns a relative URL for the tag link. * Returns a relative URL for the tag link.
* *
* @return string * @return string
*/ */
public function getLink() { public function getLink()
return Controller::join_links($this->Blog()->Link(), 'tag', $this->URLSegment); {
} return Controller::join_links($this->Blog()->Link(), 'tag', $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 null|Member $member * @param null|Member $member
* *
* @return bool * @return bool
*/ */
public function canView($member = null) { public function canView($member = null)
$extended = $this->extendedCan(__FUNCTION__, $member); {
$extended = $this->extendedCan(__FUNCTION__, $member);
if($extended !== null) { if ($extended !== null) {
return $extended; return $extended;
} }
return $this->Blog()->canView($member); 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 null|Member $member * @param null|Member $member
* *
* @return bool * @return bool
*/ */
public function canCreate($member = null) { public function canCreate($member = null)
$extended = $this->extendedCan(__FUNCTION__, $member); {
$extended = $this->extendedCan(__FUNCTION__, $member);
if($extended !== null) { if ($extended !== null) {
return $extended; return $extended;
} }
$permission = Blog::config()->grant_user_permission; $permission = Blog::config()->grant_user_permission;
return Permission::checkMember($member, $permission); return Permission::checkMember($member, $permission);
} }
/** /**
* Inherits from the parent blog or can be overwritten using a DataExtension. * Inherits from the parent blog or can be overwritten using a DataExtension.
* *
* @param null|Member $member * @param null|Member $member
* *
* @return bool * @return bool
*/ */
public function canDelete($member = null) { public function canDelete($member = null)
$extended = $this->extendedCan(__FUNCTION__, $member); {
$extended = $this->extendedCan(__FUNCTION__, $member);
if($extended !== null) { if ($extended !== null) {
return $extended; return $extended;
} }
return $this->Blog()->canEdit($member); 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 null|Member $member * @param null|Member $member
* *
* @return bool * @return bool
*/ */
public function canEdit($member = null) { public function canEdit($member = null)
$extended = $this->extendedCan(__FUNCTION__, $member); {
$extended = $this->extendedCan(__FUNCTION__, $member);
if($extended !== null) { if ($extended !== null) {
return $extended; return $extended;
} }
return $this->Blog()->canEdit($member); return $this->Blog()->canEdit($member);
} }
} }

View File

@ -3,6 +3,6 @@
/** /**
* @method ManyManyList BlogPosts * @method ManyManyList BlogPosts
*/ */
interface CategorisationObject { interface CategorisationObject
{
} }

View File

@ -1,135 +1,138 @@
<?php <?php
if(!class_exists('Widget')) { if (!class_exists('Widget')) {
return; return;
} }
/** /**
* @method Blog Blog() * @method Blog Blog()
* *
* @property string $ArchiveType * @property string $ArchiveType
* @property int $NumberToDisplay * @property int $NumberToDisplay
*/ */
class BlogArchiveWidget extends Widget { class BlogArchiveWidget extends Widget
/** {
* @var string /**
*/ * @var string
private static $title = 'Archive'; */
private static $title = 'Archive';
/**
* @var string /**
*/ * @var string
private static $cmsTitle = 'Archive'; */
private static $cmsTitle = 'Archive';
/**
* @var string /**
*/ * @var string
private static $description = 'Displays an archive list of posts.'; */
private static $description = 'Displays an archive list of posts.';
/**
* @var array /**
*/ * @var array
private static $db = array( */
'NumberToDisplay' => 'Int', private static $db = array(
'ArchiveType' => 'Enum(\'Monthly,Yearly\', \'Monthly\')', 'NumberToDisplay' => 'Int',
); 'ArchiveType' => 'Enum(\'Monthly,Yearly\', \'Monthly\')',
);
/**
* @var array /**
*/ * @var array
private static $defaults = array( */
'NumberOfMonths' => 12, private static $defaults = array(
); 'NumberOfMonths' => 12,
);
/**
* @var array /**
*/ * @var array
private static $has_one = array( */
'Blog' => 'Blog', private static $has_one = array(
); 'Blog' => 'Blog',
);
/**
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function getCMSFields() { */
$self =& $this; public function getCMSFields()
{
$this->beforeUpdateCMSFields(function ($fields) use ($self) { $self =& $this;
/**
* @var Enum $archiveType $this->beforeUpdateCMSFields(function ($fields) use ($self) {
*/ /**
$archiveType = $self->dbObject('ArchiveType'); * @var Enum $archiveType
*/
$type = $archiveType->enumValues(); $archiveType = $self->dbObject('ArchiveType');
foreach($type as $k => $v) { $type = $archiveType->enumValues();
$type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v);
} foreach ($type as $k => $v) {
$type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v);
/** }
* @var FieldList $fields
*/ /**
$fields->merge(array( * @var FieldList $fields
DropdownField::create('BlogID', _t('BlogArchiveWidget.Blog', 'Blog'), Blog::get()->map()), */
DropdownField::create('ArchiveType', _t('BlogArchiveWidget.ArchiveType', 'ArchiveType'), $type), $fields->merge(array(
NumericField::create('NumberToDisplay', _t('BlogArchiveWidget.NumberToDisplay', 'No. to Display')) 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(); });
}
return parent::getCMSFields();
/** }
* Returns a list of months where blog posts are present.
* /**
* @return DataList * Returns a list of months where blog posts are present.
*/ *
public function getArchive() { * @return DataList
$query = $this->Blog()->getBlogPosts()->dataQuery(); */
public function getArchive()
if($this->ArchiveType == 'Yearly') { {
$query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')'); $query = $this->Blog()->getBlogPosts()->dataQuery();
} else {
$query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')'); if ($this->ArchiveType == 'Yearly') {
} $query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')');
} else {
$posts = $this->Blog()->getBlogPosts()->setDataQuery($query); $query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')');
}
if($this->NumberToDisplay > 0) {
$posts = $posts->limit($this->NumberToDisplay); $posts = $this->Blog()->getBlogPosts()->setDataQuery($query);
}
if ($this->NumberToDisplay > 0) {
$archive = new ArrayList(); $posts = $posts->limit($this->NumberToDisplay);
}
if($posts->count() > 0) {
foreach($posts as $post) { $archive = new ArrayList();
/**
* @var BlogPost $post if ($posts->count() > 0) {
*/ foreach ($posts as $post) {
$date = Date::create(); /**
$date->setValue($post->PublishDate); * @var BlogPost $post
*/
if($this->ArchiveType == 'Yearly') { $date = Date::create();
$year = $date->FormatI18N("%Y"); $date->setValue($post->PublishDate);
$month = null;
$title = $year; if ($this->ArchiveType == 'Yearly') {
} else { $year = $date->FormatI18N("%Y");
$year = $date->FormatI18N("%Y"); $month = null;
$month = $date->FormatI18N("%m"); $title = $year;
$title = $date->FormatI18N("%B %Y"); } else {
} $year = $date->FormatI18N("%Y");
$month = $date->FormatI18N("%m");
$archive->push(new ArrayData(array( $title = $date->FormatI18N("%B %Y");
'Title' => $title, }
'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month)
))); $archive->push(new ArrayData(array(
} 'Title' => $title,
} 'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month)
)));
return $archive; }
} }
}
return $archive;
class BlogArchiveWidget_Controller extends Widget_Controller { }
}
}
class BlogArchiveWidget_Controller extends Widget_Controller
{
}

View File

@ -1,97 +1,100 @@
<?php <?php
if(!class_exists("Widget")) { if (!class_exists("Widget")) {
return; return;
} }
/** /**
* @method Blog Blog() * @method Blog Blog()
*/ */
class BlogCategoriesWidget extends Widget { class BlogCategoriesWidget extends Widget
/** {
* @var string /**
*/ * @var string
private static $title = 'Categories'; */
private static $title = 'Categories';
/**
* @var string /**
*/ * @var string
private static $cmsTitle = 'Blog Categories'; */
private static $cmsTitle = 'Blog Categories';
/**
* @var string /**
*/ * @var string
private static $description = 'Displays a list of blog categories.'; */
private static $description = 'Displays a list of blog categories.';
/**
* @var array /**
*/ * @var array
private static $db = array( */
'Limit' => 'Int', private static $db = array(
'Order' => 'Varchar', 'Limit' => 'Int',
'Direction' => 'Varchar', 'Order' => 'Varchar',
); 'Direction' => 'Varchar',
);
/**
* @var array /**
*/ * @var array
private static $has_one = array( */
'Blog' => 'Blog', private static $has_one = array(
); 'Blog' => 'Blog',
);
/**
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function getCMSFields() { */
$this->beforeUpdateCMSFields(function (FieldList $fields) { public function getCMSFields()
$fields[] = DropdownField::create( {
'BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map() $this->beforeUpdateCMSFields(function (FieldList $fields) {
); $fields[] = DropdownField::create(
'BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map()
$fields[] = NumericField::create( );
'Limit', _t('BlogCategoriesWidget.Limit.Label', 'Limit'), 0
) $fields[] = NumericField::create(
->setDescription(_t('BlogCategoriesWidget.Limit.Description', 'Limit the number of categories shown by this widget (set to 0 to show all categories).')) 'Limit', _t('BlogCategoriesWidget.Limit.Label', 'Limit'), 0
->setMaxLength(3); )
->setDescription(_t('BlogCategoriesWidget.Limit.Description', 'Limit the number of categories shown by this widget (set to 0 to show all categories).'))
$fields[] = DropdownField::create( ->setMaxLength(3);
'Order', _t('BlogCategoriesWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated')
) $fields[] = DropdownField::create(
->setDescription(_t('BlogCategoriesWidget.Sort.Description', 'Change the order of categories shown by this widget.')); 'Order', _t('BlogCategoriesWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated')
)
$fields[] = DropdownField::create( ->setDescription(_t('BlogCategoriesWidget.Sort.Description', 'Change the order of categories shown by this widget.'));
'Direction', _t('BlogCategoriesWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending')
) $fields[] = DropdownField::create(
->setDescription(_t('BlogCategoriesWidget.Direction.Description', 'Change the direction of ordering of categories shown by this widget.')); 'Direction', _t('BlogCategoriesWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending')
}); )
->setDescription(_t('BlogCategoriesWidget.Direction.Description', 'Change the direction of ordering of categories shown by this widget.'));
return parent::getCMSFields(); });
}
return parent::getCMSFields();
/** }
* @return DataList
*/ /**
public function getCategories() { * @return DataList
$blog = $this->Blog(); */
public function getCategories()
if (!$blog) { {
return array(); $blog = $this->Blog();
}
if (!$blog) {
$query = $blog->Categories(); return array();
}
if ($this->Limit) {
$query = $query->limit(Convert::raw2sql($this->Limit)); $query = $blog->Categories();
}
if ($this->Limit) {
if ($this->Order && $this->Direction) { $query = $query->limit(Convert::raw2sql($this->Limit));
$query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); }
}
if ($this->Order && $this->Direction) {
return $query; $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction));
} }
}
return $query;
class BlogCategoriesWidget_Controller extends Widget_Controller { }
}
}
class BlogCategoriesWidget_Controller extends Widget_Controller
{
}

View File

@ -1,77 +1,80 @@
<?php <?php
if(!class_exists("Widget")) { if (!class_exists("Widget")) {
return; return;
} }
/** /**
* @method Blog Blog() * @method Blog Blog()
* *
* @property int $NumberOfPosts * @property int $NumberOfPosts
*/ */
class BlogRecentPostsWidget extends Widget { class BlogRecentPostsWidget extends Widget
/** {
* @var string /**
*/ * @var string
private static $title = 'Recent Posts'; */
private static $title = 'Recent Posts';
/**
* @var string /**
*/ * @var string
private static $cmsTitle = 'Recent Posts'; */
private static $cmsTitle = 'Recent Posts';
/**
* @var string /**
*/ * @var string
private static $description = 'Displays a list of recent blog posts.'; */
private static $description = 'Displays a list of recent blog posts.';
/**
* @var array /**
*/ * @var array
private static $db = array( */
'NumberOfPosts' => 'Int', private static $db = array(
); 'NumberOfPosts' => 'Int',
);
/**
* @var array /**
*/ * @var array
private static $has_one = array( */
'Blog' => 'Blog', private static $has_one = array(
); 'Blog' => 'Blog',
);
/**
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function getCMSFields() { */
$this->beforeUpdateCMSFields(function ($fields) { public function getCMSFields()
/** {
* @var FieldList $fields $this->beforeUpdateCMSFields(function ($fields) {
*/ /**
$fields->merge(array( * @var FieldList $fields
DropdownField::create('BlogID', _t('BlogRecentPostsWidget.Blog', 'Blog'), Blog::get()->map()), */
NumericField::create('NumberOfPosts', _t('BlogRecentPostsWidget.NumberOfPosts', 'Number of Posts')) $fields->merge(array(
)); DropdownField::create('BlogID', _t('BlogRecentPostsWidget.Blog', 'Blog'), Blog::get()->map()),
}); NumericField::create('NumberOfPosts', _t('BlogRecentPostsWidget.NumberOfPosts', 'Number of Posts'))
));
return parent::getCMSFields(); });
}
return parent::getCMSFields();
/** }
* @return array
*/ /**
public function getPosts() { * @return array
$blog = $this->Blog(); */
public function getPosts()
if($blog) { {
return $blog->getBlogPosts() $blog = $this->Blog();
->sort('"PublishDate" DESC')
->limit($this->NumberOfPosts); if ($blog) {
} return $blog->getBlogPosts()
->sort('"PublishDate" DESC')
return array(); ->limit($this->NumberOfPosts);
} }
}
return array();
class BlogRecentPostsWidget_Controller extends Widget_Controller { }
}
}
class BlogRecentPostsWidget_Controller extends Widget_Controller
{
}

View File

@ -1,97 +1,100 @@
<?php <?php
if(!class_exists("Widget")) { if (!class_exists("Widget")) {
return; return;
} }
/** /**
* @method Blog Blog() * @method Blog Blog()
*/ */
class BlogTagsWidget extends Widget { class BlogTagsWidget extends Widget
/** {
* @var string /**
*/ * @var string
private static $title = 'Tags'; */
private static $title = 'Tags';
/**
* @var string /**
*/ * @var string
private static $cmsTitle = 'Blog Tags'; */
private static $cmsTitle = 'Blog Tags';
/**
* @var string /**
*/ * @var string
private static $description = 'Displays a list of blog tags.'; */
private static $description = 'Displays a list of blog tags.';
/**
* @var array /**
*/ * @var array
private static $db = array( */
'Limit' => 'Int', private static $db = array(
'Order' => 'Varchar', 'Limit' => 'Int',
'Direction' => 'Varchar', 'Order' => 'Varchar',
); 'Direction' => 'Varchar',
);
/**
* @var array /**
*/ * @var array
private static $has_one = array( */
'Blog' => 'Blog', private static $has_one = array(
); 'Blog' => 'Blog',
);
/**
* {@inheritdoc} /**
*/ * {@inheritdoc}
public function getCMSFields() { */
$this->beforeUpdateCMSFields(function (Fieldlist $fields) { public function getCMSFields()
$fields[] = DropdownField::create( {
'BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map() $this->beforeUpdateCMSFields(function (Fieldlist $fields) {
); $fields[] = DropdownField::create(
'BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map()
$fields[] = NumericField::create( );
'Limit', _t('BlogTagsWidget.Limit.Label', 'Limit'), 0
) $fields[] = NumericField::create(
->setDescription(_t('BlogTagsWidget.Limit.Description', 'Limit the number of tags shown by this widget (set to 0 to show all tags).')) 'Limit', _t('BlogTagsWidget.Limit.Label', 'Limit'), 0
->setMaxLength(3); )
->setDescription(_t('BlogTagsWidget.Limit.Description', 'Limit the number of tags shown by this widget (set to 0 to show all tags).'))
$fields[] = DropdownField::create( ->setMaxLength(3);
'Order', _t('BlogTagsWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated')
) $fields[] = DropdownField::create(
->setDescription(_t('BlogTagsWidget.Sort.Description', 'Change the order of tags shown by this widget.')); 'Order', _t('BlogTagsWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated')
)
$fields[] = DropdownField::create( ->setDescription(_t('BlogTagsWidget.Sort.Description', 'Change the order of tags shown by this widget.'));
'Direction', _t('BlogTagsWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending')
) $fields[] = DropdownField::create(
->setDescription(_t('BlogTagsWidget.Direction.Description', 'Change the direction of ordering of tags shown by this widget.')); 'Direction', _t('BlogTagsWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending')
}); )
->setDescription(_t('BlogTagsWidget.Direction.Description', 'Change the direction of ordering of tags shown by this widget.'));
return parent::getCMSFields(); });
}
return parent::getCMSFields();
/** }
* @return DataList
*/ /**
public function getTags() { * @return DataList
$blog = $this->Blog(); */
public function getTags()
if (!$blog) { {
return array(); $blog = $this->Blog();
}
if (!$blog) {
$query = $blog->Tags(); return array();
}
if ($this->Limit) {
$query = $query->limit(Convert::raw2sql($this->Limit)); $query = $blog->Tags();
}
if ($this->Limit) {
if ($this->Order && $this->Direction) { $query = $query->limit(Convert::raw2sql($this->Limit));
$query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); }
}
if ($this->Order && $this->Direction) {
return $query; $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction));
} }
}
return $query;
class BlogTagsWidget_Controller extends Widget_Controller { }
}
}
class BlogTagsWidget_Controller extends Widget_Controller
{
}

View File

@ -3,116 +3,124 @@
/** /**
* @mixin PHPUnit_Framework_TestCase * @mixin PHPUnit_Framework_TestCase
*/ */
class BlogCategoryTest extends FunctionalTest { class BlogCategoryTest extends FunctionalTest
/** {
* @var string /**
*/ * @var string
static $fixture_file = 'blog.yml'; */
public static $fixture_file = 'blog.yml';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setUp() { public function setUp()
parent::setUp(); {
parent::setUp();
SS_Datetime::set_mock_now('2013-10-10 20:00:00'); SS_Datetime::set_mock_now('2013-10-10 20:00:00');
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function tearDown() { public function tearDown()
SS_Datetime::clear_mock_now(); {
SS_Datetime::clear_mock_now();
parent::tearDown(); parent::tearDown();
} }
/** /**
* Tests that any blog posts returned from $category->BlogPosts() many_many are published, * Tests that any blog posts returned from $category->BlogPosts() many_many are published,
* both by normal 'save & publish' functionality and by publish date. * both by normal 'save & publish' functionality and by publish date.
*/ */
public function testBlogPosts() { public function testBlogPosts()
$member = Member::currentUser(); {
$member = Member::currentUser();
if($member) { if ($member) {
$member->logout(); $member->logout();
} }
$this->objFromFixture('BlogPost', 'FirstBlogPost'); $this->objFromFixture('BlogPost', 'FirstBlogPost');
/** /**
* @var BlogCategory $category * @var BlogCategory $category
*/ */
$category = $this->objFromFixture('BlogCategory', 'FirstCategory'); $category = $this->objFromFixture('BlogCategory', 'FirstCategory');
$this->assertEquals(1, $category->BlogPosts()->count(), 'Category blog post count'); $this->assertEquals(1, $category->BlogPosts()->count(), 'Category blog post count');
} }
public function testCanView() { public function testCanView()
$this->useDraftSite(); {
$this->useDraftSite();
$this->objFromFixture('Member', 'Admin'); $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$category = $this->objFromFixture('BlogCategory', 'SecondCategory'); $category = $this->objFromFixture('BlogCategory', 'SecondCategory');
$this->assertFalse($category->canView($editor), 'Editor should not be able to view category.'); $this->assertFalse($category->canView($editor), 'Editor should not be able to view category.');
} }
/** /**
* The first blog can be viewed by anybody. * The first blog can be viewed by anybody.
*/ */
public function testCanEdit() { public function testCanEdit()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$category = $this->objFromFixture('BlogCategory', 'FirstCategory'); $category = $this->objFromFixture('BlogCategory', 'FirstCategory');
$this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.'); $this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.');
$this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); $this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.');
$category = $this->objFromFixture('BlogCategory', 'SecondCategory'); $category = $this->objFromFixture('BlogCategory', 'SecondCategory');
$this->assertTrue($category->canEdit($admin), 'Admin should be able to edit category.'); $this->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->assertFalse($category->canEdit($editor), 'Editor should not be able to edit category.');
$category = $this->objFromFixture('BlogCategory', 'ThirdCategory'); $category = $this->objFromFixture('BlogCategory', 'ThirdCategory');
$this->assertTrue($category->canEdit($admin), 'Admin should always be able to edit category.'); $this->assertTrue($category->canEdit($admin), 'Admin should always be able to edit category.');
$this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.'); $this->assertTrue($category->canEdit($editor), 'Editor should be able to edit category.');
} }
public function testCanCreate() { public function testCanCreate()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$category = singleton('BlogCategory'); $category = singleton('BlogCategory');
$this->assertTrue($category->canCreate($admin), 'Admin should be able to create category.'); $this->assertTrue($category->canCreate($admin), 'Admin should be able to create category.');
$this->assertTrue($category->canCreate($editor), 'Editor should be able to create category.'); $this->assertTrue($category->canCreate($editor), 'Editor should be able to create category.');
} }
public function testCanDelete() { public function testCanDelete()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$category = $this->objFromFixture('BlogCategory', 'FirstCategory'); $category = $this->objFromFixture('BlogCategory', 'FirstCategory');
$this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.'); $this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.');
$this->assertTrue($category->canDelete($editor), 'Editor should be able to category category.'); $this->assertTrue($category->canDelete($editor), 'Editor should be able to category category.');
$category = $this->objFromFixture('BlogCategory', 'SecondCategory'); $category = $this->objFromFixture('BlogCategory', 'SecondCategory');
$this->assertTrue($category->canDelete($admin), 'Admin should be able to delete category.'); $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->assertFalse($category->canDelete($editor), 'Editor should not be able to delete category.');
$category = $this->objFromFixture('BlogCategory', 'ThirdCategory'); $category = $this->objFromFixture('BlogCategory', 'ThirdCategory');
$this->assertTrue($category->canDelete($admin), 'Admin should always be able to delete category.'); $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.'); $this->assertTrue($category->canDelete($editor), 'Editor should be able to delete category.');
} }
} }

View File

@ -3,40 +3,44 @@
/** /**
* @mixin PHPUnit_Framework_TestCase * @mixin PHPUnit_Framework_TestCase
*/ */
class BlogPostFilterTest extends SapphireTest { class BlogPostFilterTest extends SapphireTest
/** {
* @var string /**
*/ * @var string
static $fixture_file = 'blog.yml'; */
public static $fixture_file = 'blog.yml';
public function setUp() { public function setUp()
parent::setUp(); {
parent::setUp();
SS_Datetime::set_mock_now('2013-10-10 20:00:00'); SS_Datetime::set_mock_now('2013-10-10 20:00:00');
} }
public function tearDown() { public function tearDown()
SS_Datetime::clear_mock_now(); {
SS_Datetime::clear_mock_now();
parent::tearDown(); parent::tearDown();
} }
public function testFilter() { public function testFilter()
$member = Member::currentUser(); {
$member = Member::currentUser();
if($member) { if ($member) {
$member->logout(); $member->logout();
} }
/** /**
* @var Blog $blog * @var Blog $blog
*/ */
$blog = $this->objFromFixture('Blog', 'FirstBlog'); $blog = $this->objFromFixture('Blog', 'FirstBlog');
$this->assertEquals(3, $blog->AllChildren()->Count(), 'Filtered blog posts'); $this->assertEquals(3, $blog->AllChildren()->Count(), 'Filtered blog posts');
SS_Datetime::set_mock_now('2020-01-01 00:00:00'); SS_Datetime::set_mock_now('2020-01-01 00:00:00');
$this->assertEquals(5, $blog->AllChildren()->Count(), 'Unfiltered blog posts'); $this->assertEquals(5, $blog->AllChildren()->Count(), 'Unfiltered blog posts');
} }
} }

View File

@ -1,79 +1,82 @@
<?php <?php
class BlogPostTest extends SapphireTest { class BlogPostTest extends SapphireTest
{
/** /**
* @var string * @var string
*/ */
static $fixture_file = 'blog.yml'; public static $fixture_file = 'blog.yml';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setUp() { public function setUp()
parent::setUp(); {
} parent::setUp();
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function tearDown() { public function tearDown()
SS_Datetime::clear_mock_now(); {
parent::tearDown(); SS_Datetime::clear_mock_now();
} parent::tearDown();
}
/** /**
* @dataProvider canViewProvider * @dataProvider canViewProvider
*/ */
public function testCanView($date, $user, $page, $canView) { public function testCanView($date, $user, $page, $canView)
$userRecord = $this->objFromFixture('Member', $user); {
$pageRecord = $this->objFromFixture('BlogPost', $page); $userRecord = $this->objFromFixture('Member', $user);
SS_Datetime::set_mock_now($date); $pageRecord = $this->objFromFixture('BlogPost', $page);
$this->assertEquals($canView, $pageRecord->canView($userRecord)); SS_Datetime::set_mock_now($date);
} $this->assertEquals($canView, $pageRecord->canView($userRecord));
}
public function canViewProvider() {
$someFutureDate = '2013-10-10 20:00:00'; public function canViewProvider()
$somePastDate = '2009-10-10 20:00:00'; {
return array( $someFutureDate = '2013-10-10 20:00:00';
// Check this post given the date has passed $somePastDate = '2009-10-10 20:00:00';
array($someFutureDate, 'Editor', 'PostA', true), return array(
array($someFutureDate, 'Contributor', 'PostA', true), // Check this post given the date has passed
array($someFutureDate, 'BlogEditor', 'PostA', true), array($someFutureDate, 'Editor', 'PostA', true),
array($someFutureDate, 'Writer', 'PostA', true), array($someFutureDate, 'Contributor', 'PostA', true),
array($someFutureDate, 'BlogEditor', 'PostA', true),
// Check unpublished pages array($someFutureDate, 'Writer', 'PostA', true),
array($somePastDate, 'Editor', 'PostA', true),
array($somePastDate, 'Contributor', 'PostA', true), // Check unpublished pages
array($somePastDate, 'BlogEditor', 'PostA', true), array($somePastDate, 'Editor', 'PostA', true),
array($somePastDate, 'Writer', 'PostA', true), array($somePastDate, 'Contributor', 'PostA', true),
array($somePastDate, 'BlogEditor', 'PostA', true),
// Test a page that was authored by another user array($somePastDate, 'Writer', 'PostA', true),
// Check this post given the date has passed // Test a page that was authored by another user
array($someFutureDate, 'Editor', 'FirstBlogPost', true),
array($someFutureDate, 'Contributor', 'FirstBlogPost', true),
array($someFutureDate, 'BlogEditor', 'FirstBlogPost', true),
array($someFutureDate, 'Writer', 'FirstBlogPost', true),
// Check future pages - non-editors shouldn't be able to see this
array($somePastDate, 'Editor', 'FirstBlogPost', true),
array($somePastDate, 'Contributor', 'FirstBlogPost', false),
array($somePastDate, 'BlogEditor', 'FirstBlogPost', false),
array($somePastDate, 'Writer', 'FirstBlogPost', false),
);
}
public function testCandidateAuthors() { // Check this post given the date has passed
$blogpost = $this->objFromFixture('BlogPost', 'PostC'); array($someFutureDate, 'Editor', 'FirstBlogPost', true),
array($someFutureDate, 'Contributor', 'FirstBlogPost', true),
array($someFutureDate, 'BlogEditor', 'FirstBlogPost', true),
array($someFutureDate, 'Writer', 'FirstBlogPost', true),
// Check future pages - non-editors shouldn't be able to see this
array($somePastDate, 'Editor', 'FirstBlogPost', true),
array($somePastDate, 'Contributor', 'FirstBlogPost', false),
array($somePastDate, 'BlogEditor', 'FirstBlogPost', false),
array($somePastDate, 'Writer', 'FirstBlogPost', false),
);
}
$this->assertEquals(7, $blogpost->getCandidateAuthors()->count()); public function testCandidateAuthors()
{
$blogpost = $this->objFromFixture('BlogPost', 'PostC');
//Set the group to draw Members from $this->assertEquals(7, $blogpost->getCandidateAuthors()->count());
Config::inst()->update('BlogPost', 'restrict_authors_to_group','BlogUsers');
$this->assertEquals(3, $blogpost->getCandidateAuthors()->count()); //Set the group to draw Members from
Config::inst()->update('BlogPost', 'restrict_authors_to_group', 'BlogUsers');
$this->assertEquals(3, $blogpost->getCandidateAuthors()->count());
} }
} }

View File

@ -3,124 +3,132 @@
/** /**
* @mixin PHPUnit_Framework_TestCase * @mixin PHPUnit_Framework_TestCase
*/ */
class BlogTagTest extends FunctionalTest { class BlogTagTest extends FunctionalTest
/** {
* @var string /**
*/ * @var string
static $fixture_file = 'blog.yml'; */
public static $fixture_file = 'blog.yml';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setUp() { public function setUp()
parent::setUp(); {
parent::setUp();
SS_Datetime::set_mock_now('2013-10-10 20:00:00'); SS_Datetime::set_mock_now('2013-10-10 20:00:00');
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function tearDown() { public function tearDown()
SS_Datetime::clear_mock_now(); {
SS_Datetime::clear_mock_now();
parent::tearDown(); parent::tearDown();
} }
/** /**
* Tests that any blog posts returned from $tag->BlogPosts() many_many are published, both by * Tests that any blog posts returned from $tag->BlogPosts() many_many are published, both by
* normal 'save & publish' functionality and by publish date. * normal 'save & publish' functionality and by publish date.
*/ */
public function testBlogPosts() { public function testBlogPosts()
$member = Member::currentUser(); {
$member = Member::currentUser();
if($member) { if ($member) {
$member->logout(); $member->logout();
} }
$this->objFromFixture('BlogPost', 'FirstBlogPost'); $this->objFromFixture('BlogPost', 'FirstBlogPost');
/** /**
* @var BlogTag $tag * @var BlogTag $tag
*/ */
$tag = $this->objFromFixture('BlogTag', 'FirstTag'); $tag = $this->objFromFixture('BlogTag', 'FirstTag');
$this->assertEquals(1, $tag->BlogPosts()->count(), 'Tag blog post count'); $this->assertEquals(1, $tag->BlogPosts()->count(), 'Tag blog post count');
} }
/** /**
* The first blog can be viewed by anybody. * The first blog can be viewed by anybody.
*/ */
public function testCanView() { public function testCanView()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$tag = $this->objFromFixture('BlogTag', 'FirstTag'); $tag = $this->objFromFixture('BlogTag', 'FirstTag');
$this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.'); $this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.');
$this->assertTrue($tag->canView($editor), 'Editor should be able to view tag.'); $this->assertTrue($tag->canView($editor), 'Editor should be able to view tag.');
$tag = $this->objFromFixture('BlogTag', 'SecondTag'); $tag = $this->objFromFixture('BlogTag', 'SecondTag');
$this->assertTrue($tag->canView($admin), 'Admin should be able to view tag.'); $this->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->assertFalse($tag->canView($editor), 'Editor should not be able to view tag.');
} }
public function testCanEdit() { public function testCanEdit()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$tag = $this->objFromFixture('BlogTag', 'FirstTag'); $tag = $this->objFromFixture('BlogTag', 'FirstTag');
$this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.'); $this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.');
$this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); $this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.');
$tag = $this->objFromFixture('BlogTag', 'SecondTag'); $tag = $this->objFromFixture('BlogTag', 'SecondTag');
$this->assertTrue($tag->canEdit($admin), 'Admin should be able to edit tag.'); $this->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->assertFalse($tag->canEdit($editor), 'Editor should not be able to edit tag.');
$tag = $this->objFromFixture('BlogTag', 'ThirdTag'); $tag = $this->objFromFixture('BlogTag', 'ThirdTag');
$this->assertTrue($tag->canEdit($admin), 'Admin should always be able to edit tags.'); $this->assertTrue($tag->canEdit($admin), 'Admin should always be able to edit tags.');
$this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.'); $this->assertTrue($tag->canEdit($editor), 'Editor should be able to edit tag.');
} }
public function testCanCreate() { public function testCanCreate()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$tag = singleton('BlogTag'); $tag = singleton('BlogTag');
$this->assertTrue($tag->canCreate($admin), 'Admin should be able to create tag.'); $this->assertTrue($tag->canCreate($admin), 'Admin should be able to create tag.');
$this->assertTrue($tag->canCreate($editor), 'Editor should be able to create tag.'); $this->assertTrue($tag->canCreate($editor), 'Editor should be able to create tag.');
} }
public function testCanDelete() { public function testCanDelete()
$this->useDraftSite(); {
$this->useDraftSite();
$admin = $this->objFromFixture('Member', 'Admin'); $admin = $this->objFromFixture('Member', 'Admin');
$editor = $this->objFromFixture('Member', 'Editor'); $editor = $this->objFromFixture('Member', 'Editor');
$tag = $this->objFromFixture('BlogTag', 'FirstTag'); $tag = $this->objFromFixture('BlogTag', 'FirstTag');
$this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.'); $this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.');
$this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); $this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.');
$tag = $this->objFromFixture('BlogTag', 'SecondTag'); $tag = $this->objFromFixture('BlogTag', 'SecondTag');
$this->assertTrue($tag->canDelete($admin), 'Admin should be able to delete tag.'); $this->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->assertFalse($tag->canDelete($editor), 'Editor should not be able to delete tag.');
$tag = $this->objFromFixture('BlogTag', 'ThirdTag'); $tag = $this->objFromFixture('BlogTag', 'ThirdTag');
$this->assertTrue($tag->canDelete($admin), 'Admin should always be able to delete tags.'); $this->assertTrue($tag->canDelete($admin), 'Admin should always be able to delete tags.');
$this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.'); $this->assertTrue($tag->canDelete($editor), 'Editor should be able to delete tag.');
} }
} }

View File

@ -3,332 +3,347 @@
/** /**
* @mixin PHPUnit_Framework_TestCase * @mixin PHPUnit_Framework_TestCase
*/ */
class BlogTest extends SapphireTest { class BlogTest extends SapphireTest
/** {
* @var string /**
*/ * @var string
static $fixture_file = 'blog.yml'; */
public static $fixture_file = 'blog.yml';
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setUp() { public function setUp()
parent::setUp(); {
parent::setUp();
Config::nest(); Config::nest();
SS_Datetime::set_mock_now('2013-10-10 20:00:00'); SS_Datetime::set_mock_now('2013-10-10 20:00:00');
/** /**
* @var Blog $blog * @var Blog $blog
*/ */
$blog = $this->objFromFixture('Blog', 'FirstBlog'); $blog = $this->objFromFixture('Blog', 'FirstBlog');
$blog->publish('Stage', 'Live'); $blog->publish('Stage', 'Live');
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function tearDown() { public function tearDown()
SS_Datetime::clear_mock_now(); {
Config::unnest(); SS_Datetime::clear_mock_now();
Config::unnest();
parent::tearDown(); parent::tearDown();
} }
public function testGetExcludedSiteTreeClassNames() { public function testGetExcludedSiteTreeClassNames()
$member = Member::currentUser(); {
$member = Member::currentUser();
if($member) { if ($member) {
$member->logout(); $member->logout();
} }
/** /**
* @var Blog $blog * @var Blog $blog
*/ */
$blog = $this->objFromFixture('Blog', 'FirstBlog'); $blog = $this->objFromFixture('Blog', 'FirstBlog');
Config::inst()->update('BlogPost', 'show_in_sitetree', true); Config::inst()->update('BlogPost', 'show_in_sitetree', true);
$classes = $blog->getExcludedSiteTreeClassNames(); $classes = $blog->getExcludedSiteTreeClassNames();
$this->assertNotContains('BlogPost', $classes, 'BlogPost class should be hidden.'); $this->assertNotContains('BlogPost', $classes, 'BlogPost class should be hidden.');
Config::inst()->update('BlogPost', 'show_in_sitetree', false); Config::inst()->update('BlogPost', 'show_in_sitetree', false);
$classes = $blog->getExcludedSiteTreeClassNames(); $classes = $blog->getExcludedSiteTreeClassNames();
$this->assertContains('BlogPost', $classes, 'BlogPost class should be hidden.'); $this->assertContains('BlogPost', $classes, 'BlogPost class should be hidden.');
} }
public function testGetArchivedBlogPosts() { public function testGetArchivedBlogPosts()
$member = Member::currentUser(); {
$member = Member::currentUser();
if($member) { if ($member) {
$member->logout(); $member->logout();
} }
/** /**
* @var Blog $blog * @var Blog $blog
*/ */
$blog = $this->objFromFixture('Blog', 'FirstBlog'); $blog = $this->objFromFixture('Blog', 'FirstBlog');
$archive = $blog->getArchivedBlogPosts(2013); $archive = $blog->getArchivedBlogPosts(2013);
$this->assertEquals(2, $archive->count(), 'Incorrect Yearly Archive count for 2013'); $this->assertEquals(2, $archive->count(), 'Incorrect Yearly Archive count for 2013');
$this->assertEquals('First Post', $archive->first()->Title, 'Incorrect First Blog post'); $this->assertEquals('First Post', $archive->first()->Title, 'Incorrect First Blog post');
$this->assertEquals('Second Post', $archive->last()->Title, 'Incorrect Last Blog post'); $this->assertEquals('Second Post', $archive->last()->Title, 'Incorrect Last Blog post');
$archive = $blog->getArchivedBlogPosts(2013, 10); $archive = $blog->getArchivedBlogPosts(2013, 10);
$this->assertEquals(1, $archive->count(), 'Incorrect monthly archive count.'); $this->assertEquals(1, $archive->count(), 'Incorrect monthly archive count.');
$archive = $blog->getArchivedBlogPosts(2013, 10, 01); $archive = $blog->getArchivedBlogPosts(2013, 10, 01);
$this->assertEquals(1, $archive->count(), 'Incorrect daily archive count.'); $this->assertEquals(1, $archive->count(), 'Incorrect daily archive count.');
} }
public function testArchiveLinks() { public function testArchiveLinks()
/** {
* @var Blog $blog /**
*/ * @var Blog $blog
$blog = $this->objFromFixture('Blog', 'FirstBlog'); */
$blog = $this->objFromFixture('Blog', 'FirstBlog');
$link = Controller::join_links($blog->Link('archive'), '2013', '10', '01'); $link = Controller::join_links($blog->Link('archive'), '2013', '10', '01');
$this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200');
$link = Controller::join_links($blog->Link('archive'), '2013', '10'); $link = Controller::join_links($blog->Link('archive'), '2013', '10');
$this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200');
$link = Controller::join_links($blog->Link('archive'), '2013'); $link = Controller::join_links($blog->Link('archive'), '2013');
$this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200');
$link = Controller::join_links($blog->Link('archive'), '2011', '10', '01'); $link = Controller::join_links($blog->Link('archive'), '2011', '10', '01');
$this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200');
$link = Controller::join_links($blog->Link('archive')); $link = Controller::join_links($blog->Link('archive'));
$this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200'); $this->assertEquals(200, $this->getStatusOf($link), 'HTTP Status should be 200');
$link = Controller::join_links($blog->Link('archive'), 'invalid-year'); $link = Controller::join_links($blog->Link('archive'), 'invalid-year');
$this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404');
$link = Controller::join_links($blog->Link('archive'), '2013', '99'); $link = Controller::join_links($blog->Link('archive'), '2013', '99');
$this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404');
$link = Controller::join_links($blog->Link('archive'), '2013', '10', '99'); $link = Controller::join_links($blog->Link('archive'), '2013', '10', '99');
$this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404'); $this->assertEquals(404, $this->getStatusOf($link), 'HTTP Status should be 404');
}
}
/*
/* * Test archive year
* Test archive year */
*/ public function testArchiveYear()
public function testArchiveYear(){ {
$blog = $this->objFromFixture('Blog', 'FirstBlog'); $blog = $this->objFromFixture('Blog', 'FirstBlog');
$controller = new Blog_Controller($blog); $controller = new Blog_Controller($blog);
$this->requestURL($controller, 'first-post/archive/'); $this->requestURL($controller, 'first-post/archive/');
$this->assertEquals(2013, $controller->getArchiveYear(), 'getArchiveYear should return 2013'); $this->assertEquals(2013, $controller->getArchiveYear(), 'getArchiveYear should return 2013');
} }
/** /**
* @param string $link * @param string $link
* *
* @return int * @return int
*/ */
protected function getStatusOf($link) { protected function getStatusOf($link)
return Director::test($link)->getStatusCode(); {
} return Director::test($link)->getStatusCode();
}
public function testRoles() {
/** public function testRoles()
* @var Blog $firstBlog {
*/ /**
$firstBlog = $this->objFromFixture('Blog', 'FirstBlog'); * @var Blog $firstBlog
*/
/** $firstBlog = $this->objFromFixture('Blog', 'FirstBlog');
* @var Blog $fourthBlog
*/ /**
$fourthBlog = $this->objFromFixture('Blog', 'FourthBlog'); * @var Blog $fourthBlog
*/
/** $fourthBlog = $this->objFromFixture('Blog', 'FourthBlog');
* @var BlogPost $postA
*/ /**
$postA = $this->objFromFixture('BlogPost', 'PostA'); * @var BlogPost $postA
*/
/** $postA = $this->objFromFixture('BlogPost', 'PostA');
* @var BlogPost $postB
*/ /**
$postB = $this->objFromFixture('BlogPost', 'PostB'); * @var BlogPost $postB
*/
/** $postB = $this->objFromFixture('BlogPost', 'PostB');
* @var BlogPost $postC
*/ /**
$postC = $this->objFromFixture('BlogPost', 'PostC'); * @var BlogPost $postC
*/
/** $postC = $this->objFromFixture('BlogPost', 'PostC');
* @var Member $editor
*/ /**
$editor = $this->objFromFixture('Member', 'BlogEditor'); * @var Member $editor
*/
/** $editor = $this->objFromFixture('Member', 'BlogEditor');
* @var Member $writer
*/ /**
$writer = $this->objFromFixture('Member', 'Writer'); * @var Member $writer
*/
/** $writer = $this->objFromFixture('Member', 'Writer');
* @var Member $contributor
*/ /**
$contributor = $this->objFromFixture('Member', 'Contributor'); * @var Member $contributor
*/
/** $contributor = $this->objFromFixture('Member', 'Contributor');
* @var Member $visitor
*/ /**
$visitor = $this->objFromFixture('Member', 'Visitor'); * @var Member $visitor
*/
$this->assertEquals('Editor', $fourthBlog->RoleOf($editor)); $visitor = $this->objFromFixture('Member', 'Visitor');
$this->assertEquals('Contributor', $fourthBlog->RoleOf($contributor));
$this->assertEquals('Writer', $fourthBlog->RoleOf($writer)); $this->assertEquals('Editor', $fourthBlog->RoleOf($editor));
$this->assertEmpty($fourthBlog->RoleOf($visitor)); $this->assertEquals('Contributor', $fourthBlog->RoleOf($contributor));
$this->assertEquals('Author', $postA->RoleOf($writer)); $this->assertEquals('Writer', $fourthBlog->RoleOf($writer));
$this->assertEquals('Author', $postA->RoleOf($contributor)); $this->assertEmpty($fourthBlog->RoleOf($visitor));
$this->assertEquals('Editor', $postA->RoleOf($editor)); $this->assertEquals('Author', $postA->RoleOf($writer));
$this->assertEmpty($postA->RoleOf($visitor)); $this->assertEquals('Author', $postA->RoleOf($contributor));
$this->assertEquals('Editor', $postA->RoleOf($editor));
// Test RoleOf with string values given $this->assertEmpty($postA->RoleOf($visitor));
$this->assertEquals('Editor', $fourthBlog->RoleOf((string)(int)$editor->ID));
$this->assertEquals('Contributor', $fourthBlog->RoleOf((string)(int)$contributor->ID)); // Test RoleOf with string values given
$this->assertEquals('Writer', $fourthBlog->RoleOf((string)(int)$writer->ID)); $this->assertEquals('Editor', $fourthBlog->RoleOf((string)(int)$editor->ID));
$this->assertEmpty($fourthBlog->RoleOf((string)(int)$visitor->ID)); $this->assertEquals('Contributor', $fourthBlog->RoleOf((string)(int)$contributor->ID));
$this->assertEquals('Author', $postA->RoleOf((string)(int)$writer->ID)); $this->assertEquals('Writer', $fourthBlog->RoleOf((string)(int)$writer->ID));
$this->assertEquals('Author', $postA->RoleOf((string)(int)$contributor->ID)); $this->assertEmpty($fourthBlog->RoleOf((string)(int)$visitor->ID));
$this->assertEquals('Editor', $postA->RoleOf((string)(int)$editor->ID)); $this->assertEquals('Author', $postA->RoleOf((string)(int)$writer->ID));
$this->assertEmpty($postA->RoleOf((string)(int)$visitor->ID)); $this->assertEquals('Author', $postA->RoleOf((string)(int)$contributor->ID));
$this->assertEquals('Editor', $postA->RoleOf((string)(int)$editor->ID));
// Test RoleOf with int values given $this->assertEmpty($postA->RoleOf((string)(int)$visitor->ID));
$this->assertEquals('Editor', $fourthBlog->RoleOf((int)$editor->ID));
$this->assertEquals('Contributor', $fourthBlog->RoleOf((int)$contributor->ID)); // Test RoleOf with int values given
$this->assertEquals('Writer', $fourthBlog->RoleOf((int)$writer->ID)); $this->assertEquals('Editor', $fourthBlog->RoleOf((int)$editor->ID));
$this->assertEmpty($fourthBlog->RoleOf((int)$visitor->ID)); $this->assertEquals('Contributor', $fourthBlog->RoleOf((int)$contributor->ID));
$this->assertEquals('Author', $postA->RoleOf((int)$writer->ID)); $this->assertEquals('Writer', $fourthBlog->RoleOf((int)$writer->ID));
$this->assertEquals('Author', $postA->RoleOf((int)$contributor->ID)); $this->assertEmpty($fourthBlog->RoleOf((int)$visitor->ID));
$this->assertEquals('Editor', $postA->RoleOf((int)$editor->ID)); $this->assertEquals('Author', $postA->RoleOf((int)$writer->ID));
$this->assertEmpty($postA->RoleOf((int)$visitor->ID)); $this->assertEquals('Author', $postA->RoleOf((int)$contributor->ID));
$this->assertEquals('Editor', $postA->RoleOf((int)$editor->ID));
$this->assertTrue($fourthBlog->canEdit($editor)); $this->assertEmpty($postA->RoleOf((int)$visitor->ID));
$this->assertFalse($firstBlog->canEdit($editor));
$this->assertTrue($fourthBlog->canAddChildren($editor)); $this->assertTrue($fourthBlog->canEdit($editor));
$this->assertFalse($firstBlog->canAddChildren($editor)); $this->assertFalse($firstBlog->canEdit($editor));
$this->assertTrue($postA->canEdit($editor)); $this->assertTrue($fourthBlog->canAddChildren($editor));
$this->assertTrue($postB->canEdit($editor)); $this->assertFalse($firstBlog->canAddChildren($editor));
$this->assertTrue($postC->canEdit($editor)); $this->assertTrue($postA->canEdit($editor));
$this->assertTrue($postA->canPublish($editor)); $this->assertTrue($postB->canEdit($editor));
$this->assertTrue($postB->canPublish($editor)); $this->assertTrue($postC->canEdit($editor));
$this->assertTrue($postC->canPublish($editor)); $this->assertTrue($postA->canPublish($editor));
$this->assertTrue($postB->canPublish($editor));
$this->assertFalse($fourthBlog->canEdit($writer)); $this->assertTrue($postC->canPublish($editor));
$this->assertFalse($firstBlog->canEdit($writer));
$this->assertTrue($fourthBlog->canAddChildren($writer)); $this->assertFalse($fourthBlog->canEdit($writer));
$this->assertFalse($firstBlog->canAddChildren($writer)); $this->assertFalse($firstBlog->canEdit($writer));
$this->assertTrue($postA->canEdit($writer)); $this->assertTrue($fourthBlog->canAddChildren($writer));
$this->assertFalse($postB->canEdit($writer)); $this->assertFalse($firstBlog->canAddChildren($writer));
$this->assertTrue($postC->canEdit($writer)); $this->assertTrue($postA->canEdit($writer));
$this->assertTrue($postA->canPublish($writer)); $this->assertFalse($postB->canEdit($writer));
$this->assertFalse($postB->canPublish($writer)); $this->assertTrue($postC->canEdit($writer));
$this->assertTrue($postC->canPublish($writer)); $this->assertTrue($postA->canPublish($writer));
$this->assertFalse($postB->canPublish($writer));
$this->assertFalse($fourthBlog->canEdit($contributor)); $this->assertTrue($postC->canPublish($writer));
$this->assertFalse($firstBlog->canEdit($contributor));
$this->assertTrue($fourthBlog->canAddChildren($contributor)); $this->assertFalse($fourthBlog->canEdit($contributor));
$this->assertFalse($firstBlog->canAddChildren($contributor)); $this->assertFalse($firstBlog->canEdit($contributor));
$this->assertTrue($postA->canEdit($contributor)); $this->assertTrue($fourthBlog->canAddChildren($contributor));
$this->assertFalse($postB->canEdit($contributor)); $this->assertFalse($firstBlog->canAddChildren($contributor));
$this->assertTrue($postC->canEdit($contributor)); $this->assertTrue($postA->canEdit($contributor));
$this->assertFalse($postA->canPublish($contributor)); $this->assertFalse($postB->canEdit($contributor));
$this->assertFalse($postB->canPublish($contributor)); $this->assertTrue($postC->canEdit($contributor));
$this->assertFalse($postC->canPublish($contributor)); $this->assertFalse($postA->canPublish($contributor));
$this->assertFalse($postB->canPublish($contributor));
$this->assertFalse($fourthBlog->canEdit($visitor)); $this->assertFalse($postC->canPublish($contributor));
$this->assertFalse($firstBlog->canEdit($visitor));
$this->assertFalse($fourthBlog->canAddChildren($visitor)); $this->assertFalse($fourthBlog->canEdit($visitor));
$this->assertFalse($firstBlog->canAddChildren($visitor)); $this->assertFalse($firstBlog->canEdit($visitor));
$this->assertFalse($postA->canEdit($visitor)); $this->assertFalse($fourthBlog->canAddChildren($visitor));
$this->assertFalse($postB->canEdit($visitor)); $this->assertFalse($firstBlog->canAddChildren($visitor));
$this->assertFalse($postC->canEdit($visitor)); $this->assertFalse($postA->canEdit($visitor));
$this->assertFalse($postA->canPublish($visitor)); $this->assertFalse($postB->canEdit($visitor));
$this->assertFalse($postB->canPublish($visitor)); $this->assertFalse($postC->canEdit($visitor));
$this->assertFalse($postC->canPublish($visitor)); $this->assertFalse($postA->canPublish($visitor));
} $this->assertFalse($postB->canPublish($visitor));
$this->assertFalse($postC->canPublish($visitor));
public function testFilteredCategories() { }
$blog = $this->objFromFixture('Blog', 'FirstBlog');
$controller = new Blog_Controller($blog); public function testFilteredCategories()
{
// Root url $blog = $this->objFromFixture('Blog', 'FirstBlog');
$this->requestURL($controller, 'first-post'); $controller = new Blog_Controller($blog);
$this->assertIDsEquals(
$blog->AllChildren()->column('ID'), // Root url
$controller->PaginatedList()->column('ID') $this->requestURL($controller, 'first-post');
); $this->assertIDsEquals(
$blog->AllChildren()->column('ID'),
$controller->PaginatedList()->column('ID')
// RSS );
$this->requestURL($controller, 'first-post/rss');
$this->assertIDsEquals(
$blog->AllChildren()->column('ID'), // RSS
$controller->PaginatedList()->column('ID') $this->requestURL($controller, 'first-post/rss');
); $this->assertIDsEquals(
$blog->AllChildren()->column('ID'),
// Posts $controller->PaginatedList()->column('ID')
$firstPostID = $this->idFromFixture('BlogPost', 'FirstBlogPost'); );
$secondPostID = $this->idFromFixture('BlogPost', 'SecondBlogPost');
$firstFuturePostID = $this->idFromFixture('BlogPost', 'FirstFutureBlogPost'); // Posts
$secondFuturePostID = $this->idFromFixture('BlogPost', 'SecondFutureBlogPost'); $firstPostID = $this->idFromFixture('BlogPost', 'FirstBlogPost');
$secondPostID = $this->idFromFixture('BlogPost', 'SecondBlogPost');
// Request first tag $firstFuturePostID = $this->idFromFixture('BlogPost', 'FirstFutureBlogPost');
$this->requestURL($controller, 'first-post/tag/first-tag'); $secondFuturePostID = $this->idFromFixture('BlogPost', 'SecondFutureBlogPost');
$this->assertIDsEquals(
array($firstPostID, $firstFuturePostID, $secondFuturePostID), // Request first tag
$controller->PaginatedList() $this->requestURL($controller, 'first-post/tag/first-tag');
); $this->assertIDsEquals(
array($firstPostID, $firstFuturePostID, $secondFuturePostID),
// Request 2013 posts $controller->PaginatedList()
$this->requestURL($controller, 'first-post/archive/2013'); );
$this->assertIDsEquals(
array($firstPostID, $secondPostID, $secondFuturePostID), // Request 2013 posts
$controller->PaginatedList() $this->requestURL($controller, 'first-post/archive/2013');
); $this->assertIDsEquals(
} array($firstPostID, $secondPostID, $secondFuturePostID),
$controller->PaginatedList()
/** );
* Mock a request against a given controller }
*
* @param ContentController $controller /**
* @param string $url * Mock a request against a given controller
*/ *
protected function requestURL(ContentController $controller, $url) { * @param ContentController $controller
$request = new SS_HTTPRequest('get', $url); * @param string $url
$request->match('$URLSegment//$Action/$ID/$OtherID'); */
$request->shift(); protected function requestURL(ContentController $controller, $url)
$controller->init(); {
$controller->handleRequest($request, new DataModel()); $request = new SS_HTTPRequest('get', $url);
} $request->match('$URLSegment//$Action/$ID/$OtherID');
$request->shift();
/** $controller->init();
* Assert these id lists match $controller->handleRequest($request, new DataModel());
* }
* @param array|SS_List $left
* @param array|SS_List $right /**
*/ * Assert these id lists match
protected function assertIDsEquals($left, $right) { *
if($left instanceof SS_List) $left = $left->column('ID'); * @param array|SS_List $left
if($right instanceof SS_List) $right = $right->column('ID'); * @param array|SS_List $right
asort($left); */
asort($right); protected function assertIDsEquals($left, $right)
$this->assertEquals(array_values($left), array_values($right)); {
} if ($left instanceof SS_List) {
$left = $left->column('ID');
}
if ($right instanceof SS_List) {
$right = $right->column('ID');
}
asort($left);
asort($right);
$this->assertEquals(array_values($left), array_values($right));
}
} }