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. //Migrate comma separated tags into BlogTag objects.
foreach($this->TagNames() as $tag) { foreach ($this->TagNames() as $tag) {
$existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID));
if ($existingTag->count()) {
//if tag already exists we will simply add it to this post.
$tagObject = $existingTag->First();
} else {
$existingTag = BlogTag::get()->filter(array('Title' => $tag, 'BlogID' => $this->ParentID)); //if the tag is now we create it and add it to this post.
if($existingTag->count()) { $tagObject = new BlogTag();
//if tag already exists we will simply add it to this post. $tagObject->Title = $tag;
$tagObject = $existingTag->First(); $tagObject->BlogID = $this->ParentID;
$tagObject->write();
}
} else { if ($tagObject) {
$this->Tags()->add($tagObject);
}
}
//if the tag is now we create it and add it to this post. //Store if the original entity was published or not (draft)
$tagObject = new BlogTag(); $published = $this->IsPublished();
$tagObject->Title = $tag; // If a user has subclassed BlogEntry, it should not be turned into a BlogPost.
$tagObject->BlogID = $this->ParentID; if ($this->ClassName === 'BlogEntry') {
$tagObject->write(); $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;
}
if($tagObject){ /**
$this->Tags()->add($tagObject); * 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));
//Store if the original entity was published or not (draft) $results = array();
$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. foreach ($tags as $tag) {
$this->write(); if ($tag) {
if($published){ $results[mb_strtolower($tag)] = $tag;
$this->publish('Stage','Live'); }
$message = "PUBLISHED: "; }
} else {
$message = "DRAFT: ";
}
return $message . $this->Title;
}
/**
* Safely split and parse all distinct tags assigned to this BlogEntry.
*
* @deprecated since version 2.0
*
* @return array
*/
public function TagNames() {
$tags = preg_split('/\s*,\s*/', trim($this->Tags));
$results = array();
foreach($tags as $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
*/
protected function message($text)
{
if (Controller::curr() instanceof DatabaseAdmin) {
DB::alteration_message($text, 'obsolete');
} else {
echo $text . "<br/>";
}
}
} /**
* Migrate records of a single class
*
* @param string $class
* @param null|string $stage
*/
protected function upClass($class)
{
if (!class_exists($class)) {
return;
}
/** if (is_subclass_of($class, 'SiteTree')) {
* @param string $text $items = SiteTree::get()->filter('ClassName', $class);
*/ } else {
protected function message($text) { $items = $class::get();
if(Controller::curr() instanceof DatabaseAdmin) { }
DB::alteration_message($text, 'obsolete');
} else {
echo $text . "<br/>";
}
}
/** if ($count = $items->count()) {
* Migrate records of a single class $this->message(
* sprintf(
* @param string $class 'Migrating %s legacy %s records.',
* @param null|string $stage $count,
*/ $class
protected function upClass($class) { )
if(!class_exists($class)) { );
return;
}
if(is_subclass_of($class, 'SiteTree')) { foreach ($items as $item) {
$items = SiteTree::get()->filter('ClassName', $class); $cancel = $item->extend('onBeforeUp');
} else {
$items = $class::get();
}
if($count = $items->count()) { if ($cancel && min($cancel) === false) {
$this->message( continue;
sprintf( }
'Migrating %s legacy %s records.',
$count,
$class
)
);
foreach($items as $item) { /**
$cancel = $item->extend('onBeforeUp'); * @var MigratableObject $item
*/
$result = $item->up();
$this->message($result);
if($cancel && min($cancel) === false) { $item->extend('onAfterUp');
continue; }
} }
}
/** /**
* @var MigratableObject $item * {@inheritdoc}
*/ */
$result = $item->up(); public function down()
$this->message($result); {
$this->message('BlogMigrationTask::down() not implemented');
$item->extend('onAfterUp'); }
}
}
}
/**
* {@inheritdoc}
*/
public function down() {
$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

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

@ -7,36 +7,39 @@
* @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)
{
$stage = Versioned::current_stage();
if (Controller::curr() instanceof LeftAndMain) { if (Controller::curr() instanceof LeftAndMain) {
return; return;
} }
if($stage == 'Live' || !Permission::check('VIEW_DRAFT_CONTENT')) { if ($stage == 'Live' || !Permission::check('VIEW_DRAFT_CONTENT')) {
$query->addWhere(sprintf('"PublishDate" < \'%s\'', Convert::raw2sql(SS_Datetime::now()))); $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 * 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 * BlogPost table in its query. Leaving this table out means the default sort order column
* PublishDate causes an error. * PublishDate causes an error.
* *
* @see https://github.com/silverstripe/silverstripe-framework/issues/1682 * @see https://github.com/silverstripe/silverstripe-framework/issues/1682
* *
* @param SQLQuery $query * @param SQLQuery $query
* @param mixed $dataQuery * @param mixed $dataQuery
* @param mixed $parent * @param mixed $parent
*/ */
public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent) { public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent)
$dataQuery->innerJoin('BlogPost', '"SiteTree"."ID" = "BlogPost"."ID"'); {
} $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()
{
$sidebar = Cookie::get('blog-admin-sidebar');
if($sidebar == 1 || is_null($sidebar)) { if ($sidebar == 1 || is_null($sidebar)) {
return true; return true;
} }
return false; return false;
} }
} }

