NEW Decouple gridfield stuff into lumberjack module

This commit is contained in:
vagrant 2014-12-11 10:42:36 +00:00 committed by micmania1
parent 5255168d1b
commit 4166d025e4
30 changed files with 119 additions and 399 deletions

View File

@ -1,21 +1,32 @@
language: php
php:
- 5.3
language: php
env:
- DB=MYSQL CORE_RELEASE=3.1
global:
- DB=MYSQL CORE_RELEASE=3.1
matrix:
include:
- php: 5.6
env: DB=MYSQL
- php: 5.5
env: DB=MYSQL
- php: 5.4
env: DB=MYSQL CORE_RELEASE=3.1
env: DB=MYSQL
- php: 5.3
env: DB=MYSQL
- php: hhvm-nightly
env: DB=MYSQL
before_install:
- sudo apt-get update -qq
- sudo apt-get install -y tidy
before_script:
- phpenv rehash
- composer self-update
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
- cd ~/builds/ss
script:
script:
- phpunit silverstripe-blog/tests/

View File

@ -5,17 +5,4 @@
*
* @return string
**/
function blog_dir() {
return trim(str_replace(BASE_PATH, "", dirname(__FILE__)), DIRECTORY_SEPARATOR);
}
/**
* Returns the absolute path of the current module path
*
* @return string
**/
function blog_path() {
return BASE_PATH . '/' . blog_dir();
}
define('BLOGGER_DIR', ltrim(Director::makeRelative(realpath(__DIR__)), DIRECTORY_SEPARATOR));

View File

