This bugtracker is archived (announcement). New tickets are created on github.com. See all framework issues, cms issues, and search the module listings for more specific bugtrackers.

Ticket #6830: BlogTree.php

File BlogTree.php, 10.1 KB (added by zucchi, 3 years ago)

Manually updated BlogTree?.php fixing Zend_Date implementation

Line 
1<?php
2
3/**
4 * @package blog
5 */
6
7/**
8 * Blog tree allows a tree of Blog Holders. Viewing branch nodes shows all blog entries from all blog holder children
9 */
10
11class BlogTree extends Page {
12       
13        // Default number of blog entries to show
14        static $default_entries_limit = 10;
15       
16        static $db = array(
17                'Name' => 'Varchar',
18                'InheritSideBar' => 'Boolean',
19                'LandingPageFreshness' => 'Varchar',
20        );
21       
22        static $defaults = array(
23                'InheritSideBar' => True
24        );
25       
26        static $has_one = array(
27                "SideBar" => "WidgetArea",
28        );
29       
30        static $allowed_children = array(
31                'BlogTree', 'BlogHolder'
32        );
33
34        /*
35         * Finds the BlogTree object most related to the current page.
36         * - If this page is a BlogTree, use that
37         * - If this page is a BlogEntry, use the parent Holder
38         * - Otherwise, try and find a 'top-level' BlogTree
39         *
40         * @param $page allows you to force a specific page, otherwise,
41         *                              uses current
42         */
43        static function current($page = null) {
44               
45                if (!$page) {
46                        $controller = Controller::curr();
47                        if($controller) $page = $controller->data();
48                }
49               
50                // If we _are_ a BlogTree, use us
51                if ($page instanceof BlogTree) return $page;
52               
53                // Or, if we a a BlogEntry underneath a BlogTree, use our parent
54                if($page->is_a("BlogEntry")) {
55                        $parent = $page->getParent();
56                        if($parent instanceof BlogTree) return $parent;
57                }
58               
59                // Try to find a top-level BlogTree
60                $top = DataObject::get_one('BlogTree', "\"ParentID\" = '0'");
61                if($top) return $top;
62               
63                // Try to find any BlogTree that is not inside another BlogTree
64                foreach(DataObject::get('BlogTree') as $tree) {
65                        if(!($tree->getParent() instanceof BlogTree)) return $tree;
66                }
67               
68                // This shouldn't be possible, but assuming the above fails, just return anything you can get
69                return DataObject::get_one('BlogTree');
70        }
71
72        /* ----------- ACCESSOR OVERRIDES -------------- */
73       
74        public function getLandingPageFreshness() {
75                $freshness = $this->getField('LandingPageFreshness');
76                // If we want to inherit freshness, try that first
77                if ($freshness == "INHERIT" && $this->getParent()) $freshness = $this->getParent()->LandingPageFreshness;
78                // If we don't have a parent, or the inherited result was still inherit, use default
79                if ($freshness == "INHERIT") $freshness = '';
80                return $freshness;
81        }
82       
83        function SideBar() {
84                if($this->InheritSideBar && $this->getParent()) {
85                        if (method_exists($this->getParent(), 'SideBar')) return $this->getParent()->SideBar();
86                }
87               
88                if($this->SideBarID){
89                        return DataObject::get_by_id('WidgetArea', $this->SideBarID);
90                        // @todo: This segfaults - investigate why then fix: return $this->getComponent('SideBar');
91                }
92        }
93       
94        /* ----------- CMS CONTROL -------------- */
95       
96        function getCMSFields() {
97                $fields = parent::getCMSFields();
98                $fields->addFieldToTab("Root.Content.Main", new TextField("Name", "Name of blog"));
99                $fields->addFieldToTab('Root.Content.Main', new DropdownField('LandingPageFreshness', 'When you first open the blog, how many entries should I show', array(
100                        "" => "All entries",
101                        "1" => "Last month's entries",
102                        "2" => "Last 2 months' entries",
103                        "3" => "Last 3 months' entries",
104                        "4" => "Last 4 months' entries",
105                        "5" => "Last 5 months' entries",
106                        "6" => "Last 6 months' entries",
107                        "7" => "Last 7 months' entries",
108                        "8" => "Last 8 months' entries",
109                        "9" => "Last 9 months' entries",
110                        "10" => "Last 10 months' entries",
111                        "11" => "Last 11 months' entries",
112                        "12" => "Last year's entries",
113                        "INHERIT" => "Take value from parent Blog Tree"
114                )));
115       
116                $fields->addFieldToTab("Root.Content.Widgets", new CheckboxField("InheritSideBar", 'Inherit Sidebar From Parent'));
117                $fields->addFieldToTab("Root.Content.Widgets", new WidgetAreaEditor("SideBar"));
118               
119                return $fields;
120        }
121               
122        /* ----------- New accessors -------------- */
123       
124        public function loadDescendantBlogHolderIDListInto(&$idList) {
125                if ($children = $this->AllChildren()) {
126                        foreach($children as $child) {
127                                if(in_array($child->ID, $idList)) continue;
128                               
129                                if($child instanceof BlogHolder) {
130                                        $idList[] = $child->ID;
131                                } elseif($child instanceof BlogTree) {
132                                        $child->loadDescendantBlogHolderIDListInto($idList);
133                                }                             
134                        }
135                }
136        }
137       
138        // Build a list of all IDs for BlogHolders that are children of us
139        public function BlogHolderIDs() {
140                $holderIDs = array();
141                $this->loadDescendantBlogHolderIDListInto($holderIDs);
142                return $holderIDs;
143        }
144               
145        /**
146         * Get entries in this blog.
147         * @param string limit A clause to insert into the limit clause.
148         * @param string tag Only get blog entries with this tag
149         * @param string date Only get blog entries on this date - either a year, or a year-month eg '2008' or '2008-02'
150         * @param callback retrieveCallback A function to call with pagetype, filter and limit for custom blog sorting or filtering
151         * @param string $where
152         * @return DataObjectSet
153         */
154        public function Entries($limit = '', $tag = '', $date = '', $retrieveCallback = null, $filter = '') {
155               
156                $tagCheck = '';
157                $dateCheck = '';
158               
159                if($tag) {
160                        $SQL_tag = Convert::raw2sql($tag);
161                        $tagCheck = "AND \"BlogEntry\".\"Tags\" LIKE '%$SQL_tag%'";
162                }
163
164                if($date) {
165                        if(strpos($date, '-')) {
166                                $year = (int) substr($date, 0, strpos($date, '-'));
167                                $month = (int) substr($date, strpos($date, '-') + 1);
168
169                                if($year && $month) {
170                                        if(method_exists(DB::getConn(), 'formattedDatetimeClause')) {
171                                                $db_date=DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%m');
172                                                $dateCheck = "AND CAST($db_date AS " . DB::getConn()->dbDataType('unsigned integer') . ") = $month AND " . DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%Y') . " = '$year'";
173                                        } else {
174                                                $dateCheck = "AND MONTH(\"BlogEntry\".\"Date\") = '$month' AND YEAR(\"BlogEntry\".\"Date\") = '$year'";
175                                        }
176                                }
177                        } else {
178                                $year = (int) $date;
179                                if($year) {
180                                        if(method_exists(DB::getConn(), 'formattedDatetimeClause')) {
181                                                $dateCheck = "AND " . DB::getConn()->formattedDatetimeClause('"BlogEntry"."Date"', '%Y') . " = '$year'";
182                                        } else {
183                                                $dateCheck = "AND YEAR(\"BlogEntry\".\"Date\") = '$year'";
184                                        }
185                                }
186                        }
187                }
188
189                // Build a list of all IDs for BlogHolders that are children of us
190                $holderIDs = $this->BlogHolderIDs();
191               
192                // If no BlogHolders, no BlogEntries. So return false
193                if(empty($holderIDs)) return false;
194               
195                // Otherwise, do the actual query
196                if($filter) $filter .= ' AND ';
197                $filter .= '"ParentID" IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck";
198
199                $order = '"BlogEntry"."Date" DESC';
200
201                // By specifying a callback, you can alter the SQL, or sort on something other than date.
202                if($retrieveCallback) return call_user_func($retrieveCallback, 'BlogEntry', $filter, $limit, $order);
203               
204                return DataObject::get('BlogEntry', $filter, $order, '', $limit);
205        }
206}
207
208class BlogTree_Controller extends Page_Controller {
209       
210        static $allowed_actions = array(
211                'index',
212                'rss',
213                'tag',
214                'date'
215        );
216       
217        function init() {
218                parent::init();
219               
220                $this->IncludeBlogRSS();
221               
222                Requirements::themedCSS("blog");
223        }
224
225        function BlogEntries($limit = null) {
226                require_once('Zend/Date.php');
227               
228                if($limit === null) $limit = BlogTree::$default_entries_limit;
229
230                // only use freshness if no action is present (might be displaying tags or rss)
231                if ($this->LandingPageFreshness && !$this->request->param('Action')) {
232                        $d = new Zend_Date(SS_Datetime::now()->getValue());
233                        $d->sub((int)$this->LandingPageFreshness, Zend_Date::MONTH);
234                        $date = $d->toString('YYYY-MM-dd');
235                        $filter = "\"BlogEntry\".\"Date\" > '$date'";
236                } else {
237                        $filter = '';
238                }
239                // allow filtering by author field and some blogs have an authorID field which
240                // may allow filtering by id
241                if(isset($_GET['author']) && isset($_GET['authorID'])) {
242                        $author = Convert::raw2sql($_GET['author']);
243                        $id = Convert::raw2sql($_GET['authorID']);
244                       
245                        $filter .= " \"BlogEntry\".\"Author\" LIKE '". $author . "' OR \"BlogEntry\".\"AuthorID\" = '". $id ."'";
246                }
247                else if(isset($_GET['author'])) {
248                        $filter .=  " \"BlogEntry\".\"Author\" LIKE '". Convert::raw2sql($_GET['author']) . "'";
249                }
250                else if(isset($_GET['authorID'])) {
251                        $filter .=  " \"BlogEntry\".\"AuthorID\" = '". Convert::raw2sql($_GET['authorID']). "'";
252                }
253               
254                $start = isset($_GET['start']) ? (int) $_GET['start'] : 0;
255               
256                $date = $this->SelectedDate();
257               
258                return $this->Entries("$start,$limit", $this->SelectedTag(), ($date) ? $date : '', null, $filter);
259        }
260
261        /**
262         * This will create a <link> tag point to the RSS feed
263         */
264        function IncludeBlogRSS() {
265                RSSFeed::linkToFeed($this->Link() . "rss", _t('BlogHolder.RSSFEED',"RSS feed of these blogs"));
266        }
267       
268        /**
269         * Get the rss feed for this blog holder's entries
270         */
271        function rss() {
272                global $project_name;
273
274                $blogName = $this->Name;
275                $altBlogName = $project_name . ' blog';
276               
277                $entries = $this->Entries(20);
278
279                if($entries) {
280                        $rss = new RSSFeed($entries, $this->Link(), ($blogName ? $blogName : $altBlogName), "", "Title", "RSSContent");
281                        $rss->outputToBrowser();
282                }
283        }
284       
285        /**
286         * Protection against infinite loops when an RSS widget pointing to this page is added to this page
287         */
288        function defaultAction($action) {
289                if(stristr($_SERVER['HTTP_USER_AGENT'], 'SimplePie')) return $this->rss();
290               
291                return parent::defaultAction($action);
292        }
293       
294        /**
295         * Return the currently viewing tag used in the template as $Tag
296         *
297         * @return String
298         */
299        function SelectedTag() {
300                return ($this->request->latestParam('Action') == 'tag') ? Convert::raw2xml($this->request->latestParam('ID')) : '';
301        }
302       
303        /**
304         * Return the selected date from the blog tree
305         *
306         * @return Date
307         */
308        function SelectedDate() {
309                if($this->request->latestParam('Action') == 'date') {
310                        $year = $this->request->latestParam('ID');
311                        $month = $this->request->latestParam('OtherID');
312       
313                        if(is_numeric($year) && is_numeric($month) && $month < 13) {
314               
315                                $date = $year .'-'. $month;
316                                return $date;
317                               
318                        } else {
319                               
320                                if(is_numeric($year)) return $year;     
321                        }
322                }
323                       
324                return false;
325        }
326       
327        function SelectedNiceDate(){
328                $date = $this->SelectedDate();
329               
330                if(strpos($date, '-')) {
331                        $date = explode("-",$date);
332                        return date("F", mktime(0, 0, 0, $date[1], 1, date('Y'))). " " .date("Y", mktime(0, 0, 0, date('m'), 1, $date[0]));
333               
334                } else {
335                        return date("Y", mktime(0, 0, 0, date('m'), 1, $date));
336                }
337        }
338}