2009-05-01 00:05:54 +02:00
< ? php
/**
* @ package blog
*/
/**
* Blog tree allows a tree of Blog Holders . Viewing branch nodes shows all blog entries from all blog holder children
*/
class BlogTree extends Page {
static $db = array (
2009-05-20 04:18:48 +02:00
'Name' => 'Varchar' ,
2009-05-01 00:05:54 +02:00
'InheritSideBar' => 'Boolean' ,
'LandingPageFreshness' => 'Varchar' ,
);
static $defaults = array (
'InheritSideBar' => True
);
static $has_one = array (
" SideBar " => " WidgetArea " ,
);
static $allowed_children = array (
'BlogTree' , 'BlogHolder'
);
/*
* Finds the BlogTree object most related to the current page .
* - If this page is a BlogTree , use that
* - If this page is a BlogEntry , use the parent Holder
* - Otherwise , try and find a 'top-level' BlogTree
*/
static function current () {
$page = Director :: currentPage ();
// If we _are_ a BlogTree, use us
if ( $page instanceof BlogTree ) return $page ;
// Or, if we a a BlogEntry underneath a BlogTree, use our parent
if ( $page -> is_a ( " BlogEntry " )) {
$parent = $page -> getParent ();
if ( $parent instanceof BlogTree ) return $parent ;
}
// Try to find a top-level BlogTree
2009-05-11 04:48:24 +02:00
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$top = DataObject :: get_one ( 'BlogTree' , " \" ParentID \" = '0' " );
} else {
$top = DataObject :: get_one ( 'BlogTree' , 'ParentID = 0' );
}
2009-05-01 00:05:54 +02:00
if ( $top ) return $top ;
// Try to find any BlogTree that is not inside another BlogTree
foreach ( DataObject :: get ( 'BlogTree' ) as $tree ) {
if ( ! ( $tree -> getParent () instanceof BlogTree )) return $tree ;
}
// This shouldn't be possible, but assuming the above fails, just return anything you can get
return DataObject :: get_one ( 'BlogTree' );
}
/* ----------- ACCESSOR OVERRIDES -------------- */
public function getLandingPageFreshness () {
$freshness = $this -> getField ( 'LandingPageFreshness' );
// If we want to inherit freshness, try that first
if ( $freshness = " INHERIT " && $this -> getParent ()) $freshness = $this -> getParent () -> LandingPageFreshness ;
// If we don't have a parent, or the inherited result was still inherit, use default
if ( $freshness = " INHERIT " ) $freshness = '' ;
return $freshness ;
}
function SideBar () {
2009-05-26 00:30:10 +02:00
if ( $this -> InheritSideBar && $this -> getParent ()) {
if ( method_exists ( $this -> getParent (), 'SideBar' )) return $this -> getParent () -> SideBar ();
}
2009-05-15 05:46:49 +02:00
return DataObject :: get_by_id ( 'WidgetArea' , $this -> SideBarID );
// @todo: This segfaults - investigate why then fix: return $this->getComponent('SideBar');
2009-05-01 00:05:54 +02:00
}
/* ----------- CMS CONTROL -------------- */
function getCMSFields () {
$fields = parent :: getCMSFields ();
2009-05-20 04:18:48 +02:00
$fields -> addFieldToTab ( " Root.Content.Main " , new TextField ( " Name " , " Name of blog " ));
2009-05-01 00:05:54 +02:00
$fields -> addFieldToTab ( 'Root.Content.Main' , new DropdownField ( 'LandingPageFreshness' , 'When you first open the blog, how many entries should I show' , array (
" " => " All entries " ,
" 1 MONTH " => " Last month's entries " ,
" 2 MONTH " => " Last 2 months' entries " ,
" 3 MONTH " => " Last 3 months' entries " ,
" 4 MONTH " => " Last 4 months' entries " ,
" 5 MONTH " => " Last 5 months' entries " ,
" 6 MONTH " => " Last 6 months' entries " ,
" 7 MONTH " => " Last 7 months' entries " ,
" 8 MONTH " => " Last 8 months' entries " ,
" 9 MONTH " => " Last 9 months' entries " ,
" 10 MONTH " => " Last 10 months' entries " ,
" 11 MONTH " => " Last 11 months' entries " ,
" 12 MONTH " => " Last year's entries " ,
" INHERIT " => " Take value from parent Blog Tree "
)));
$fields -> addFieldToTab ( " Root.Content.Widgets " , new CheckboxField ( " InheritSideBar " , 'Inherit Sidebar From Parent' ));
$fields -> addFieldToTab ( " Root.Content.Widgets " , new WidgetAreaEditor ( " SideBar " ));
return $fields ;
}
/* ----------- New accessors -------------- */
public function loadDescendantBlogHolderIDListInto ( & $idList ) {
if ( $children = $this -> AllChildren ()) {
foreach ( $children as $child ) {
if ( in_array ( $child -> ID , $idList )) continue ;
if ( $child instanceof BlogHolder ) $idList [] = $child -> ID ;
else $child -> loadDescendantBlogHolderIDListInto ( $idList );
}
}
}
// Build a list of all IDs for BlogHolders that are children of us
public function BlogHolderIDs () {
$holderIDs = array ();
$this -> loadDescendantBlogHolderIDListInto ( $holderIDs );
return $holderIDs ;
}
/**
* Get entries in this blog .
* @ param string limit A clause to insert into the limit clause .
* @ param string tag Only get blog entries with this tag
* @ param string date Only get blog entries on this date - either a year , or a year - month eg '2008' or '2008-02'
* @ param callback retrieveCallback A function to call with pagetype , filter and limit for custom blog sorting or filtering
* @ return DataObjectSet
*/
public function Entries ( $limit = '' , $tag = '' , $date = '' , $retrieveCallback = null ) {
$tagCheck = '' ;
$dateCheck = '' ;
if ( $tag ) {
$SQL_tag = Convert :: raw2sql ( $tag );
2009-05-11 04:48:24 +02:00
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$tagCheck = " AND \" BlogEntry \" . \" Tags \" LIKE '% $SQL_tag %' " ;
} else {
$tagCheck = " AND `BlogEntry`.Tags LIKE '% $SQL_tag %' " ;
}
2009-05-01 00:05:54 +02:00
}
if ( $date ) {
if ( strpos ( $date , '-' )) {
$year = ( int ) substr ( $date , 0 , strpos ( $date , '-' ));
$month = ( int ) substr ( $date , strpos ( $date , '-' ) + 1 );
if ( $year && $month ) {
2009-05-11 04:48:24 +02:00
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$dateCheck = " AND MONTH( \" BlogEntry \" . \" Date \" ) = ' $month ' AND YEAR( \" BlogEntry \" . \" Date \" ) = ' $year ' " ;
} else {
$dateCheck = " AND MONTH(`BlogEntry`.Date) = $month AND YEAR(`BlogEntry`.Date) = $year " ;
}
2009-05-01 00:05:54 +02:00
}
} else {
$year = ( int ) $date ;
if ( $year ) {
2009-05-11 04:48:24 +02:00
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$dateCheck = " AND YEAR( \" BlogEntry \" . \" Date \" ) = ' $year ' " ;
} else {
$dateCheck = " AND YEAR(`BlogEntry`.Date) = $year " ;
}
2009-05-01 00:05:54 +02:00
}
}
}
2009-05-11 04:48:24 +02:00
elseif ( $this -> LandingPageFreshness ) {
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$dateCheck = " AND \" BlogEntry \" . \" Date \" > NOW() - INTERVAL " . $this -> LandingPageFreshness ;
} else {
$dateCheck = " AND `BlogEntry`.Date > NOW() - INTERVAL " . $this -> LandingPageFreshness ;
}
2009-05-01 00:05:54 +02:00
}
// Build a list of all IDs for BlogHolders that are children of us
$holderIDs = $this -> BlogHolderIDs ();
// If no BlogHolders, no BlogEntries. So return false
if ( empty ( $holderIDs )) return false ;
// Otherwise, do the actual query
2009-05-11 04:48:24 +02:00
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$where = '"ParentID" IN (' . implode ( ',' , $holderIDs ) . " ) $tagCheck $dateCheck " ;
} else {
$where = 'ParentID IN (' . implode ( ',' , $holderIDs ) . " ) $tagCheck $dateCheck " ;
}
if ( defined ( 'Database::USE_ANSI_SQL' )) {
$order = '"BlogEntry"."Date" DESC' ;
} else {
$order = '`BlogEntry`.`Date` DESC' ;
}
2009-05-01 00:05:54 +02:00
// By specifying a callback, you can alter the SQL, or sort on something other than date.
if ( $retrieveCallback ) return call_user_func ( $retrieveCallback , 'BlogEntry' , $where , $limit );
2009-05-11 04:48:24 +02:00
else return DataObject :: get ( 'BlogEntry' , $where , $order , '' , $limit );
2009-05-01 00:05:54 +02:00
}
}
class BlogURL {
static function tag () {
if ( Director :: urlParam ( 'Action' ) == 'tag' ) return Director :: urlParam ( 'ID' );
return '' ;
}
static function date () {
$year = Director :: urlParam ( 'Action' );
$month = Director :: urlParam ( 'ID' );
if ( $month && is_numeric ( $month ) && $month >= 1 && $month <= 12 && is_numeric ( $year )) {
return " $year - $month " ;
}
elseif ( is_numeric ( $year )) {
return $year ;
}
return '' ;
}
}
class BlogTree_Controller extends Page_Controller {
function init () {
parent :: init ();
// This will create a <link> tag point to the RSS feed
RSSFeed :: linkToFeed ( $this -> Link () . " rss " , _t ( 'BlogHolder.RSSFEED' , " RSS feed of these blogs " ));
Requirements :: themedCSS ( " blog " );
}
function BlogEntries ( $limit = 10 ) {
$start = isset ( $_GET [ 'start' ]) ? ( int ) $_GET [ 'start' ] : 0 ;
return $this -> Entries ( " $start , $limit " , BlogURL :: tag (), BlogURL :: date ());
}
/*
* @ todo : It doesn ' t look like these are used . Remove if no - one complains - Hamish
/**
* Gets the archived blogs for a particular month or year , in the format / year / month / eg : / 2008 / 10 /
* /
function showarchive () {
$month = addslashes ( $this -> urlParams [ 'ID' ]);
return array (
" Children " => DataObject :: get ( 'SiteTree' , " ParentID = $this->ID AND DATE_FORMAT(`BlogEntry`.`Date`, '%Y-%M') = ' $month ' " ),
);
}
function ArchiveMonths () {
$months = DB :: query ( " SELECT DISTINCT DATE_FORMAT(`BlogEntry`.`Date`, '%M') AS `Month`, DATE_FORMAT(`BlogEntry`.`Date`, '%Y') AS `Year` FROM `BlogEntry` ORDER BY `BlogEntry`.`Date` DESC " );
$output = new DataObjectSet ();
foreach ( $months as $month ) {
$month [ 'Link' ] = $this -> Link () . " showarchive/ $month[Year] - $month[Month] " ;
$output -> push ( new ArrayData ( $month ));
}
return $output ;
}
function tag () {
if ( Director :: urlParam ( 'Action' ) == 'tag' ) {
return array (
'Tag' => Convert :: raw2xml ( Director :: urlParam ( 'ID' ))
);
}
return array ();
}
*/
/**
* Get the rss feed for this blog holder ' s entries
*/
function rss () {
2009-05-20 04:34:57 +02:00
global $project_name ;
2009-05-01 00:05:54 +02:00
$blogName = $this -> Name ;
2009-05-20 04:34:57 +02:00
$altBlogName = $project_name . ' blog' ;
2009-05-01 00:05:54 +02:00
$entries = $this -> Entries ( 20 );
if ( $entries ) {
$rss = new RSSFeed ( $entries , $this -> Link (), ( $blogName ? $blogName : $altBlogName ), " " , " Title " , " ParsedContent " );
$rss -> outputToBrowser ();
}
}
function defaultAction ( $action ) {
// Protection against infinite loops when an RSS widget pointing to this page is added to this page
if ( stristr ( $_SERVER [ 'HTTP_USER_AGENT' ], 'SimplePie' )) return $this -> rss ();
return parent :: defaultAction ( $action );
}
}