View File

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

View File

@ -7,88 +7,91 @@
* @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) {
$modifiedLabel = '';
if($record->isModifiedOnStage) { if ($record->isModifiedOnStage) {
$modifiedLabel = '<span class="modified">' . _t('GridFieldBlogPostState.Modified') . '</span>'; $modifiedLabel = '<span class="modified">' . _t('GridFieldBlogPostState.Modified') . '</span>';
} }
if(!$record->isPublished()) { if (!$record->isPublished()) {
/** /**
* @var SS_Datetime $lastEdited * @var SS_Datetime $lastEdited
*/ */
$lastEdited = $record->dbObject('LastEdited'); $lastEdited = $record->dbObject('LastEdited');
return _t( return _t(
'GridFieldBlogPostState.Draft', 'GridFieldBlogPostState.Draft',
'<i class="btn-icon gridfield-icon btn-icon-pencil"></i> Saved as Draft on {date}', '<i class="btn-icon gridfield-icon btn-icon-pencil"></i> Saved as Draft on {date}',
'State for when a post is saved.', 'State for when a post is saved.',
array( array(
'date' => $lastEdited->Nice(), 'date' => $lastEdited->Nice(),
) )
); );
} }
/** /**
* @var SS_Datetime $publishDate * @var SS_Datetime $publishDate
*/ */
$publishDate = $record->dbObject('PublishDate'); $publishDate = $record->dbObject('PublishDate');
if(strtotime($record->PublishDate) > time()) { if (strtotime($record->PublishDate) > time()) {
return _t( return _t(
'GridFieldBlogPostState.Timer', 'GridFieldBlogPostState.Timer',
'<i class="gridfield-icon blog-icon-timer"></i> Publish at {date}', '<i class="gridfield-icon blog-icon-timer"></i> Publish at {date}',
'State for when a post is published.', 'State for when a post is published.',
array( array(
'date' => $publishDate->Nice(), 'date' => $publishDate->Nice(),
) )
) . $modifiedLabel; ) . $modifiedLabel;
} }
return _t( return _t(
'GridFieldBlogPostState.Published', 'GridFieldBlogPostState.Published',
'<i class="btn-icon gridfield-icon btn-icon-accept"></i> Published on {date}', '<i class="btn-icon gridfield-icon btn-icon-accept"></i> Published on {date}',
'State for when a post is published.', 'State for when a post is published.',
array( array(
'date' => $publishDate->Nice(), 'date' => $publishDate->Nice(),
) )
) . $modifiedLabel; ) . $modifiedLabel;
} }
} }
return ''; return '';
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getColumnAttributes($gridField, $record, $columnName) { public function getColumnAttributes($gridField, $record, $columnName)
if($columnName == 'State') { {
if($record instanceof BlogPost) { if ($columnName == 'State') {
$published = $record->isPublished(); if ($record instanceof BlogPost) {
$published = $record->isPublished();
if(!$published) { if (!$published) {
$class = 'gridfield-icon draft'; $class = 'gridfield-icon draft';
} else if(strtotime($record->PublishDate) > time()) { } elseif (strtotime($record->PublishDate) > time()) {
$class = 'gridfield-icon timer'; $class = 'gridfield-icon timer';
} else { } else {
$class = 'gridfield-icon published'; $class = 'gridfield-icon published';
} }
return array( return array(
'class' => $class, 'class' => $class,
); );
} }
} }
return array(); return array();
} }
} }

View File

