root/trunk/gregarius/cls/channels.php

Revision 1730, 9.5 kB (checked in by mbonetti, 18 months ago)

Rolled back [1727] because it kind of completely broke my installation.
Also, we don't wanna change existing permalinks, do we?

  • Property svn:eolstyle set to native
Line 
1<?php
2###############################################################################
3# Gregarius - A PHP based RSS aggregator.
4# Copyright (C) 2003 - 2006 Marco Bonetti
5#
6###############################################################################
7# This program is free software and open source software; you can redistribute
8# it and/or modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the License,
10# or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15# more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  or visit
20# http://www.gnu.org/licenses/gpl.html
21#
22###############################################################################
23# E-mail:      mbonetti at gmail dot com
24# Web page:    http://gregarius.net/
25#
26###############################################################################
27
28
29define('COLLAPSED_FOLDERS_COOKIE', 'collapsedfolders');
30
31/**
32 * A FeedListItem object holds a single item in the feeds sidecolumn
33 */
34class FeedListItem {
35
36        /** Database id (e.g. item.cid, channels.id) for this feed */
37        var $id;
38        /** Feed title */
39        var $title;
40        /** URL of this feed */ 
41        var $url;
42        /** URL of this feed, escaped from login/password information, if any */       
43        var $publicUrl;
44        /** URL of the website publishing this feed */ 
45        var $siteurl;
46        /** Name of the folder holding this feed */     
47        var $name;
48        /** ID of the folder holding this feed (e.g. channels.parent) */       
49        var $parent;
50        /** URL of the icon for this feed, probably offsite */ 
51        var $icon;
52        /** The "description" for this feed. (e.g. channel.description) */             
53        var $descr = "";
54        /** Feed "mode" (e.g. private, deprecated, ...)*/               
55        var $mode;
56        /** True when the user is reading the current feed in "feed mode" */   
57        var $isActiveFeed;
58       
59        /**
60         * Constructor. Fills in the instance variables, escapes urls accordingly
61         */
62        function FeedListItem($id, $title, $url, $siteurl, $name, $parent, $icon, $descr, $mode, $unreadCount) {
63                $this->id = $id;
64                $this->title = $title;
65                $this->url = $url;
66                $this->publicUrl = preg_replace(
67                        '|(https?://)([^:]+:[^@]+@)(.+)$|','\1\3',$url
68                );
69                $this->siteurl = $siteurl;
70                $this->name = $name;
71                $this->parent = $parent;
72
73               
74                if ( getConfig('rss.output.showfavicons') && $icon){
75                        if (substr($icon,0,5) == 'blob:') {
76                                $this->icon = getPath() . "extlib/favicon.php?url=". rss_real_escape_string(substr($icon,5));
77                        } else {
78                                $this->icon = $icon;
79                        }
80                } elseif (getConfig('rss.output.showfavicons')) {
81            $this->icon = getExternalThemeFile("media/noicon.png");
82                } else {
83            $this->icon = false;
84                }
85               
86                $this->descr = $descr;
87                $this->mode = $mode;
88
89                if (getConfig('rss.output.usemodrewrite')) {
90                        $this->rlink = getPath(rss_uri($title)) . "/";
91                } else {
92                        $this->rlink = getPath()."feed.php?channel=$id";
93                }
94
95
96                if ($unreadCount > 0) {
97                        $this->rdLbl= sprintf(__('<strong id="%s" style="%s">(%d unread)</strong>'), "cid$id","",$unreadCount);
98                        $this->class_= "feed title unread";
99                } else {
100                        $this->rdLbl= "";
101                        $this->class_= "feed title";
102                }
103        }
104
105
106        /**
107         * Renders this FeedListItem: Moves the superglobal "current feed" pointer
108         * to this, then includes the relevant template
109         */
110        function render() {
111                $GLOBALS['rss']->currentFeedsFeed = $this;
112                include($GLOBALS['rss'] ->getTemplateFile("feedsfeed.php"));   
113        }
114
115}
116
117
118class FeedFolder {
119        var $feeds = array ();
120        var $name;
121        var $id;
122        var $isCollapsed = false;
123        var $rlink;
124        var $isRootFolder = false;
125        var $rootList;
126        function FeedFolder($name, $id, &$rootList) {
127                $this->name = $name;
128                $this->id = $id;
129                if (getConfig('rss.output.usemodrewrite')) {
130                        $this->rlink = $this -> makeFolderUrl($name); // getPath().preg_replace("/[^a-zA-Z0-9_]/", "_", $name)."/";
131                } else {
132                        $this->rlink = getPath()."feed.php?folder=$id";
133                }
134                $this->isRootFolder = ($id == 0);
135                $this->rootList = $rootList;
136        }
137       
138        function makeFolderUrl($fn) {
139                return getPath(
140                        preg_replace('#\s#','_',sanitize($fn,RSS_SANITIZER_URL))
141                ) .'/';
142        }
143       
144        function render() {
145                if ((!getConfig('rss.output.minimalchannellist')) || ($this->feeds)) { 
146                        $GLOBALS['rss']->currentFeedsFolder = $this; 
147                        require($GLOBALS['rss'] ->getTemplateFile("feedsfolder.php")); 
148                }
149        }
150}
151
152class FeedList {
153
154        var $collapsed_folders = array ();
155        var $collapsed_ids = array ();
156        var $folders = array ();
157        var $activeId;
158        var $feedCount = 0;
159        var $columnTitle;
160        var $stats;
161       
162        function FeedList($activeId) {
163                _pf('FeedList() ctor');
164                $this ->columnTitle= __('Feeds');
165                $this->activeId = $activeId;
166                $this->loadCollapsedState();
167                $this->populate();
168        }
169       
170        function getStats() {
171                _pf('getStats()');
172                _pf(' ... unreadCount');
173
174                $unread = getUnreadCount(null, null);
175                _pf(' ... done: unreadCount');         
176
177                _pf(' ... totalCount');         
178                $sql ="select count(*) from ".getTable("item") . "i " 
179                           ."inner join " . getTable('channels') . " c "
180         ."  on c.id = i.cid "
181                                 ." where not(i.unread & ".RSS_MODE_DELETED_STATE.") "
182                           ." and not (c.mode & " .RSS_MODE_DELETED_STATE.")"
183                        . (hidePrivate()? " and not(unread & ".RSS_MODE_PRIVATE_STATE.")":"");
184                       
185                        //echo $sql;
186                        $res = rss_query($sql);
187                list ($total) = rss_fetch_row($res);
188                _pf(' ... done: totalCount');           
189               
190
191                _pf(' ... feedsCount');                         
192                $res = rss_query("select count(*) from "
193                        .getTable("channels")." where not(mode & ".RSS_MODE_DELETED_STATE.")"
194                        . (hidePrivate()? " and not(mode & ".RSS_MODE_PRIVATE_STATE.")":"")
195                        );
196                       
197                list ($channelcount) = rss_fetch_row($res);
198                _pf(' ... done: feedsCount');                           
199               
200                $this ->stats = sprintf(__('<strong>%d</strong> items (<strong id="fucnt">%d</strong> unread) in <strong>%d</strong> feeds'), $total, $unread, $channelcount);
201                _pf('done: getStats()');
202                return $this -> stats;
203        }
204       
205       
206        function loadCollapsedState() {
207            _pf('FeedList->loadCollapsedState()...');
208           
209                if (getConfig('rss.output.channelcollapse')) {
210       
211                        //read per-user stored collapsed folders
212                        if (array_key_exists(COLLAPSED_FOLDERS_COOKIE, $_COOKIE)) {
213                                $this->collapsed_ids = explode(":", $_COOKIE[COLLAPSED_FOLDERS_COOKIE]);
214                        }  elseif (empty($this->collapsed_ids) && getConfig("rss.output.channelcollapsedefault")) {
215                           // Lets collapse all folders
216                           $res = rss_query("select id from " . getTable('folders') . " where id != 0");
217                           while (list ($this->collapsed_ids[]) = rss_fetch_row($res)) {}
218                           if (!headers_sent()) { // Sajax does not allow us to set cookies
219                            setcookie(COLLAPSED_FOLDERS_COOKIE, 
220                                  implode(":", $this->collapsed_ids ) , time()+COOKIE_LIFESPAN,getPath());
221                           }
222                        }
223       
224                        //get unread count per folder                                                                       
225                        $sql = "select f.id, f.name, count(*) as cnt "
226                        ." from " .getTable('item') ." i "
227                        ." inner join " . getTable('channels') . " c on c.id = i.cid "
228                        ." inner join " . getTable('folders') ." f on f.id = c.parent "
229                        ." where i.unread & ". RSS_MODE_UNREAD_STATE
230                        ." and not(i.unread & ". RSS_MODE_DELETED_STATE .")";
231                        if (hidePrivate()) {
232                                $sql .=" and not(unread & " . RSS_MODE_PRIVATE_STATE .") ";
233                        }
234                        $sql .= " and not(c.mode & " . RSS_MODE_DELETED_STATE .") ";
235                        $sql .= " group by f.id";
236                _pf('query');
237                        $res = rss_query($sql);
238                _pf('ok');     
239                        while (list ($cid, $cname, $cuc) = rss_fetch_row($res)) {
240                                $this->collapsed_folders[$cid] = $cuc;
241                        }
242               
243                        sort($this->collapsed_ids);
244                }
245            _pf('done');
246
247        }
248       
249        function getFeedCount() {
250                return $this -> feedCount;
251        }
252
253        function populate() {
254                _pf('FeedList->populate() ...');
255                $sql = "select "." c.id, c.title, c.url, c.siteurl, f.name, c.parent, c.icon, c.descr, c.mode "." from ".getTable("channels")." c "
256                ."inner join " . getTable("folders")." f on f.id = c.parent";
257
258                if (hidePrivate()) {
259                        $sql .= " and not(c.mode & ".RSS_MODE_PRIVATE_STATE.") ";
260                }
261
262                $sql .= " and not(c.mode & ".RSS_MODE_DELETED_STATE.") ";
263
264                if (getConfig('rss.config.absoluteordering')) {
265                        $sql .= " order by f.position asc, c.position asc";
266                } else {
267                        $sql .= " order by f.name, c.title asc";
268                }
269                $res = rss_query($sql);
270                $this -> feedCount = rss_num_rows($res);
271               
272                $ucres = rss_query ("select cid, count(*) from " .getTable("item")
273        ." where unread & "  . RSS_MODE_UNREAD_STATE
274        . " and not(unread & " . RSS_MODE_DELETED_STATE .") group by cid");
275                $uc = array();
276                while (list($uccid,$ucuc) = rss_fetch_row($ucres)) {
277                        $uc[$uccid]=$ucuc;
278                }
279                 
280                while (list ($cid, $ctitle, $curl, $csiteurl, $fname, $cparent, $cico, $cdescr, $cmode) = rss_fetch_row($res)) {
281                        $ucc= 0;
282                        if (array_key_exists($cid,$uc)) {
283                                $ucc=$uc[$cid];
284                        } 
285                        $f = new FeedListItem($cid, $ctitle, $curl, $csiteurl, $fname, $cparent, $cico, $cdescr, $cmode, $ucc);
286                        $f -> isActiveFeed = ($this->activeId && $cid == $this->activeId ); 
287                        if (!array_key_exists($cparent, $this->folders)) {
288                                $this->folders[$cparent] = new FeedFolder($fname, $cparent,$this);
289                        }
290                        //$this->folders[$cparent]->feeds[] = $f;
291                        if(($ucc != 0) || (!getConfig('rss.output.minimalchannellist'))) { 
292                                $this->folders[$cparent]->feeds[] = $f; 
293                        }
294                        $this->folders[$cparent]->isCollapsed = in_array($cparent, $this->collapsed_ids) && ($cparent > 0);
295
296                }
297                _pf('done');
298        }
299
300        function render() {
301                _pf('FeedList->render() ...');
302                include($GLOBALS['rss'] ->getTemplateFile("feeds.php"));
303                _pf('done');           
304        }
305}
306?>
Note: See TracBrowser for help on using the browser.