@ -10,7 +10,7 @@
* @author Michael Strong <github@michaelstrong.co.uk>
*
**/
class BlogFilter extends Hierarchy {
class BlogFilter extends Lumberjack {
/**
* Augments (@link Hierarchy::stageChildren()}
@ -21,14 +21,8 @@ class BlogFilter extends Hierarchy {
public function stageChildren($showAll = false) {
$staged = parent::stageChildren($showAll);
$controller = Controller::curr();
if($controller->class == "CMSPagesController"
&& in_array($controller->getAction(), array("treeview", "listview", "getsubtree"))
) {
// Filter the SiteTree
return $staged->exclude("ClassName", $this->owner->getExcludedSiteTreeClassNames());
} else if(in_array($this->owner->ClassName, ClassInfo::subClassesFor("Blog"))
if(!$this->shouldFilter()
&& in_array(get_class($this->owner), ClassInfo::subClassesFor("Blog"))
&& !Permission::check("VIEW_DRAFT_CONTENT")
) {
@ -39,10 +33,9 @@ class BlogFilter extends Hierarchy {
// Filter published posts
$dataQuery = $staged->dataQuery()
->innerJoin("BlogPost", "BlogPost" . $stage . ".ID = SiteTree" . $stage . ".ID")
->where("PublishDate < '" . Convert::raw2sql(SS_Datetime::now()) . "'");
->innerJoin("BlogPost", '"BlogPost' . $stage . '"."ID" = "SiteTree' . $stage . '"."ID"')
->where('"PublishDate" < \'' . Convert::raw2sql(SS_Datetime::now()) . '\'');
$staged = $staged->setDataQuery($dataQuery);
}
return $staged;
}
@ -58,20 +51,14 @@ class BlogFilter extends Hierarchy {
public function liveChildren($showAll = false, $onlyDeletedFromStage = false) {
$staged = parent::liveChildren($showAll, $onlyDeletedFromStage);
$controller = Controller::curr();
if($controller->class == "CMSPagesController"
&& in_array($controller->getAction(), array("treeview", "listview", "getsubtree"))
) {
// Filter the SiteTree
return $staged->exclude("ClassName", $this->owner->getExcludedSiteTreeClassNames());
} else if(in_array($this->owner->ClassName, ClassInfo::subClassesFor("Blog"))
if(!$this->shouldFilter()
&& in_array(get_class($this->owner), ClassInfo::subClassesFor("Blog"))
&& !Permission::check("VIEW_DRAFT_CONTENT")
) {
// Filter publish posts
$dataQuery = $staged->dataQuery()
->innerJoin("BlogPost", "BlogPost_Live.ID = SiteTree_Live.ID")
->where("PublishDate < '" . Convert::raw2sql(SS_Datetime::now()) . "'");
->innerJoin("BlogPost", '"BlogPost_Live"."ID" = "SiteTree"_"Live"."ID"')
->where('"PublishDate" < \'' . Convert::raw2sql(SS_Datetime::now()) . '\'');
$staged = $staged->setDataQuery($dataQuery);
}
return $staged;

View File

@ -29,10 +29,8 @@ class BlogPostFilter extends DataExtension {
* @see https://github.com/silverstripe/silverstripe-framework/issues/1682
**/
public function augmentLoadLazyFields(SQLQuery &$query, &$dataQuery, $parent) {
// Ensures that we're joining the BlogPost table which holds required db fields.
$dataQuery->innerJoin("BlogPost", "`SiteTree`.`ID` = `BlogPost`.`ID`");
}
}

View File

@ -1,63 +1,50 @@
<?php
/**
* Provides a component to the {@link GridField} which tells the user whether or not a
* Provides a component to the {@link GridField} which tells the user whether or not a
* blog post has been published and when.
*
* @package silverstripe
* @subpackage blog
*
* @author Michael Strong <github@michaelstrong.co.uk>
**/
class GridFieldBlogPostState implements GridField_ColumnProvider {
public function augmentColumns($gridField, &$columns) {
// Ensure Actions always appears as the last column.
$key = array_search("Actions", $columns);
if($key !== FALSE) unset($columns[$key]);
$columns = array_merge($columns, array(
"State",
"Actions",
));
}
public function getColumnsHandled($gridField) {
return array("State");
}
**/
class GridFieldBlogPostState extends GridFieldSiteTreeState {
public function getColumnContent($gridField, $record, $columnName) {
if($columnName == "State") {
Requirements::css(BLOGGER_DIR . '/css/cms.css');
if($record->hasMethod("isPublished")) {
$modifiedLabel = "";
if($record->isModifiedOnStage) {
$modifiedLabel = "<span class='modified'>" . _t("GridFieldBlogPostState.Modified") . "</span>";
}
}
$published = $record->isPublished();
if(!$published) {
return _t(
"GridFieldBlogPostState.Draft",
'<i class="btn-icon blog-icon btn-icon-pencil"></i> Saved as Draft on {date}',
"State for when a post is saved.",
"GridFieldBlogPostState.Draft",
'<i class="btn-icon gridfield-icon btn-icon-pencil"></i> Saved as Draft on {date}',
"State for when a post is saved.",
array(
"date" => $record->dbObject("LastEdited")->Nice()
)
);
} else if (strtotime($record->PublishDate) > time()) {
return _t(
"GridFieldBlogPostState.Timer",
'<i class="blog-icon blog-icon-timer"></i> Publish at {date}',
"State for when a post is published.",
"GridFieldBlogPostState.Timer",
'<i class="gridfield-icon blog-icon-timer"></i> Publish at {date}',
"State for when a post is published.",
array(
"date" => $record->dbObject("PublishDate")->Nice()
)
) . $modifiedLabel;
} else {
return _t(
"GridFieldBlogPostState.Published",
'<i class="btn-icon blog-icon btn-icon-accept"></i> Published on {date}',
"State for when a post is published.",
"GridFieldBlogPostState.Published",
'<i class="btn-icon gridfield-icon btn-icon-accept"></i> Published on {date}',
"State for when a post is published.",
array(
"date" => $record->dbObject("PublishDate")->Nice()
)
@ -72,11 +59,11 @@ class GridFieldBlogPostState implements GridField_ColumnProvider {
if($record->hasMethod("isPublished")) {
$published = $record->isPublished();
if(!$published) {
$class = "blog-icon draft";
$class = "gridfield-icon draft";
} else if (strtotime($record->PublishDate) > time()) {
$class = "blog-icon timer";
$class = "gridfield-icon timer";
} else {
$class = "blog-icon published";
$class = "gridfield-icon published";
}
return array("class" => $class);
}
@ -84,11 +71,4 @@ class GridFieldBlogPostState implements GridField_ColumnProvider {
return array();
}
public function getColumnMetaData($gridField, $columnName) {
switch($columnName) {
case 'State':
return array("title" => _t("GridFieldBlogPostState.StateTitle", "State", "Column title for state"));
}
}
}
}

View File

@ -13,10 +13,10 @@ class GridFieldConfig_BlogPost extends GridFieldConfig {
public function __construct($itemsPerPage = null) {
parent::__construct($itemsPerPage);
$this->addComponent(new GridFieldButtonRow('before'));
$this->addComponent(new GridFieldBlogPostAddNewButton('buttons-before-left'));
$this->addComponent(new GridFieldSiteTreeAddNewButton('buttons-before-left'));
$this->addComponent(new GridFieldToolbarHeader());
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldSortableHeader());
$this->addComponent(new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldSiteTreeEditButton());
$this->addComponent(new GridFieldPageCount('toolbar-header-right'));

54
model/Blog.php → code/model/Blog.php Executable file → Normal file
View File

@ -15,48 +15,32 @@ class Blog extends Page {
);
private static $has_many = array(
"Tags" => "BlogTag",
"Categories" => "BlogCategory",
);
private static $allowed_children = array(
"BlogPost",
);
private static $extensions = array(
"BlogFilter",
);
private static $defaults = array(
"ProvideComments" => false,
);
private static $description = 'Adds a blog to your website.';
public function getCMSFields() {
$self =& $this;
$this->beforeUpdateCMSFields(function($fields) use ($self) {
$posts = $self->getBlogPosts();
$excluded = $self->getExcludedSiteTreeClassNames();
if(!empty($excluded)) {
$posts = $posts->filter("ClassName", $excluded);
$gridField = new GridField(
"BlogPost",
_t("Blog.BlogPosts", "Blog Posts"),
$posts,
GridFieldConfig_BlogPost::create()
);
$fields->addFieldToTab("Root.BlogPosts", $gridField);
}
// Create categories and tag config
$config = GridFieldConfig_RecordEditor::create();
@ -85,6 +69,11 @@ class Blog extends Page {
});
$fields = parent::getCMSFields();
// Ensure we're using the BlogPost GridField config and not Lumberjack's
$gridField = $fields->dataFieldByName('ChildPages');
$gridField->setConfig(GridFieldConfig_BlogPost::create());
return $fields;
}
@ -101,26 +90,7 @@ class Blog extends Page {
/**
* Loops through subclasses of BlogPost and checks whether they have been configured
* to be hidden. If so, then they will be excluded from the SiteTree.
*
* @return array
**/
public function getExcludedSiteTreeClassNames() {
$classes = array();
$tmpClasses = $this->allowedChildren();
foreach($tmpClasses as $class) {
if(!Config::inst()->get($class, "show_in_sitetree")) {
$classes[$class] = $class;
}
}
return $classes;
}
/**
* Return blogs posts
* Return blog posts
*
* @return DataList of BlogPost objects
**/
@ -160,6 +130,16 @@ class Blog extends Page {
return $this->getBlogPosts()->setDataQuery($query);
}
/**
* This sets the title for our gridfield
*
* @return string
*/
public function getLumberjackTitle() {
return _t('Blog.LumberjackTitle', 'Blog Posts');
}
}

0
model/BlogCategory.php → code/model/BlogCategory.php Executable file → Normal file
View File

57
model/BlogPost.php → code/model/BlogPost.php Executable file → Normal file
View File

@ -58,31 +58,26 @@ class BlogPost extends Page {
public function getCMSFields() {
Requirements::css(BLOGGER_DIR . '/css/cms.css');
$self =& $this;
$this->beforeUpdateCMSFields(function($fields) use ($self) {
// Add Publish date fields
$fields->insertAfter(
$publishDate = DatetimeField::create("PublishDate", _t("BlogPost.PublishDate", "Publish Date")),
"Content"
);
$fields->addFieldsToTab('Root.Main', array(
HeaderField::create('Post Options', 3),
$publishDate = DatetimeField::create("PublishDate", _t("BlogPost.PublishDate", "Publish Date")),
ListboxField::create(
"Categories",
_t("BlogPost.Categories", "Categories"),
$self->Parent()->Categories()->map()->toArray()
)->setMultiple(true),
ListboxField::create(
"Tags",
_t("BlogPost.Tags", "Tags"),
$self->Parent()->Tags()->map()->toArray()
)->setMultiple(true)
));
$publishDate->getDateField()->setConfig("showcalendar", true);
// Add Categories & Tags fields
$categoriesField = ListboxField::create(
"Categories",
_t("BlogPost.Categories", "Categories"),
$self->Parent()->Categories()->map()->toArray()
)->setMultiple(true);
$fields->insertAfter($categoriesField, "PublishDate");
$tagsField = ListboxField::create(
"Tags",
_t("BlogPost.Tags", "Tags"),
$self->Parent()->Tags()->map()->toArray()
)->setMultiple(true);
$fields->insertAfter($tagsField, "Categories");
// Add featured image
$fields->insertBefore(
$uploadField = UploadField::create("FeaturedImage", _t("BlogPost.FeaturedImage", "Featured Image")),
@ -92,6 +87,28 @@ class BlogPost extends Page {
});
$fields = parent::getCMSFields();
// We're going to make an SEO tab and move all the usual crap there
$menuTitle = $fields->dataFieldByName('MenuTitle');
$urlSegment = $fields->dataFieldByName('URLSegment');
$fields->addFieldsToTab('Root.SEO', array(
$menuTitle,
$urlSegment,
));
$metaField = $fields->fieldByName('Root.Main.Metadata');
if($metaField) {
$metaFields = $metaField->getChildren();
if($metaFields->count() > 0) {
$tab = $fields->findOrMakeTab('Root.SEO');
$tab->push(HeaderField::create('Meta', 3));
foreach($metaFields as $field) {
$tab->push($field);
}
}
$fields->removeByName('Metadata');
}
return $fields;
}

0
model/BlogTag.php → code/model/BlogTag.php Executable file → Normal file
View File

View File

View File

View File

@ -4,7 +4,8 @@
"keywords": ["silverstripe", "blog", "news"],
"type": "silverstripe-module",
"require": {
"silverstripe/cms": "~3.1"
"silverstripe/cms": "^3.1.0",
"micmania1/silverstripe-lumberjack": "1.0.*@stable"
},
"license": "BSD-2-Clause",
"authors": [

View File

@ -5,42 +5,19 @@
* Include Compass framework */
/*
* Sprite maps & Icons */
/* line 42, blog-icon/*.png */
.blog-icon-sprite, .blog-icon .blog-icon-timer {
background: url('../images/blog-icon-s1d712fffa2.png') no-repeat;
/* line 48, blog-icon/*.png */
.blog-icon-sprite, .gridfield-icon .blog-icon-timer {
background-image: url('../images/blog-icon-s0a5ab5f851.png');
background-repeat: no-repeat;
}
/* line 60, ../../../../lib/gems/1.8/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss */
.blog-icon .blog-icon-timer {
/* line 84, ../../../../home/vagrant/.rvm/gems/ruby-2.1.5/gems/compass-core-1.0.1/stylesheets/compass/utilities/sprites/_base.scss */
.gridfield-icon .blog-icon-timer {
background-position: 0 0;
}
/* line 21, ../scss/cms.scss */
.cms .ss-gridfield .gridfield-dropdown {
margin: 3px 8px 0 0;
border-bottom: none;
}
/* line 26, ../scss/cms.scss */
.cms .ss-gridfield .gridfield-dropdown .chzn-container,
.cms .ss-gridfield .gridfield-dropdown .dropdown {
min-width: 195px;
}
/* line 35, ../scss/cms.scss */
.cms table.ss-gridfield-table tr td .blog-icon {
width: 16px;
height: 16px;
display: block;
/* line 18, ../scss/cms.scss */
#FeaturedImage .middleColumn {
clear: none;
float: left;
margin-right: 6px;
}
/* line 42, ../scss/cms.scss */
.cms table.ss-gridfield-table tr td .modified {
margin-left: 5px;
color: #7E7470;
background-color: #fff0bc;
padding: 1px 3px;
border: 1px solid #C9B800;
font-size: 80%;
border-radius: 3px;
text-transform: uppercase;
}

View File

@ -1,126 +0,0 @@
<?php
/**
* This component provides a button for opening the add new form provided by
* {@link GridFieldDetailForm}.
*
* Only returns a button if {@link DataObject->canCreate()} for this record
* returns true.
*
* @package framework
* @subpackage fields-gridfield
*
* @author Michael Strong <github@michaelstrong.co.uk>
*/
class GridFieldBlogPostAddNewButton extends GridFieldAddNewButton
implements GridField_ActionProvider {
public function getHTMLFragments($gridField) {
$singleton = singleton($gridField->getModelClass());
if(!$singleton->canCreate()) {
return array();
}
$parent = SiteTree::get()->byId(Controller::curr()->currentPageID());
if(!$this->buttonName) {
// provide a default button name, can be changed by calling {@link setButtonName()} on this component
$objectName = $singleton->i18n_singular_name();
$this->buttonName = _t('GridFieldSiteTreeAddNewButton.Add', 'Add {name}', "Add button text", array('name' => $singleton->i18n_singular_name()));
}
$state = $gridField->State->GridFieldSiteTreeAddNewButton;
$state->currentPageID = $parent->ID;
$state->pageType = $parent->defaultChild();
$addAction = new GridField_FormAction($gridField,
'add',
$this->buttonName,
'add',
'add'
);
$addAction->setAttribute('data-icon', 'add')->addExtraClass("no-ajax");
$allowedChildren = $parent->allowedChildren();
$children = array();
foreach($allowedChildren as $class) {
if(!Config::inst()->get($class, "show_in_sitetree")) {
$children[$class] = singleton($class)->i18n_singular_name();
}
}
$pageTypes = DropdownField::create(
"PageType",
"Page Type",
$children,
$singleton->defaultChild()
);
$pageTypes->setFieldHolderTemplate("BlogDropdownField_holder")
->addExtraClass("gridfield-dropdown no-change-track");
$forTemplate = new ArrayData(array());
$forTemplate->Fields = new ArrayList();
$forTemplate->Fields->push($pageTypes);
$forTemplate->Fields->push($addAction);
Requirements::css(blog_dir() . "/css/cms.css");
Requirements::javascript(blog_dir() . "/javascript/GridField.js");
return array(
$this->targetFragment => $forTemplate->renderWith("GridFieldSiteTreeAddNewButton")
);
}
/**
* Provide actions to this component.
*
* @param $gridField GridField
*
* @return array
**/
public function getActions($gridField) {
return array("add");
}
/**
* Handles the add action, but only acts as a wrapper for {@link CMSPageAddController::doAdd()}
*
* @param $gridFIeld GridFIeld
* @param $actionName string
* @param $arguments mixed
* @param $data array
**/
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if($actionName == "add") {
$tmpData = json_decode($data['BlogPost']['GridState'], true);
$tmpData = $tmpData['GridFieldSiteTreeAddNewButton'];
$data = array(
"ParentID" => $tmpData['currentPageID'],
"PageType" => $tmpData['pageType']
);
$controller = Injector::inst()->create("CMSPageAddController");
$form = $controller->AddForm();
$form->loadDataFrom($data);
$controller->doAdd($data, $form);
$response = $controller->getResponseNegotiator()->getResponse();
// Get the current record
$record = SiteTree::get()->byId($controller->currentPageID());
if($record) {
$response->redirect(Director::absoluteBaseURL() . $record->CMSEditLink(), 301);
}
return $response;
}
}
}

View File

@ -1,31 +0,0 @@
<?php
/**
* Swaps the GridField Link out for the SiteTree edit link using {@link SiteTree::CMSEditLink()}
*
* @package silverstripe
* @subpackage blog
*
* @author Michael Strong <github@michaelstrong.co.uk>
**/
class GridFieldSiteTreeEditButton extends GridFieldEditButton {
/**
* @param GridField $gridField
* @param DataObject $record
* @param string $columnName
*
* @return string - the HTML for the column
*/
public function getColumnContent($gridField, $record, $columnName) {
// No permission checks - handled through GridFieldDetailForm
// which can make the form readonly if no edit permissions are available.
$data = new ArrayData(array(
'Link' => $record->CMSEditLink()
));
return $data->renderWith('GridFieldEditButton');
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 844 B

View File

@ -1,16 +0,0 @@
(function($){
$.entwine('ss', function($) {
$('.ss-gridfield .field .gridfield-dropdown').entwine({
onchange: function() {
var gridField = this.getGridField();
var state = gridField.getState().GridFieldSiteTreeAddNewButton;
state.pageType = this.val();
gridField.setState("GridFieldSiteTreeAddNewButton", state);
}
});
});
}(jQuery));

View File

@ -3,8 +3,6 @@ en:
AddFail: 'Unable to save {class} to the database.'
PermissionFail: 'You don''t have permission to create a {class}.'
Add: 'Add {name}'
GridFieldSiteTreeAddNewButton:
Add: 'Add {name}'
GridFieldBlogPostState:
StateTitle: 'State'
Draft: '<i class="btn-icon blog-icon btn-icon-pencil"></i> Saved as Draft on {date}'

View File

@ -11,45 +11,11 @@
@import "compass/utilities/sprites/base";
@import "blog-icon/*.png";
.blog-icon {
.gridfield-icon {
@include all-blog-icon-sprites;
}
.cms {
.ss-gridfield {
.gridfield-dropdown {
margin: 3px 8px 0 0;
border-bottom: none;
.chzn-container,
.dropdown {
min-width: 195px;
}
}
}
table.ss-gridfield-table {
tr {
td {
.blog-icon {
width: 16px;
height: 16px;
display: block;
float: left;
margin-right: 6px;
}
.modified {
margin-left: 5px;
color: #7E7470;
background-color: #fff0bc;
padding: 1px 3px;
border: 1px solid #C9B800;
font-size: 80%;
border-radius: 3px;
text-transform: uppercase;
}
}
}
}
#FeaturedImage .middleColumn {
clear: none;
float: left;
}

View File

@ -1,3 +0,0 @@
<div class="field<% if $extraClass %> $extraClass<% end_if %>">
$Field
</div>

View File

@ -1,3 +0,0 @@
<% loop Fields %>
$Field
<% end_loop %>

View File

@ -1,3 +0,0 @@
<% loop Fields %>
$FieldHolder
<% end_loop %>