@ -6,14 +6,16 @@
* @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)
{
parent::__construct($itemsPerPage);
$this->removeComponentsByType('GridFieldSiteTreeState'); $this->removeComponentsByType('GridFieldSiteTreeState');
$this->addComponent(new GridFieldBlogPostState()); $this->addComponent(new GridFieldBlogPostState());
} }
} }

View File

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

@ -11,135 +11,143 @@
* @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( 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('BlogCategory.Title', 'Title')) $fields = new FieldList(
); TextField::create('Title', _t('BlogCategory.Title', 'Title'))
);
$this->extend('updateCMSFields', $fields); $this->extend('updateCMSFields', $fields);
return $fields; return $fields;
} }
/** /**
* Returns a relative link to this category. * Returns a relative link to this category.
* *
* @return string * @return string
*/ */
public function getLink() { public function getLink()
return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment); {
} return Controller::join_links($this->Blog()->Link(), 'category', $this->URLSegment);
}
/** /**
* Inherits from the parent blog or can be overwritten using a DataExtension. * Inherits from the parent blog or can be overwritten using a DataExtension.
* *
* @param 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

@ -15,672 +15,693 @@
* @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)
{
$labels = parent::fieldLabels($includeRelations);
$labels['Title'] = _t('BlogPost.PageTitleLabel', 'Post Title');
return $labels;
}
/**
* {@inheritdoc}
*/
protected function onBeforeWrite()
{
parent::onBeforeWrite();
if (!$this->exists() && ($member = Member::currentUser())) {
$this->Authors()->add($member);
}
}
} }
/** /**
* @package silverstripe * @package silverstripe
* @subpackage blog * @subpackage blog
*/ */
class BlogPost_Controller extends Page_Controller { 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,7 +1,7 @@
<?php <?php
if(!class_exists('Widget')) { if (!class_exists('Widget')) {
return; return;
} }
/** /**
@ -10,126 +10,129 @@ if(!class_exists('Widget')) {
* @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( private static $db = array(
'NumberToDisplay' => 'Int', 'NumberToDisplay' => 'Int',
'ArchiveType' => 'Enum(\'Monthly,Yearly\', \'Monthly\')', 'ArchiveType' => 'Enum(\'Monthly,Yearly\', \'Monthly\')',
); );
/** /**
* @var array * @var array
*/ */
private static $defaults = array( private static $defaults = array(
'NumberOfMonths' => 12, 'NumberOfMonths' => 12,
); );
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'Blog' => 'Blog', 'Blog' => 'Blog',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getCMSFields() { public function getCMSFields()
$self =& $this; {
$self =& $this;
$this->beforeUpdateCMSFields(function ($fields) use ($self) { $this->beforeUpdateCMSFields(function ($fields) use ($self) {
/** /**
* @var Enum $archiveType * @var Enum $archiveType
*/ */
$archiveType = $self->dbObject('ArchiveType'); $archiveType = $self->dbObject('ArchiveType');
$type = $archiveType->enumValues(); $type = $archiveType->enumValues();
foreach($type as $k => $v) { foreach ($type as $k => $v) {
$type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v); $type[$k] = _t('BlogArchiveWidget.' . ucfirst(strtolower($v)), $v);
} }
/** /**
* @var FieldList $fields * @var FieldList $fields
*/ */
$fields->merge(array( $fields->merge(array(
DropdownField::create('BlogID', _t('BlogArchiveWidget.Blog', 'Blog'), Blog::get()->map()), DropdownField::create('BlogID', _t('BlogArchiveWidget.Blog', 'Blog'), Blog::get()->map()),
DropdownField::create('ArchiveType', _t('BlogArchiveWidget.ArchiveType', 'ArchiveType'), $type), DropdownField::create('ArchiveType', _t('BlogArchiveWidget.ArchiveType', 'ArchiveType'), $type),
NumericField::create('NumberToDisplay', _t('BlogArchiveWidget.NumberToDisplay', 'No. to Display')) 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. * Returns a list of months where blog posts are present.
* *
* @return DataList * @return DataList
*/ */
public function getArchive() { public function getArchive()
$query = $this->Blog()->getBlogPosts()->dataQuery(); {
$query = $this->Blog()->getBlogPosts()->dataQuery();
if($this->ArchiveType == 'Yearly') { if ($this->ArchiveType == 'Yearly') {
$query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')'); $query->groupBy('DATE_FORMAT("PublishDate", \'%Y\')');
} else { } else {
$query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')'); $query->groupBy('DATE_FORMAT("PublishDate", \'%Y-%M\')');
} }
$posts = $this->Blog()->getBlogPosts()->setDataQuery($query); $posts = $this->Blog()->getBlogPosts()->setDataQuery($query);
if($this->NumberToDisplay > 0) { if ($this->NumberToDisplay > 0) {
$posts = $posts->limit($this->NumberToDisplay); $posts = $posts->limit($this->NumberToDisplay);
} }
$archive = new ArrayList(); $archive = new ArrayList();
if($posts->count() > 0) { if ($posts->count() > 0) {
foreach($posts as $post) { foreach ($posts as $post) {
/** /**
* @var BlogPost $post * @var BlogPost $post
*/ */
$date = Date::create(); $date = Date::create();
$date->setValue($post->PublishDate); $date->setValue($post->PublishDate);
if($this->ArchiveType == 'Yearly') { if ($this->ArchiveType == 'Yearly') {
$year = $date->FormatI18N("%Y"); $year = $date->FormatI18N("%Y");
$month = null; $month = null;
$title = $year; $title = $year;
} else { } else {
$year = $date->FormatI18N("%Y"); $year = $date->FormatI18N("%Y");
$month = $date->FormatI18N("%m"); $month = $date->FormatI18N("%m");
$title = $date->FormatI18N("%B %Y"); $title = $date->FormatI18N("%B %Y");
} }
$archive->push(new ArrayData(array( $archive->push(new ArrayData(array(
'Title' => $title, 'Title' => $title,
'Link' => Controller::join_links($this->Blog()->Link('archive'), $year, $month) '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( private static $db = array(
'Limit' => 'Int', 'Limit' => 'Int',
'Order' => 'Varchar', 'Order' => 'Varchar',
'Direction' => 'Varchar', 'Direction' => 'Varchar',
); );
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'Blog' => 'Blog', 'Blog' => 'Blog',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getCMSFields() { public function getCMSFields()
$this->beforeUpdateCMSFields(function (FieldList $fields) { {
$fields[] = DropdownField::create( $this->beforeUpdateCMSFields(function (FieldList $fields) {
'BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map() $fields[] = DropdownField::create(
); 'BlogID', _t('BlogCategoriesWidget.Blog', 'Blog'), Blog::get()->map()
);
$fields[] = NumericField::create( $fields[] = NumericField::create(
'Limit', _t('BlogCategoriesWidget.Limit.Label', 'Limit'), 0 'Limit', _t('BlogCategoriesWidget.Limit.Label', 'Limit'), 0
) )
->setDescription(_t('BlogCategoriesWidget.Limit.Description', 'Limit the number of categories shown by this widget (set to 0 to show all categories).')) ->setDescription(_t('BlogCategoriesWidget.Limit.Description', 'Limit the number of categories shown by this widget (set to 0 to show all categories).'))
->setMaxLength(3); ->setMaxLength(3);
$fields[] = DropdownField::create( $fields[] = DropdownField::create(
'Order', _t('BlogCategoriesWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated') 'Order', _t('BlogCategoriesWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated')
) )
->setDescription(_t('BlogCategoriesWidget.Sort.Description', 'Change the order of categories shown by this widget.')); ->setDescription(_t('BlogCategoriesWidget.Sort.Description', 'Change the order of categories shown by this widget.'));
$fields[] = DropdownField::create( $fields[] = DropdownField::create(
'Direction', _t('BlogCategoriesWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending') '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.')); ->setDescription(_t('BlogCategoriesWidget.Direction.Description', 'Change the direction of ordering of categories shown by this widget.'));
}); });
return parent::getCMSFields(); return parent::getCMSFields();
} }
/** /**
* @return DataList * @return DataList
*/ */
public function getCategories() { public function getCategories()
$blog = $this->Blog(); {
$blog = $this->Blog();
if (!$blog) { if (!$blog) {
return array(); return array();
} }
$query = $blog->Categories(); $query = $blog->Categories();
if ($this->Limit) { if ($this->Limit) {
$query = $query->limit(Convert::raw2sql($this->Limit)); $query = $query->limit(Convert::raw2sql($this->Limit));
} }
if ($this->Order && $this->Direction) { if ($this->Order && $this->Direction) {
$query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction));
} }
return $query; return $query;
} }
} }
class BlogCategoriesWidget_Controller extends Widget_Controller { class BlogCategoriesWidget_Controller extends Widget_Controller
{
} }

View File

@ -1,7 +1,7 @@
<?php <?php
if(!class_exists("Widget")) { if (!class_exists("Widget")) {
return; return;
} }
/** /**
@ -9,69 +9,72 @@ if(!class_exists("Widget")) {
* *
* @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( private static $db = array(
'NumberOfPosts' => 'Int', 'NumberOfPosts' => 'Int',
); );
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'Blog' => 'Blog', 'Blog' => 'Blog',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getCMSFields() { public function getCMSFields()
$this->beforeUpdateCMSFields(function ($fields) { {
/** $this->beforeUpdateCMSFields(function ($fields) {
* @var FieldList $fields /**
*/ * @var FieldList $fields
$fields->merge(array( */
DropdownField::create('BlogID', _t('BlogRecentPostsWidget.Blog', 'Blog'), Blog::get()->map()), $fields->merge(array(
NumericField::create('NumberOfPosts', _t('BlogRecentPostsWidget.NumberOfPosts', 'Number of Posts')) 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 * @return array
*/ */
public function getPosts() { public function getPosts()
$blog = $this->Blog(); {
$blog = $this->Blog();
if($blog) { if ($blog) {
return $blog->getBlogPosts() return $blog->getBlogPosts()
->sort('"PublishDate" DESC') ->sort('"PublishDate" DESC')
->limit($this->NumberOfPosts); ->limit($this->NumberOfPosts);
} }
return array(); 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( private static $db = array(
'Limit' => 'Int', 'Limit' => 'Int',
'Order' => 'Varchar', 'Order' => 'Varchar',
'Direction' => 'Varchar', 'Direction' => 'Varchar',
); );
/** /**
* @var array * @var array
*/ */
private static $has_one = array( private static $has_one = array(
'Blog' => 'Blog', 'Blog' => 'Blog',
); );
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getCMSFields() { public function getCMSFields()
$this->beforeUpdateCMSFields(function (Fieldlist $fields) { {
$fields[] = DropdownField::create( $this->beforeUpdateCMSFields(function (Fieldlist $fields) {
'BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map() $fields[] = DropdownField::create(
); 'BlogID', _t('BlogTagsWidget.Blog', 'Blog'), Blog::get()->map()
);
$fields[] = NumericField::create( $fields[] = NumericField::create(
'Limit', _t('BlogTagsWidget.Limit.Label', 'Limit'), 0 'Limit', _t('BlogTagsWidget.Limit.Label', 'Limit'), 0
) )
->setDescription(_t('BlogTagsWidget.Limit.Description', 'Limit the number of tags shown by this widget (set to 0 to show all tags).')) ->setDescription(_t('BlogTagsWidget.Limit.Description', 'Limit the number of tags shown by this widget (set to 0 to show all tags).'))
->setMaxLength(3); ->setMaxLength(3);
$fields[] = DropdownField::create( $fields[] = DropdownField::create(
'Order', _t('BlogTagsWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated') 'Order', _t('BlogTagsWidget.Sort.Label', 'Sort'), array('Title' => 'Title', 'Created' => 'Created', 'LastUpdated' => 'Updated')
) )
->setDescription(_t('BlogTagsWidget.Sort.Description', 'Change the order of tags shown by this widget.')); ->setDescription(_t('BlogTagsWidget.Sort.Description', 'Change the order of tags shown by this widget.'));
$fields[] = DropdownField::create( $fields[] = DropdownField::create(
'Direction', _t('BlogTagsWidget.Direction.Label', 'Direction'), array('ASC' => 'Ascending', 'DESC' => 'Descending') '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.')); ->setDescription(_t('BlogTagsWidget.Direction.Description', 'Change the direction of ordering of tags shown by this widget.'));
}); });
return parent::getCMSFields(); return parent::getCMSFields();
} }
/** /**
* @return DataList * @return DataList
*/ */
public function getTags() { public function getTags()
$blog = $this->Blog(); {
$blog = $this->Blog();
if (!$blog) { if (!$blog) {
return array(); return array();
} }
$query = $blog->Tags(); $query = $blog->Tags();
if ($this->Limit) { if ($this->Limit) {
$query = $query->limit(Convert::raw2sql($this->Limit)); $query = $query->limit(Convert::raw2sql($this->Limit));
} }
if ($this->Order && $this->Direction) { if ($this->Order && $this->Direction) {
$query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction)); $query = $query->sort(Convert::raw2sql($this->Order), Convert::raw2sql($this->Direction));
} }
return $query; 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
*/
public static $fixture_file = 'blog.yml';
/** /**
* @var string * {@inheritdoc}
*/ */
static $fixture_file = 'blog.yml'; public function setUp()
{
parent::setUp();
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function setUp() { public function tearDown()
parent::setUp(); {
} SS_Datetime::clear_mock_now();
parent::tearDown();
}
/** /**
* {@inheritdoc} * @dataProvider canViewProvider
*/ */
public function tearDown() { public function testCanView($date, $user, $page, $canView)
SS_Datetime::clear_mock_now(); {
parent::tearDown(); $userRecord = $this->objFromFixture('Member', $user);
} $pageRecord = $this->objFromFixture('BlogPost', $page);
SS_Datetime::set_mock_now($date);
$this->assertEquals($canView, $pageRecord->canView($userRecord));
}
/** public function canViewProvider()
* @dataProvider canViewProvider {
*/ $someFutureDate = '2013-10-10 20:00:00';
public function testCanView($date, $user, $page, $canView) { $somePastDate = '2009-10-10 20:00:00';
$userRecord = $this->objFromFixture('Member', $user); return array(
$pageRecord = $this->objFromFixture('BlogPost', $page); // Check this post given the date has passed
SS_Datetime::set_mock_now($date); array($someFutureDate, 'Editor', 'PostA', true),
$this->assertEquals($canView, $pageRecord->canView($userRecord)); array($someFutureDate, 'Contributor', 'PostA', true),
} array($someFutureDate, 'BlogEditor', 'PostA', true),
array($someFutureDate, 'Writer', 'PostA', true),
public function canViewProvider() { // Check unpublished pages
$someFutureDate = '2013-10-10 20:00:00'; array($somePastDate, 'Editor', 'PostA', true),
$somePastDate = '2009-10-10 20:00:00'; array($somePastDate, 'Contributor', 'PostA', true),
return array( array($somePastDate, 'BlogEditor', 'PostA', true),
// Check this post given the date has passed array($somePastDate, 'Writer', 'PostA', true),
array($someFutureDate, 'Editor', 'PostA', true),
array($someFutureDate, 'Contributor', 'PostA', true),
array($someFutureDate, 'BlogEditor', 'PostA', true),
array($someFutureDate, 'Writer', 'PostA', true),
// Check unpublished pages // Test a page that was authored by another user
array($somePastDate, 'Editor', 'PostA', true),
array($somePastDate, 'Contributor', 'PostA', true),
array($somePastDate, 'BlogEditor', 'PostA', true),
array($somePastDate, 'Writer', 'PostA', true),
// Test a page that was authored by another user // Check this post given the date has passed
array($someFutureDate, 'Editor', 'FirstBlogPost', true),
array($someFutureDate, 'Contributor', 'FirstBlogPost', true),
array($someFutureDate, 'BlogEditor', 'FirstBlogPost', true),
array($someFutureDate, 'Writer', 'FirstBlogPost', true),
// Check this post given the date has passed // Check future pages - non-editors shouldn't be able to see this
array($someFutureDate, 'Editor', 'FirstBlogPost', true), array($somePastDate, 'Editor', 'FirstBlogPost', true),
array($someFutureDate, 'Contributor', 'FirstBlogPost', true), array($somePastDate, 'Contributor', 'FirstBlogPost', false),
array($someFutureDate, 'BlogEditor', 'FirstBlogPost', true), array($somePastDate, 'BlogEditor', 'FirstBlogPost', false),
array($someFutureDate, 'Writer', 'FirstBlogPost', true), array($somePastDate, 'Writer', 'FirstBlogPost', false),
);
}
// Check future pages - non-editors shouldn't be able to see this public function testCandidateAuthors()
array($somePastDate, 'Editor', 'FirstBlogPost', true), {
array($somePastDate, 'Contributor', 'FirstBlogPost', false), $blogpost = $this->objFromFixture('BlogPost', 'PostC');
array($somePastDate, 'BlogEditor', 'FirstBlogPost', false),
array($somePastDate, 'Writer', 'FirstBlogPost', false),
);
}
public function testCandidateAuthors() { $this->assertEquals(7, $blogpost->getCandidateAuthors()->count());
$blogpost = $this->objFromFixture('BlogPost', 'PostC');
$this->assertEquals(7, $blogpost->getCandidateAuthors()->count()); //Set the group to draw Members from
Config::inst()->update('BlogPost', 'restrict_authors_to_group', 'BlogUsers');
//Set the group to draw Members from $this->assertEquals(3, $blogpost->getCandidateAuthors()->count());
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));
}
} }