source: trunk/content/plugins/sb_base/libs/SbBaseFunctions.php @ 1375

Revision 1375, 18.9 KB checked in by nick_ramsay, 3 years ago (diff)

[Trunk] Hotaru 1.1.3 [Run upgrade script]

Line 
1<?php
2/**
3 * SB Base functions
4 * Notes: This file is part of the SB Submit plugin.
5 *
6 * PHP version 5
7 *
8 * LICENSE: Hotaru CMS is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, either version 3 of
11 * the License, or (at your option) any later version.
12 *
13 * Hotaru CMS is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with Hotaru CMS. If not, see http://www.gnu.org/licenses/.
19 *
20 * @category  Content Management System
21 * @package   HotaruCMS
22 * @author    Nick Ramsay <admin@hotarucms.org>
23 * @copyright Copyright (c) 2009, Hotaru CMS
24 * @license   http://www.gnu.org/copyleft/gpl.html GNU General Public License
25 * @link      http://www.hotarucms.org/
26 */
27
28class SbBaseFunctions
29{
30    /**
31     * Prepare filter and breadcrumbs for social bookmarking pages
32     * Two main types: one for list pages and the other for
33     * miscelleneous stuff like Sidebar Posts
34     *
35     * @param string $type e.g. latest, upcoming, top-24-hours
36     * @param string $return - 'posts', 'count' or 'query'
37     * @return array
38     */
39    public function prepareList($h, $type = '', $return = 'posts')
40    {
41        if (!isset($h->vars['filter'])) { $h->vars['filter'] = array(); }
42       
43        if ($type) {
44            // For the posts widget or other non-pages...
45            $h->vars['filter'] = array(); // flush filter
46            $this->prepareListFilters($h, $type);
47           
48        } else {
49            // for pages, i.e. lists of stories with pagination
50            switch ($h->pageName) {
51                case 'index':
52                    $this->prepareListFilters($h, 'top');
53                    break;
54                case 'latest':
55                    $this->prepareListFilters($h, 'new');
56                    break;
57                case 'upcoming':
58                    $this->prepareListFilters($h, 'upcoming');
59                    break;
60                case 'sort':
61                    $sort = $h->cage->get->testPage('sort');
62                    $this->prepareListFilters($h, $sort);
63                    break;
64                default:
65                    $this->prepareListFilters($h, 'all');
66                }
67
68            $h->pluginHook('sb_base_functions_preparelist', '', array('return' => $return)); // formerly post_list_filter
69        }
70       
71        // defaults
72        if (!isset($h->vars['select'])) { $h->vars['select'] = '*'; }
73        if (!isset($h->vars['orderby'])) { $h->vars['orderby'] = 'post_date DESC'; }
74        $limit = 0;
75        $all = true;
76       
77        // $type is used in sidebar posts, etc so we need to specify a limit, e.g. 10.
78        if ($type) {
79            if ($h->vars['limit']) { $limit = $h->vars['limit']; } else { $limit = 0; }
80            $all = false;
81        }
82       
83        // if we want to count the totals, we need to replace the select clause with COUNT, but some queries that use MATCH and relevance are a bit complicated,
84        // so we'll let those plugins (e.g. search) add COUNT to their queries themselves and skip them here (which we can do by checking for MATCH).
85        if ($return == 'count' && (strpos($h->vars['select'], "MATCH") === false)) { $h->vars['select'] = "count(post_id) AS number"; }
86        if ($return == 'query') { $all = true; }    // this removes the "LIMIT" parameter so we can add it later when paginating.
87       
88        $prepared_filter = $this->filter($h->vars['filter'], $limit, $all, $h->vars['select'], $h->vars['orderby']);
89       
90        if ($return == 'query') {
91            if (isset($prepared_filter[1])) {
92                return $h->db->prepare($prepared_filter);
93            } else {
94                return $prepared_filter[0];    // returns the prepared query array
95            }
96        } elseif($return == 'count') {
97            unset($h->vars['select']);  // so it doesn't get used again unintentionally
98            $count_array = $this->getPosts($h, $prepared_filter);
99            return $count_array[0]->number; // returns the number of posts
100        } else {
101            return $this->getPosts($h, $prepared_filter);   // returns the posts OR post count depending on the query
102        }
103    }
104   
105   
106    /**
107     * Prepare list filters
108     *
109     * @param string $type e.g. latest, upcoming, top-24-hours
110     */
111    public function prepareListFilters($h, $type = '')
112    {
113        if ($type == 'new')
114        {
115            // Filters page to "new" stories only
116            $h->vars['filter']['post_archived = %s'] = 'N';
117            $h->vars['filter']['post_status = %s'] = 'new';
118            $h->vars['orderby'] = "post_date DESC";
119        }
120        elseif ($type == 'upcoming')
121        {
122            // Filters page to "new" stories by most votes, but only stories from the last X days!
123            $vote_settings = unserialize($h->getSetting('vote_settings', 'vote'));
124            $upcoming_duration = "-" . $vote_settings['upcoming_duration'] . " days"; // default: -5 days
125           
126            $h->vars['filter']['post_archived = %s'] = 'N';
127            $h->vars['filter']['post_status = %s'] = 'new';
128            $start = date('YmdHis', strtotime("now"));
129            $end = date('YmdHis', strtotime($upcoming_duration)); // should be negative
130            $h->vars['filter']['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
131            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
132        }
133        elseif ($type == 'top-24-hours')
134        {
135            // Filters page to "top" stories from the last 24 hours only
136            $h->vars['filter']['post_status = %s'] = 'top';
137            $start = date('YmdHis', strtotime("now"));
138            $end = date('YmdHis', strtotime("-1 day"));
139            $h->vars['filter']['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
140            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
141        }
142        elseif ($type == 'top-48-hours')
143        {
144            // Filters page to "top" stories from the last 48 hours only
145            $h->vars['filter']['post_status = %s'] = 'top';
146            $start = date('YmdHis', strtotime("now"));
147            $end = date('YmdHis', strtotime("-2 days"));
148            $h->vars['filter']['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
149            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
150        }
151        elseif ($type == 'top-7-days')
152        {
153            // Filters page to "top" stories from the last 7 days only
154            $h->vars['filter']['post_status = %s'] = 'top';
155            $start = date('YmdHis', strtotime("now"));
156            $end = date('YmdHis', strtotime("-7 days"));
157            $h->vars['filter']['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
158            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
159        }
160        elseif ($type == 'top-30-days')
161        {
162            // Filters page to "top" stories from the last 30 days only
163            $h->vars['filter']['post_status = %s'] = 'top';
164            $start = date('YmdHis', strtotime("now"));
165            $end = date('YmdHis', strtotime("-30 days"));
166            $h->vars['filter']['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
167            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
168        }
169        elseif ($type == 'top-365-days')
170        {
171            // Filters page to "top" stories from the last 365 days only
172            $h->vars['filter']['post_status = %s'] = 'top';
173            $start = date('YmdHis', strtotime("now"));
174            $end = date('YmdHis', strtotime("-365 days"));
175            $h->vars['filter']['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
176            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
177        }
178        elseif ($type == 'top-all-time')
179        {
180            // Filters page to "top" stories in order of votes
181            $h->vars['filter']['post_status = %s'] = 'top';
182            $h->vars['orderby'] = "post_votes_up DESC, post_date DESC";
183        }
184        elseif ($type == 'top')
185        {
186            // Assume 'top' page and filter to 'top' stories.
187            $h->vars['filter']['post_archived = %s'] = 'N';
188            $h->vars['filter']['post_status = %s'] = 'top';
189            $h->vars['orderby'] = "post_date DESC";
190        }
191        else
192        {
193            // Filters page to "all" stories
194            $h->vars['filter']['post_archived = %s'] = 'N';
195            $h->vars['filter']['(post_status = %s OR post_status = %s)'] = array('top', 'new');
196            $h->vars['orderby'] = "post_date DESC";
197        }
198    }
199   
200   
201    /**
202     * Gets all the posts from the database
203     *
204     * @param array $vars - search parameters
205     * @param int $limit - no. of rows to retrieve
206     * @param bool $all - true to retrieve ALL rows, else default 20
207     * @param string $select - the select clause
208     * @param string $orderby - the order by clause
209     * @return array|false $prepare_array is the prepared SQL statement
210     *
211     * Example usage: $post->filter(array('post_tags LIKE %s' => '%tokyo%'), 10);
212     */   
213    public function filter($vars = array(), $limit = 0, $all = false, $select = '*', $orderby = 'post_date DESC')
214    {
215        if(!isset($filter)) { $filter = ''; }
216        $prepare_array = array();
217        $prepare_array[0] = "temp";    // placeholder to be later filled with the SQL query.
218       
219        if (!empty($vars)) {
220            $filter = " WHERE ";
221            foreach ($vars as $key => $value) {
222                $filter .= $key . " AND ";    // e.g. " post_tags LIKE %s "
223               
224                // Push the values of %s and %d into the prepare_array
225               
226                // sometimes the filter might contain multiple values, eg.
227                // WHERE post_status = %s OR post_status = %s. In that case,
228                // the values are stored in an array, e.g. array('top', 'new').
229                if (is_array($value)) {
230                    foreach ($value as $v) {
231                        array_push($prepare_array, $v);
232                    }
233                } else {
234                    // otherwise, push the single value into $prepared_array:
235                    array_push($prepare_array, $value);
236                }
237               
238            }
239            $filter = rstrtrim($filter, " AND ");
240        }
241       
242        if ($all == true) {
243            $limit = '';
244        } elseif ($limit == 0) {
245            $limit = " LIMIT 20";
246        } else {
247            $limit = " LIMIT " . $limit;
248        }
249       
250        if ($orderby) { $orderby = "ORDER BY " . $orderby; }
251       
252        $sql = "SELECT " . $select . " FROM " . TABLE_POSTS . $filter . " " . $orderby . $limit;
253       
254        $prepare_array[0] = $sql;
255       
256        // $prepare_array needs to be passed to $this->db->prepare, i.e. $this->db->get_results($this->db->prepare($prepare_array));
257               
258        if ($prepare_array) { return $prepare_array; } else { return false; }
259    }
260   
261   
262    /**
263     * Gets all the posts from the database
264     *
265     * @param array $prepared array - prepared SQL statement from filter()
266     * @return array|false - array of posts
267     */   
268    public function getPosts($h, $prepared_array = array())
269    {
270        if (!$prepared_array) { return false; }
271       
272        if (empty($prepared_array[1])) {
273            $h->smartCache('on', 'posts', 60, $prepared_array[0]); // start using cache
274            $posts = $h->db->get_results($prepared_array[0]); // ignoring the prepare function.
275        } else {
276            $query = $h->db->prepare($prepared_array);
277            $h->smartCache('on', 'posts', 60, $query); // start using cache
278            $posts = $h->db->get_results($query);
279        }
280       
281        $h->smartCache('off'); // stop using cache
282       
283        if ($posts) { return $posts; } else { return false; }
284    }
285   
286   
287    /**
288     * Publish content as an RSS feed
289     * Uses the 3rd party RSS Writer class.
290     */   
291    public function rssFeed($h)
292    {
293        require_once(EXTENSIONS . 'RSSWriterClass/rsswriter.php');
294       
295        $select = '*';
296       
297        $status = $h->cage->get->testAlpha('status');
298        $limit = $h->cage->get->getInt('limit');
299        $user = $h->cage->get->testUsername('user');
300        $tag = $h->cage->get->noTags('tag');
301        $media = $h->cage->get->testAlnumLines('media');
302        $search = $h->cage->get->sanitizeTags('search');
303        $category = $h->cage->get->noTags('category');
304               
305        //if (!$status) { $status = "top"; }
306        if (!$limit) { $limit = 10; }
307                   
308        if ($status) { $filter['post_status = %s'] = $status; }
309        if ($user) {
310            $user_id = $h->getUserIdFromName($user);
311            if ($user_id) { $filter['post_author = %d'] = $user_id; }
312        }
313        if ($tag) {
314            $filter['post_tags LIKE %s'] = '%' . urlencode(stripslashes($tag)) . '%'; }
315        if ($media) { $filter['post_media = %s'] = $media; }
316        if ($category && (FRIENDLY_URLS == "true")) { $cat_id = $h->getCatId($category); }
317        if ($category && (FRIENDLY_URLS == "false")) { $cat_id = $category; }
318       
319        if ($status == 'upcoming') {
320            // Filters page to "new" stories by most votes, but only stories from the last X days!
321            $vote_settings = unserialize($h->getSetting('vote_settings', 'vote'));
322            $upcoming_duration = "-" . $vote_settings['upcoming_duration'] . " days"; // default: -5 days
323           
324            $filter['post_status = %s'] = 'new';
325            $start = date('YmdHis', strtotime("now"));
326            $end = date('YmdHis', strtotime($upcoming_duration)); // should be negative
327            $filter['(post_date >= %s AND post_date <= %s)'] = array($end, $start);
328            $orderby = "post_votes_up DESC";
329        }
330       
331        // When a user clicks a parent category, we need to show posts from all child categories, too.
332        // This only works for one level of sub-categories.
333        if ($category && $cat_id) {
334            $filter_string = '(post_category = %d';
335            $values = array($cat_id);
336            $parent = $h->getCatParent($cat_id);
337            if ($parent == 1) {
338                $children = $h->getCatChildren($cat_id);
339                if ($children) {
340                    foreach ($children as $child_id) {
341                        $filter_string .= ' || post_category = %d';
342                        array_push($values, $child_id->category_id);
343                    }
344                }
345            }
346            $filter_string .= ')';
347            $filter[$filter_string] = $values;
348        }
349        // end categories
350               
351        if ($search && $h->isActive('search')) {
352            require_once(PLUGINS . 'search/search.php');
353            $search_plugin = new Search();
354            $prepared_search = $search_plugin->prepareSearchFilter($h, $search);
355            extract($prepared_search);
356            $orderby = "post_date DESC";    // override "relevance DESC" so the RSS feed updates with the latest related terms.
357        }
358       
359        $h->pluginHook('post_rss_feed');
360       
361        $feed           = new RSS();
362        $feed->title    = SITE_NAME;
363        $feed->link     = BASEURL;
364       
365        if ($media)
366        {
367            $h->includeLanguage('media_select', 'media_select');
368            if (isset($status) && ($status != '')) { $status .= "_"; } else { $status = ""; }
369            $media_word = "sb_base_rss_stories_media_" . $status . $media;
370            $feed->description = $h->lang[$media_word];
371        }
372        elseif ($status == 'new')
373        {
374            $feed->description = $h->lang["sb_base_rss_latest_from"] . " " . SITE_NAME;
375        }
376        elseif ($status == 'top')
377        {
378            $feed->description = $h->lang["sb_base_rss_top_stories_from"] . " " . SITE_NAME;
379        }
380        elseif ($status == 'upcoming')
381        {
382            $feed->description = $h->lang["sb_base_rss_upcoming_stories_from"] . " " . SITE_NAME;
383        }
384        elseif ($user)
385        {
386            $feed->description = $h->lang["sb_base_rss_stories_from_user"] . " " . $user;
387        }
388        elseif ($tag)
389        {
390            $tag = str_replace('_', ' ', stripslashes(html_entity_decode($tag, ENT_QUOTES,'UTF-8')));
391            $feed->description = $h->lang["sb_base_rss_stories_tagged"] . " " . $tag;
392        }
393        elseif (isset($cat_id))
394        {
395            $category = str_replace('_', ' ', stripslashes(html_entity_decode($cat_id, ENT_QUOTES,'UTF-8')));
396            $feed->description = $h->lang["sb_base_rss_stories_in_category"] . " " . $h->getCatName($cat_id);
397        }
398        elseif ($search)
399        {
400        $feed->description = $h->lang["sb_base_rss_stories_search"] . " " . stripslashes($search);
401        }
402        else
403        {
404       
405        }
406               
407        if (!isset($filter))  $filter['post_status = %s || post_status = %s'] = array('top', 'new'); // default to all posts
408        $prepared_array = $this->filter($filter, $limit, false, $select);
409       
410        $results = $this->getPosts($h, $prepared_array);
411           
412        if ($results) {
413       
414            // get sb base settings
415            $sb_base_settings = $h->getSerializedSettings('sb_base');
416           
417            foreach ($results as $result)
418            {
419                $h->post->url = $result->post_url; // used in Hotaru's url function
420                $h->post->category = $result->post_category; // used in Hotaru's url function
421               
422                $item = new RSSItem();
423                $title = html_entity_decode(urldecode($result->post_title), ENT_QUOTES,'UTF-8');
424                $item->title = stripslashes($title);
425               
426                // if RSS redirecting is enabled, append forward=1 to the url
427                if (isset($sb_base_settings['rss_redirect']) && !empty($sb_base_settings['rss_redirect'])) {
428                    $item->link  = html_entity_decode($h->url(array('page'=>$result->post_id, 'forward'=>$result->post_id)), ENT_QUOTES,'UTF-8');
429                } else {
430                    $item->link  = $h->url(array('page'=>$result->post_id));
431                }
432                $item->setPubDate($result->post_date);
433                $item->description = "<![CDATA[ " . stripslashes(urldecode($result->post_content)) . " ]]>";
434                $feed->addItem($item);
435            }
436        }
437        echo $feed->serve();
438    }
439}
440?>
Note: See TracBrowser for help on using the repository browser.