root/trunk/gregarius/feed.php

Revision 1785, 49.6 kB (checked in by cfriesen, 5 months ago)

undo the changes made to the core in the attempt to make the plugin change the output count

  • Property svn:eol-style set to native
  • Property svn:eolstyle set to native
  • Property svn:keywords set to Author Date Id Revision
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
29
30 require_once('init.php');
31 rss_require('extlib/rss_fetch.inc');
32
33 define ('ACT_NAV_PREV_PREFIX','&larr;&nbsp;');
34 define ('ACT_NAV_SUCC_POSTFIX','&nbsp;&rarr;');
35
36 // Show unread items on the front page?
37 // default to the config value, user can override this via a cookie
38 $show_what = (getConfig('rss.output.frontpage.mixeditems') ?
39     SHOW_READ_AND_UNREAD : SHOW_UNREAD_ONLY);
40
41 if (array_key_exists(SHOW_WHAT,$_POST)) {
42     $show_what = $_POST[SHOW_WHAT];
43     $period = time()+COOKIE_LIFESPAN;
44     setcookie(SHOW_WHAT, $show_what , $period, getPath());
45 }
46 elseif (array_key_exists(SHOW_WHAT,$_COOKIE)) {
47     $show_what = $_COOKIE[SHOW_WHAT];
48 }
49
50 if (array_key_exists('chkPrivate', $_POST)) {
51   $show_private = empty($_POST['chkPrivate']) ? 0 : $_POST['chkPrivate'];
52   setcookie('chkPrivate', $show_private, time()+COOKIE_LIFESPAN, getPath());
53 } else {
54   $show_private = empty($_COOKIE['chkPrivate']) ? 0 : $_COOKIE['chkPrivate'];
55 }
56
57 rss_user_set_show_private($show_private);
58
59 $y=$m=$d=0;
60 if (
61     getConfig('rss.output.usemodrewrite')
62     && array_key_exists('channel',$_REQUEST)
63     // this is nasty because a numeric feed title could break it
64     && !is_numeric($_REQUEST['channel'])
65 ) {
66     $sqlid = preg_replace('#'.RSS_URI_SEPARATOR.'#','_',
67         sanitize($_REQUEST['channel'] , RSS_SANITIZER_SIMPLE_SQL )
68         );
69
70     $sql = "select id from " . getTable("channels") ." where title like '$sqlid'";
71     if (hidePrivate()) {
72         $sql .=" and not(mode & " . RSS_MODE_PRIVATE_STATE .") ";
73     }
74
75     // don't hide deprecated items becuase we want items of deprecated feeds to be accessible
76     // $sql .= " and not(mode & " . RSS_MODE_DELETED_STATE . ") ";
77
78 //    die($sql);
79     $res rss_query( $sql );
80     //echo $sql;
81     if ( rss_num_rows ( $res ) >= 1) {
82         list($cid) = rss_fetch_row($res);
83     } else {
84         $cid = "";
85
86         // is this a folder?
87         $sql = "select c.id, c.parent from ". getTable('channels')." c "
88                ." inner join " . getTable('folders') . " f on f.id = c.parent "
89                ." where f.name like '$sqlid' and f.id > 0";
90
91         if (hidePrivate()) {
92             $sql .=" and not(c.mode & " . RSS_MODE_PRIVATE_STATE .") ";
93         }
94         $sql .= " and not(c.mode & " RSS_MODE_DELETED_STATE .") ";
95
96         $res = rss_query( $sql );
97         if ( rss_num_rows ( $res ) > 0) {
98             $cids = array();
99             while (list ($cid__,$fid__) = rss_fetch_row($res)) {
100                 $cids[] = $cid__;
101                 $fid = $fid__;
102             }
103         } else {
104             // maybe it's a virtual folder?
105             $sql = "select c.id, m.tid from ". getTable('channels')." c "
106                    ."inner join " . getTable('metatag') . " m on m.fid = c.id "
107                    ."inner join " . getTable('tag') . " t on t.id = m.tid "
108                    . "where m.ttype = 'channel' "
109                    . "and t.tag like '$sqlid'";
110
111             if (hidePrivate()) {
112                 $sql .=" and not(c.mode & " . RSS_MODE_PRIVATE_STATE .") ";
113             }
114             $sql .= " and not(c.mode & " RSS_MODE_DELETED_STATE .") ";
115
116             $res = rss_query( $sql );
117             if ( rss_num_rows ( $res ) > 0) {
118                 $cids = array();
119                 while (list ($cid__,$vfid__) = rss_fetch_row($res)) {
120                     $cids[] = $cid__;
121                     $vfid = $vfid__;
122                 }
123             }
124         }
125     }
126
127     // date ?
128     if ($cid != ""
129             && array_key_exists('y',$_REQUEST) && $_REQUEST['y'] != "" && is_numeric($_REQUEST['y'])
130             && array_key_exists('m',$_REQUEST) && $_REQUEST['m'] != "" && is_numeric($_REQUEST['m'])) {
131         $y = (int) $_REQUEST['y'];
132         if ($y < 1000)
133             $y+=2000;
134
135         $m =  (int)$_REQUEST['m'];
136         if ($m > 12) {
137             $m = date("m");
138         }
139
140         $d =  (int)$_REQUEST['d'];
141         if ($d > 31) {
142             $d = date("d");
143         }
144     }
145
146
147
148     // lets see if theres an item id as well
149     $iid = "";
150     if ($cid != "" && array_key_exists('iid',$_REQUEST) && $_REQUEST['iid'] != "") {
151         $sqlid preg_replace("/[_';]/","%",sanitize($_REQUEST['iid'],RSS_SANITIZER_SIMPLE_SQL|RSS_SANITIZER_NO_SPACES));
152         $sql = "select id from " .getTable("item") ." i where i.title like '$sqlid' and i.cid=$cid";
153         if ($m > 0 && $y > 0) {
154             $sql .= " and month(ifnull(i.pubdate,i.added))= $m "
155                     ." and year(ifnull(i.pubdate, i.added))= $y ";
156
157             if ($d > 0) {
158                 $sql .= " and dayofmonth(ifnull(i.pubdate,i.added))= $d ";
159             }
160
161         }
162
163         if (hidePrivate()) {
164             $sql .=" and not(i.unread & " . RSS_MODE_PRIVATE_STATE .") ";
165         }
166
167         $sql .=" and not(i.unread & " . RSS_MODE_DELETED_STATE  .") ";
168         $sql .=" order by i.added desc, i.id asc";
169
170         $res rss_query( $sql );
171
172         if ( rss_num_rows ( $res ) >0) {
173             list($iid) = rss_fetch_row($res);
174         }
175     }
176     // no mod rewrite: ugly but effective
177 }
178 elseif (array_key_exists('channel',$_REQUEST) || array_key_exists('folder',$_REQUEST) || array_key_exists('vfolder',$_REQUEST)) {
179     $cid= (array_key_exists('channel',$_REQUEST))?sanitize($_REQUEST['channel'],RSS_SANITIZER_NUMERIC):"";
180     $iid= (array_key_exists('iid',$_REQUEST))?sanitize($_REQUEST['iid'],RSS_SANITIZER_NUMERIC):"";
181     $fid= (array_key_exists('folder',$_REQUEST))?sanitize($_REQUEST['folder'],RSS_SANITIZER_NUMERIC):"";
182     $vfid= (array_key_exists('vfolder',$_REQUEST))?sanitize($_REQUEST['vfolder'],RSS_SANITIZER_NUMERIC):"";
183     
184     $y= (array_key_exists('y',$_REQUEST))?sanitize($_REQUEST['y'],RSS_SANITIZER_NUMERIC):"0";
185     $m= (array_key_exists('m',$_REQUEST))?sanitize($_REQUEST['m'],RSS_SANITIZER_NUMERIC):"0";
186     $d= (array_key_exists('d',$_REQUEST))?sanitize($_REQUEST['d'],RSS_SANITIZER_NUMERIC):"0";
187
188     if ($fid) {
189         $sql = "select c.id from ". getTable('channels')." c "
190                ." where c.parent=$fid and c.parent > 0";
191         $sql .= " and not(c.mode & " RSS_MODE_DELETED_STATE .") ";
192
193         if (hidePrivate()) {
194             $sql .=" and not(c.mode & " . RSS_MODE_PRIVATE_STATE .") ";
195         }
196         $res = rss_query( $sql );
197
198         if ( rss_num_rows ( $res ) > 0) {
199             $cids = array();
200             while (list ($cid__) = rss_fetch_row($res)) {
201                 $cids[] = $cid__;
202             }
203         }
204     }
205     elseif ($vfid) {
206         $sql = "select c.id, m.tid from ". getTable('channels')." c "
207                ."inner join " . getTable('metatag') . " m on m.fid = c.id "
208                ."inner join " . getTable('tag') . " t on t.id = m.tid "
209                . "where m.ttype = 'channel'";
210         // $vfid can be numeric (t.id) or alphabetic (t.tag)
211         if(is_numeric($vfid)) {
212             $sql .= "and t.id = $vfid";
213         } else {
214             $sql .= "and t.tag like '$vfid'";
215         }
216         $sql .= " and not(c.mode & " RSS_MODE_DELETED_STATE .") ";
217
218         if (hidePrivate()) {
219             $sql .=" and not(c.mode & " . RSS_MODE_PRIVATE_STATE .") ";
220         }
221         $res = rss_query( $sql );
222
223         if ( rss_num_rows ( $res ) > 0) {
224             $cids = array();
225             while (list ($cid__,$vfid__) = rss_fetch_row($res)) {
226                 $cids[] = $cid__;
227                 $vfid = $vfid__;
228             }
229         }
230     }
231     elseif ($cid) {
232         if (hidePrivate()) {
233             $sql = "select id from ". getTable('channels')." where id=$cid ";
234             $sql .=" and not(mode & " . RSS_MODE_PRIVATE_STATE .") ";
235             list ($cid) = rss_fetch_row(rss_query($sql));
236         }
237     }
238 }
239 elseif (
240     array_key_exists('y',$_REQUEST) && $_REQUEST['y'] != "" && is_numeric($_REQUEST['y'])
241     && array_key_exists('m',$_REQUEST) && $_REQUEST['m'] != "" && is_numeric($_REQUEST['m'])
242     && array_key_exists('d',$_REQUEST) && $_REQUEST['d'] != "" && is_numeric($_REQUEST['d'])
243 )   {
244
245     $y = (int) sanitize($_REQUEST['y'],RSS_SANITIZER_NUMERIC);
246     if ($y < 1000)
247         $y+=2000;
248
249     $m =  (int) sanitize($_REQUEST['m'],RSS_SANITIZER_NUMERIC);
250     if ($m > 12) {
251         $m = date("m");
252     }
253
254     $d =  (int) sanitize($_REQUEST['d'],RSS_SANITIZER_NUMERIC);
255     if ($d > 31) {
256         $d = date("d");
257     }
258     $iid = $cid  = null;
259 }
260
261 // If we have no channel-id something went terribly wrong.
262 // Send a 404.
263 if (
264     // channel id:
265     (
266         // not set
267         !isset($cid)     ||
268         // ...or empty
269         $cid == ""         ||
270         // or not numeric while mod_rewrite is off
271         (
272             !getConfig('rss.output.usemodrewrite') && !is_numeric($cid)
273         )
274     )
275
276     &&
277     // folder id
278     (
279         // not set
280         !isset($cids) ||
281         // not an array of ids
282         !is_array($cids) ||
283         // zero elements
284         !count($cids)
285     )
286
287     &&
288     // virtual folder id
289     (!isset($vfid))
290
291     &&
292     // date?
293     ($d == 0 && $m == 0 && $y == 0)
294 ) {
295     rss_404();
296     exit;
297 }
298 //echo ("cid=".(isset($cid)?"$cid":"") . " fid=" . (isset($fid)?"$fid":""));
299
300 if (isLoggedIn() && array_key_exists ('metaaction', $_REQUEST)) {
301
302     if (array_key_exists('markreadids',$_POST)) {
303         $IdsToMarkAsRead = explode(",",rss_real_escape_string($_POST['markreadids']));
304         //var_dump($IdsToMarkAsRead);
305     } else {
306         $IdsToMarkAsRead = array();
307     }
308     switch ($_REQUEST['metaaction']) {
309
310     case  'ACT_MARK_CHANNEL_READ':
311
312         /** mark channel as read **/
313         $sql = "update " .getTable("item")
314                ." set unread = unread & ".SET_MODE_READ_STATE." where cid=$cid";
315         if (hidePrivate()) {
316             $sql .= " and not(unread & " . RSS_MODE_PRIVATE_STATE . ")";
317         }
318         if (count($IdsToMarkAsRead)) {
319             $sql .= " and id in (" . implode(',',$IdsToMarkAsRead) .")";
320         }
321         rss_query($sql);
322
323         rss_invalidate_cache();
324
325         /* Redirect! If this feed has more unread items, self-redirect */
326
327         $sql = "select count(*) from " .getTable("item") . " i "
328                ." where i.unread & " .RSS_MODE_UNREAD_STATE
329                ." and i.cid=$cid"
330                ." and not(i.unread & " . RSS_MODE_DELETED_STATE  .") "
331                ;
332         if (hidePrivate()) {
333             $sql .=" and not(i.unread & " . RSS_MODE_PRIVATE_STATE .") ";
334         }
335         list($hasMoreUnreads) = rss_fetch_row(rss_query($sql));
336
337
338         //more unread items in this feed?
339         if ($hasMoreUnreads) {
340             $next_unread_id=$cid;
341
342         } else {
343
344             /*
345                 Find where we should redirect
346                  - The next feed in the list with unread items, or, failing that:
347                  - The first feed in the list with unread items, or, faling that:
348                  - The main page
349             */
350
351             // 1: build a list of all feeds:
352             $feeds = array();
353             $sql = "select c.id from " . getTable('channels') . " c "
354                    ."inner join " . getTable('folders') . " f on f.id = c.parent "
355                    . "where not (c.mode & " . RSS_MODE_DELETED_STATE .") ";
356
357             if (hidePrivate()) {
358                 $sql .= " and not (c.mode & " . RSS_MODE_PRIVATE_STATE . ") ";
359             }
360             if (getConfig('rss.config.absoluteordering')) {
361                 $sql .= " order by f.position asc, c.position asc";
362             } else {
363                 $sql .=" order by f.name asc, c.title asc";
364             }
365             $res = rss_query($sql);
366             while (list($cid__) = rss_fetch_row($res)) {
367                 $feeds[$cid__] = 0;
368             }
369
370             // 2: Get the unread count for each feed:
371             $sql = "select cid, count(*) from " .getTable('item')
372                    ." where (unread & ".RSS_MODE_UNREAD_STATE . ") "
373                    ." and not (unread & " .RSS_MODE_DELETED_STATE . ") ";
374             if (hidePrivate()) {
375                 $sql .= " and not (unread & " . RSS_MODE_PRIVATE_STATE . ") ";
376             }
377             $sql .= " group by cid";
378             $res = rss_query($sql);
379             while (list($cid__,$uc__) = rss_fetch_row($res)) {
380                 // this makes sure only the feeds that were gathered in the
381                 // last query are put into this array.. fixes #305
382                 if(array_key_exists($cid__, $feeds)) {
383                     $feeds[$cid__] = $uc__;
384                 }
385             }
386
387             // 3: iterate over the feeds and see where we should redirect.
388             $found = false;
389             $first_unread_id = $next_unread_id = 0;
390             foreach($feeds as $cid__ => $cnt) {
391                 // reached the feed we're coming from?
392                 if ($cid == $cid__) {
393                     $found = true;
394                 }
395                 // if not yet, get a hold of the first in the list with unread items
396                 if ($cnt && !$first_unread_id) {
397                     $first_unread_id = $cid__;
398                 }
399
400                 // passed the previous feed? We got a winner!
401                 if ($cnt && $found) {
402                     $next_unread_id = $cid__;
403                     break;
404                 }
405             }
406
407             // found none after the previous feed, but there is on on top
408             if (!$next_unread_id && $first_unread_id) {
409                 $next_unread_id = $first_unread_id;
410             }
411         }
412
413         //redirect
414         if (!$next_unread_id) {
415             rss_redirect();
416         } else {
417             $cid = $next_unread_id;
418         }
419
420         break;
421
422         // folder
423     case 'ACT_MARK_FOLDER_READ':
424         $fid = sanitize($_REQUEST['folder'],RSS_SANITIZER_NUMERIC);
425         $rs  = rss_query("select id from " .getTable('channels') . " where parent=$fid");
426         $cids_ = array();
427         while(list($cid_) = rss_fetch_row($rs)) {
428             $cids_[]=$cid_;
429         }
430         
431         
432         $sql = "update " .getTable('item')
433                . " set unread = unread & ".SET_MODE_READ_STATE
434                . " where cid  in (" .implode(',', $cids_) . ") ";
435           unset($cids_);
436         if (count($IdsToMarkAsRead)) {
437             $sql .= " and id in (" . implode(',',$IdsToMarkAsRead) .")";
438         }
439
440         //die($sql);
441         rss_query($sql);
442
443         rss_invalidate_cache();
444
445         $next_fid = $first_fid = 0;
446         $found = false;
447         $res = rss_query( " select id from " .getTable('folders') ." f order by "
448                           .(getConfig('rss.config.absoluteordering')?" f.position asc":"f.name asc")
449                         );
450
451         while (list($fid__) = rss_fetch_row($res)) {
452             if($fid__ == $fid) {
453                 $found = true;
454             }
455             
456             if( $found || !$first_fid ) {
457                 $sql = "select count(*) from " . getTable('item') ." i "
458                        ."inner join " . getTable('channels') ." c on c.id = i.cid "
459                        ." where i.unread & " .RSS_MODE_UNREAD_STATE ." and c.parent = $fid__";
460                 if (hidePrivate()) {
461                     $sql .= " and not(i.unread & " . RSS_MODE_PRIVATE_STATE . ")";
462                 }
463     
464                 list($c) = rss_fetch_row(rss_query($sql));
465                 //echo "$fid__ -> $c\n";
466
467                 if ($c > 0) {
468                     if (!$first_fid)
469                         $first_fid = $fid__;
470                     if ($found) {
471                         $next_fid = $fid__;
472                         break;
473                     }
474                 }
475             }
476         }
477         
478         if( !$next_fid && $first_fid )
479             $next_fid = $first_fid;
480
481         if ( $next_fid ) {
482             $fid = $next_fid;
483             $sql = "select id from " . getTable('channels') ." where parent=$fid";
484             $res = rss_query(