'Varchar', '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 * * @param $page allows you to force a specific page, otherwise, * uses current */ static function current($page = null) { if (!$page) { $controller = Controller::curr(); if($controller) $page = $controller->data(); } // 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 $top = DataObject::get_one('BlogTree', "\"ParentID\" = '0'"); 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() { if($this->InheritSideBar && $this->getParent()) { if (method_exists($this->getParent(), 'SideBar')) return $this->getParent()->SideBar(); } if($this->SideBarID){ return DataObject::get_by_id('WidgetArea', $this->SideBarID); // @todo: This segfaults - investigate why then fix: return $this->getComponent('SideBar'); } } /* ----------- CMS CONTROL -------------- */ function getCMSFields() { $fields = parent::getCMSFields(); $fields->addFieldToTab("Root.Content.Main", new TextField("Name", "Name of blog")); $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; } elseif($child instanceof BlogTree) { $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 * @param string $where * @return DataObjectSet */ public function Entries($limit = '', $tag = '', $date = '', $retrieveCallback = null, $filter = '') { $tagCheck = ''; $dateCheck = ''; if($tag) { $SQL_tag = Convert::raw2sql($tag); $tagCheck = "AND \"BlogEntry\".\"Tags\" LIKE '%$SQL_tag%'"; } if($date) { if(strpos($date, '-')) { $year = (int) substr($date, 0, strpos($date, '-')); $month = (int) substr($date, strpos($date, '-') + 1); if($year && $month) { if(method_exists(DB::getConn(), 'formattedDatetimeClause')) { $db_date=DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%m'); $dateCheck = "AND CAST($db_date AS " . DB::getConn()->dbDataType('unsigned integer') . ") = $month AND " . DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%Y') . " = '$year'"; } else { $dateCheck = "AND MONTH(\"BlogEntry\".\"Date\") = '$month' AND YEAR(\"BlogEntry\".\"Date\") = '$year'"; } } } else { $year = (int) $date; if($year) { if(method_exists(DB::getConn(), 'formattedDatetimeClause')) { $dateCheck = "AND " . DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%Y') . " = '$year'"; } else { $dateCheck = "AND YEAR(\"BlogEntry\".\"Date\") = '$year'"; } } } } // 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 if($filter) $filter .= ' AND '; $filter .= '"ParentID" IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck"; $order = '"BlogEntry"."Date" DESC'; // By specifying a callback, you can alter the SQL, or sort on something other than date. if($retrieveCallback) return call_user_func($retrieveCallback, 'BlogEntry', $filter, $limit, $order); return DataObject::get('BlogEntry', $filter, $order, '', $limit); } } class BlogTree_Controller extends Page_Controller { static $allowed_actions = array( 'index', 'rss', 'post', 'BlogEntryForm' ); function init() { parent::init(); $this->IncludeBlogRSS(); Requirements::themedCSS("blog"); } function BlogEntries($limit = null) { if($limit === null) $limit = BlogTree::$default_entries_limit; // only use freshness if no action is present (might be displaying tags or rss) if ($this->LandingPageFreshness && !$this->request->param('Action')) { $filter = "\"BlogEntry\".\"Date\" > NOW() - INTERVAL " . $this->LandingPageFreshness; } else { $filter = ''; } // allow filtering by author field and some blogs have an authorID field which // may allow filtering by id if(isset($_GET['author']) && isset($_GET['authorID'])) { $author = Convert::raw2sql($_GET['author']); $id = Convert::raw2sql($_GET['authorID']); $filter .= " \"BlogEntry\".\"Author\" LIKE '". $author . "' OR \"BlogEntry\".\"AuthorID\" = '". $id ."'"; } else if(isset($_GET['author'])) { $filter .= " \"BlogEntry\".\"Author\" LIKE '". Convert::raw2sql($_GET['author']) . "'"; } else if(isset($_GET['authorID'])) { $filter .= " \"BlogEntry\".\"AuthorID\" = '". Convert::raw2sql($_GET['authorID']). "'"; } $start = isset($_GET['start']) ? (int) $_GET['start'] : 0; $date = $this->SelectedDate(); return $this->Entries("$start,$limit", $this->SelectedTag(), ($date) ? $date->Format('Y-m') : '', null, $filter); } /** * This will create a tag point to the RSS feed */ function IncludeBlogRSS() { RSSFeed::linkToFeed($this->Link() . "rss", _t('BlogHolder.RSSFEED',"RSS feed of these blogs")); } /** * Get the rss feed for this blog holder's entries */ function rss() { global $project_name; $blogName = $this->Name; $altBlogName = $project_name . ' blog'; $entries = $this->Entries(20); if($entries) { $rss = new RSSFeed($entries, $this->Link(), ($blogName ? $blogName : $altBlogName), "", "Title", "ParsedContent"); $rss->outputToBrowser(); } } /** * Protection against infinite loops when an RSS widget pointing to this page is added to this page */ function defaultAction($action) { if(stristr($_SERVER['HTTP_USER_AGENT'], 'SimplePie')) return $this->rss(); return parent::defaultAction($action); } /** * Return the currently viewing tag used in the template as $Tag * * @return String */ function SelectedTag() { return ($this->request->latestParam('Action') == 'tag') ? $this->request->latestParam('ID') : ''; } /** * Return the selected date from the blog tree * * @return Date */ function SelectedDate() { if($this->request->latestParam('Action') == 'date') { $year = $this->request->latestParam('ID'); $month = $this->request->latestParam('OtherID'); if(is_numeric($year) && is_numeric($month) && $month < 13) { $date = new Date(); $date->setValue($year .'-'. $month); return $date; } } return false; } function providePermissions() { return array("BLOGMANAGEMENT" => "Blog management"); } /** * Post a new blog entry */ function post(){ if(!Permission::check('BLOGMANAGEMENT')) return Security::permissionFailure(); $page = $this->customise(array( 'Content' => false, 'Form' => $this->BlogEntryForm() )); return $page->renderWith('Page'); } /** * A simple form for creating blog entries */ function BlogEntryForm() { if(!Permission::check('BLOGMANAGEMENT')) return Security::permissionFailure(); $id = 0; if($this->request->latestParam('ID')) { $id = (int) $this->request->latestParam('ID'); } $codeparser = new BBCodeParser(); $membername = Member::currentMember() ? Member::currentMember()->getName() : ""; if(BlogEntry::$allow_wysiwyg_editing) { $contentfield = new HtmlEditorField("BlogPost", _t("BlogEntry.CN")); } else { $contentfield = new CompositeField( new LiteralField("BBCodeHelper",""._t("BlogEntry.BBH")."
" ), new TextareaField("BlogPost", _t("BlogEntry.CN"),20), // This is called BlogPost as the id #Content is generally used already new LiteralField("BBCodeTags","
".$codeparser->useable_tagsHTML()."
") ); } if(class_exists('TagField')) { $tagfield = new TagField('Tags', null, null, 'BlogEntry'); $tagfield->setSeparator(', '); } else { $tagfield = new TextField('Tags'); } $field = 'TextField'; if(!$this->AllowCustomAuthors && !Permission::check('ADMIN')) { $field = 'ReadonlyField'; } $fields = new FieldSet( new HiddenField("ID", "ID"), new TextField("Title", _t('BlogHolder.SJ', "Subject")), new $field("Author", _t('BlogEntry.AU'), $membername), $contentfield, $tagfield, new LiteralField("Tagsnote"," ") ); $submitAction = new FormAction('postblog', _t('BlogHolder.POST', 'Post blog entry')); $actions = new FieldSet($submitAction); $validator = new RequiredFields('Title','Content'); $form = new Form($this, 'BlogEntryForm',$fields, $actions,$validator); if($id != 0) { $entry = DataObject::get_by_id('BlogEntry', $id); if($entry->IsOwner()) { $form->loadDataFrom($entry); $form->datafieldByName('BlogPost')->setValue($entry->Content); } } else { $form->loadDataFrom(array("Author" => Cookie::get("BlogHolder_Name"))); } return $form; } function postblog($data, $form) { if(!Permission::check('BLOGMANAGEMENT')) return Security::permissionFailure(); Cookie::set("BlogHolder_Name", $data['Author']); $blogentry = false; if(isset($data['ID']) && $data['ID']) { $blogentry = DataObject::get_by_id("BlogEntry", $data['ID']); if(!$blogentry->IsOwner()) { unset($blogentry); } } if(!$blogentry) { $blogentry = new BlogEntry(); } $form->saveInto($blogentry); if($this->ClassName == "BlogHolder") $parentID = $this->ID; else{ $parentID = $this->BlogHolderIDs(); $parentID = $parentID[0]; } $blogentry->ParentID = $this->ID; $blogentry->Content = $form->datafieldByName('BlogPost')->dataValue(); $blogentry->Status = "Published"; $blogentry->writeToStage("Stage"); $blogentry->publish("Stage", "Live"); Director::redirect($this->Link()); } }